Aparato de gimnasio prensa de pierna de peso libre

$27,900.00

Disponibilidad: 1 disponibles

Guaranteed Safe Checkout
,

Valoraciones

Valoraciones

No hay valoraciones aún.

Sé el primero en valorar “Aparato de gimnasio prensa de pierna de peso libre”

Descripción

El aparato de gimnasio de prensa para pierna, es uno de los ejercicios más efectivos para el desarrollo de fuerza en las piernas, con esta máquina podrás incrementar el peso de manera personalizada, tiene dos racks para discos olímpicos, suficientes para llevar tu entrenamiento al siguiente nivel.


ESPECIFICACIONES

Peso de la máquina: 150 Kg
Material: Acero y Forro de Uso Rudo.
Medidas: Largo 154 mm / Ancho 103 mm / Alto 168 mm
Tapizado: Espuma de alta densidad con vinil antibacteriano


BENEFICIOS

  • Su inclinación reduce la tensión en la espalda baja
  • Enfoca de manera efectiva todos los músculos de las piernas
  • Permite agregar cargas pesadas con seguridad y comodidad
  • Su movimiento guiado prioriza el entrenamiento de pierna sin involucrar otros músculos

TIENES DUDAS ACERCA DEL EQUIPO:
Envíanos un mensaje a WhatsApp o vía llamada telefónica, nuestros expertos resolverán todas tus dudas antes de comprar y te orientarán a la mejor opción

También te recomendamos…

Carrito de compra
CARRITO DE COMPRAS0
No hay productos en el carrito!
0
Scroll al inicio
// --- Self-executing function to encapsulate the entire widget --- (() => { // Wait for the main document to be fully loaded before running the script. document.addEventListener('DOMContentLoaded', () => { // 1. CREATE THE HOST ELEMENT AND ATTACH SHADOW DOM // This is the container on your main page where the widget will live. const host = document.createElement('div'); host.id = 'falcon-chat-host'; document.body.appendChild(host); // Attach a shadow root, which isolates the widget's HTML and CSS. const shadowRoot = host.attachShadow({ mode: 'open' }); // 2. DEFINE THE WIDGET'S CSS AND HTML // All styles are defined here and will only apply inside the shadow DOM. const widgetCSS = ` :host { /* Ensures the widget itself doesn't have strange default styles */ all: initial; } /* --- Fonts and Base Styles --- */ .font-inter { font-family: 'Inter', sans-serif; } /* --- Custom Scrollbar --- */ #chat-messages::-webkit-scrollbar { width: 8px; } #chat-messages::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 10px; } #chat-messages::-webkit-scrollbar-thumb { background: #888; border-radius: 10px; } #chat-messages::-webkit-scrollbar-thumb:hover { background: #555; } /* --- Animations --- */ .chat-window-enter { opacity: 0; transform: translateY(20px) scale(0.95); transition: opacity 0.3s ease-out, transform 0.3s ease-out; } .chat-window-enter-active { opacity: 1; transform: translateY(0) scale(1); } .chat-window-leave { opacity: 1; transform: translateY(0) scale(1); transition: opacity 0.2s ease-in, transform 0.2s ease-in; } .chat-window-leave-active { opacity: 0; transform: translateY(20px) scale(0.95); } /* --- Loading Pulse Animation --- */ @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } .animate-pulse { animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; } `; // The complete HTML structure for the chat widget. const widgetHTML = `
`; // 3. INJECT RESOURCES INTO THE SHADOW DOM // This adds the necessary external stylesheets and scripts inside the isolated widget. const fontLink = document.createElement('link'); fontLink.href = 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'; fontLink.rel = 'stylesheet'; shadowRoot.appendChild(fontLink); const tailwindScript = document.createElement('script'); tailwindScript.src = 'https://cdn.tailwindcss.com'; shadowRoot.appendChild(tailwindScript); const styleSheet = document.createElement('style'); styleSheet.textContent = widgetCSS; shadowRoot.appendChild(styleSheet); const htmlWrapper = document.createElement('div'); htmlWrapper.innerHTML = widgetHTML; shadowRoot.appendChild(htmlWrapper); // 4. WIDGET LOGIC (SCOPED TO THE SHADOW DOM) // All event listeners and functions will now only find elements inside the shadow root. const chatWindow = shadowRoot.querySelector('#chat-window'); const chatToggle = shadowRoot.querySelector('#chat-toggle'); const closeChat = shadowRoot.querySelector('#close-chat'); const chatMessages = shadowRoot.querySelector('#chat-messages'); const chatForm = shadowRoot.querySelector('#chat-form'); const chatInput = shadowRoot.querySelector('#chat-input'); const sendButton = shadowRoot.querySelector('#send-button'); const toggleChatWindow = () => { const isHidden = chatWindow.classList.contains('hidden'); if (isHidden) { chatWindow.classList.remove('hidden', 'chat-window-leave-active'); chatWindow.classList.add('flex', 'chat-window-enter'); setTimeout(() => chatWindow.classList.add('chat-window-enter-active'), 10); chatToggle.classList.add('hidden'); } else { chatWindow.classList.remove('chat-window-enter-active'); chatWindow.classList.add('chat-window-leave'); setTimeout(() => { chatWindow.classList.add('chat-window-leave-active', 'hidden'); chatWindow.classList.remove('chat-window-leave', 'flex'); }, 200); chatToggle.classList.remove('hidden'); } }; chatToggle.addEventListener('click', toggleChatWindow); closeChat.addEventListener('click', toggleChatWindow); chatForm.addEventListener('submit', async (e) => { e.preventDefault(); const userMessage = chatInput.value.trim(); if (!userMessage) return; addMessage(userMessage, 'user'); chatInput.value = ''; setFormDisabled(true); showLoadingIndicator(); try { const aiResponse = await getAiResponseWithRetry(userMessage); removeLoadingIndicator(); addMessage(aiResponse.text, 'ai', aiResponse.sources); } catch (error) { removeLoadingIndicator(); console.error('Error fetching AI response:', error); addMessage('Lo siento, un error inesperado ocurrió. Por favor, intenta de nuevo más tarde.', 'ai'); } finally { setFormDisabled(false); } }); const setFormDisabled = (disabled) => { chatInput.disabled = disabled; sendButton.disabled = disabled; if (!disabled) chatInput.focus(); }; const addMessage = (text, sender, sources = []) => { const messageContainer = document.createElement('div'); messageContainer.className = `flex mb-4 ${sender === 'user' ? 'justify-end' : 'justify-start'}`; const tempDiv = document.createElement('div'); tempDiv.innerText = text; const sanitizedText = tempDiv.innerHTML.replace(/\n/g, '
'); let sourcesHtml = ''; if (sources.length > 0) { sourcesHtml = '
Fuentes:
'; } messageContainer.innerHTML = `

${sanitizedText}

${sourcesHtml}
`; chatMessages.appendChild(messageContainer); chatMessages.scrollTop = chatMessages.scrollHeight; }; const showLoadingIndicator = () => { const loadingElement = document.createElement('div'); loadingElement.id = 'loading-indicator'; loadingElement.className = 'flex justify-start mb-4'; loadingElement.innerHTML = `
`; chatMessages.appendChild(loadingElement); chatMessages.scrollTop = chatMessages.scrollHeight; }; const removeLoadingIndicator = () => { shadowRoot.getElementById('loading-indicator')?.remove(); }; const getAiResponseWithRetry = async (userQuery, retries = 4) => { let delay = 1000; for (let i = 0; i <= retries; i++) { try { return await getAiResponse(userQuery); } catch (error) { if (error.status === 429 && i < retries) { await new Promise(resolve => setTimeout(resolve, delay)); delay *= 2; } else { throw error; } } } }; const getAiResponse = async (userQuery) => { const systemPrompt = `Eres un asistente de ventas experto para "Falcon Fitness". Tu única fuente de información es el sitio web www.falconfitness.mx. Tu objetivo es responder las preguntas de los usuarios sobre los productos que se encuentran EXCLUSIVAMENTE en ese sitio web. Reglas estrictas: 1. Basa TODAS tus respuestas únicamente en la información encontrada en www.falconfitness.mx. No uses conocimiento general. 2. Si la respuesta no se encuentra en el sitio web, responde amablemente: "No encontré información sobre eso en www.falconfitness.mx. ¿Puedo ayudarte con algún otro equipo?". 3. Sé amable, profesional y conversacional. Responde siempre en español. 4. No inventes precios, especificaciones o disponibilidad. Si no está en el sitio, no lo sabes.`; const apiKey = ""; const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-05-20:generateContent?key=${apiKey}`; const payload = { contents: [{ parts: [{ text: userQuery }] }], tools: [{ "google_search": {} }], systemInstruction: { parts: [{ text: systemPrompt }] }, }; const response = await fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (!response.ok) { const error = new Error(`API request failed with status ${response.status}`); error.status = response.status; throw error; } const result = await response.json(); const candidate = result.candidates?.[0]; if (candidate?.content?.parts?.[0]?.text) { const text = candidate.content.parts[0].text; let sources = []; const groundingMetadata = candidate.groundingMetadata; if (groundingMetadata?.groundingAttributions) { const uniqueUris = new Set(); sources = groundingMetadata.groundingAttributions .map(attr => ({ uri: attr.web?.uri, title: attr.web?.title })) .filter(source => { if (source.uri && source.uri.includes('falconfitness.mx') && !uniqueUris.has(source.uri)) { uniqueUris.add(source.uri); return true; } return false; }); } return { text, sources }; } else { throw new Error(`Invalid response structure from API: ${JSON.stringify(result)}`); } }; }); })();