{"slug": "script-ai-js", "title": "script-ai.js", "summary": "A developer published script-ai.js, a browser bookmarklet that injects a draggable \"QX AI V16.2\" overlay panel into any web page. The script cycles through a hardcoded list of local and LAN server addresses on port 5050, suggesting it connects to a self-hosted AI backend rather than a cloud service.", "body_md": "|  | javascript:(function(){ | \n|  | var old=document.getElementById('qx-ai-root'); | \n|  | if(old)old.remove(); | \n|  | var SERVERS=[ | \n|  | 'http://127.0.0.1:5050', | \n|  | 'http://192.168.0.103:5050', | \n|  | 'http://10.254.60.18:5050', | \n|  | 'http://192.168.0.100:5050', | \n|  | 'http://192.168.0.117:5050', | \n|  | 'http://192.168.0.205:5050' | \n|  | ]; | \n|  | var serverIndex=0; | \n|  | var host=document.createElement('div'); | \n|  | host.id='qx-ai-root'; | \n|  | host.style.cssText='position:fixed;top:0;left:0;width:0;height:0;z-index:999999999'; | \n|  | document.documentElement.appendChild(host); | \n|  | var css=document.createElement('style'); | \n|  | css.textContent= | \n|  | '#qx-ai-root *{box-sizing:border-box;font-family:system-ui,sans-serif;user-select:none;-webkit-tap-highlight-color:transparent}'+ | \n|  | '.qx-i{position:fixed;top:70px;right:12px;width:54px;height:54px;border-radius:50%;background:#0f172a;border:2px solid #38bdf8;color:#38bdf8;font-weight:800;font-size:11px;display:flex;align-items:center;justify-content:center;cursor:grab;z-index:999999999;box-shadow:0 0 16px rgba(56,189,248,.45);touch-action:none}'+ | \n|  | '.qx-p{position:fixed;top:80px;left:8px;width:min(420px,96vw);min-height:200px;background:rgba(7,18,36,.98);color:#e2e8f0;border:1px solid #334155;border-radius:16px;display:none;overflow:hidden;z-index:999999998;box-shadow:0 20px 50px #000;flex-direction:column}'+ | \n|  | '.qx-p.show{display:flex}'+ | \n|  | '.qx-h{background:linear-gradient(90deg,#0ea5e9,#6366f1);padding:12px 14px;font-weight:700;font-size:13px;display:flex;justify-content:space-between;align-items:center;cursor:move;touch-action:none}'+ | \n|  | '.qx-b{padding:12px;overflow-y:auto;flex:1;max-height:78vh}'+ | \n|  | '.qx-res{text-align:center;padding:12px;background:#1e293b;border-radius:12px;font-size:14px;font-weight:700;margin-bottom:8px;border:1px solid #334155}'+ | \n|  | '.qx-meta{font-size:11px;color:#94a3b8;line-height:1.45;margin-bottom:8px}'+ | \n|  | '.qx-row{display:flex;gap:6px;flex-wrap:wrap;margin:6px 0}'+ | \n|  | '.qx-row label{font-size:11px;color:#94a3b8;display:flex;flex-direction:column;gap:3px;flex:1;min-width:90px}'+ | \n|  | '.qx-row select,.qx-row input{background:#0f172a;border:1px solid #334155;color:#e2e8f0;border-radius:8px;padding:6px 8px;font-size:12px}'+ | \n|  | '.qx-btn{flex:1;padding:10px;border:0;border-radius:10px;font-weight:700;font-size:12px;cursor:pointer}'+ | \n|  | '.qx-scan{background:linear-gradient(90deg,#0ea5e9,#6366f1);color:#fff}'+ | \n|  | '.qx-stop{background:#7f1d1d;color:#fecaca}'+ | \n|  | '.qx-tog{background:#1e293b;color:#94a3b8;border:1px solid #334155}'+ | \n|  | '.qx-tog.on{background:#14532d;color:#86efac;border-color:#22c55e}'+ | \n|  | '.qx-ov{position:fixed;inset:0;background:rgba(15,23,42,.28);backdrop-filter:blur(2px);z-index:999999990;display:none;pointer-events:none}'+ | \n|  | '.qx-ov.on{display:block}'+ | \n|  | '.qx-laser{position:absolute;left:0;width:100%;height:3px;background:linear-gradient(90deg,transparent,#38bdf8,#818cf8,transparent);box-shadow:0 0 14px #38bdf8;animation:qxScan 1.1s ease-in-out infinite alternate}'+ | \n|  | '@keyframes qxScan{from{top:4%}to{top:96%}}'+ | \n|  | '.qx-rs{position:absolute;right:0;bottom:0;width:18px;height:18px;cursor:nwse-resize;background:linear-gradient(135deg,transparent 50%,#38bdf8 50%);opacity:.7}'; | \n|  | host.appendChild(css); | \n|  | var overlay=document.createElement('div'); | \n|  | overlay.className='qx-ov'; | \n|  | overlay.innerHTML='<div class=\"qx-laser\"></div>'; | \n|  | host.appendChild(overlay); | \n|  | var icon=document.createElement('div'); | \n|  | icon.className='qx-i'; | \n|  | icon.textContent='QX'; | \n|  | host.appendChild(icon); | \n|  | var panel=document.createElement('div'); | \n|  | panel.className='qx-p'; | \n|  | panel.innerHTML= | \n|  | '<div class=\"qx-h\"><span>QX AI V16.2</span><span id=\"qxSrv\" style=\"font-size:10px;opacity:.85\">...</span></div>'+ | \n|  | '<div class=\"qx-b\">'+ | \n|  | '<div class=\"qx-res\" id=\"qxResult\">Ready</div>'+ | \n|  | '<div class=\"qx-meta\" id=\"qxMeta\">Connecting...</div>'+ | \n|  | '<div class=\"qx-row\">'+ | \n|  | '<label>Candles<select id=\"qxCandles\"><option>30</option><option selected>50</option><option>80</option><option>100</option><option>200</option><option>300</option><option value=\"all\">ALL</option></select></label>'+ | \n|  | '<label>Duration<select id=\"qxDur\"><option value=\"5\">5s</option><option value=\"10\">10s</option><option value=\"15\">15s</option><option value=\"30\">30s</option><option value=\"60\" selected>60s</option></select></label>'+ | \n|  | '<label>Trades<input id=\"qxTrades\" type=\"number\" min=\"1\" max=\"20\" value=\"1\"></label>'+ | \n|  | '</div>'+ | \n|  | '<div class=\"qx-row\">'+ | \n|  | '<label>Entry<select id=\"qxEntry\"><option value=\"smart\">Smart</option><option value=\"before_1s\">Before 1s</option><option value=\"before_2s\">Before 2s</option><option value=\"exact\">Exact 00</option><option value=\"instant\">Instant</option></select></label>'+ | \n|  | '<label>Mode<select id=\"qxMode\"><option value=\"normal\">Normal</option><option value=\"ultra\">Ultra</option></select></label>'+ | \n|  | '<label>After<select id=\"qxAfter\"><option value=\"2s\">2s</option><option value=\"now\">Now</option><option value=\"duration\">Duration</option></select></label>'+ | \n|  | '</div>'+ | \n|  | '<div class=\"qx-row\">'+ | \n|  | '<button class=\"qx-btn qx-scan\" id=\"qxScan\">SCAN / LOOP</button>'+ | \n|  | '<button class=\"qx-btn qx-stop\" id=\"qxStop\">STOP</button>'+ | \n|  | '</div>'+ | \n|  | '<div class=\"qx-row\">'+ | \n|  | '<button class=\"qx-btn qx-tog\" id=\"qxAnim\">ANIM ON</button>'+ | \n|  | '<button class=\"qx-btn qx-tog\" id=\"qxHunt\">HUNT OFF</button>'+ | \n|  | '</div>'+ | \n|  | '</div>'+ | \n|  | '<div class=\"qx-rs\" id=\"qxRs\"></div>'; | \n|  | host.appendChild(panel); | \n|  | function $(id){return panel.querySelector('#'+id)\\|\\|document.getElementById(id);} | \n|  | var STOP=false,BUSY=false,LOCK=false,HUNT=false,ANIM=true; | \n|  | var TIMERS=[]; | \n|  | function beep(){ | \n|  | try{ | \n|  | var a=new (window.AudioContext\\|\\|window.webkitAudioContext)(); | \n|  | var o=a.createOscillator();var g=a.createGain(); | \n|  | o.connect(g);g.connect(a.destination); | \n|  | o.frequency.value=880;g.gain.value=0.04;o.start(); | \n|  | setTimeout(function(){try{o.stop();a.close();}catch(e){}},120); | \n|  | }catch(e){} | \n|  | } | \n|  | function fetchJSON(path,opt,retry){ | \n|  | retry=retry\\|\\|3; | \n|  | opt=opt\\|\\|{}; | \n|  | return new Promise(function(resolve,reject){ | \n|  | var last=null; | \n|  | var attempt=0; | \n|  | function tryOnce(){ | \n|  | if(attempt>=retry){reject(last\\|\\|new Error('offline'));return;} | \n|  | attempt++; | \n|  | var s; | \n|  | var chain=Promise.resolve(); | \n|  | for(s=0;s<SERVERS.length;s++){ | \n|  | (function(idx){ | \n|  | chain=chain.then(function(done){ | \n|  | if(done)return done; | \n|  | var base=SERVERS[(serverIndex+idx)%SERVERS.length]; | \n|  | var ctrl=typeof AbortController!=='undefined'?new AbortController():null; | \n|  | var to=ctrl?setTimeout(function(){ctrl.abort();},16000):null; | \n|  | var o2={}; | \n|  | for(var k in opt){if(Object.prototype.hasOwnProperty.call(opt,k))o2[k]=opt[k];} | \n|  | if(ctrl)o2.signal=ctrl.signal; | \n|  | return fetch(base+path,o2).then(function(r){ | \n|  | if(to)clearTimeout(to); | \n|  | if(!r.ok)throw new Error('HTTP '+r.status); | \n|  | serverIndex=(serverIndex+idx)%SERVERS.length; | \n|  | var el=$('qxSrv'); | \n|  | if(el)el.textContent=base.replace('http://',''); | \n|  | return r.json().then(function(j){return {ok:true,j:j};}); | \n|  | }).catch(function(e){last=e;if(to)clearTimeout(to);return null;}); | \n|  | }); | \n|  | })(s); | \n|  | } | \n|  | chain.then(function(done){ | \n|  | if(done&&done.ok)resolve(done.j); | \n|  | else setTimeout(tryOnce,400); | \n|  | }); | \n|  | } | \n|  | tryOnce(); | \n|  | }); | \n|  | } | \n|  | function clickDir(dir){ | \n|  | try{ | \n|  | document.querySelectorAll('[class*=\"close\"],[aria-label=\"Close\"]').forEach(function(b){try{b.click();}catch(e){}}); | \n|  | }catch(e){} | \n|  | var btns=[].slice.call(document.querySelectorAll('button,div[role=\"button\"],[class*=\"btn\"]')); | \n|  | var keys=dir==='UP'?['up','call','higher']:['down','put','lower']; | \n|  | for(var i=0;i<btns.length;i++){ | \n|  | var b=btns[i]; | \n|  | var t=((b.innerText\\|\\|b.textContent\\|\\|'')+'').toLowerCase().trim(); | \n|  | if(!t\\|\\|t.length>24)continue; | \n|  | var hit=false; | \n|  | for(var k=0;k<keys.length;k++){if(t.indexOf(keys[k])>=0)hit=true;} | \n|  | if(hit&&t.indexOf('support')<0&&t.indexOf('chat')<0&&t.indexOf('deposit')<0){ | \n|  | try{b.dispatchEvent(new PointerEvent('pointerdown',{bubbles:true}));}catch(e){} | \n|  | b.click(); | \n|  | return true; | \n|  | } | \n|  | } | \n|  | return false; | \n|  | } | \n|  | function doTrades(dir,num){ | \n|  | if(LOCK\\|\\|dir==='WAIT')return; | \n|  | LOCK=true; | \n|  | var max=Math.min(20,Math.max(1,parseInt(num,10)\\|\\|1)); | \n|  | var done=0; | \n|  | var iv=setInterval(function(){ | \n|  | if(done>=max){clearInterval(iv);LOCK=false;return;} | \n|  | clickDir(dir);done++; | \n|  | },280); | \n|  | } | \n|  | function isGoodSignal(g){ | \n|  | var dir=(g.direction\\|\\|'WAIT').toUpperCase(); | \n|  | if(dir==='CALL')dir='UP'; | \n|  | if(dir==='PUT')dir='DOWN'; | \n|  | if((g.status\\|\\|'')==='SIGNAL'&&(dir==='UP'\\|\\|dir==='DOWN')){ | \n|  | var z=g.zone\\|\\|{}; | \n|  | if(dir==='UP'&&z.chase_up)return{ok:false,dir:dir,why:'chase'}; | \n|  | if(dir==='DOWN'&&z.chase_dn)return{ok:false,dir:dir,why:'chase'}; | \n|  | return{ok:true,dir:dir,conf:parseInt(g.confidence,10)\\|\\|62,why:'server'}; | \n|  | } | \n|  | if(dir!=='UP'&&dir!=='DOWN'){ | \n|  | return{ok:false,dir:dir,why:String(g.wait_why\\|\\|g.reason\\|\\|'WAIT').slice(0,48)}; | \n|  | } | \n|  | var z2=g.zone\\|\\|{}; | \n|  | if(dir==='UP'&&z2.chase_up)return{ok:false,dir:dir,why:'chase'}; | \n|  | if(dir==='DOWN'&&z2.chase_dn)return{ok:false,dir:dir,why:'chase'}; | \n|  | return{ok:true,dir:dir,conf:parseInt(g.confidence,10)\\|\\|62,why:'ok'}; | \n|  | } | \n|  | function entryStillOk(dir){ | \n|  | return fetchJSON('/pressure?dir='+encodeURIComponent(dir),{method:'GET'},2).then(function(p){ | \n|  | if(p.block)return{ok:false,why:p.block_reason\\|\\|'block'}; | \n|  | return{ok:true,why:'ok'}; | \n|  | }).catch(function(){return{ok:true,why:'skip_check'};}); | \n|  | } | \n|  | function sleep(ms){ | \n|  | return new Promise(function(r){var t=setTimeout(r,ms);TIMERS.push(t);}); | \n|  | } | \n|  | function oneSignalCall(){ | \n|  | var body={ | \n|  | candle_limit:$('qxCandles').value, | \n|  | duration:parseInt($('qxDur').value,10)\\|\\|60, | \n|  | mode:$('qxMode').value\\|\\|'normal' | \n|  | }; | \n|  | return fetchJSON('/signal',{ | \n|  | method:'POST', | \n|  | headers:{'Content-Type':'application/json'}, | \n|  | body:JSON.stringify(body) | \n|  | }); | \n|  | } | \n|  | function paintMeta(g){ | \n|  | var L=g.learn\\|\\|{}; | \n|  | var z=g.zone\\|\\|{}; | \n|  | var txt= | \n|  | 'Mkt '+(g.market\\|\\|'-')+ | \n|  | ' \\| C '+(g.candles_loaded\\|\\|0)+'/'+(g.candles_total\\|\\|0)+ | \n|  | ' \\| T '+(g.ticks_loaded\\|\\|0)+'/'+(g.ticks_total\\|\\|0)+ | \n|  | ' \\| Local '+(g.local_direction\\|\\|'-')+ | \n|  | ' Q'+Math.round(g.q\\|\\|g.local_score\\|\\|0)+ | \n|  | ' agree '+(g.agree\\|\\|0)+'/5'+ | \n|  | ' class '+(g.setup_class\\|\\|'-')+ | \n|  | ' \\| closed '+(g.closed_bias\\|\\|'-')+ | \n|  | ' pd '+(z.pd\\|\\|'-')+ | \n|  | ' \\| W/L '+(L.wins\\|\\|0)+'/'+(L.losses\\|\\|0)+ | \n|  | ' ('+(L.win_rate\\|\\|0)+'%)'+ | \n|  | ' \\| '+(g.wait_why\\|\\|g.reason\\|\\|''); | \n|  | $('qxMeta').textContent=txt.slice(0,320); | \n|  | } | \n|  | function fireEntryAdaptive(dir,cnt,mode,delayMs){ | \n|  | if(mode==='instant'){ | \n|  | return entryStillOk(dir).then(function(chk){ | \n|  | if(!chk.ok)return{ok:false,why:chk.why}; | \n|  | doTrades(dir,cnt); | \n|  | return{ok:true,dir:dir}; | \n|  | }); | \n|  | } | \n|  | var wait=delayMs; | \n|  | if(mode==='before_1s')wait=Math.max(0,delayMs-1000); | \n|  | if(mode==='before_2s')wait=Math.max(0,delayMs-2000); | \n|  | if(mode==='exact')wait=delayMs; | \n|  | if(mode==='smart')wait=Math.max(200,delayMs-400); | \n|  | $('qxResult').textContent=dir+' in '+Math.round(wait/1000)+'s'; | \n|  | return sleep(wait).then(function(){ | \n|  | if(STOP)return{ok:false,why:'stop'}; | \n|  | return entryStillOk(dir).then(function(chk){ | \n|  | if(!chk.ok){ | \n|  | return oneSignalCall().then(function(g){ | \n|  | paintMeta(g); | \n|  | var sg=isGoodSignal(g); | \n|  | if(!sg.ok)return{ok:false,why:chk.why+'\\|'+sg.why}; | \n|  | doTrades(sg.dir,cnt); | \n|  | return{ok:true,dir:sg.dir}; | \n|  | }); | \n|  | } | \n|  | doTrades(dir,cnt); | \n|  | return{ok:true,dir:dir}; | \n|  | }); | \n|  | }); | \n|  | } | \n|  | function runContinuousLoop(){ | \n|  | if(BUSY)return; | \n|  | BUSY=true;STOP=false; | \n|  | $('qxScan').disabled=true; | \n|  | function loop(){ | \n|  | if(STOP){ | \n|  | BUSY=false; | \n|  | $('qxScan').disabled=false; | \n|  | overlay.classList.remove('on'); | \n|  | return; | \n|  | } | \n|  | if(ANIM)overlay.classList.add('on'); | \n|  | $('qxResult').textContent='Analyzing...'; | \n|  | $('qxResult').style.color='#94a3b8'; | \n|  | oneSignalCall().then(function(g){ | \n|  | paintMeta(g); | \n|  | var chk=isGoodSignal(g); | \n|  | if(!chk.ok){ | \n|  | $('qxResult').textContent='WAIT - '+chk.why; | \n|  | $('qxResult').style.color='#fbbf24'; | \n|  | overlay.classList.remove('on'); | \n|  | return sleep(HUNT?2500:3500).then(function(){ | \n|  | if(HUNT&&!STOP)loop(); | \n|  | else{BUSY=false;$('qxScan').disabled=false;} | \n|  | }); | \n|  | } | \n|  | beep(); | \n|  | var cnt=Math.max(1,parseInt($('qxTrades').value,10)\\|\\|1); | \n|  | var mode=$('qxEntry').value; | \n|  | var delayMs=parseInt(g.delay_ms,10); | \n|  | if(!delayMs\\|\\|isNaN(delayMs)){ | \n|  | delayMs=(60-new Date().getSeconds())*1000-new Date().getMilliseconds(); | \n|  | if(delayMs<200)delayMs+=60000; | \n|  | } | \n|  | return fireEntryAdaptive(chk.dir,cnt,mode,delayMs).then(function(res){ | \n|  | if(res.ok){ | \n|  | $('qxResult').textContent=(res.dir\\|\\|chk.dir)+' x'+cnt; | \n|  | $('qxResult').style.color=(res.dir\\|\\|chk.dir)==='UP'?'#38bdf8':'#f87171'; | \n|  | }else{ | \n|  | $('qxResult').textContent='Skip entry - '+(res.why\\|\\|''); | \n|  | $('qxResult').style.color='#fbbf24'; | \n|  | } | \n|  | overlay.classList.remove('on'); | \n|  | var after=$('qxAfter').value; | \n|  | var cool=2000; | \n|  | if(after==='now')cool=400; | \n|  | if(after==='duration')cool=(parseInt($('qxDur').value,10)\\|\\|60)*1000+500; | \n|  | return sleep(cool).then(function(){ | \n|  | if(HUNT&&!STOP)loop(); | \n|  | else{BUSY=false;$('qxScan').disabled=false;} | \n|  | }); | \n|  | }); | \n|  | }).catch(function(){ | \n|  | $('qxResult').textContent='SERVER OFF'; | \n|  | $('qxResult').style.color='#f87171'; | \n|  | overlay.classList.remove('on'); | \n|  | sleep(2000).then(function(){ | \n|  | if(HUNT&&!STOP)loop(); | \n|  | else{BUSY=false;$('qxScan').disabled=false;} | \n|  | }); | \n|  | }); | \n|  | } | \n|  | loop(); | \n|  | } | \n|  | /* drag icon */ | \n|  | (function(){ | \n|  | var ox=0,oy=0,sx=0,sy=0,drag=false; | \n|  | function start(e){ | \n|  | drag=true; | \n|  | var p=e.touches?e.touches[0]:e; | \n|  | sx=p.clientX;sy=p.clientY; | \n|  | var r=icon.getBoundingClientRect();ox=r.left;oy=r.top; | \n|  | } | \n|  | function move(e){ | \n|  | if(!drag)return; | \n|  | e.preventDefault(); | \n|  | var p=e.touches?e.touches[0]:e; | \n|  | icon.style.left=(ox+p.clientX-sx)+'px'; | \n|  | icon.style.top=(oy+p.clientY-sy)+'px'; | \n|  | icon.style.right='auto'; | \n|  | } | \n|  | function end(){drag=false;} | \n|  | icon.addEventListener('mousedown',start); | \n|  | icon.addEventListener('touchstart',start,{passive:false}); | \n|  | window.addEventListener('mousemove',move,{passive:false}); | \n|  | window.addEventListener('touchmove',move,{passive:false}); | \n|  | window.addEventListener('mouseup',end); | \n|  | window.addEventListener('touchend',end); | \n|  | })(); | \n|  | /* drag panel + resize */ | \n|  | (function(){ | \n|  | var hd=panel.querySelector('.qx-h'); | \n|  | var ox=0,oy=0,sx=0,sy=0,drag=false; | \n|  | function start(e){ | \n|  | if(e.target&&e.target.id==='qxRs')return; | \n|  | drag=true; | \n|  | var p=e.touches?e.touches[0]:e; | \n|  | sx=p.clientX;sy=p.clientY; | \n|  | var r=panel.getBoundingClientRect();ox=r.left;oy=r.top; | \n|  | } | \n|  | function move(e){ | \n|  | if(!drag)return; | \n|  | e.preventDefault(); | \n|  | var p=e.touches?e.touches[0]:e; | \n|  | panel.style.left=(ox+p.clientX-sx)+'px'; | \n|  | panel.style.top=(oy+p.clientY-sy)+'px'; | \n|  | } | \n|  | function end(){drag=false;} | \n|  | hd.addEventListener('mousedown',start); | \n|  | hd.addEventListener('touchstart',start,{passive:false}); | \n|  | window.addEventListener('mousemove',move,{passive:false}); | \n|  | window.addEventListener('touchmove',move,{passive:false}); | \n|  | window.addEventListener('mouseup',end); | \n|  | window.addEventListener('touchend',end); | \n|  | var rs=$('qxRs'); | \n|  | var rw=false,bs=0,bh=0,bx=0,by=0; | \n|  | function rsStart(e){ | \n|  | rw=true; | \n|  | var p=e.touches?e.touches[0]:e; | \n|  | bx=p.clientX;by=p.clientY; | \n|  | var r=panel.getBoundingClientRect();bs=r.width;bh=r.height; | \n|  | e.preventDefault();e.stopPropagation(); | \n|  | } | \n|  | function rsMove(e){ | \n|  | if(!rw)return; | \n|  | var p=e.touches?e.touches[0]:e; | \n|  | panel.style.width=Math.max(280,bs+(p.clientX-bx))+'px'; | \n|  | panel.style.maxHeight='none'; | \n|  | panel.style.height=Math.max(180,bh+(p.clientY-by))+'px'; | \n|  | } | \n|  | function rsEnd(){rw=false;} | \n|  | rs.addEventListener('mousedown',rsStart); | \n|  | rs.addEventListener('touchstart',rsStart,{passive:false}); | \n|  | window.addEventListener('mousemove',rsMove); | \n|  | window.addEventListener('touchmove',rsMove,{passive:false}); | \n|  | window.addEventListener('mouseup',rsEnd); | \n|  | window.addEventListener('touchend',rsEnd); | \n|  | })(); | \n|  | icon.onclick=function(){panel.classList.toggle('show');}; | \n|  | $('qxAnim').onclick=function(){ | \n|  | ANIM=!ANIM; | \n|  | $('qxAnim').textContent=ANIM?'ANIM ON':'ANIM OFF'; | \n|  | if(ANIM)$('qxAnim').classList.add('on'); | \n|  | else $('qxAnim').classList.remove('on'); | \n|  | }; | \n|  | $('qxHunt').onclick=function(){ | \n|  | HUNT=!HUNT; | \n|  | $('qxHunt').textContent=HUNT?'HUNT ON':'HUNT OFF'; | \n|  | if(HUNT)$('qxHunt').classList.add('on'); | \n|  | else $('qxHunt').classList.remove('on'); | \n|  | }; | \n|  | $('qxScan').onclick=function(){ | \n|  | STOP=false;HUNT=true; | \n|  | $('qxHunt').classList.add('on'); | \n|  | $('qxHunt').textContent='HUNT ON'; | \n|  | runContinuousLoop(); | \n|  | }; | \n|  | $('qxStop').onclick=function(){ | \n|  | STOP=true;HUNT=false;BUSY=false;LOCK=false; | \n|  | TIMERS.forEach(clearTimeout);TIMERS=[]; | \n|  | $('qxHunt').classList.remove('on'); | \n|  | $('qxHunt').textContent='HUNT OFF'; | \n|  | overlay.classList.remove('on'); | \n|  | $('qxScan').disabled=false; | \n|  | $('qxResult').textContent='STOPPED'; | \n|  | $('qxResult').style.color='#f87171'; | \n|  | }; | \n|  | fetchJSON('/status',{method:'GET'}).then(function(s){ | \n|  | $('qxMeta').textContent= | \n|  | 'Online v'+(s.version\\|\\|'?')+ | \n|  | ' \\| '+(s.market\\|\\|'')+ | \n|  | ' \\| C'+(s.candles\\|\\|0)+ | \n|  | ' T'+(s.ticks\\|\\|0); | \n|  | }).catch(function(){ | \n|  | $('qxMeta').textContent='Server offline - check IP or tunnel'; | \n|  | }); | \n|  | })(); |", "url": "https://wpnews.pro/news/script-ai-js", "canonical_source": "https://gist.github.com/skillwavepro-arch/34e554718b49ac65dece5c240ef3236e", "published_at": "2026-09-09 16:54:06+00:00", "updated_at": "2026-10-01 06:18:46.428416+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "artificial-intelligence"], "entities": ["QX AI"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/script-ai-js", "markdown": "https://wpnews.pro/news/script-ai-js.md", "text": "https://wpnews.pro/news/script-ai-js.txt", "jsonld": "https://wpnews.pro/news/script-ai-js.jsonld"}}