SuperB
SuperB
  • Ghina Inmobiliaria
  • Catalogo Inmobiliario
  • Constructora
  • Vende Tu propiedad
  • Bitácora
  • Contacto Encuentranos

Inmobiliaria Ghina

Inversiones Sólidas.
Resultados Reales.

Somos Inmobiliaria y Constructora. Controlamos cada fase del proyecto para que usted obtenga el máximo valor por su dinero, sin intermediarios ni retrasos.

COMPRAR / INVERTIR VENDER PROPIEDAD

Hacemos que su propiedad valga más.

Si desea vender, no solo somos su agencia inmobiliaria; somos su brazo técnico. Evaluamos el potencial de su terreno o vivienda y ejecutamos las mejoras o el desarrollo necesario para que el precio final sea superior al promedio del mercado. Con nosotros, su patrimonio no se estanca, se transforma.

▸ Análisis de plusvalía y proyectos de desarrollo a medida.

Construido para durar. Diseñado para vivir.

Comprar con nosotros es comprar directo de la fuente. Al ser constructores, garantizamos la integridad de cada estructura. Utilizamos materiales de primer nivel y mano de obra calificada en cada etapa. Usted recibe una propiedad legalmente saneada, técnicamente impecable y con un costo de mantenimiento mínimo.

+ Calidad
Materiales certificados
- Intermediarios
Precio directo
+ Garantía
Respaldo técnico

Infraestructura que respalda su inversión.

Nuestra capacidad operativa nos permite ofrecer servicios integrales de obra civil, remodelación y suministro de materiales. No dependemos de terceros para cumplir nuestros plazos. Esta integración nos permite ser competitivos en precio sin sacrificar un solo gramo de calidad en la mezcla. Si nosotros lo construimos, usted puede estar tranquilo.

¿Listo para dar el siguiente paso?

Sea una venta estratégica o su próxima gran inversión, tenemos la estructura necesaria para lograrlo.

HABLAR CON UN ESPECIALISTA

Subcategorías

Casas

Comercial

Compra o vende ya! Estamos para ayudarte. 🕊️💖 

{source}

<?php

// ================= CONFIGURACION ARRIBA - TODO SE CAMBIA AQUI =================

$GROQ_KEY = getenv('GROQ_KEY')?: getenv('GROQ_API_KEY')?: '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';

$GROQ_MODEL = getenv('GROQ_MODEL')?: 'qwen/qwen3.8-27b';

$TG_TOKEN = getenv('TG_TOKEN')?: '974360070:AAF--t8M4aHv08tFfZv0xuoSiM5kF7y6i5Y';

$TG_CHAT_ID = getenv('TG_CHAT_ID')?: '638161571';

$SYS_PROMPT = 'Eres asistente empresa . Tu unica memoria es historial. Responde corto, texto plano, sin asteriscos. Max 40 palabras.';

$TEXTOS = [

'cache_default' => 'Alta demanda ahora. Dime nombre, personas, fecha y hora y te confirmo.',

'btn_open' => 'Contactanos',

'titulo_inicial' => 'Formulario',

'titulo_continua'=> 'Continua',

'btn_enviar' => 'Enviar',

'btn_limpiar' => 'Limpiar chat',

'btn_escuchar' => '🔊 Escuchar',

'btn_callate' => '🔇 Callate',

'btn_copiar' => 'Copiar',

'voz_bienvenida' => 'Hola, soy tu asistente virtual. Dime en que te ayudo.',

'alerta_campos' => 'Completa nombre y telefono valido',

'alerta_copiado' => 'Copiado.',

'alerta_limpiar' => '¿Borrar toda la conversacion?',

'prefijo_tu' => 'Tu: ',

'prefijo_asistente' => 'Asistente: ',

'error_flood' => 'Vas muy rapido, espera 1 min.',

'error_corto' => 'Escribe algo.',

'error_conexion' => 'Sin conexion, reintenta.',

'error_csrf' => 'Sesion expirada, recarga.',

'error_bot' => 'Verificacion fallida.',

'error_pow' => 'Verificando...',

'error_pow_silent'=> '__RETRY_POW__',

'error_cookie' => 'Activa cookies y recarga.',

'error_tel' => 'Telefono invalido',

'error_enviando' => 'Espera la respuesta anterior...',

'tip_enter' => 'Escribe tu mensaje...',

'escribiendo' => 'Escribiendo...',

'error_https' => 'Requiere HTTPS',

];

// =============== FIN CONFIGURACION - ABAJO NO TOCAR =================

 

if(!isset($_COOKIE[session_name()])){

  if($_SERVER['REQUEST_METHOD']==='POST' && isset($_POST['ai_action'])){

    header('Cache-Control: no-store'); header('Content-Type: application/json');

    echo json_encode(['reply'=>$TEXTOS['error_cookie'],'ok'=>false]); exit;

  }

  if(session_status()===PHP_SESSION_NONE) session_start();

  $_SESSION['AI_INIT']=time();

}else{

  if(session_status()===PHP_SESSION_NONE) session_start();

  if(empty($_SESSION['AI_INIT'])){ session_regenerate_id(true); $_SESSION['AI_INIT']=time(); }

}

function ai_rand_hex($len=6){

  try{ return bin2hex(random_bytes($len)); }catch(Throwable $e){}

  try{ $b=openssl_random_pseudo_bytes($len,$strong); if($b!==false && $strong) return bin2hex($b); }catch(Throwable $e){}

  return substr(hash('sha256', session_id().microtime(true).($_SERVER['REMOTE_ADDR']??'').$len),0,$len*2);

}

if(!isset($_SESSION['AI_FORMS_VALID'])) $_SESSION['AI_FORMS_VALID']=[];

$FORM_ID='ai_'.substr(ai_rand_hex(6),0,12);

$_SESSION['AI_FORMS_VALID'][$FORM_ID]=['t'=>time(),'challenge'=>substr(ai_rand_hex(8),0,16),'csrf'=>substr(ai_rand_hex(16),0,32)];

$NOW=time();

foreach($_SESSION['AI_FORMS_VALID'] as $k=>$v){

  if($NOW-$v['t']>3600){ unset($_SESSION['AI_FORMS_VALID'][$k],$_SESSION[$k.'_historial'],$_SESSION['flood_form_'.$k],$_SESSION[$k.'_down']); }

}

if(count($_SESSION['AI_FORMS_VALID'])>15){

  uasort($_SESSION['AI_FORMS_VALID'],fn($a,$b)=>$a['t']<=>$b['t']);

  $old=array_slice(array_keys($_SESSION['AI_FORMS_VALID']),0,count($_SESSION['AI_FORMS_VALID'])-15);

  foreach($old as $k){ unset($_SESSION['AI_FORMS_VALID'][$k],$_SESSION[$k.'_historial'],$_SESSION['flood_form_'.$k],$_SESSION[$k.'_down']); }

}

$csrf_tmp=$_SESSION['AI_FORMS_VALID'][$FORM_ID]['csrf']; $challenge_tmp=$_SESSION['AI_FORMS_VALID'][$FORM_ID]['challenge'];

$REAL_IP=$_SERVER['REMOTE_ADDR']??'0.0.0.0'; $REAL_IP=filter_var($REAL_IP,FILTER_VALIDATE_IP)?$REAL_IP:'0.0.0.0';

$k_ip_get="flood_ip_".md5($REAL_IP); if(!isset($_SESSION[$k_ip_get])) $_SESSION[$k_ip_get]=[]; $_SESSION[$k_ip_get]=array_filter($_SESSION[$k_ip_get],fn($t)=>$NOW-$t<60);

 

if($_SERVER['REQUEST_METHOD']==='POST' && isset($_POST['ai_action'])){

  header('Cache-Control: no-store'); header('Content-Type: application/json');

  if(!isset($_COOKIE[session_name()])){ echo json_encode(['reply'=>$TEXTOS['error_cookie'],'ok'=>false]); exit; }

  $fid=trim($_POST['ai_action']); if(!preg_match('/^ai_[a-f0-9]{12}$/',$fid)||!isset($_SESSION['AI_FORMS_VALID'][$fid])){ http_response_code(400); echo json_encode(['reply'=>$TEXTOS['error_csrf'],'ok'=>false]); exit; }

  $st=$_SESSION['AI_FORMS_VALID'][$fid];

  if(!hash_equals($st['csrf']??'',$_POST['csrf']??'')){ echo json_encode(['reply'=>$TEXTOS['error_csrf'],'ok'=>false]); exit; }

  if(!empty($_POST['website_url'])){ echo json_encode(['reply'=>$TEXTOS['error_bot'],'ok'=>false]); exit; }

  $ip=$_SERVER['REMOTE_ADDR']??'0.0.0.0'; $k_ip="flood_ip_".md5($ip); $k_form="flood_form_".$fid;

  if(!isset($_SESSION[$k_ip])) $_SESSION[$k_ip]=[]; if(!isset($_SESSION[$k_form])) $_SESSION[$k_form]=[];

  $_SESSION[$k_ip]=array_filter($_SESSION[$k_ip],fn($t)=>$NOW-$t<60); $_SESSION[$k_form]=array_filter($_SESSION[$k_form],fn($t)=>$NOW-$t<60);

  if(count($_SESSION[$k_ip])>=30||count($_SESSION[$k_form])>=10){ echo json_encode(['reply'=>$TEXTOS['error_flood'],'ok'=>false,'new_challenge'=>$st['challenge'],'new_diff'=>'000']); exit; }

  $chal=$st['challenge']??''; $pow_str=(string)($_POST['pow_solution']??'');

  if(!$chal||$pow_str===''||!ctype_digit($pow_str)||substr(hash('sha256',$chal.$pow_str),0,3)!=='000'){

    $_SESSION['AI_FORMS_VALID'][$fid]['challenge']=substr(ai_rand_hex(8),0,16);

    echo json_encode(['reply'=>$TEXTOS['error_pow_silent'],'ok'=>false,'new_challenge'=>$_SESSION['AI_FORMS_VALID'][$fid]['challenge'],'new_diff'=>'000']); exit;

  }

  $_SESSION['AI_FORMS_VALID'][$fid]['challenge']=substr(ai_rand_hex(8),0,16); $_SESSION['AI_FORMS_VALID'][$fid]['csrf']=substr(ai_rand_hex(16),0,32);

  $new_ch=$_SESSION['AI_FORMS_VALID'][$fid]['challenge']; $new_csrf=$_SESSION['AI_FORMS_VALID'][$fid]['csrf'];

  $_SESSION[$k_ip][]=$NOW; $_SESSION[$k_form][]=$NOW;

  $txt=trim($_POST['texto_user']??''); $nom=trim($_POST['nombre']??''); $tel=trim($_POST['telefono']??'');

  if(mb_strlen($txt)<2){ echo json_encode(['reply'=>$TEXTOS['error_corto'],'ok'=>false,'new_challenge'=>$new_ch,'new_csrf'=>$new_csrf,'new_diff'=>'000']); exit; }

  if(mb_strlen($txt)>500) $txt=mb_substr($txt,0,500);

  $k_hist=$fid.'_historial'; if(!isset($_SESSION[$k_hist])) $_SESSION[$k_hist]=[]; $is_first=count($_SESSION[$k_hist])==0;

  if($is_first &&!preg_match('/^[\d\+\s\-\(\)]{7,20}$/',$tel)){ echo json_encode(['reply'=>$TEXTOS['error_tel'],'ok'=>false,'new_challenge'=>$new_ch,'new_csrf'=>$new_csrf,'new_diff'=>'000']); exit; }

  $save=$is_first?mb_substr($nom,0,50).": ".mb_substr($txt,0,150):mb_substr($txt,0,150);

  $_SESSION[$k_hist][]=['role'=>'user','content'=>$save]; if(count($_SESSION[$k_hist])>6) $_SESSION[$k_hist]=array_slice($_SESSION[$k_hist],-6);

  $messages=array_merge([['role'=>'system','content'=>$SYS_PROMPT]],$_SESSION[$k_hist]);

  $groq_ok=false; $reply='';

  if(isset($_SESSION[$fid.'_down']) && time()<$_SESSION[$fid.'_down']){ $reply=$TEXTOS['cache_default']; }

  else{

    if(session_status()===PHP_SESSION_ACTIVE) session_write_close();

    if(strpos($GROQ_KEY,'AQUI_TU_')===false){

      $ch=curl_init('https://api.groq.com/openai/v1/chat/completions');

      curl_setopt_array($ch,[CURLOPT_HTTPHEADER=>["Authorization: Bearer $GROQ_KEY","Content-Type: application/json"],CURLOPT_POSTFIELDS=>json_encode(['model'=>$GROQ_MODEL,'messages'=>$messages,'temperature'=>0.3],JSON_UNESCAPED_UNICODE),CURLOPT_RETURNTRANSFER=>true,CURLOPT_TIMEOUT=>12]);

      $res=curl_exec($ch); $http=curl_getinfo($ch,CURLINFO_HTTP_CODE); curl_close($ch); $data=json_decode($res,true);

      if(session_status()===PHP_SESSION_NONE) session_start();

      if($http===429){ $_SESSION[$fid.'_down']=time()+30; $reply=$TEXTOS['cache_default']; }

      elseif($http===200 &&!empty($data['choices'][0]['message']['content'])){ $reply=trim(str_replace(['**','##','*'],'',$data['choices'][0]['message']['content'])); $reply=mb_substr($reply,0,800); $groq_ok=true; $_SESSION[$k_hist][]=['role'=>'assistant','content'=>mb_substr($reply,0,150)]; }

      else $reply=$TEXTOS['cache_default'];

    } else { $reply=$TEXTOS['cache_default']; }

  }

  if(session_status()===PHP_SESSION_ACTIVE) session_write_close();

  echo json_encode(['reply'=>$reply,'ok'=>$groq_ok,'tipo'=>$groq_ok?'ok':'cache','new_challenge'=>$new_ch,'new_csrf'=>$new_csrf,'new_diff'=>'000'],JSON_UNESCAPED_UNICODE);

  if(session_status()===PHP_SESSION_NONE) session_start(); $k_tg="tg_last_".md5($ip); $last=$_SESSION[$k_tg]??0; $should_tg=($is_first||$groq_ok)&&($NOW-$last>=10); if($should_tg) $_SESSION[$k_tg]=$NOW; session_write_close();

  if(function_exists('fastcgi_finish_request')) fastcgi_finish_request(); if(!$should_tg) exit; if(strpos($TG_TOKEN,'AQUI_TU_')!==false) exit;

  $tg_text="[$fid] NOM:".mb_substr(strip_tags($nom),0,50)." TEL:".mb_substr(strip_tags($tel),0,30)." | USER:".mb_substr($txt,0,250)." | GROQ:".mb_substr($reply,0,300)." IP:$ip";

  if(mb_strlen($tg_text)>3800) $tg_text=mb_substr($tg_text,0,3800); ignore_user_abort(true);

  $ch_tg=curl_init("https://api.telegram.org/bot$TG_TOKEN/sendMessage"); curl_setopt_array($ch_tg,[CURLOPT_POST=>true,CURLOPT_POSTFIELDS=>['chat_id'=>$TG_CHAT_ID,'text'=>$tg_text],CURLOPT_RETURNTRANSFER=>true,CURLOPT_TIMEOUT=>2]); @curl_exec($ch_tg); @curl_close($ch_tg); exit;

}

?>

<style>

#<?php echo $FORM_ID;?>_container{margin:20px auto;max-width:600px;font-family:Arial,sans-serif;display:none;box-sizing:border-box}

.fg{margin-bottom:12px} label{display:block;font-weight:bold;margin-bottom:5px}

input,textarea{width:100%;padding:10px;font-size:16px;border:1px solid #ccc;border-radius:4px;box-sizing:border-box}

input:focus-visible,textarea:focus-visible,button:focus-visible{outline:2px solid #007bff;outline-offset:2px}

#<?php echo $FORM_ID;?>_chat{max-height:60vh;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;padding:10px;border:1px solid #eee;border-radius:8px;display:none;background:#fff}

#<?php echo $FORM_ID;?>_chat:not(:empty){margin-top:15px}

.user-m{background:#007bff;color:white;padding:10px;border-radius:8px;margin-bottom:10px;text-align:right;overflow-wrap:anywhere;word-break:break-word}

.assist-m{background:#f1f1f1;padding:10px;border-radius:8px;margin-bottom:10px;overflow-wrap:anywhere;word-break:break-word}

.assist-m.err{background:#ffe0e0;color:#900}

button.btn{padding:8px 16px;font-size:15px;cursor:pointer;border-radius:8px;border:none;margin:5px;color:white;background:#007bff}

button.btn-clear{background:#dc3545} button.btn-talking{background:#b71c1c!important;color:#fff!important;font-weight:bold}

button:disabled{opacity:.6;cursor:not-allowed}

.hid{display:none!important}.hp{position:absolute;left:-5000px;opacity:0;height:0;width:0}

#<?php echo $FORM_ID;?>_open{background:#007bff;color:white;padding:10px 14px;font-size:16px;cursor:pointer;border:3px ridge #ccc;border-radius:10px;margin:20px auto;display:block;font-weight:bold}

</style>

<button id="<?php echo $FORM_ID;?>_open"><?php echo htmlspecialchars($TEXTOS['btn_open'],ENT_QUOTES);?></button>

<div id="<?php echo $FORM_ID;?>_container"><form id="<?php echo $FORM_ID;?>_form"><h4 id="<?php echo $FORM_ID;?>_title" aria-live="polite"><?php echo htmlspecialchars($TEXTOS['titulo_inicial'],ENT_QUOTES);?></h4>

<div class="fg" id="<?php echo $FORM_ID;?>_g1"><label for="<?php echo $FORM_ID;?>_name">Nombre:</label><input type="text" id="<?php echo $FORM_ID;?>_name" maxlength="60" required autocomplete="name"></div>

<div class="fg" id="<?php echo $FORM_ID;?>_g2"><label for="<?php echo $FORM_ID;?>_phone">Telefono:</label><input type="tel" id="<?php echo $FORM_ID;?>_phone" maxlength="20" required autocomplete="tel"></div>

<div class="fg" id="<?php echo $FORM_ID;?>_g3"><label for="<?php echo $FORM_ID;?>_msg">Mensaje:</label><textarea id="<?php echo $FORM_ID;?>_msg" maxlength="500" required placeholder="<?php echo htmlspecialchars($TEXTOS['tip_enter'],ENT_QUOTES);?>"></textarea></div>

<div class="hp"><input type="text" name="website_url" id="<?php echo $FORM_ID;?>_hp" tabindex="-1" autocomplete="off"></div>

<input type="hidden" id="<?php echo $FORM_ID;?>_csrf" value="<?php echo htmlspecialchars($csrf_tmp,ENT_QUOTES);?>">

<input type="hidden" id="<?php echo $FORM_ID;?>_challenge" value="<?php echo htmlspecialchars($challenge_tmp,ENT_QUOTES);?>">

<input type="hidden" id="<?php echo $FORM_ID;?>_pow_solution" value="">

<button type="submit" class="btn" id="<?php echo $FORM_ID;?>_send"><?php echo htmlspecialchars($TEXTOS['btn_enviar'],ENT_QUOTES);?></button>

<button type="button" class="btn btn-clear" id="<?php echo $FORM_ID;?>_clear"><?php echo htmlspecialchars($TEXTOS['btn_limpiar'],ENT_QUOTES);?></button>

</form><div id="<?php echo $FORM_ID;?>_chat" role="log" aria-live="polite"></div><div class="hid" id="<?php echo $FORM_ID;?>_actions"><button class="btn" id="<?php echo $FORM_ID;?>_read"><?php echo htmlspecialchars($TEXTOS['btn_escuchar'],ENT_QUOTES);?></button><button class="btn" id="<?php echo $FORM_ID;?>_copy"><?php echo htmlspecialchars($TEXTOS['btn_copiar'],ENT_QUOTES);?></button></div></div>

<script>(function(){

const FID="<?php echo $FORM_ID;?>"; const CFG=<?php echo json_encode($TEXTOS, JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP|JSON_UNESCAPED_UNICODE);?>;

const $=id=>document.getElementById(FID+"_"+id); let isSpeaking=false,isSending=false,savedName='',savedPhone='',powReady=false,powSolving=false,currentChallenge=$("challenge").value,alreadyOpened=false,lastUserText='',isResetting=false,typingEl=null,retryTimer=null;

async function solvePoW(ch){

  if(!window.isSecureContext||!window.crypto||!crypto.subtle){ return; }

  if(powSolving) return; powSolving=true; powReady=false; $("send").disabled=true; $("send").textContent=CFG.error_pow;

  let n=0, hard=120000, batch=500; try{ const enc=new TextEncoder(); while(n<hard){ for(let i=0;i<batch;i++){ const buf=await crypto.subtle.digest('SHA-256', enc.encode(ch+n)); const hex=Array.from(new Uint8Array(buf)).map(b=>b.toString(16).padStart(2,'0')).join(''); if(hex.startsWith('000')){ $("pow_solution").value=n; powReady=true; $("send").disabled=false; $("send").textContent=CFG.btn_enviar; powSolving=false; return; } n++; } await new Promise(r=>setTimeout(r,0)); } }catch(e){} powSolving=false; $("send").disabled=false; $("send").textContent=CFG.btn_enviar;

}

function addMsg(c,t){ const d=document.createElement('div'); d.className=c; d.textContent=t; $("chat").appendChild(d); $("chat").style.display='block'; $("chat").scrollTop=$("chat").scrollHeight; return d; }

function showTyping(){ if(typingEl) try{typingEl.remove();}catch(e){} const d=document.createElement('div'); d.className='assist-m'; d.textContent=CFG.escribiendo; $("chat").appendChild(d); $("chat").style.display='block'; typingEl=d; }

function hideTyping(){ if(typingEl) try{typingEl.remove();}catch(e){} typingEl=null; }

function resetSpeak(){ try{ isResetting=true; isSpeaking=false; const b=$("read"); if(b){b.textContent=CFG.btn_escuchar; b.classList.remove('btn-talking');} speechSynthesis.cancel(); }catch(e){} setTimeout(()=>isResetting=false,120); }

function speakLong(t){ if(!t) return; try{ speechSynthesis.cancel(); }catch(e){} setTimeout(()=>{ try{ const u=new SpeechSynthesisUtterance(t); u.lang='es-PE'; u.onend=resetSpeak; u.onerror=resetSpeak; isSpeaking=true; const b=$("read"); if(b){b.textContent=CFG.btn_callate; b.classList.add('btn-talking');} speechSynthesis.speak(u); }catch(e){} },80); }

async function enviar(tx){

  if(isSending){ addMsg('assist-m err',CFG.prefijo_asistente+CFG.error_enviando); return; }

  if(!powReady){ solvePoW(currentChallenge); return; }

  isSending=true; $("send").disabled=true; $("send").textContent='Enviando...'; lastUserText=tx; addMsg('user-m',CFG.prefijo_tu+tx); showTyping();

  const fd=new FormData(); fd.append('ai_action',FID); fd.append('csrf',$("csrf").value); fd.append('website_url',$("hp").value); fd.append('pow_solution',$("pow_solution").value); fd.append('nombre',savedName||$("name").value); fd.append('telefono',savedPhone||$("phone").value); fd.append('texto_user',tx);

  let ctrl=new AbortController(); let to=setTimeout(()=>ctrl.abort(),15000);

  try{

    const r=await fetch(location.href.split('?')[0],{method:'POST',body:fd,signal:ctrl.signal}); clearTimeout(to); if(!r.ok) throw new Error('http');

    const data=await r.json(); hideTyping(); if(data.new_csrf) $("csrf").value=data.new_csrf;

    if(data.reply===CFG.error_pow_silent){ currentChallenge=data.new_challenge; $("challenge").value=currentChallenge; powReady=false; isSending=false; $("send").textContent=CFG.btn_enviar; $("send").disabled=false; solvePoW(currentChallenge); if(retryTimer) clearInterval(retryTimer); let waited=0; retryTimer=setInterval(()=>{ waited+=300; if(powReady){ clearInterval(retryTimer); retryTimer=null; enviar(lastUserText); } if(waited>15000){ clearInterval(retryTimer); retryTimer=null; } },300); return; }

    addMsg(data.ok===false?'assist-m err':'assist-m',CFG.prefijo_asistente+data.reply);

    if(data.new_challenge){ currentChallenge=data.new_challenge; $("challenge").value=currentChallenge; powReady=false; solvePoW(currentChallenge); }

    if(data.ok!==false||data.tipo){ $("actions").classList.remove('hid'); resetSpeak(); speakLong(data.reply); }

  }catch(e){ clearTimeout(to); hideTyping(); addMsg('assist-m err',CFG.prefijo_asistente+CFG.error_conexion); powReady=false; solvePoW(currentChallenge); }

  finally{ isSending=false; if(powReady){ $("send").textContent=CFG.btn_enviar; $("send").disabled=false; } }

}

function attachEnter(el){ if(!el||el.dataset.enterAttached) return; el.dataset.enterAttached='1'; el.addEventListener('keydown',ev=>{ if(ev.key==='Enter'&&!ev.shiftKey){ ev.preventDefault(); $("form").requestSubmit(); } }); el.addEventListener('focus',()=>{ setTimeout(()=>{ try{ el.scrollIntoView({behavior:'smooth',block:'center'});}catch(e){} },300); }); }

function trapFocus(e){

  if(e.key!=='Tab') return; const cont=$("container"); if(cont.style.display!=='block') return;

  const focusable=Array.from(cont.querySelectorAll('input:not([type=hidden]), textarea, button:not([disabled])')).filter(el=>el.offsetParent!==null);

  if(!focusable.length) return; const first=focusable[0], last=focusable[focusable.length-1];

  if(e.shiftKey){ if(document.activeElement===first){ e.preventDefault(); last.focus(); } }

  else{ if(document.activeElement===last){ e.preventDefault(); first.focus(); } }

}

$("form").onsubmit=e=>{ e.preventDefault(); const first=!document.getElementById(FID+"_cont"); const el=document.getElementById(FID+"_cont")||$("msg"); if(!el.value.trim()) return; if(first){ const ph=$("phone").value.trim(); if(!$("name").value.trim()||!ph||!/^[\d\+\s\-\(\)]{7,20}$/.test(ph)){ alert(CFG.alerta_campos); return; } savedName=$("name").value; savedPhone=$("phone").value; } const t=el.value; el.value=''; if(first){ $("g1").style.display='none'; $("g2").style.display='none'; $("g3").style.display='none'; try{$("name").required=false; $("phone").required=false; $("msg").required=false;}catch(e){} $("title").textContent=CFG.titulo_continua; if(!document.getElementById(FID+"_g4")){ const d=document.createElement('div'); d.className='fg'; d.id=FID+"_g4"; const lab=document.createElement('label'); lab.textContent='Mensaje:'; lab.setAttribute('for',FID+"_cont"); const ta=document.createElement('textarea'); ta.id=FID+"_cont"; ta.maxLength=500; ta.placeholder=CFG.tip_enter; d.appendChild(lab); d.appendChild(ta); $("form").insertBefore(d,$("send")); attachEnter(document.getElementById(FID+"_cont")); try{document.getElementById(FID+"_cont").focus();}catch(e){} } } enviar(t); };

attachEnter($("msg"));

document.addEventListener('keydown', trapFocus);

$("clear").onclick=()=>{

  if(!confirm(CFG.alerta_limpiar)) return;

  if(retryTimer){ clearInterval(retryTimer); retryTimer=null; }

  resetSpeak(); hideTyping(); $("chat").innerHTML=''; $("chat").style.display='none'; $("actions").classList.add('hid');

  savedName=''; savedPhone='';

  $("g1").style

Correo Messenger Instagram Teléfono WhatsApp Telegram

SuperB
© Roberto Connolly 1998 - 2026
Ir arriba