1 2 document.addEventListener('DOMContentLoaded', function() { 3 (function() { 4 var items = [].slice.call(document.querySelectorAll('#inside-acc .inside-item')); 5 var labels = [].slice.call(document.querySelectorAll('.inside-labels span')); 6 var sceneEl = document.getElementById('inside-scene'); 7 var sectionEl = document.querySelector('.inside-section'); 8 if (!items.length || !sceneEl) return; 9 10 var STATES = ['ui', 'exec', 'solana']; 11 var SLOTS = { ui: ['uiLeft', 'uiRight'], exec: ['execChain'], solana: ['solanaBase'] }; 12 13 (function buildNodes() { 14 var host = sceneEl.querySelector('.xt-nodes'); 15 if (!host) return; 16 var SQUASH = 0.58, TILT = -3.3 * Math.PI / 180; 17 var ORBITS = [{ r: 74, n: 6, phase: 0 }, { r: 124, n: 8, phase: 0.4 }, { r: 172, n: 10, phase: 0.2 }]; 18 var REACH = 180, WAVE = 2.0; 19 var frag = document.createDocumentFragment(); 20 ORBITS.forEach(function (o) { 21 var ring = document.createElement('b'); 22 ring.style.width = (o.r * 2) + 'px'; 23 ring.style.height = (o.r * 2 * SQUASH) + 'px'; 24 ring.style.margin = (-o.r * SQUASH) + 'px 0 0 ' + (-o.r) + 'px'; 25 frag.appendChild(ring); 26 for (var k = 0; k < o.n; k++) { 27 var t = (k / o.n + o.phase) * Math.PI * 2; 28 var ex = o.r * Math.cos(t), ey = o.r * SQUASH * Math.sin(t); 29 var dot = document.createElement('i'); 30 dot.style.left = (ex * Math.cos(TILT) - ey * Math.sin(TILT)).toFixed(1) + 'px'; 31 dot.style.top = (ex * Math.sin(TILT) + ey * Math.cos(TILT)).toFixed(1) + 'px'; 32 dot.style.setProperty('--delay', (Math.min(1, o.r / REACH) * WAVE).toFixed(2) + 's'); 33 frag.appendChild(dot); 34 } 35 }); 36 host.appendChild(frag); 37 })(); 38 var slabs = {}; 39 STATES.forEach(function (s) { slabs[s] = sceneEl.querySelector('.xt-slab[data-state="' + s + '"]'); }); 40 var conns = {}, pills = {}; 41 42 var extras = []; 43 [].forEach.call(sceneEl.querySelectorAll('.xt-conn'), function (el) { conns[el.getAttribute('data-slot')] = el; }); 44 [].forEach.call(sceneEl.querySelectorAll('.xt-ripple, .xt-nodes'), function (el) { extras.push(el); }); 45 [].forEach.call(sceneEl.querySelectorAll('.xt-pill-wrap'), function (el) { pills[el.getAttribute('data-slot')] = el; }); 46 47 var DUR = 5900, cur = -1, timer = null, inView = true; 48 var hasGsap = (typeof gsap !== 'undefined'); 49 50 function show(i) { 51 if (i === cur) return; 52 cur = i; 53 var st = STATES[i]; 54 items.forEach(function (it, k) { 55 it.classList.toggle('active', k === i); 56 var h = it.querySelector('.inside-head'); 57 if (h) h.setAttribute('aria-expanded', k === i ? 'true' : 'false'); 58 }); 59 items.forEach(function (it, k) { 60 var bar = it.querySelector('.inside-progress > span'); 61 if (!bar) return; 62 if (hasGsap) { 63 gsap.killTweensOf(bar); 64 if (k === i) gsap.fromTo(bar, { width: '0%' }, { width: '100%', duration: DUR / 1000, ease: 'none' }); 65 else gsap.set(bar, { width: '0%' }); 66 } else { 67 bar.style.transition = 'none'; bar.style.width = '0%'; 68 if (k === i) { void bar.offsetWidth; bar.style.transition = 'width ' + (DUR / 1000) + 's linear'; bar.style.width = '100%'; } 69 } 70 }); 71 STATES.forEach(function (s) { slabs[s].classList.toggle('on', s === st); });
72 Object.keys(conns).forEach(function (key) { 73 var on = SLOTS[st].indexOf(key) > -1; 74 conns[key].classList.toggle('on', on); 75 if (pills[key]) pills[key].classList.toggle('on', on); 76 }); 77 extras.forEach(function (el) { 78 79 el.classList.remove('on'); 80 if (SLOTS[st].indexOf(el.getAttribute('data-slot')) > -1) { 81 void el.offsetWidth; 82 el.classList.add('on'); 83 } 84 }); 85 labels.forEach(function (l, k) { l.classList.toggle('on', k === i); }); 86 if (timer) clearTimeout(timer); 87 if (inView) timer = setTimeout(function () { show((cur + 1) % 3); }, DUR); 88 } 89 90 items.forEach(function (it) { 91 it.addEventListener('click', function () { show(+it.getAttribute('data-i')); }); 92 var h = it.querySelector('.inside-head'); 93 if (h) h.addEventListener('keydown', function (e) { 94 if (e.key === 'Enter' || e.key === ' ' || e.key === 'Spacebar') { e.preventDefault(); show(+it.getAttribute('data-i')); } 95 }); 96 }); 97 labels.forEach(function (l, k) { l.addEventListener('click', function () { show(k); }); }); 98 99 if (sectionEl && 'IntersectionObserver' in window) { 100 new IntersectionObserver(function (es) { 101 inView = es[0].isIntersecting; 102 if (!inView) { if (timer) { clearTimeout(timer); timer = null; } } 103 else if (!timer && cur !== -1) { timer = setTimeout(function () { show((cur + 1) % 3); }, DUR); } 104 }, { threshold: 0 }).observe(sectionEl); 105 } 106 107 show(0); 108 })(); 109 110 (function () { 111 var canvas = document.getElementById('security-3d-canvas'); 112 if (!canvas) return; 113 var section = document.getElementById('security'); 114 115 function withThree(cb) { 116 if (window.THREE && THREE.GLTFLoader) return cb(); 117 var s = document.createElement('script'); 118 s.src = '/assets/js/vendor/three.min.js'; 119 s.onload = function () { 120 var script = document.createElement('script'); 121 script.src = '/assets/js/vendor/GLTFLoader.js'; 122 script.onload = cb; 123 document.head.appendChild(script); 124 }; 125 document.head.appendChild(s); 126 } 127 128 var started = false; 129 function start() { 130 if (started) return; 131 started = true; 132 133 var reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches; 134 135 var renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true, alpha: true }); 136 renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); 137 renderer.outputEncoding = THREE.sRGBEncoding; 138 renderer.toneMapping = THREE.ACESFilmicToneMapping; 139 renderer.toneMappingExposure = 0.80; 140 141 var scene = new THREE.Scene(); 142 143 var camera = new THREE.PerspectiveCamera(30, 1, 0.1, 100); 144 camera.position.set(0, 1.45, 4.0); 145 camera.lookAt(0, -0.1, 0); 146 147 (function buildEnv() { 148 var ec = document.createElement('canvas'); ec.width = 128; ec.height = 64; 149 var x = ec.getContext('2d'); 150 var g = x.createLinearGradient(0, 0, 0, 64); 151 g.addColorStop(0.00, '#080b11'); 152 g.addColorStop(0.40, '#283242'); 153 g.addColorStop(0.50, '#3c4a5e'); 154 g.addColorStop(0.60, '#1d242f'); 155 g.addColorStop(1.00, '#05070a'); 156 x.fillStyle = g; x.fillRect(0, 0, 128, 64);
157 var envTex = new THREE.CanvasTexture(ec); 158 envTex.mapping = THREE.EquirectangularReflectionMapping; 159 var pmrem = new THREE.PMREMGenerator(renderer); 160 var rt = pmrem.fromEquirectangular(envTex); 161 scene.environment = rt.texture; 162 envTex.dispose(); pmrem.dispose(); 163 })(); 164 165 var amb = new THREE.AmbientLight(0x0e141c, 0.16); scene.add(amb); 166 var key = new THREE.DirectionalLight(0xeaf2ff, 3.0); key.position.set(-4.5, 3.2, 3.5); scene.add(key); 167 var rim = new THREE.DirectionalLight(0xffffff, 2.1); rim.position.set(4, 3.5, -4); scene.add(rim); 168 var accent = new THREE.DirectionalLight(0x4cd7f4, 0.28); accent.position.set(-5, 1.5, 3); scene.add(accent); 169 170 var BASE_RX = 0.58, BASE_RY = 0.20; 171 var holder = new THREE.Group(); 172 holder.rotation.x = BASE_RX; 173 holder.rotation.y = BASE_RY; 174 scene.add(holder); 175 176 var LOGO_OUTLINE = [[-0.1966,-0.437],[0.2479,-0.4177],[0.1118,-0.0679],[0.1524,-0.0273], 177 [0.4232,-0.0079],[0.2485,0.3606],[-0.1959,0.3606],[-0.1959,0.3028],[-0.059,-0.0102], 178 [-0.0995,-0.0507],[-0.3705,-0.07]]; 179 function buildRoundedLogoGeo() { 180 var pts = LOGO_OUTLINE.map(function (p) { return new THREE.Vector2(p[0], -p[1]); }); 181 var shape = new THREE.Shape(), n = pts.length, R = 0.05; 182 for (var i = 0; i < n; i++) { 183 var prev = pts[(i - 1 + n) % n], cur = pts[i], next = pts[(i + 1) % n]; 184 var v1 = cur.clone().sub(prev), v2 = next.clone().sub(cur); 185 var rr = Math.min(R, v1.length() * 0.45, v2.length() * 0.45); 186 v1.normalize(); v2.normalize(); 187 var pIn = cur.clone().addScaledVector(v1, -rr); 188 var pOut = cur.clone().addScaledVector(v2, rr); 189 if (i === 0) shape.moveTo(pIn.x, pIn.y); else shape.lineTo(pIn.x, pIn.y); 190 shape.quadraticCurveTo(cur.x, cur.y, pOut.x, pOut.y); 191 } 192 shape.closePath(); 193 var g = new THREE.ExtrudeGeometry(shape, { depth: 0.03, bevelEnabled: false, curveSegments: 6 }); 194 g.rotateX(-Math.PI / 2); 195 g.computeVertexNormals(); 196 return g; 197 } 198 199 var loader = new THREE.GLTFLoader(); 200 var basePath = '/assets/inside/'; 201 loader.load(basePath + 'platform_shield_zexo.glb', function (gltf) { 202 var model = gltf.scene; 203 204 model.scale.set(1, 1, 1); 205 206 var box = new THREE.Box3().setFromObject(model); 207 var center = box.getCenter(new THREE.Vector3()); 208 model.position.sub(center); 209 210 model.traverse(function (o) { 211 if (!o.isMesh || !o.material) return; 212 var m = o.material; 213 if (m.name === 'WhiteLogoMat') { 214 m.emissive = new THREE.Color(0xffffff); 215 m.emissiveIntensity = 2.15; 216 m.side = THREE.DoubleSide; 217 o.geometry.dispose(); 218 o.geometry = buildRoundedLogoGeo(); 219 } else if (m.name === 'ContactShadowMat') { 220 o.visible = false; 221 } else if (m.name === 'ShieldRimMat') { 222 223 m.roughness = 0.23; 224 m.envMapIntensity = 1.35; 225 } else { 226 227 var pm = new THREE.MeshPhysicalMaterial({ 228 color: m.color.clone(), metalness: m.metalness, 229 roughness: 0.36, envMapIntensity: 0.62, 230 clearcoat: 0.7, clearcoatRoughness: 0.26 231 }); 232 pm.name = 'ShieldBaseMat'; 233 o.material = m = pm; 234 } 235 m.needsUpdate = true; 236 }); 237 holder.add(model); 238 }); 239 240 function resize() { 241 var w = canvas.clientWidth, h = canvas.clientHeight; 242 if (!w || !h) return; 243 camera.aspect = w / h; 244 camera.updateProjectionMatrix(); 245 renderer.setSize(w, h, false); 246 } 247 window.addEventListener('resize', resize); 248 resize(); 249 250 var running = true, raf = null; 251 function loop() { 252 if (!running) { raf = null; return; } 253 raf = requestAnimationFrame(loop); 254 if (!reduce) { 255 256 var t = performance.now() * 0.001; 257 holder.rotation.y = BASE_RY + Math.sin(t * 0.40) * 0.17; 258 holder.rotation.x = BASE_RX + Math.sin(t * 0.29) * 0.03; 259 } 260 renderer.render(scene, camera); 261 } 262 function play() { if (!running) { running = true; } if (!raf) loop(); } 263 function pause() { running = false; } 264 265 if ('IntersectionObserver' in window) { 266 new IntersectionObserver(function (es) {
267 es.forEach(function (e) { e.isIntersecting ? play() : pause(); }); 268 }, { rootMargin: '100px' }).observe(section || canvas); 269 } 270 loop(); 271 } 272 273 if ('IntersectionObserver' in window) { 274 var io = new IntersectionObserver(function (es) { 275 es.forEach(function (e) { if (e.isIntersecting) { withThree(start); io.disconnect(); } }); 276 }, { rootMargin: '300px' }); 277 io.observe(section || canvas); 278 279 var warmThree = function () { 280 var idle = window.requestIdleCallback || function (f) { return setTimeout(f, 2500); }; 281 idle(function () { withThree(function () {}); }, { timeout: 6000 }); 282 }; 283 if (document.readyState === 'complete') setTimeout(warmThree, 1500); 284 else window.addEventListener('load', function () { setTimeout(warmThree, 1500); }, { once: true }); 285 } else { 286 withThree(start); 287 } 288 })(); 289 }); 290 291 function toggleMenu() { 292 const panel = document.querySelector('.menu-panel'); 293 const overlay = document.querySelector('.menu-overlay'); 294 const btn = document.querySelector('.hamburger-btn'); 295 const isOpen = panel.classList.contains('active'); 296 if (isOpen) { 297 panel.classList.remove('active'); 298 overlay.classList.remove('active'); 299 btn.classList.remove('active'); 300 btn.setAttribute('aria-expanded', 'false'); 301 document.body.style.overflow = ''; 302 } else { 303 panel.classList.add('active'); 304 overlay.classList.add('active'); 305 btn.classList.add('active'); 306 btn.setAttribute('aria-expanded', 'true'); 307 document.body.style.overflow = 'hidden'; 308 } 309 } 310 311 document.addEventListener('keydown', function (e) { 312 if (e.key !== 'Escape') return; 313 var panel = document.querySelector('.menu-panel'); 314 if (panel && panel.classList.contains('active')) { 315 toggleMenu(); 316 var btn = document.querySelector('.hamburger-btn'); 317 if (btn) btn.focus(); 318 } 319 }); 320 321 [].slice.call(document.querySelectorAll('.nav-dropdown')).forEach(function(dd) { 322 var btn = dd.querySelector('.nav-dropdown-btn'); 323 if (!btn) return; 324 function sync() { 325 var open = dd.matches(':hover') || dd.contains(document.activeElement); 326 btn.setAttribute('aria-expanded', open ? 'true' : 'false'); 327 } 328 ['mouseenter', 'mouseleave', 'focusin', 'focusout'].forEach(function(ev) { 329 dd.addEventListener(ev, sync); 330 }); 331 dd.addEventListener('keydown', function(e) { 332 if (e.key === 'Escape') { btn.focus(); document.activeElement.blur(); } 333 }); 334 }); 335 (function () { 336 var host = document.querySelector('.hero-rays-gl'); 337 if (!host) return; 338 339 if (!(window.matchMedia && window.matchMedia('(max-width: 768px)').matches)) return; 340 341 var glowZone = document.querySelector('.hero-glow-mobile'); 342 if (!glowZone || (window.getComputedStyle && getComputedStyle(glowZone).display === 'none')) return; 343 344 var s = document.createElement('script'); 345 s.src = '/assets/js/rays-core.js?v=2529'; 346 s.onload = mount; 347 document.head.appendChild(s); 348 349 function mount() { 350 if (typeof JetRays !== 'function') return; 351 352 var rays = JetRays(host, { 353 strips: 'bottom', 354 frame: false, 355 colors: ['#4cd7f4', '#325249'], 356 speed: 1.6, 357 brightness: 2.6, 358 noiseOpacity: 0.4,
359 stripHeight: 320 360 }); 361 if (!rays || !rays.supported) return; 362 363 var fallback = document.querySelector('.hero-rays'); 364 if (fallback) fallback.style.display = 'none'; 365 366 var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches; 367 if (!reduce && 'IntersectionObserver' in window) { 368 var io = new IntersectionObserver(function (entries) { 369 entries.forEach(function (e) { if (e.isIntersecting) { rays.play(); } else { rays.pause(); } }); 370 }, { rootMargin: '120px' }); 371 io.observe(document.getElementById('hero') || host); 372 } 373 } 374 })(); 375 (function(){ 376 var sec = document.getElementById('callouts'); 377 var box = document.getElementById('callouts-lottie'); 378 if(!sec || !box) return; 379 380 var stage = document.getElementById('callouts-lottie-stage') || box; 381 var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches; 382 var anim = null, started = false; 383 function ensureLottie(cb){ 384 if(window.lottie) return cb(); 385 var s = document.createElement('script'); 386 s.src = '/assets/js/lottie_svg.min.js'; 387 s.onload = cb; document.head.appendChild(s); 388 } 389 390 var coarse = window.matchMedia && window.matchMedia('(hover: none) and (pointer: coarse)').matches; 391 var scenePath = coarse ? '/assets/callouts/hero-touch.json?v=2782' 392 : '/assets/callouts/hero.json?v=2782'; 393 function start(){ 394 if(started) return; started = true; 395 ensureLottie(function(){ 396 anim = lottie.loadAnimation({ container:stage, renderer:'svg', 397 loop:!reduce, autoplay:false, path:scenePath }); 398 window.__calloutsLottie = anim; 399 anim.addEventListener('DOMLoaded', function(){ 400 401 anim.setSubframe(false); 402 if(reduce){ anim.goToAndStop(0, true); return; } 403 404 resume(); 405 }); 406 }); 407 } 408 409 if(reduce){ start(); return; } 410 411 var warm = function(){ 412 var idle = window.requestIdleCallback || function(f){ return setTimeout(f, 1200); }; 413 414 idle(function(){ start(); }, { timeout: 3000 }); 415 }; 416 if(document.readyState === 'complete') warm(); 417 else window.addEventListener('load', warm, { once:true }); 418 419 var inView = false, scrolling = false, idle = 0; 420 421 var canPark = window.CSS && CSS.supports && CSS.supports('content-visibility', 'hidden'); 422 function park(on){ if(canPark) box.classList.toggle('is-parked', !!on); } 423 function resume(){ if(anim && inView && !scrolling) anim.play(); } 424 function suspend(){ if(anim) anim.pause(); } 425 park(true); 426 427 var io = new IntersectionObserver(function(entries){ 428 entries.forEach(function(e){ 429 inView = e.isIntersecting; 430 if(inView){ park(false); start(); resume(); } 431 else { suspend(); park(true); } 432 }); 433 }, { rootMargin:'600px' }); 434 io.observe(sec); 435 436 window.addEventListener('scroll', function(){ 437 if(!scrolling){ scrolling = true; suspend(); } 438 clearTimeout(idle); 439 idle = setTimeout(function(){ scrolling = false; resume(); }, 180); 440 }, { passive:true }); 441 })(); 442 (function(){ 443 var card = document.querySelector('.signal-card'); 444 var svg = document.getElementById('signal-candles'); 445 var chart = document.getElementById('signal-chart'); 446 if(!card || !svg || !chart) return; 447 var NS='http://www.w3.org/2000/svg'; 448 var W=182,H=120,padX=12,padTop=8,padBot=8; 449 var C=[ 450 {o:52,c:60,h:64,l:50},{o:60,c:55,h:62,l:52},{o:55,c:68,h:71,l:53}, 451 {o:68,c:62,h:70,l:58},{o:62,c:44,h:66,l:40},{o:44,c:34,h:46,l:30}, 452 {o:34,c:50,h:53,l:32},{o:50,c:58,h:61,l:48},{o:58,c:65,h:69,l:56} 453 ]; 454 var n=C.length, slot=(W-padX*2)/n, bw=Math.min(12, slot*0.5); 455 function y(p){ return padTop + (1-p/100)*(H-padTop-padBot); } 456 function cx(i){ return padX + slot*(i+0.5); } 457 var GREEN='#26d07c', RED='#f6465d'; 458 var BASE=y(0); 459 var candleEls=[];
460 C.forEach(function(d,i){ 461 var up=d.c>=d.o, col=up?GREEN:RED, x=cx(i); 462 var gEl=document.createElementNS(NS,'g'); 463 var wick=document.createElementNS(NS,'line'); 464 wick.setAttribute('x1',x); wick.setAttribute('x2',x); 465 wick.setAttribute('y1',y(d.h)); wick.setAttribute('y2',y(d.l)); 466 wick.setAttribute('stroke',col); wick.setAttribute('stroke-width','1.2'); 467 gEl.appendChild(wick); 468 var top=y(Math.max(d.o,d.c)), bot=y(Math.min(d.o,d.c)); 469 var body=document.createElementNS(NS,'rect'); 470 body.setAttribute('x',x-bw/2); body.setAttribute('y',top); 471 body.setAttribute('width',bw); body.setAttribute('height',Math.max(2,bot-top)); 472 body.setAttribute('rx','1.5'); body.setAttribute('fill',col); 473 gEl.appendChild(body); 474 svg.appendChild(gEl); 475 candleEls.push({el:gEl,x:x}); 476 }); 477 478 var volTop=86, volBot=114, VOL=[0.45,0.38,0.66,0.5,0.92,1.0,0.72,0.5,0.8], volEls=[]; 479 C.forEach(function(d,i){ 480 var up=d.c>=d.o, col=up?GREEN:RED, x=cx(i);
481 var vh=Math.max(2, VOL[i]*(volBot-volTop)); 482 var vg=document.createElementNS(NS,'g'); 483 var vbar=document.createElementNS(NS,'rect'); 484 vbar.setAttribute('x',x-bw/2); vbar.setAttribute('y',volBot-vh); 485 vbar.setAttribute('width',bw); vbar.setAttribute('height',vh); 486 vbar.setAttribute('rx','1'); vbar.setAttribute('fill',col); vbar.setAttribute('opacity','0.4'); 487 vg.appendChild(vbar); svg.appendChild(vg); 488 volEls.push({el:vg,x:x}); 489 }); 490 var avatars=['assets/images/callouts_icon1.webp','assets/images/callouts_icon2.webp','assets/images/callouts_icon3.webp']; 491 var sigIdx=[2,5,7], bubbles=[]; 492 sigIdx.forEach(function(ci,k){ 493 var x=cx(ci), highY=y(C[ci].h); 494 var b=document.createElement('div'); b.className='signal-bubble'; 495 b.style.left=(x/W*100)+'%'; 496 var ping=document.createElement('div'); ping.className='signal-bubble-ping'; 497 var img=document.createElement('div'); img.className='signal-bubble-av'; 498 499 img.style.backgroundImage='url('+avatars[k%avatars.length]+')'; 500 img.style.opacity='0'; 501 var line=document.createElement('div'); line.className='signal-bubble-line'; 502 line.style.height=Math.max(6, highY-28)+'px'; line.style.transform='scaleY(0)'; 503 b.appendChild(ping); b.appendChild(img); b.appendChild(line); 504 chart.appendChild(b); 505 bubbles.push({img:img,line:line,ping:ping}); 506 }); 507 var imgs=bubbles.map(function(b){return b.img;}); 508 var lines=bubbles.map(function(b){return b.line;}); 509 var pings=bubbles.map(function(b){return b.ping;}); 510 var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches; 511 if(reduce){ 512 card.style.opacity='1'; 513 imgs.forEach(function(im){ im.style.opacity='1'; }); 514 lines.forEach(function(ln){ ln.style.transform='scaleY(1)'; }); 515 return; 516 } 517 function whenGsap(cb){ if(window.gsap) return cb(); setTimeout(function(){whenGsap(cb);},120); } 518 whenGsap(function(){ 519 var g=window.gsap; 520 521 g.set(imgs,{scale:0,opacity:0,transformOrigin:'center center'}); 522 g.set(lines,{scaleY:0}); 523 g.set(pings,{scale:0.5,opacity:0,transformOrigin:'center center'}); 524 candleEls.forEach(function(c){ g.set(c.el,{scaleY:0, svgOrigin:c.x+' '+BASE}); }); 525 volEls.forEach(function(v){ g.set(v.el,{scaleY:0, svgOrigin:v.x+' '+volBot}); }); 526 var content=g.timeline({paused:true}); 527 528 candleEls.forEach(function(c,i){ 529 content.to(c.el,{scaleY:1,duration:0.5,ease:'power3.out'}, i*0.05); 530 content.to(volEls[i].el,{scaleY:1,duration:0.45,ease:'power3.out'}, i*0.05+0.04); 531 }); 532 533 bubbles.forEach(function(bb,idx){ 534 var at=0.6 + idx*0.42; 535 content.to(bb.line,{scaleY:1,duration:0.3,ease:'power2.out'}, at); 536 content.fromTo(bb.ping,{scale:0.5,opacity:0.6},{scale:2,opacity:0,duration:0.6,ease:'power2.out'}, at+0.06); 537 content.to(bb.img,{scale:1,opacity:1,duration:0.42,ease:'back.out(1.6)'}, at+0.1); 538 }); 539 540 (window.__hubCards||(window.__hubCards=[])).push({el:card, tl:content, frame:11}); 541 }); 542 })(); 543 (function(){ 544 function whenGsap(cb){ if(window.gsap) return cb(); setTimeout(function(){whenGsap(cb);},120); } 545 whenGsap(function(){ 546 547 var PATH=[ 548 {t:0.0,x:738.0,y:286.0,s:0.0,o:0.0},{t:0.067,x:738.0,y:286.0,s:0.0,o:0.0},{t:0.133,x:738.0,y:286.0,s:0.0,o:0.0}, 549 {t:0.2,x:745.7,y:283.0,s:0.053,o:1.0},{t:0.267,x:766.4,y:276.9,s:0.16,o:1.0},{t:0.333,x:787.1,y:270.8,s:0.267,o:1.0}, 550 {t:0.4,x:807.8,y:264.7,s:0.373,o:1.0},{t:0.467,x:828.5,y:258.6,s:0.48,o:1.0},{t:0.533,x:849.1,y:252.6,s:0.587,o:1.0}, 551 {t:0.6,x:869.8,y:246.5,s:0.693,o:1.0},{t:0.667,x:890.5,y:240.4,s:0.8,o:1.0},{t:0.733,x:901.7,y:239.9,s:0.808,o:1.0}, 552 {t:0.8,x:912.7,y:239.5,s:0.816,o:1.0},{t:0.867,x:923.7,y:239.0,s:0.824,o:1.0},{t:0.933,x:934.8,y:238.6,s:0.832,o:1.0}, 553 {t:1.0,x:945.8,y:238.1,s:0.84,o:1.0},{t:1.067,x:956.9,y:237.7,s:0.848,o:1.0},{t:1.133,x:967.9,y:237.2,s:0.856,o:1.0}, 554 {t:1.2,x:978.9,y:236.8,s:0.864,o:1.0},{t:1.267,x:990.0,y:236.3,s:0.872,o:1.0},{t:1.333,x:1001.0,y:235.8,s:0.88,o:1.0}, 555 {t:1.4,x:1012.0,y:235.4,s:0.888,o:1.0},{t:1.467,x:1023.1,y:234.9,s:0.896,o:1.0},{t:1.533,x:1034.1,y:234.5,s:0.904,o:1.0},
556 {t:1.6,x:1045.2,y:234.0,s:0.912,o:1.0},{t:1.667,x:1056.2,y:233.6,s:0.92,o:1.0},{t:1.733,x:1067.2,y:233.1,s:0.928,o:1.0}, 557 {t:1.8,x:1078.3,y:232.6,s:0.936,o:1.0},{t:1.867,x:1089.3,y:232.2,s:0.944,o:1.0},{t:1.933,x:1100.3,y:231.7,s:0.952,o:1.0}, 558 {t:2.0,x:1111.4,y:231.3,s:0.96,o:1.0},{t:2.067,x:1122.4,y:230.8,s:0.968,o:1.0},{t:2.133,x:1133.5,y:230.4,s:0.976,o:1.0}, 559 {t:2.2,x:1144.5,y:229.9,s:0.984,o:1.0},{t:2.267,x:1155.5,y:229.5,s:0.992,o:1.0},{t:2.333,x:1166.6,y:229.0,s:1.0,o:1.0}, 560 {t:2.4,x:1177.6,y:228.5,s:1.008,o:1.0},{t:2.467,x:1188.6,y:228.1,s:1.016,o:1.0},{t:2.533,x:1199.7,y:227.6,s:1.024,o:1.0}, 561 {t:2.6,x:1210.7,y:227.2,s:1.032,o:1.0},{t:2.667,x:1221.8,y:226.7,s:1.04,o:1.0},{t:2.733,x:1232.8,y:226.3,s:1.048,o:1.0}, 562 {t:2.8,x:1243.8,y:225.8,s:1.056,o:1.0},{t:2.867,x:1254.9,y:225.4,s:1.064,o:1.0},{t:2.933,x:1265.9,y:224.9,s:1.072,o:1.0}, 563 {t:3.0,x:1276.9,y:224.4,s:1.08,o:1.0},{t:3.067,x:1308.3,y:224.0,s:1.088,o:1.0},{t:3.133,x:1346.4,y:223.5,s:1.096,o:1.0}, 564 {t:3.2,x:1384.1,y:223.3,s:1.1,o:1.0},{t:3.267,x:1421.4,y:223.3,s:1.1,o:1.0},{t:3.333,x:1458.7,y:223.3,s:1.1,o:1.0}, 565 {t:3.4,x:1496.1,y:223.3,s:1.1,o:1.0},{t:3.467,x:1533.4,y:223.3,s:1.1,o:1.0},{t:3.533,x:1561.4,y:223.3,s:1.1,o:1.0} 566 ]; 567 var last=PATH[PATH.length-1]; 568 var lot=document.getElementById('callouts-lottie'); 569 570 var CYCLE=8; 571 var BASE_FRAME=11; 572 var cards=window.__hubCards||(window.__hubCards=[]); 573 574 function applyAt(card, content, CONTENT_DUR, T, g){ 575 if(!lot) return; 576 var x,y,s,o; 577 if(T>=8.067){ x=last.x; y=last.y; s=last.s; o=0; } 578 else if(T>=3.533){ x=last.x; y=last.y; s=last.s; o=1; } 579 else { 580 var i=0; while(i<PATH.length-1 && PATH[i+1].t<=T) i++; 581 var a=PATH[i], b=PATH[Math.min(i+1,PATH.length-1)]; 582 var f=(b.t>a.t)?(T-a.t)/(b.t-a.t):0; 583 x=a.x+(b.x-a.x)*f; y=a.y+(b.y-a.y)*f; s=a.s+(b.s-a.s)*f; o=a.o+(b.o-a.o)*f; 584 } 585 586 if(x > 1458) o *= Math.max(0, (1528 - x) / 70); 587 588 content.seek(Math.max(0, Math.min(CONTENT_DUR, T - 0.3)), false); 589 590 var Y_NUDGE = g.isDesktop ? 42 : -11; 591 592 var fit = g.isDesktop ? 1 : (g.w/1440); 593 card.style.position='absolute'; 594 595 card.style.width='182px'; card.style.height='182px'; 596 card.style.left=(g.left+(x/1440)*g.w)+'px'; 597 card.style.top =(g.top +((y+Y_NUDGE)/500)*g.h)+'px'; 598 card.style.transform='translate(-50%,-50%) scale('+(s*fit)+')'; 599 card.style.transformOrigin='center center'; 600 card.style.opacity=o; 601 } 602 603 var mqDesktop = window.matchMedia('(min-width:1200px)'); 604 function tick(T){ 605 if(!cards.length || !lot) return; 606 607 var g={ left:lot.offsetLeft, top:lot.offsetTop, w:lot.offsetWidth, h:lot.offsetHeight, 608 isDesktop:mqDesktop.matches }; 609 for(var i=0;i<cards.length;i++){ 610 var c=cards[i]; 611 if(c.dur===undefined) c.dur=c.tl.duration(); 612 var Tl=T-(c.frame-BASE_FRAME)/60; 613 if(Tl<0) Tl+=CYCLE; 614 applyAt(c.el, c.tl, c.dur, Tl, g); 615 } 616 } 617 function whenLottie(cb){ var a=window.__calloutsLottie; if(a){cb(a);return;} setTimeout(function(){whenLottie(cb);},120); } 618 if(lot){ 619 whenLottie(function(a){ 620 a.addEventListener('enterFrame', function(){ tick(a.currentFrame / 90); }); 621 tick(a.currentFrame / 90); 622 }); 623 } 624 625 }); 626 })(); 627 (function(){ 628 var card=document.querySelector('.predict-card'); 629 if(!card) return; 630 var bets=[].slice.call(card.querySelectorAll('.predict-bet b')); 631 632 var CENTS=[68,32]; 633 var payouts=[].slice.call(card.querySelectorAll('.predict-payout')); 634
635 payouts.forEach(function(p,i){ p.textContent='$100 â $'+Math.round(100/(CENTS[i]/100)); }); 636 function show(i,v){ bets[i].textContent=Math.round(v)+'¢'; } 637 var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches; 638 if(reduce){ 639 card.style.opacity='1'; 640 CENTS.forEach(function(v,i){ show(i,v); }); 641 return; 642 } 643 function whenGsap(cb){ if(window.gsap) return cb(); setTimeout(function(){whenGsap(cb);},120); } 644 whenGsap(function(){ 645 var g=window.gsap; 646 var q=card.querySelector('.predict-q'), foot=card.querySelector('.predict-foot'); 647 var spark=card.querySelector('.spark-line'); 648 var content=g.timeline({paused:true}); 649 content.fromTo(q,{opacity:0,y:6},{opacity:1,y:0,duration:0.4,ease:'power2.out'},0.05); 650 if(spark){ 651 var len=spark.getTotalLength(); 652 g.set(spark,{strokeDasharray:len, strokeDashoffset:len}); 653 content.to(spark,{strokeDashoffset:0,duration:0.7,ease:'power2.out'},0.2); 654 } 655 bets.forEach(function(b,i){ 656 var at=0.35+i*0.12; 657 content.fromTo([b.parentElement,payouts[i]],{opacity:0,y:6},{opacity:1,y:0,duration:0.4,ease:'power2.out'},at); 658 659 var n={v:0}; 660 content.to(n,{v:CENTS[i],duration:0.7,ease:'power2.out', 661 onUpdate:function(){ show(i,n.v); }},at); 662 }); 663 content.fromTo(foot,{opacity:0},{opacity:1,duration:0.35},1.05); 664 (window.__hubCards||(window.__hubCards=[])).push({el:card, tl:content, frame:90}); 665 }); 666 })(); 667 (function(){ 668 var card=document.querySelector('.stocks-card'); 669 if(!card) return; 670 var rows=[].slice.call(card.querySelectorAll('.stock-row')); 671 var ORDERLY='https://api.orderly.org/v1/public/'; 672 673 function paint(row, price, pct){ 674 row.querySelector('.stock-price').textContent= 675 isFinite(price) ? '$'+price.toLocaleString('en-US',{minimumFractionDigits:2,maximumFractionDigits:2}) : '--'; 676 var chg=row.querySelector('.stock-chg'); 677 chg.textContent=(pct>0?'+':'')+pct.toFixed(2)+'%'; 678 679 chg.className='stock-chg '+(pct>0?'up':pct<0?'down':''); 680 } 681 function json(path){ return fetch(ORDERLY+path).then(function(r){ return r.json(); }); } 682 683 function fromTicker(quotes){ 684 rows.forEach(function(row){ 685 var t=/^PERP_([A-Z0-9]+)_/.exec(row.getAttribute('data-sym')); 686 var q=t && quotes[t[1]]; 687 if(q && isFinite(q.price)) paint(row, q.price, q.change||0); 688 }); 689 } 690 document.addEventListener('zexo:quotes', function(e){ fromTicker(e.detail); }); 691 692 function load(){ 693 rows.forEach(function(row){ 694 var sym=row.getAttribute('data-sym'); 695 696 json('info/'+encodeURIComponent(sym)).then(function(d){ 697 var m=d&&d.data; 698 699 if(m && m.base_imr>0) row.querySelector('.stock-lev').textContent=Math.round(1/m.base_imr)+'x'; 700 }).catch(function(){}); 701 }); 702 703 if(window.__zexoQuotes) return fromTicker(window.__zexoQuotes); 704 rows.forEach(function(row){ 705 json('futures/'+encodeURIComponent(row.getAttribute('data-sym'))).then(function(d){ 706 var m=d&&d.data, open=m&&m['24h_open'], close=m&&m['24h_close']; 707 if(open>0 && close>0) paint(row, close, (close-open)/open*100); 708 }).catch(function(){}); 709 }); 710 } 711 712 var sec=document.getElementById('callouts'); 713 if(sec && 'IntersectionObserver' in window){ 714 var io=new IntersectionObserver(function(entries){ 715 entries.forEach(function(e){ if(e.isIntersecting){ load(); io.disconnect(); } }); 716 }, { rootMargin:'200px' }); 717 io.observe(sec); 718 } else { load(); } 719 720 var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches; 721 if(reduce){ card.style.opacity='1'; return; } 722 function whenGsap(cb){ if(window.gsap) return cb(); setTimeout(function(){whenGsap(cb);},120); } 723 whenGsap(function(){ 724 var g=window.gsap; 725 var content=g.timeline({paused:true}); 726 rows.forEach(function(row,i){
727 content.fromTo(row,{opacity:0,x:10},{opacity:1,x:0,duration:0.45,ease:'power2.out'},0.1+i*0.14); 728 }); 729 (window.__hubCards||(window.__hubCards=[])).push({el:card, tl:content, frame:170}); 730 }); 731 })(); 732 (function(){ 733 var perf=document.querySelector('.perf-card'), roi=document.querySelector('.roi-card'); 734 if(!perf || !roi) return; 735 var vals=[].slice.call(perf.querySelectorAll('.perf-val')); 736 var roiVal=roi.querySelector('.roi-foot b'); 737 738 function fmt(el,v){ 739 var kind=el.getAttribute('data-kind'); 740 if(kind==='mult') return v.toFixed(1)+'x'; 741 return (kind==='gain' ? '+' : '')+Math.round(v)+'%'; 742 } 743 function show(el,v){ el.textContent=fmt(el,v); } 744 function target(el){ return parseFloat(el.getAttribute('data-to')); } 745 746 var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches; 747 if(reduce){ 748 perf.style.opacity='1'; roi.style.opacity='1'; 749 vals.concat([roiVal]).forEach(function(el){ show(el,target(el)); }); 750 return; 751 } 752 function whenGsap(cb){ if(window.gsap) return cb(); setTimeout(function(){whenGsap(cb);},120); } 753 whenGsap(function(){ 754 var g=window.gsap, cards=(window.__hubCards||(window.__hubCards=[])); 755 756 var perfTl=g.timeline({paused:true}); 757 vals.forEach(function(el,i){ 758 var at=0.1+i*0.14; 759 perfTl.fromTo(el.parentElement,{opacity:0,x:10},{opacity:1,x:0,duration:0.45,ease:'power2.out'},at); 760 var n={v:0}; 761 perfTl.to(n,{v:target(el),duration:0.7,ease:'power2.out', 762 onUpdate:function(){ show(el,n.v); }},at); 763 }); 764 cards.push({el:perf, tl:perfTl, frame:250}); 765 766 var roiTl=g.timeline({paused:true}); 767 var line=roi.querySelector('.roi-line'), fill=roi.querySelector('.roi-fill'); 768 var tabs=[].slice.call(roi.querySelectorAll('.roi-tab')); 769 roiTl.fromTo(tabs,{opacity:0,y:-4},{opacity:1,y:0,duration:0.35,stagger:0.05,ease:'power2.out'},0.05); 770 var len=line.getTotalLength(); 771 g.set(line,{strokeDasharray:len, strokeDashoffset:len}); 772 roiTl.to(line,{strokeDashoffset:0,duration:0.85,ease:'power2.out'},0.2); 773 774 roiTl.fromTo(fill,{opacity:0},{opacity:1,duration:0.6,ease:'power1.out'},0.5); 775 var rn={v:0}; 776 roiTl.to(rn,{v:target(roiVal),duration:0.8,ease:'power2.out', 777 onUpdate:function(){ show(roiVal,rn.v); }},0.35); 778 cards.push({el:roi, tl:roiTl, frame:330}); 779 }); 780 })(); 781 (function () { 782 if (typeof JetPulser !== "function") return; 783 if (!document.getElementById("trade-circuit")) return; 784 window.__tradePulser = JetPulser('#trade-circuit', { 785 speed: 1, 786 colors: ['#4cd7f4', '#7ce7ff'], 787 carveDir: 'vertical' 788 }); 789 790 if (window.matchMedia('(max-width: 768px)').matches) { 791 window.__tradePulser.setOptions({ carveBand: 22 }); 792 } 793 })(); 794 (function() { 795 var canvas = document.getElementById('matrix-canvas'); 796 797 if (!canvas) return; 798 var ctx = canvas.getContext('2d'); 799 var W, H; 800 var particles = []; 801 var PARTICLE_COUNT = 28; 802 803 var logoPath = new Path2D('M31.527 0.052C32.825 0.13 33.45 1.225 33.091 2.633C33.044 2.93 31.464 6.512 29.557 10.579C27.024 16.006 26.101 18.149 26.101 18.572C26.101 19.338 26.57 20.167 27.211 20.542C27.712 20.84 28.103 20.855 34.076 20.934C40.096 21.012 40.424 21.027 40.831 21.325C41.44 21.763 42.012 22.426 41.847 23.483C41.769 23.984 34.31 40.173 33.826 40.924C33.685 41.127 33.278 41.44 32.903 41.596C32.246 41.894 31.793 41.894 21.285 41.862L10.356 41.815C9.058 41.815 8.12 40.799 8.792 39.234C8.839 38.937 10.418 35.355 12.326 31.288C14.859 25.861 15.781 23.718 15.781 23.295C15.781 22.529 15.312 21.7 14.671 21.325C14.171 21.027 13.78 21.012 7.807 20.934C1.787 20.855 1.458 20.84 1.052 20.542C0.442 20.105 -0.153 19.593 0.036 18.384C0.114 17.883 7.572 1.694 8.057 0.943C8.198 0.74 8.589 0.443 8.948 0.271C9.574 -0.011 10.074 -0.027 20.566 0.02L31.527 0.052Z'); 804 805 function resize() { 806 W = canvas.width = canvas.parentElement.offsetWidth; 807 H = canvas.height = canvas.parentElement.offsetHeight; 808 if (particles.length === 0) initParticles(); 809 } 810 811 function initParticles() { 812 particles = []; 813 for (var i = 0; i < PARTICLE_COUNT; i++) { 814 particles.push(createParticle(true)); 815 } 816 } 817 818 function createParticle(randomY) { 819 var scale = 0.6 + Math.random() * 1.8; 820 return { 821 x: Math.random() * W, 822 y: randomY ? Math.random() * H : H + 50 + Math.random() * 100, 823 vx: (Math.random() - 0.5) * 0.2, 824 vy: -0.12 - Math.random() * 0.28, 825 scale: scale, 826 alpha: 0.02 + Math.random() * 0.04, 827 rotation: Math.random() * Math.PI * 2, 828 rotSpeed: (Math.random() - 0.5) * 0.002 829 }; 830 } 831 832 resize(); 833 window.addEventListener('resize', resize); 834 835 function renderFrame() { 836 ctx.clearRect(0, 0, W, H); 837 838 for (var i = 0; i < particles.length; i++) { 839 var p = particles[i]; 840 841 ctx.save(); 842 ctx.translate(p.x, p.y); 843 ctx.rotate(p.rotation); 844 ctx.scale(p.scale, p.scale); 845 846 ctx.translate(-21, -21); 847 ctx.globalAlpha = p.alpha; 848 ctx.fillStyle = '#4cd7f4'; 849 ctx.fill(logoPath);
850 ctx.restore(); 851 852 p.x += p.vx; 853 p.y += p.vy; 854 p.rotation += p.rotSpeed; 855 856 if (p.y < -60 * p.scale) { 857 particles[i] = createParticle(false); 858 } 859 if (p.x < -60) p.x = W + 30; 860 if (p.x > W + 60) p.x = -30; 861 } 862 } 863 864 var inView = true, matrixRaf = 0; 865 function draw() { 866 matrixRaf = 0; 867 if (!inView) return; 868 renderFrame(); 869 matrixRaf = requestAnimationFrame(draw); 870 } 871 function wake() { if (inView && !matrixRaf) matrixRaf = requestAnimationFrame(draw); } 872 873 var reduceMotion = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches; 874 if (reduceMotion) { 875 876 renderFrame(); 877 } else { 878 if ('IntersectionObserver' in window) { 879 var io = new IntersectionObserver(function (entries) { 880 entries.forEach(function (e) { inView = e.isIntersecting; wake(); }); 881 }, { rootMargin: '120px' }); 882 io.observe(canvas.parentElement); 883 } 884 draw(); 885 } 886 })(); 887 (function initAnimations() { 888 if (typeof gsap === 'undefined' || typeof ScrollTrigger === 'undefined' || document.readyState === 'loading') { 889 setTimeout(initAnimations, 100); 890 return; 891 } 892 gsap.registerPlugin(ScrollTrigger); 893 894 var REDUCED = window.matchMedia('(prefers-reduced-motion: reduce)').matches; 895 var SMALL = window.matchMedia('(max-width: 768px)').matches; 896 var TRAVEL = SMALL ? 0.6 : 1; 897 var EASE_RISE = 'expo.out', EASE_SOFT = 'power2.out', EASE_CARD = 'power3.out'; 898 899 function reveal(el, voice, opts) { 900 if (!el) return; 901 opts = opts || {}; 902 var start = opts.start || 'top 84%'; 903 var delay = opts.delay || 0; 904 var from, to; 905 if (voice === 'headline') { 906 from = { opacity: 0, clipPath: 'inset(0 0 100% 0)', webkitClipPath: 'inset(0 0 100% 0)' }; 907 to = { opacity: 1, clipPath: 'inset(0 0 0% 0)', webkitClipPath: 'inset(0 0 0% 0)', duration: 0.9, ease: EASE_RISE, 908 onComplete: function () { gsap.set(el, { clearProps: 'clipPath,webkitClipPath' }); } }; 909 } else if (voice === 'title') { 910 911 from = { opacity: 0, y: 18 * TRAVEL }; 912 to = { opacity: 1, y: 0, duration: 0.85, ease: EASE_CARD }; 913 } else if (voice === 'eyebrow') { 914 from = { opacity: 0, y: 10 * TRAVEL }; 915 to = { opacity: 1, y: 0, duration: 0.5, ease: EASE_SOFT }; 916 } else if (voice === 'body') { 917 from = { opacity: 0, y: 14 * TRAVEL }; 918 to = { opacity: 1, y: 0, duration: 0.9, ease: EASE_SOFT }; 919 } else { 920 from = { opacity: 0, scale: 0.94 }; 921 to = { opacity: 1, scale: 1, duration: 1.2, ease: 'power2.out' }; 922 } 923 gsap.set(el, from); 924 ScrollTrigger.create({ 925 trigger: el, start: start, once: true, 926 onEnter: function () { gsap.to(el, Object.assign({ delay: delay }, to)); } 927 }); 928 } 929 930 function revealGroup(sel, voice, opts) { 931 gsap.utils.toArray(sel).forEach(function (el) { reveal(el, voice, opts); }); 932 } 933 934 function revealStagger(sel, opts) { 935 var items = gsap.utils.toArray(sel); 936 if (!items.length) return; 937 opts = opts || {}; 938 var axis = opts.axis || 'y'; 939 var dist = (opts.dist != null ? opts.dist : 32) * TRAVEL; 940 var from = axis === 'x' 941 ? { opacity: 0, x: -dist } 942 : { opacity: 0, y: dist, scale: opts.scale === false ? 1 : 0.985 }; 943 gsap.set(items, from); 944 ScrollTrigger.batch(items, { 945 start: opts.start || 'top 86%', once: true, 946 onEnter: function (batch) { 947 var t = axis === 'x' ? { opacity: 1, x: 0 } : { opacity: 1, y: 0, scale: 1 }; 948 t.duration = opts.duration || 0.85; 949 t.ease = EASE_CARD; 950 t.stagger = { each: opts.each || 0.09, from: opts.from || 'start' }; 951 952 t.onComplete = function () { gsap.set(batch, { clearProps: 'opacity,transform' }); }; 953 gsap.to(batch, t); 954 } 955 }); 956 } 957 958 function parallax(sel, amount) { 959 if (SMALL) return; 960 gsap.utils.toArray(sel).forEach(function (el) { 961 gsap.to(el, { 962 yPercent: amount, ease: 'none', 963 scrollTrigger: { trigger: el, start: 'top bottom', end: 'bottom top', scrub: 0.6 } 964 }); 965 }); 966 } 967 968 if (!REDUCED) { 969 970 revealGroup('.coins-badge, .season-badge, .security-badge', 'eyebrow'); 971 972 revealGroup('.products-title, .security-title', 'headline', { delay: 0.06 }); 973 974 revealGroup('.coins-title, .inside-title, .season-title, .trade-title', 'title', { delay: 0.05 }); 975 976 revealGroup('.season-desc, .trade-desc, .security-note', 'body', { delay: 0.16 }); 977 revealGroup('.coins-cta', 'body', { delay: 0.2, start: 'top 90%' });
978 979 revealStagger('.product-card', { each: 0.1, start: 'top 80%' }); 980 revealStagger('.security-card', { each: 0.09, from: 'center' }); 981 revealStagger('.inside-item', { each: 0.07, dist: 22, scale: false, start: 'top 88%' }); 982 983 revealStagger('.season-step', { axis: 'x', each: 0.1 }); 984 revealStagger('.trade-feature', { each: 0.07, dist: 20, scale: false }); 985 986 revealGroup('.security-3d', 'media', { delay: 0.1, start: 'top 82%' }); 987 reveal(document.querySelector('.ticker-board'), 'media', { delay: 0.15, start: 'top 84%' }); 988 989 parallax('.security-3d', -4); 990 } else { 991 992 gsap.set('.coins-badge,.season-badge,.security-badge,.coins-title,.inside-title,.products-title,.season-title,.security-title,.trade-title,.season-desc,.trade-desc,.coins-cta,.product-card,.security-card,.inside-item,.season-step,.trade-feature,.security-3d,.ticker-board', 993 { opacity: 1, x: 0, y: 0, scale: 1, clearProps: 'clipPath' }); 994 } 995 996 if (!REDUCED) { 997 gsap.set('.hero-left h1 .line-inner', { yPercent: 120 }); 998 gsap.set('.hero-left .hero-desc', { opacity: 0, y: 18 }); 999 gsap.set('.hero-buttons', { opacity: 0, y: 18 }); 1000 gsap.set('.hero-stats', { opacity: 0, y: 18 }); 1001 gsap.set('.screen-frame', { opacity: 0, y: 36, scale: 0.96, rotationX: 13, transformPerspective: 1500, transformOrigin: 'center center' }); 1002 1003 var heroTl = gsap.timeline({ defaults: { ease: EASE_SOFT } }); 1004 heroTl 1005 .to('.hero-left h1 .line-inner', { yPercent: 0, duration: 1.05, stagger: 0.12, ease: EASE_RISE }, 0.25) 1006 .to('.hero-left .hero-desc', { opacity: 1, y: 0, duration: 0.8 }, 0.75) 1007 .to('.hero-buttons', { opacity: 1, y: 0, duration: 0.7 }, 0.95) 1008 .to('.hero-stats', { opacity: 1, y: 0, duration: 0.7 }, 1.15) 1009 .to('.screen-frame', { opacity: 1, y: 0, scale: 1, duration: 1.3, ease: EASE_CARD }, 0.45); 1010 } 1011 1012 function animateCounters() { 1013 document.querySelectorAll('.stat-value[data-count]').forEach(function(el) { 1014 var target = parseFloat(el.getAttribute('data-count')); 1015 var decimals = parseInt(el.getAttribute('data-decimals')) || 0; 1016 var prefix = el.getAttribute('data-prefix') || ''; 1017 var suffix = el.getAttribute('data-suffix') || ''; 1018 var obj = { val: 0 }; 1019 1020 if (REDUCED) { 1021 el.textContent = prefix + target.toFixed(decimals) + suffix; 1022 return; 1023 } 1024 1025 gsap.to(obj, { 1026 val: target, 1027 duration: 2.2, 1028 delay: 1.5, 1029 ease: 'power2.out', 1030 onUpdate: function() { 1031 el.textContent = prefix + obj.val.toFixed(decimals) + suffix; 1032 } 1033 }); 1034 }); 1035 } 1036 animateCounters(); 1037 1038 (function () { 1039 var beam = document.querySelector('.pts-beam'); 1040 if (!beam || REDUCED) return; 1041 if (!('IntersectionObserver' in window)) { beam.classList.add('is-live'); return; } 1042 new IntersectionObserver(function (entries) { 1043 entries.forEach(function (e) { beam.classList.toggle('is-live', e.isIntersecting); }); 1044 }, { rootMargin: '150px' }).observe(beam); 1045 })(); 1046 1047 var coins = [
1048 { id: 'bitcoin', name: 'Bitcoin', ticker: 'BTC', perp: 'PERP_BTC_USDC', price: '--', change: '', down: false, img: 'assets/images/instruments/btc.svg', binance: 'btcusdt' }, 1049 { id: 'ethereum', name: 'Ethereum', ticker: 'ETH', perp: 'PERP_ETH_USDC', price: '--', change: '', down: false, img: 'assets/images/instruments/eth.svg', binance: 'ethusdt' }, 1050 { id: 'solana', name: 'Solana', ticker: 'SOL', perp: 'PERP_SOL_USDC', price: '--', change: '', down: false, img: 'assets/images/instruments/sol.svg', binance: 'solusdt' }, 1051 { id: 'binancecoin', name: 'BNB', ticker: 'BNB', perp: 'PERP_BNB_USDC', price: '--', change: '', down: false, img: 'assets/images/instruments/bnb.svg', binance: 'bnbusdt' }, 1052 { id: 'ripple', name: 'XRP', ticker: 'XRP', perp: 'PERP_XRP_USDC', price: '--', change: '', down: false, img: 'assets/images/instruments/xrp.svg', binance: 'xrpusdt' }, 1053 ]; 1054 1055 var stocks = [ 1056 { sym: 'NVDA', perp: 'PERP_NVDA_USDC', name: 'NVIDIA', ticker: 'NVDA', img: 'assets/images/instruments/nvda.svg' }, 1057 { sym: 'META', perp: 'PERP_META_USDC_mythos', name: 'Meta', ticker: 'META', img: 'assets/images/instruments/meta.svg' }, 1058 { sym: 'SPY', perp: 'PERP_SPY_USDC_mythos', name: 'S&P 500', ticker: 'SPY', img: 'assets/images/instruments/spy.svg' }, 1059 { sym: 'EUR/USD', perp: 'PERP_EURUSD_USDC', name: 'Euro', ticker: 'EUR/USD', img: 'assets/images/instruments/eurusd.svg' }, 1060 ]; 1061 1062 var cryptoCoins = coins.filter(function (c) { return !!c.binance; }); 1063 1064 function marketHref(c) { 1065 return c.perp ? 'https://trade.zipmex.com/perps/' + c.perp : null; 1066 } 1067 1068 var MARKET_TARGET = ' target="_blank" rel="noopener"'; 1069 1070 function buildCoinCard(c, dup) { 1071 var cls = (c.change || '').charAt(0) === '-' ? 'down' : 'up'; 1072 var href = marketHref(c); 1073 var hidden = dup ? ' tabindex="-1" aria-hidden="true"' : ''; 1074 var open = href 1075 ? '<a class="coin-card" href="' + href + '"' + MARKET_TARGET + 1076 ' aria-label="Trade ' + c.ticker + ' (opens in a new tab)"' + hidden + 1077 ' data-inst="' + (c.sym || c.id) + '">' 1078 : '<div class="coin-card" data-inst="' + (c.sym || c.id) + '">'; 1079 return open + 1080 '<div class="coin-icon"><img src="' + c.img + '" width="30" height="30" alt="' + c.name + '" loading="lazy"></div>' + 1081 '<div class="coin-info">' + 1082 '<div class="coin-name-row"><span class="coin-name">' + c.name + '</span><span class="coin-ticker">' + c.ticker + '</span></div>' + 1083 '<div class="coin-price-row">' + 1084 '<span class="coin-price">' + c.price + '</span>' + 1085 '<span class="coin-change ' + cls + '">' + (c.change || '') + '</span>' + 1086 '</div>' + 1087 '</div>' + (href ? '</a>' : '</div>'); 1088 } 1089 1090 function fillRow(id, coinsList) { 1091 var el = document.getElementById(id); 1092 if (!el) return; 1093 var html = ''; 1094 for (var r = 0; r < 4; r++) { 1095 coinsList.forEach(function(c) { html += buildCoinCard(c, r > 0); }); 1096 } 1097 el.innerHTML = html; 1098 } 1099 1100 fillRow('coins-row-1', coins); 1101 fillRow('coins-row-2', stocks.map(function (x) { 1102 return { sym: x.sym, perp: x.perp, name: x.name, ticker: x.ticker, img: x.img, price: '--', change: '' }; 1103 })); 1104 1105 (function() { 1106 var coinsSection = document.querySelector('.coins-section'); 1107 if (!coinsSection) return; 1108 var tracks = coinsSection.querySelectorAll('.coins-track'); 1109 if ('IntersectionObserver' in window) { 1110 1111 var obs = new IntersectionObserver(function(entries) { 1112 entries.forEach(function(e) { 1113 tracks.forEach(function(t) { t.classList.toggle('running', e.isIntersecting); }); 1114 }); 1115 }, { threshold: 0, rootMargin: '200px' }); 1116 obs.observe(coinsSection); 1117 } else { 1118 tracks.forEach(function(t) { t.classList.add('running'); }); 1119 } 1120 })(); 1121 1122 (function () { 1123 var container = document.getElementById('tv-chart'); 1124 if (!container) return; 1125 1126 var MARKET_API = 'https://api.orderly.org/v1/tv/history'; 1127 1128 var fallbackEl = document.getElementById('chart-fallback'); 1129 var nameEl = document.getElementById('chart-quote-name'); 1130 var priceEl = document.getElementById('chart-quote-price'); 1131 var changeEl = document.getElementById('chart-quote-change'); 1132 var tabs = [].slice.call(document.querySelectorAll('.chart-inst')); 1133 1134 var chart = null; 1135 var series = null; 1136 var started = false; 1137 var narrow = window.matchMedia('(max-width: 768px)').matches; 1138 1139 function setState(state, text) { 1140 if (!fallbackEl) return; 1141 fallbackEl.classList.toggle('is-hidden', state === 'ready'); 1142 fallbackEl.classList.toggle('is-error', state === 'error'); 1143 if (text) { 1144 var t = fallbackEl.querySelector('.chart-fallback-text'); 1145 if (t) t.textContent = text; 1146 } 1147 } 1148 1149 function fmt(n) { 1150 if (!isFinite(n)) return '--'; 1151 if (n >
1151= 1000) return '$' + n.toLocaleString('en-US', { maximumFractionDigits: 2 }); 1152 if (n >= 1) return '$' + n.toFixed(2); 1153 return '$' + n.toFixed(4); 1154 } 1155 1156 function initChart() { 1157 chart = LightweightCharts.createChart(container, { 1158 layout: { 1159 background: { type: 'solid', color: 'transparent' }, 1160 textColor: 'rgba(255,255,255,0.35)', 1161 fontFamily: '"Banana Grotesk Mono", monospace', 1162 fontSize: 10, 1163 attributionLogo: false 1164 }, 1165 grid: { 1166 vertLines: { color: 'rgba(255,255,255,0.03)' }, 1167 horzLines: { color: 'rgba(255,255,255,0.03)' } 1168 }, 1169 rightPriceScale: { borderColor: 'rgba(255,255,255,0.06)' }, 1170 timeScale: { borderColor: 'rgba(255,255,255,0.06)', timeVisible: !narrow }, 1171 crosshair: { mode: LightweightCharts.CrosshairMode.Normal }, 1172 handleScroll: !narrow, 1173 handleScale: !narrow 1174 }); 1175 series = chart.addCandlestickSeries({ 1176 upColor: '#00c076', downColor: '#ff4d4d', 1177 borderUpColor: '#00c076', borderDownColor: '#ff4d4d', 1178 wickUpColor: '#00c076', wickDownColor: '#ff4d4d' 1179 }); 1180 new ResizeObserver(function () { 1181 if (chart) chart.applyOptions({ width: container.clientWidth, height: container.clientHeight }); 1182 }).observe(container); 1183 } 1184 1185 var iconEl = document.getElementById('chart-quote-icon'); 1186 1187 function paintQuote(label, candles, icon, day) { 1188 if (nameEl) nameEl.textContent = label; 1189 if (iconEl && icon) iconEl.src = icon; 1190 if (!candles.length) return; 1191 var price = day ? day.close : candles[candles.length - 1].close; 1192 var pct = day ? (day.close - day.open) / day.open * 100 : 0; 1193 if (priceEl) priceEl.textContent = fmt(price); 1194 if (changeEl) { 1195 1196 changeEl.textContent = (pct > 0 ? '+' : '') + pct.toFixed(2) + '%'; 1197 changeEl.className = 'chart-quote-change ' + (pct > 0 ? 'up' : pct < 0 ? 'down' : ''); 1198 } 1199 } 1200 1201 function iconFor(symbol) { 1202 var btn = document.querySelector('.chart-inst[data-symbol="' + symbol + '"] img'); 1203 return btn ? btn.getAttribute('src') : null; 1204 } 1205 1206 function load(symbol, label) { 1207 setState('loading', 'Loading ' + label + 'â¦'); 1208 1209 var step = narrow ? 86400 : 3600; 1210 var to = Math.floor(Date.now() / 1000); 1211 var url = MARKET_API + '?symbol=' + encodeURIComponent(symbol) + 1212 '&resolution=' + (narrow ? '1D' : '60') + 1213 '&from=' + (to - 130 * step) + '&to=' + to; 1214 1215 var day = fetch('https://api.orderly.org/v1/public/futures/' + encodeURIComponent(symbol)) 1216 .then(function (r) { return r.json(); }) 1217 .then(function (d) { 1218 var m = d && d.data; 1219 return (m && m['24h_open'] > 0 && m['24h_close'] > 0) 1220 ? { open: m['24h_open'], close: m['24h_close'] } : null; 1221 }) 1222 .catch(function () { return null; }); 1223 1224 Promise.all([fetch(url).then(function (r) { return r.json(); }), day]) 1225 .then(function (res) { 1226 var d = res[0]; 1227 if (d.s !== 'ok' || !d.t || !d.t.length) throw new Error('no data'); 1228 var candles = d.t.map(function (t, i) { 1229 return { time: t, open: d.o[i], high: d.h[i], low: d.l[i], close: d.c[i] }; 1230 }).filter(function (c) { return isFinite(c.close); }).slice(-120); 1231 if (!candles.length) throw new Error('no data'); 1232 series.setData(candles); 1233 chart.timeScale().fitContent(); 1234 paintQuote(label, candles, iconFor(symbol), res[1]); 1235 setState('ready'); 1236 }) 1237 .catch(function () { 1238 setState('error', 'Market data is unavailable right now'); 1239 }); 1240 } 1241 1242 function select(btn) {
1243 tabs.forEach(function (t) { 1244 var on = t === btn; 1245 t.classList.toggle('is-active', on); 1246 t.setAttribute('aria-selected', String(on)); 1247 }); 1248 load(btn.getAttribute('data-symbol'), btn.getAttribute('data-label')); 1249 } 1250 1251 tabs.forEach(function (btn) { 1252 btn.addEventListener('click', function () { select(btn); }); 1253 }); 1254 1255 function start() { 1256 if (started || typeof LightweightCharts === 'undefined') return; 1257 started = true; 1258 initChart(); 1259 var active = document.querySelector('.chart-inst.is-active') || tabs[0]; 1260 if (active) load(active.getAttribute('data-symbol'), active.getAttribute('data-label')); 1261 } 1262 1263 var script = document.createElement('script'); 1264 script.src = '/assets/js/vendor/lightweight-charts.standalone.production.js'; 1265 script.onload = function () { 1266 if ('IntersectionObserver' in window) { 1267 var io = new IntersectionObserver(function (entries) { 1268 entries.forEach(function (e) { if (e.isIntersecting) { start(); io.disconnect(); } }); 1269 }, { rootMargin: '200px' }); 1270 io.observe(container); 1271 } else { 1272 start(); 1273 } 1274 }; 1275 script.onerror = function () { setState('error', 'Chart library failed to load'); }; 1276 document.head.appendChild(script); 1277 })(); 1278 1279 (function () { 1280 var API = 'https://api.orderly.org/v1/public/futures'; 1281 var section = document.querySelector('.coins-section'); 1282 if (!section) return; 1283 1284 function fmtPrice(n) { 1285 if (!isFinite(n)) return '--'; 1286 if (n >= 1000) return '$' + n.toLocaleString('en-US', { maximumFractionDigits: 0 }); 1287 if (n >= 1) return '$' + n.toFixed(2); 1288 return '$' + n.toFixed(4); 1289 } 1290 1291 function apply(quotes) { 1292 1293 window.__zexoQuotes = quotes; 1294 document.dispatchEvent(new CustomEvent('zexo:quotes', { detail: quotes })); 1295 stocks.forEach(function (x) { 1296 var q = quotes[x.sym]; 1297 if (!q) return; 1298 var price = fmtPrice(q.price); 1299 1300 var pct = (q.change > 0 ? '+' : '') + (q.change || 0).toFixed(2) + '%'; 1301 var cards = document.querySelectorAll('[data-inst="' + x.sym + '"]'); 1302 cards.forEach(function (card) { 1303 var priceEl = card.querySelector('.coin-price'); 1304 var changeEl = card.querySelector('.coin-change'); 1305 if (priceEl && priceEl.textContent !== price) { 1306 1307 priceEl.textContent = price; 1308 } 1309 if (changeEl) { 1310 changeEl.textContent = pct; 1311 changeEl.className = 'coin-change ' + (q.change >= 0 ? 'up' : 'down'); 1312 } 1313 }); 1314 }); 1315 } 1316 1317 function load() { 1318 1319 Promise.all(stocks.map(function (x) { 1320 return fetch(API + '/' + encodeURIComponent(x.perp)) 1321 .then(function (r) { return r.json(); }) 1322 .then(function (d) { return { sym: x.sym, m: d && d.data }; }) 1323 .catch(function () { return null; }); 1324 })).then(function (list) { 1325 var quotes = {}; 1326 list.forEach(function (row) { 1327 if (!row || !row.m) return; 1328 var open = row.m['24h_open'], close = row.m['24h_close']; 1329 if (!(open > 0) || !(close > 0)) return; 1330 quotes[row.sym] = { price: close, change: (close - open) / open * 100 }; 1331 }); 1332 if (Object.keys(quotes).length) apply(quotes); 1333 }); 1334 } 1335 var timer = null; 1336 function startPolling() { 1337 if (timer) return; 1338 load(); 1339 timer = setInterval(load, 2 * 60 * 1000); 1340 } 1341 function stopPolling() { 1342 if (!timer) return; 1343 clearInterval(timer); 1344 timer = null; 1345 } 1346 1347 if ('IntersectionObserver' in window) { 1348 new IntersectionObserver(function (entries) {
1349 entries.forEach(function (e) { e.isIntersecting ? startPolling() : stopPolling(); }); 1350 }, { rootMargin: '200px' }).observe(section); 1351 } else { 1352 startPolling(); 1353 } 1354 })(); 1355 1356 function fmtPrice(n) { 1357 if (n >= 1000) return '$' + n.toLocaleString('en-US', { maximumFractionDigits: 0 }); 1358 if (n >= 1) return '$' + n.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); 1359 return '$' + n.toLocaleString('en-US', { minimumFractionDigits: 3, maximumFractionDigits: 4 }); 1360 } 1361 1362 function buildSparkSvg(prices, isUp) { 1363 if (!prices || prices.length < 2) return ''; 1364 var step = Math.max(1, Math.floor(prices.length / 24)); 1365 var pts = []; 1366 for (var i = 0; i < prices.length; i += step) pts.push(prices[i]); 1367 var min = Math.min.apply(null, pts); 1368 var max = Math.max.apply(null, pts); 1369 var range = max - min || 1; 1370 var w = 80, h = 28, pad = 2; 1371 var points = pts.map(function(p, i) { 1372 var x = pad + (i / (pts.length - 1)) * (w - pad * 2); 1373 var y = pad + (1 - (p - min) / range) * (h - pad * 2); 1374 return x.toFixed(1) + ',' + y.toFixed(1); 1375 }).join(' '); 1376 var color = isUp ? '#00c076' : '#ff4d4d'; 1377 return '<svg viewBox="0 0 ' + w + ' ' + h + '" fill="none"><polyline points="' + points + '" stroke="' + color + '" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>'; 1378 } 1379 1380 var tickerData = {}; 1381 1382 function renderTickerBoard() { 1383 var board = document.getElementById('ticker-board-body'); 1384 if (!board) return; 1385 var shown = coins.slice(0, 8); 1386 var html = ''; 1387 shown.forEach(function(c) { 1388 var d = tickerData[c.id] || {}; 1389 var price = d.price || c.price; 1390 var ch = d.change != null ? d.change : 0; 1391 var isUp = ch >= 0; 1392 var spark = d.sparkPrices ? buildSparkSvg(d.sparkPrices, isUp) : ''; 1393 1394 var href = marketHref(c); 1395 html += (href 1396 ? '<a class="ticker-row" href="' + href + '"' + MARKET_TARGET + 1397 ' aria-label="Trade ' + c.ticker + ' (opens in a new tab)" data-ticker="' + (c.binance || '') + '">' 1398 : '<div class="ticker-row" data-ticker="' + (c.binance || '') + '">') + 1399 '<div class="ticker-asset">' + 1400 '<img src="' + c.img + '" width="28" height="28" alt="' + c.ticker + '" loading="lazy">' + 1401 '<span class="ticker-asset-name">' + c.name + '<span class="ticker-asset-ticker">' + c.ticker + '</span></span>' + 1402 '</div>' + 1403 '<span class="ticker-price" data-coin-price="' + c.id + '">' + (typeof price === 'number' ? fmtPrice(price) : price) + '</span>' + 1404 '<span class="ticker-change ' + (isUp ? 'up' : 'down') + '">' + (isUp ? '+' : '') + ch.toFixed(2) + '%</span>' + 1405 '<span class="ticker-spark">' + spark + '</span>' + 1406 (href ? '</a>' : '</div>'); 1407 }); 1408 board.innerHTML = html; 1409 } 1410 1411 renderTickerBoard(); 1412 connectBinanceWS(); 1413 1414 function fetchLivePrices(retries) { 1415 if (typeof retries === 'undefined') retries = 2; 1416 var ids = cryptoCoins.map(function(c) { return c.id; }).join(','); 1417 fetch('https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=' + ids + '&sparkline=true&price_change_percentage=24h') 1418 .then(function(r) { 1419 if (!r.ok) throw new Error(r.status); 1420 return r.json(); 1421 }) 1422 .then(function(data) { 1423 data.forEach(function(d) { 1424 1425 tickerData[d.id] = { 1426 price: d.current_price, 1427 change: d.price_change_percentage_24h || 0, 1428 sparkPrices: d.sparkline_in_7d ? d.sparkline_in_7d.price : null 1429 }; 1430 }); 1431 cryptoCoins.forEach(function(c) { 1432 var d = tickerData[c.id]; 1433 if (!d) return; 1434 c.price = fmtPrice(d.price); 1435 c.down = d.change < 0; 1436 c.change = (d.change >= 0 ? '+' : '') + d.change.toFixed(2) + '%'; 1437 }); 1438 fillRow('coins-row-1', coins); 1439 renderTickerBoard(); 1440 }) 1441 .catch(function() { 1442 if (retries > 0) { 1443 setTimeout(function() { fetchLivePrices(retries - 1); }, 3000); 1444 } 1445 }); 1446 } 1447 fetchLivePrices(); 1448 1449 function connectBinanceWS() { 1450 var symbols = cryptoCoins.map(function(c) { return c.binance + '@miniTicker'; }); 1451 if (!symbols.length) return; 1452 var ws = new WebSocket('wss://stream.binance.com:9443/stream?streams=' + symbols.join('/')); 1453 ws.onmessage = function(evt) { 1454 var msg = JSON.parse(evt.data); 1455 var d = msg.data; 1456 if (!d || !d.s) return; 1457 var coin = null; 1458 cryptoCoins.forEach(function(c) { if (d.s.toLowerCase() === c.binance) coin = c; }); 1459 if (!coin) return; 1460 var newPrice = parseFloat(d.c); 1461 var oldPrice = tickerData[coin.id] ? tickerData[coin.id].price : newPrice; 1462 var ch24 = ((newPrice - parseFloat(d.o)) / parseFloat(d.o) * 100); 1463 if (!tickerData[coin.id]) tickerData[coin.id] = {}; 1464 tickerData[coin.id].price = newPrice; 1465 tickerData[coin.id].change = ch24; 1466 var priceEl = document.querySelector('[data-coin-price="' + coin.id + '"]'); 1467 if (priceEl) { 1468 priceEl.textContent = fmtPrice(newPrice); 1469 priceEl.classList.remove('flash-up', 'flash-down'); 1470 void priceEl.offsetWidth; 1471 priceEl.classList.add(newPrice >= oldPrice ? 'flash-up' : 'flash-down'); 1472 } 1473 var row = priceEl ? priceEl.closest('.ticker-row') : null; 1474 if (row) { 1475 var changeEl = row.querySelector('.ticker-change'); 1476 if (changeEl) { 1477 changeEl.textContent = (ch24 >= 0 ? '+' : '') + ch24.toFixed(2) + '%'; 1478 changeEl.className = 'ticker-change ' + (ch24 >= 0 ? 'up' : 'down'); 1479 } 1480 } 1481 coin.price = fmtPrice(newPrice); 1482 coin.down = ch24 < 0; 1483 coin.change = (ch24 >= 0 ? '+' : '') + ch24.toFixed(2) + '%'; 1484 1485 document.querySelectorAll('[data-inst="' + coin.id + '"]').forEach(function (card) { 1486 var p = card.querySelector('.coin-price'); 1487 var ch = card.querySelector('.coin-change'); 1488 if (p && p.textContent !== coin.price) { 1489 1490 p.textContent = coin.price; 1491 } 1492 if (ch) { 1493 ch.textContent = coin.change; 1494 ch.className = 'coin-change ' + (ch24 >= 0 ? 'up' : 'down'); 1495 } 1496 }); 1497 }; 1498 ws.onclose = function() { setTimeout(connectBinanceWS, 3000); }; 1499 ws.onerror = function() { ws.close(); }; 1500 } 1501 })(); 1502 (function pageTransitions() { 1503 var docEl = document.documentElement; 1504 var REDUCE = window.matchMedia('(prefers-reduced-motion: reduce)').matches; 1505 1506 var lenis = null; 1507 function initSmoothScroll() { 1508 if (REDUCE || typeof window.Lenis === 'undefined') return; 1509 1510 if (window.matchMedia && window.matchMedia('(hover: none) and (pointer: coarse)').matches) { 1511 docEl.style.scrollBehavior = 'auto'; 1512 return; 1513 } 1514 try { 1515 lenis = new window.Lenis({ 1516 1517 duration: 0.6, 1518 easing: function (x) { return Math.min(1, 1.001 - Math.pow(2, -10 * x)); }, 1519 smoothWheel: true, 1520 wheelMultiplier: 1.0, 1521 touchMultiplier: 1.4 1522 }); 1523 docEl.style.scrollBehavior = 'auto'; 1524 window.__lenis = lenis; 1525 lenis.on('scroll', function () { if (window.ScrollTrigger) window.ScrollTrigger.update(
1525); }); 1526 1527 var raf = function (t) { lenis.raf(t); requestAnimationFrame(raf); }; 1528 requestAnimationFrame(raf); 1529 1530 var backTop = document.querySelector('.footer-back-top'); 1531 if (backTop) { 1532 backTop.onclick = function () { lenis.scrollTo(0, { duration: 1.2 }); return false; }; 1533 } 1534 } catch (e) { lenis = null; } 1535 } 1536 1537 function whenReady(cb) { 1538 if (window.gsap && window.ScrollTrigger) return cb(); 1539 setTimeout(function () { whenReady(cb); }, 80); 1540 } 1541 1542 whenReady(function () { 1543 initSmoothScroll(); 1544 if (window.ScrollTrigger) window.ScrollTrigger.refresh(); 1545 }); 1546 })(); 1547 (function () { 1548 var v = document.getElementById('hero-video'); 1549 if (!v) return; 1550 if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) { 1551 v.removeAttribute('autoplay'); 1552 v.pause(); 1553 v.style.opacity = '1'; 1554 return; 1555 } 1556 1557 v.addEventListener('playing', function () { 1558 v.style.opacity = '1'; 1559 }, { once: true }); 1560 1561 v.addEventListener('ended', function () { 1562 v.pause(); 1563 }, { once: true }); 1564 1565 var started = false; 1566 function startHeroVideo() { 1567 if (started) return; 1568 started = true; 1569 v.load(); 1570 try { v.currentTime = 0; } catch (e) {} 1571 var p = v.play(); 1572 if (p && p.catch) p.catch(function () {}); 1573 } 1574 startHeroVideo(); 1575 })(); 1576 (function () { 1577 if (location.search.indexOf('perf') === -1) return; 1578 1579 var CASES = [ 1580 { id: 'lottie', name: 'СÑена Alpha Suite', css: '' }, 1581 { id: 'dust', name: 'ÐÑÐ»Ñ Ð² лÑÑе Season', css: '.beam-dust{display:none!important}' }, 1582 { id: 'beam', name: 'ÐÑÑ Ð»ÐµÐ½Ñа Season', css: '.pts-beam{display:none!important}' }, 1583 { id: 'headerbg',name: 'РазмÑÑие Ñапки', css: '.header{backdrop-filter:none!important;-webkit-backdrop-filter:none!important;background:#06060c!important}' }, 1584 { id: 'masks', name: 'ÐаÑки security и trade', css: '.security-3d,#trade-circuit{-webkit-mask-image:none!important;mask-image:none!important}' }, 1585 { id: 'webgl', name: 'WebGL-кнопки', css: '.lm-canvas{display:none!important}' }, 1586 { id: 'shield', name: 'Ð©Ð¸Ñ security (3D)', css: '.security-3d canvas{display:none!important}' }, 1587 { id: 'pulser', name: 'Ð¡Ñ ÐµÐ¼Ð° в trade', css: '#trade-circuit{display:none!important}' }, 1588 { id: 'coins', name: 'ÐенÑа монеÑ', css: '.coins-track{animation:none!important}' }, 1589 { id: 'anim', name: 'ÐСРcss-анимаÑии', css: '*{animation:none!important;transition:none!important}' } 1590 ]; 1591 1592 var style = document.createElement('style'); 1593 document.head.appendChild(style); 1594 var off = {}; 1595 1596 function applyCases() { 1597 var css = ''; 1598 CASES.forEach(function (c) { if (off[c.id] && c.css) css += c.css + '\n'; }); 1599 style.textContent = css; 1600 var lot = window.__calloutsLottie; 1601 if (lot) { off.lottie ? lot.pause() : lot.play(); } 1602 } 1603 1604 var panel = document.createElement('div'); 1605 panel.setAttribute('style', [ 1606 'position:fixed', 'right:8px', 'bottom:8px', 'z-index:99999', 1607 'width:250px', 'max-height:70vh', 'overflow:auto', 1608 'background:rgba(0,0,0,.88)', 'color:#fff', 'border:1px solid rgba(255,255,255,.2)', 1609 'border-radius:10px', 'padding:10px 12px', 1610 'font:12px/1.45 ui-monospace,Menlo,Consolas,monospace', 1611 '-webkit-backdrop-filter:none', 'backdrop-filter:none' 1612 ].join(';')); 1613 1614 var read = document.createElement('div'); 1615 read.style.cssText = 'font-size:13px;margin-bottom:8px'; 1616 panel.appendChild(read); 1617 1618 var hint = document.createElement('div'); 1619 hint.style.cssText = 'color:#869396;margin-bottom:8px'; 1620 hint.textContent = 'ÐÑÑÑиÑе ÑÑÑаниÑÑ. ÐаÑем гаÑиÑе пÑнкÑÑ Ð¿Ð¾ Ð¾Ð´Ð½Ð¾Ð¼Ñ Ð¸ ÑмоÑÑиÑе, ÑÑо ÑбиÑÐ°ÐµÑ ÑÑвки.'; 1621 panel.appendChild(hint); 1622 1623 CASES.forEach(function (c) { 1624 var row = document.createElement('label'); 1625 row.style.cssText = 'display:flex;align-items:center;gap:8px;padding:3px 0;color:#cfd6d7'; 1626 var cb = document.createElement('input'); 1627 cb.type = 'checkbox'; 1628 cb.onchange = function () { off[c.id] = cb.checked; applyCases(); reset(); }; 1629 row.appendChild(cb); 1630 row.appendChild(document.createTextNode('вÑклÑÑиÑÑ: ' + c.name)); 1631 panel.appendChild(row);
1632 }); 1633 1634 var btn = document.createElement('button'); 1635 btn.textContent = 'СбÑоÑиÑÑ ÑÑÑÑÑики'; 1636 btn.style.cssText = 'margin-top:8px;width:100%;padding:7px;border-radius:6px;border:1px solid rgba(255,255,255,.25);background:#1a1a1a;color:#fff;font:inherit'; 1637 panel.appendChild(btn); 1638 document.body.appendChild(panel); 1639 1640 var frames = 0, long33 = 0, long100 = 0, worst = 0, t0 = 0, last = 0; 1641 function reset() { frames = 0; long33 = 0; long100 = 0; worst = 0; t0 = performance.now(); last = t0; } 1642 btn.onclick = reset; 1643 reset(); 1644 1645 function tick(now) { 1646 var dt = now - last; last = now; 1647 frames++; 1648 if (dt > 33) long33++; 1649 if (dt > 100) long100++; 1650 if (dt > worst) worst = dt; 1651 var sec = (now - t0) / 1000; 1652 if (sec > 0.4) { 1653 read.innerHTML = 1654 '<b>' + Math.round(frames / sec) + ' fps</b> за ' + sec.toFixed(0) + ' Ñ<br>' + 1655 'ÑÑвков (>33 мÑ): <b>' + long33 + '</b><br>' + 1656 'ÑилÑнÑÑ (>100 мÑ): <b>' + long100 + '</b><br>' + 1657 'Ñ ÑдÑий кадÑ: <b>' + Math.round(worst) + ' мÑ</b>'; 1658 } 1659 requestAnimationFrame(tick); 1660 } 1661 requestAnimationFrame(tick); 1662 })();
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.