{"product_id":"elephant-stl","title":"ELEPHANT STL","description":"\u003cp\u003eELEPHANT STL \u003c\/p\u003e\n\u003cp\u003e \u003c\/p\u003e\n\u003cp\u003e \u003c\/p\u003e\n\u003cp\u003e——————————-\u003c\/p\u003e\n\u003cp\u003e(function() {\u003cbr\u003e \/\/ ═══════════════════════════════════════════════════════════════\u003cbr\u003e \/\/ RUNWAY AUTO-GENERATE v6 - BALANCEADA\u003cbr\u003e \/\/ 2 clicks por burst, pausa de 14-17 min entre bursts completos.\u003cbr\u003e \/\/ Si un burst queda incompleto, re-evalua en 30s.\u003cbr\u003e \/\/ Stop: window.__runwayStop() Status: window.__runwayStatus()\u003cbr\u003e \/\/ ═══════════════════════════════════════════════════════════════\u003c\/p\u003e\n\u003cp\u003eif (window.__runwayBotActive) {\u003cbr\u003e console.warn('Bot ya activo. window.__runwayStop() primero.');\u003cbr\u003e return;\u003cbr\u003e }\u003cbr\u003e window.__runwayBotActive = true;\u003c\/p\u003e\n\u003cp\u003e\/\/ ─── Config v6 ────────────────────────────────────────────────\u003cbr\u003e var MAX_ACTIVE_TASKS = 2;\u003cbr\u003e var GAP_MIN_SEC = 7;\u003cbr\u003e var GAP_MAX_SEC = 15;\u003cbr\u003e var SAFETY_PAUSE_MIN = 14;\u003cbr\u003e var SAFETY_PAUSE_MAX = 17;\u003cbr\u003e var INCOMPLETE_BURST_RETRY_SEC = 30;\u003cbr\u003e var THROTTLE_BACKOFF = 60;\u003cbr\u003e var CHECK_INTERVAL_MS = 3000;\u003cbr\u003e var ACTIVE_STATES = ['PENDING', 'RUNNING', 'THROTTLED'];\u003c\/p\u003e\n\u003cp\u003e\/\/ ─── Estado interno ───────────────────────────────────────────\u003cbr\u003e var taskStates = {};\u003cbr\u003e var stopped = false;\u003cbr\u003e var lastBurstEndTs = 0;\u003cbr\u003e var lastBurstClicks = 0;\u003cbr\u003e var nextBurstAfterTs = Date.now();\u003cbr\u003e var throttleCount = 0;\u003cbr\u003e var clicksSent = 0;\u003cbr\u003e var burstsSent = 0;\u003c\/p\u003e\n\u003cp\u003efunction rand(a, b) { return Math.random() * (b - a) + a; }\u003cbr\u003e function sleep(ms) { return new Promise(function(r){ setTimeout(r, ms); }); }\u003cbr\u003e function ts() { return new Date().toLocaleTimeString('en-GB'); }\u003cbr\u003e function log(msg) { console.log('%c[' + ts() + '] ' + msg, 'color:#4ade80;font-weight:bold'); }\u003cbr\u003e function warn(msg) { console.warn('[' + ts() + '] ' + msg); }\u003c\/p\u003e\n\u003cp\u003ewindow.__runwayStop = function() {\u003cbr\u003e stopped = true;\u003cbr\u003e window.__runwayBotActive = false;\u003cbr\u003e warn('STOP solicitado.');\u003cbr\u003e };\u003c\/p\u003e\n\u003cp\u003eif (!window.__origFetchBot) {\u003cbr\u003e window.__origFetchBot = window.fetch;\u003cbr\u003e } else {\u003cbr\u003e window.fetch = window.__origFetchBot;\u003cbr\u003e }\u003cbr\u003e window.fetch = async function() {\u003cbr\u003e var args = arguments;\u003cbr\u003e var url = typeof args[0] === 'string' ? args[0] : (args[0] \u0026amp;\u0026amp; args[0].url);\u003cbr\u003e var res = await window.__origFetchBot.apply(this, args);\u003cbr\u003e var m = url \u0026amp;\u0026amp; url.match(\/\\\/v1\\\/tasks\\\/([0-9a-f-]{36})\/);\u003cbr\u003e if (m \u0026amp;\u0026amp; res.ok) {\u003cbr\u003e var uuid = m[1];\u003cbr\u003e try {\u003cbr\u003e var clone = res.clone();\u003cbr\u003e var json = await clone.json();\u003cbr\u003e var t = (json \u0026amp;\u0026amp; json.task) ? json.task : json;\u003cbr\u003e if (t \u0026amp;\u0026amp; t.status) {\u003cbr\u003e var prev = taskStates[uuid];\u003cbr\u003e taskStates[uuid] = t.status;\u003cbr\u003e if (prev !== t.status) {\u003cbr\u003e log('Task ' + uuid.slice(0,8) + ': ' + (prev || '(new)') + ' -\u0026gt; ' + t.status);\u003cbr\u003e if (t.status === 'THROTTLED') throttleCount++;\u003cbr\u003e else if (t.status === 'SUCCEEDED' || t.status === 'RUNNING') throttleCount = 0;\u003cbr\u003e }\u003cbr\u003e }\u003cbr\u003e } catch(e) {}\u003cbr\u003e }\u003cbr\u003e return res;\u003cbr\u003e };\u003c\/p\u003e\n\u003cp\u003efunction countActive() {\u003cbr\u003e var c = 0;\u003cbr\u003e for (var k in taskStates) if (ACTIVE_STATES.indexOf(taskStates[k]) !== -1) c++;\u003cbr\u003e return c;\u003cbr\u003e }\u003c\/p\u003e\n\u003cp\u003efunction findGenerateButton() {\u003cbr\u003e var btns = document.querySelectorAll('button[type=\"submit\"]');\u003cbr\u003e for (var i = 0; i \u0026lt; btns.length; i++) {\u003cbr\u003e var b = btns[i];\u003cbr\u003e if ((b.textContent || '').trim() === 'Generate' \u0026amp;\u0026amp; b.offsetParent !== null) return b;\u003cbr\u003e }\u003cbr\u003e var all = document.querySelectorAll('button');\u003cbr\u003e for (var i = 0; i \u0026lt; all.length; i++) {\u003cbr\u003e var b = all[i];\u003cbr\u003e if ((b.textContent || '').trim() === 'Generate' \u0026amp;\u0026amp; b.offsetParent !== null) return b;\u003cbr\u003e }\u003cbr\u003e return null;\u003cbr\u003e }\u003c\/p\u003e\n\u003cp\u003easync function humanClick() {\u003cbr\u003e var btn = findGenerateButton();\u003cbr\u003e if (!btn) { warn('Boton Generate no encontrado.'); return false; }\u003cbr\u003e if (btn.getAttribute('data-soft-disabled') === 'true' || btn.disabled) {\u003cbr\u003e warn('Boton soft-disabled. Skip.');\u003cbr\u003e return false;\u003cbr\u003e }\u003cbr\u003e var rect = btn.getBoundingClientRect();\u003cbr\u003e var mx = rect.width * 0.20, my = rect.height * 0.25;\u003cbr\u003e var x = rect.left + rand(mx, rect.width - mx);\u003cbr\u003e var y = rect.top + rand(my, rect.height - my);\u003cbr\u003e log('Click en (' + x.toFixed(1) + ', ' + y.toFixed(1) + ')');\u003c\/p\u003e\n\u003cp\u003evar base = { bubbles:true, cancelable:true, composed:true, view:window,\u003cbr\u003e clientX:x, clientY:y, screenX:x, screenY:y, button:0, buttons:1 };\u003cbr\u003e var baseUp = Object.assign({}, base, { buttons:0 });\u003c\/p\u003e\n\u003cp\u003ebtn.dispatchEvent(new PointerEvent('pointermove', Object.assign({}, baseUp, { pointerType:'mouse', pointerId:1 })));\u003cbr\u003e btn.dispatchEvent(new MouseEvent('mousemove', baseUp));\u003cbr\u003e await sleep(rand(80, 180));\u003cbr\u003e btn.dispatchEvent(new PointerEvent('pointerdown', Object.assign({}, base, { pointerType:'mouse', pointerId:1, isPrimary:true })));\u003cbr\u003e btn.dispatchEvent(new MouseEvent('mousedown', base));\u003cbr\u003e await sleep(rand(40, 110));\u003cbr\u003e btn.dispatchEvent(new PointerEvent('pointerup', Object.assign({}, baseUp, { pointerType:'mouse', pointerId:1, isPrimary:true })));\u003cbr\u003e btn.dispatchEvent(new MouseEvent('mouseup', baseUp));\u003cbr\u003e btn.dispatchEvent(new MouseEvent('click', baseUp));\u003c\/p\u003e\n\u003cp\u003eclicksSent++;\u003cbr\u003e return true;\u003cbr\u003e }\u003c\/p\u003e\n\u003cp\u003easync function runBurst() {\u003cbr\u003e burstsSent++;\u003cbr\u003e log('===== BURST #' + burstsSent + ' =====');\u003cbr\u003e var clicksThisBurst = 0;\u003c\/p\u003e\n\u003cp\u003ewhile (!stopped \u0026amp;\u0026amp; clicksThisBurst \u0026lt; MAX_ACTIVE_TASKS) {\u003cbr\u003e if (countActive() \u0026gt;= MAX_ACTIVE_TASKS) {\u003cbr\u003e log('Cola llena. Burst termina.');\u003cbr\u003e break;\u003cbr\u003e }\u003cbr\u003e var ok = await humanClick();\u003cbr\u003e if (ok) {\u003cbr\u003e clicksThisBurst++;\u003cbr\u003e log('Click ' + clicksThisBurst + '\/' + MAX_ACTIVE_TASKS + ' enviado.');\u003cbr\u003e } else break;\u003c\/p\u003e\n\u003cp\u003eif (clicksThisBurst \u0026lt; MAX_ACTIVE_TASKS) {\u003cbr\u003e var gap = rand(GAP_MIN_SEC, GAP_MAX_SEC);\u003cbr\u003e log('Esperando ' + gap.toFixed(1) + 's...');\u003cbr\u003e await sleep(gap * 1000);\u003cbr\u003e if (countActive() \u0026gt;= MAX_ACTIVE_TASKS) {\u003cbr\u003e log('Cola llena tras el gap. Burst termina con ' + clicksThisBurst + ' click(s).');\u003cbr\u003e break;\u003cbr\u003e }\u003cbr\u003e }\u003cbr\u003e }\u003c\/p\u003e\n\u003cp\u003elastBurstEndTs = Date.now();\u003cbr\u003e lastBurstClicks = clicksThisBurst;\u003cbr\u003e log('Burst #' + burstsSent + ' completado. Clicks: ' + clicksThisBurst);\u003cbr\u003e }\u003c\/p\u003e\n\u003cp\u003efunction scheduleNextBurst() {\u003cbr\u003e var pauseMs;\u003cbr\u003e if (lastBurstClicks \u0026lt; MAX_ACTIVE_TASKS) {\u003cbr\u003e pauseMs = INCOMPLETE_BURST_RETRY_SEC * 1000;\u003cbr\u003e log('Burst incompleto. Re-evaluacion en ' + INCOMPLETE_BURST_RETRY_SEC + 's.');\u003cbr\u003e } else {\u003cbr\u003e pauseMs = rand(SAFETY_PAUSE_MIN, SAFETY_PAUSE_MAX) * 60 * 1000;\u003cbr\u003e }\u003cbr\u003e var throttleMs = throttleCount * THROTTLE_BACKOFF * 1000;\u003cbr\u003e nextBurstAfterTs = lastBurstEndTs + pauseMs + throttleMs;\u003cbr\u003e var nextDate = new Date(nextBurstAfterTs).toLocaleTimeString('en-GB');\u003cbr\u003e log('Proximo intento: ' + nextDate +\u003cbr\u003e ' (' + (pauseMs \/ 60000).toFixed(1) + 'min' +\u003cbr\u003e (throttleCount \u0026gt; 0 ? ' + ' + throttleCount + ' throttle-backoffs' : '') + ')');\u003cbr\u003e }\u003c\/p\u003e\n\u003cp\u003easync function mainLoop() {\u003cbr\u003e log('Bot v6 BALANCEADA activo.');\u003cbr\u003e while (!stopped) {\u003cbr\u003e await sleep(CHECK_INTERVAL_MS);\u003cbr\u003e if (Date.now() \u0026lt; nextBurstAfterTs) continue;\u003cbr\u003e if (countActive() \u0026gt;= MAX_ACTIVE_TASKS) continue;\u003cbr\u003e await runBurst();\u003cbr\u003e scheduleNextBurst();\u003cbr\u003e }\u003cbr\u003e log('Bot v6 detenido. Bursts: ' + burstsSent + ', clicks: ' + clicksSent);\u003cbr\u003e }\u003c\/p\u003e\n\u003cp\u003ewindow.__runwayStatus = function() {\u003cbr\u003e console.log('=== ESTADO BOT v6 BALANCEADA ===');\u003cbr\u003e console.log('Bursts:', burstsSent, '| Clicks:', clicksSent);\u003cbr\u003e console.log('Tasks activas:', countActive(), '\/', MAX_ACTIVE_TASKS);\u003cbr\u003e console.log('Ultimo burst:', lastBurstClicks, 'clicks');\u003cbr\u003e console.log('Throttles acumulados:', throttleCount);\u003cbr\u003e console.log('Estados:', taskStates);\u003cbr\u003e var waitS = Math.max(0, (nextBurstAfterTs - Date.now()) \/ 1000);\u003cbr\u003e console.log('Proximo en:', waitS.toFixed(0) + 's');\u003cbr\u003e };\u003c\/p\u003e\n\u003cp\u003emainLoop();\u003cbr\u003e})();\u003c\/p\u003e\n\u003cp\u003e \u003c\/p\u003e\n\u003cp\u003e \u003c\/p\u003e","brand":"FUSSION3D","offers":[{"title":"Default Title","offer_id":53671557366126,"sku":null,"price":3.99,"currency_code":"USD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0988\/4139\/5566\/files\/3.png?v=1777101794","url":"https:\/\/fussion3d.com\/products\/elephant-stl","provider":"FUSSION3D","version":"1.0","type":"link"}