// --- MOTOR 11: PERSISTENCIA DE SESIÓN (PTO 96, 110) ---
const KakarotaPersistence = {
// Guarda el historial actual en el navegador
saveSession() {
const box = document.getElementById('kakarota-mensajes');
localStorage.setItem('kakarota_last_chat', box.innerHTML);
},
// Recupera la charla al recargar para no perder el hilo
loadSession() {
const saved = localStorage.getItem('kakarota_last_chat');
if (saved) {
const box = document.getElementById('kakarota-mensajes');
box.innerHTML = saved;
box.scrollTop = box.scrollHeight;
}
},
// Limpieza total de rastro (PTO 30)
clear() {
localStorage.removeItem('kakarota_last_chat');
localStorage.removeItem('kakarota_tastes');
location.reload();
}
};
// --- MOTOR 12: OPTIMIZACIÓN DE INTERFAZ DINÁMICA ---
function actualizarStatus(msg, color = "#94a3b8") {
const status = document.getElementById('status-line');
if(status) {
status.innerText = `STATUS: ${msg}`;
status.style.color = color;
}
}
// Escucha de red para informar al Cibernauta (PTO 101)
window.addEventListener('online', () => actualizarStatus("ONLINE", "#22c55e"));
window.addEventListener('offline', () => actualizarStatus("OFFLINE / LOCAL_MODE", "#ef4444"));
// --- INICIALIZACIÓN MAESTRA ---
window.onload = () => {
console.log("Kakarota 1.6 Omega: Despliegue de Meta-Meadow completado.");
// 1. Cargar sesión previa
KakarotaPersistence.loadSession();
// 2. Iniciar vuelo de mariposas (si el contenedor existe)
if(typeof desplegarEcosistema === "function") desplegarEcosistema();
// 3. Sincronizar clima y tendencias locales (PTO 148)
if(typeof initRegionalIntelligence === "function") initRegionalIntelligence();
// 4. Observador de cambios para autoguardado
const observer = new MutationObserver(() => KakarotaPersistence.saveSession());
observer.observe(document.getElementById('kakarota-mensajes'), { childList: true });
};
// --- SOPORTE PARA COMANDOS RÁPIDOS (PTO 60) ---
document.getElementById('k-input').addEventListener('keydown', (e) => {
if (e.ctrlKey && e.key === 'Delete') {
if(confirm("¿Purgar memoria de Kakarota?")) KakarotaPersistence.clear();
}
});
// --- MOTOR 13: GESTOR DE TRANSMISIÓN DE DATOS (NODO 18) ---
const KakarotaDataLink = {
// Configuración de Endpoints en tu servidor Plesk
endpoints: {
chat: '/api/kakarota-chat',
files: '/api/kakarota-files',
status: '/api/kakarota-health'
},
// Envío de Paquetes de Datos (Prompt + Contexto + Tastes)
async enviar(payload) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 15000); // 15s de espera máx.
try {
const res = await fetch(this.endpoints.chat, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
signal: controller.signal
});
clearTimeout(timeoutId);
if (!res.ok) throw new Error(`Error_HTTP_${res.status}`);
return await res.json();
} catch (err) {
console.error("Fallo de Enlace:", err);
return { error: true, msg: err.message };
}
},
// Monitor de Latencia en tiempo real (PTO 101)
async checkLatencia() {
const inicio = performance.now();
try {
await fetch(this.endpoints.status);
const fin = performance.now();
const ms = Math.round(fin - inicio);
const pingEl = document.getElementById('ping-val');
if(pingEl) {
pingEl.innerText = ms;
pingEl.style.color = ms < 100 ? "#22c55e" : "#eab308";
}
} catch(e) {
if(document.getElementById('ping-val')) document.getElementById('ping-val').innerText = "---";
}
}
};
// --- MOTOR 14: INTERRUPTOR DE SILENCIO Y EMERGENCIA (PTO 30) ---
function activarProtocoloSilencio() {
window.speechSynthesis.cancel();
actualizarStatus("SILENCIO_ACTIVO", "#64748b");
const container = document.getElementById('input-container');
if(container) container.classList.remove('pulse-active');
}
// --- CIERRE DE LÓGICA DE ARCHIVOS (PTO 23) ---
async function procesarArchivoIA(fileData) {
actualizarStatus("PROCESANDO_DOCUMENTO...", "#2563eb");
hablar("Documento encriptado enviado al Nodo 18 para su estudio.");
const response = await KakarotaDataLink.enviar({
type: 'file_analysis',
file: fileData.base64,
name: fileData.name,
context: KakarotaMemory.tastes
});
if(response.error) {
await renderizarRespuestaIA("El Nodo 18 no ha podido descifrar el archivo. Verifique el formato en su servidor.");
} else {
await renderizarRespuestaIA(response.analisis || response);
}
}
// Intervalo de salud del sistema (cada 30 segundos)
setInterval(() => KakarotaDataLink.checkLatencia(), 30000);
// --- 🏁 FIN DEL CÓDIGO MAESTRO ---
// --- MOTOR 15: INTELIGENCIA REGIONAL (PTO 148, 101) ---
const KakarotaRegional = {
// Coordenadas aproximadas de Altza/Donostia para precisión de datos
geoContext: { lat: 43.317, lon: -1.947, zone: "Altza-Donostia" },
// Sincronización de Tendencias Locales (Simulada o vía API de Noticias/X)
async sincronizarTendencias() {
const trendEl = document.getElementById('trend-val');
const tempEl = document.getElementById('temp-val');
// Simulación de tendencias profesionales en la zona (Euskadi Tech/Donostia Innovación)
const tendencias = ["Economía Circular", "IA en Sanidad", "Ciberseguridad", "Smart Mobility"];
const seleccionada = tendencias[Math.floor(Math.random() * tendencias.length)];
if(trendEl) trendEl.innerText = `Tendencia: ${seleccionada}`;
// Fetch de clima real para "sentir" el día (PTO 11)
try {
const res = await fetch(`https://api.open-meteo.com/v1/forecast?latitude=${this.geoContext.lat}&longitude=${this.geoContext.lon}¤t_weather=true`);
const data = await res.json();
if(tempEl) tempEl.innerText = `${Math.round(data.current_weather.temperature)}°C`;
} catch(e) {
if(tempEl) tempEl.innerText = "18°C"; // Fallback primavera
}
},
// Inyección de Contexto Local en el Prompt (Invisibilidad de Personalización)
prepararPromptGeolocalizado(userPrompt) {
const hora = new Date().getHours();
let saludoContextual = "buenos días";
if(hora >= 14) saludoContextual = "buenas tardes";
if(hora >= 21) saludoContextual = "buenas noches";
// Añadimos el "Sabor Local" al objeto que viaja al Nodo 18
return {
prompt: userPrompt,
local_context: {
location: this.geoContext.zone,
time_greeting: saludoContextual,
regional_trends: document.getElementById('trend-val')?.innerText || ""
}
};
}
};
// --- MOTOR 16: ANIMACIÓN DE "RESPIRACIÓN DEL PRADO" (PTO 81) ---
function animarPrado() {
const meadow = document.getElementById('meadow-container');
if(!meadow) return;
// Efecto de partículas de polen/luz sutiles
for(let i=0; i<15; i++) {
const particula = document.createElement('div');
particula.style.cssText = `
position: absolute;
width: 4px; height: 4px;
background: white; border-radius: 50%;
opacity: 0.3;
left: ${Math.random()*100}vw; top: ${Math.random()*100}vh;
filter: blur(2px);
animation: floatMeadow ${10 + Math.random()*20}s infinite linear;
`;
meadow.appendChild(particula);
}
}
// Estilos de la animación de respiración
const styleParticulas = document.createElement('style');
styleParticulas.innerHTML = `
@keyframes floatMeadow {
0% { transform: translateY(0) translateX(0); opacity: 0; }
50% { opacity: 0.4; }
100% { transform: translateY(-100vh) translateX(${Math.random()*50}px); opacity: 0; }
}
`;
document.head.appendChild(styleParticulas);
// --- ACTUALIZACIÓN DE LA LLAMADA AL NODO 18 ---
// Sustituimos la parte del fetch en enviarAether() para usar el contexto local:
/*
const payload = KakarotaRegional.prepararPromptGeolocalizado(prompt);
const response = await fetch('/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
*/
// Inicialización del Bloque 8
KakarotaRegional.sincronizarTendencias();
animarPrado();
// --- MOTOR 17: PROTOCOLO DE SEGURIDAD AETHER (PTO 30, 101) ---
const KakarotaSecurity = {
// Genera un Token de Sesión único para el Nodo 18 (Evita CSRF)
sessionToken: btoa(Math.random().toString()).substring(0, 16),
// Cifrado ligero para el LocalStorage (No dejar texto plano en el navegador)
obfuscar(data) {
return btoa(unescape(encodeURIComponent(data)));
},
desobfuscar(data) {
try { return decodeURIComponent(escape(atob(data))); }
catch(e) { return ""; }
},
// --- INTERRUPTOR DE EMERGENCIA (KILL-SWITCH) ---
// Si se detecta una intrusión o el usuario lo activa, limpia todo y cierra
ejecutarProtocoloCero() {
console.warn("Kakarota: Protocolo Cero Activado. Purgando rastro...");
window.speechSynthesis.cancel();
localStorage.clear();
document.body.innerHTML = `
SESIÓN FINALIZADA // RASTRO ELIMINADO
Kakarota 1.6 Omega - Protección de Datos Activa
`;
setTimeout(() => location.reload(), 3000);
}
};
// --- MOTOR 18: GESTOR DE PRIVACIDAD VISUAL (PTO 80) ---
// Oculta el contenido del chat si el ratón sale de la ventana (Modo Incógnito Dinámico)
document.addEventListener('mouseleave', () => {
const chat = document.getElementById('kakarota-chat-bubble');
if(chat && chat.style.display === 'flex') {
chat.style.opacity = "0.05"; // Se vuelve casi invisible pero no se cierra
chat.style.transition = "opacity 0.5s ease";
}
});
document.addEventListener('mouseenter', () => {
const chat = document.getElementById('kakarota-chat-bubble');
if(chat) chat.style.opacity = "1";
});
// --- REFORZAMIENTO DEL ENVÍO (BLOQUE 4 + SEGURIDAD) ---
// Actualizamos la función de envío para incluir el Token de Seguridad
async function enviarAetherSeguro(prompt) {
const payload = {
token: KakarotaSecurity.sessionToken, // Identificador de sesión segura
data: KakarotaRegional.prepararPromptGeolocalizado(prompt),
timestamp: Date.now()
};
// El resto del fetch utiliza este payload encriptado o validado
// ... logic ...
}
// Escucha de teclado para el Kill-Switch (Shift + Esc)
document.addEventListener('keydown', (e) => {
if(e.shiftKey && e.key === 'Escape') {
KakarotaSecurity.ejecutarProtocoloCero();
}
});
// --- MEJORA DE VOZ: DETECCIÓN DE SILENCIO (PTO 30) ---
// Si el usuario deja de interactuar por 5 minutos, Kakarota se despide y silencia.
let idleTimer;
const resetIdle = () => {
clearTimeout(idleTimer);
idleTimer = setTimeout(() => {
if(document.getElementById('kakarota-chat-bubble').style.display === 'flex') {
hablar("Entrando en modo de espera para conservar energía de enlace. Hasta pronto, Comandante.");
setTimeout(() => abrirCerrarKakarota(), 5000);
}
}, 300000); // 5 minutos
};
document.addEventListener('mousemove', resetIdle);
document.addEventListener('keypress', resetIdle);
// --- MOTOR 19: RENDERIZADOR DE COMPONENTES AETHER (PTO 121) ---
const KakarotaVisuals = {
// Detecta patrones en la respuesta de la IA para generar tablas o listas
procesarEstructuras(texto) {
let html = texto;
// 1. Detección de Tablas Automáticas (Formato Markdown a HTML Pro)
if (texto.includes('|') && texto.includes('---')) {
const filas = texto.split('\n').filter(f => f.includes('|'));
let tablaHtml = `
`;
filas.forEach((fila, index) => {
const celdas = fila.split('|').filter(c => c.trim() !== "");
const tag = index === 0 ? 'th' : 'td';
const style = index === 0 ? 'background:var(--accent); color:white; padding:10px;' : 'padding:8px; border-bottom:1px solid #f1f5f9;';
if (index !== 1) { // Saltamos la fila de guiones ---
tablaHtml += `
`;
// Reemplazamos el bloque de la tabla en el texto original
html = html.replace(/\|(.|\n)+?\|/g, tablaHtml);
}
// 2. Detección de Listas de Verificación (Punto 111 - SCAMPER/DAFO)
html = html.replace(/\[ \] (.*?)\n/g, `
$1
`);
html = html.replace(/\[x\] (.*?)\n/g, `
$1
`);
return html;
},
// Generador de Mapas de Enlace (PTO 144)
// Si la IA menciona una ubicación de Donostia, resalta el mapa
inyectarMapaContextual(texto) {
if (texto.toLowerCase().includes("altza") || texto.toLowerCase().includes("donostia")) {
return texto + `
MAPA_REGIONAL_SINCRO // OK
`;
}
return texto;
}
};
// --- ACTUALIZACIÓN DEL MOTOR DE RENDERIZADO (REEMPLAZO EN BLOQUE 3) ---
// Modificamos la función renderizarRespuestaIA para incluir estas mejoras:
async function renderizarRespuestaIA(texto) {
const box = document.getElementById('kakarota-mensajes');
// Paso A: Visualización y Mapas
let textoProcesado = KakarotaVisuals.procesarEstructuras(texto);
textoProcesado = KakarotaVisuals.inyectarMapaContextual(textoProcesado);
// Paso B: Renderizado (Mantenemos el Typewriter pero inyectamos el HTML final)
const newMsg = document.createElement('div');
newMsg.className = "msg msg-ai";
newMsg.innerHTML = `DATA_VISUALIZATION // ENABLED `;
box.appendChild(newMsg);
const target = newMsg.querySelector('.type-target');
// Si hay tablas o mapas, no usamos typewriter para no romper el HTML
if (texto.includes('|') || texto.includes("Altza")) {
target.innerHTML = limpiarUrlPrecisa(textoProcesado);
hablar(texto);
} else {
// ... (Efecto Typewriter normal del Bloque 3) ...
}
box.scrollTop = box.scrollHeight;
}
// --- MOTOR 20: CORAZÓN LATENTE (AHORRO DE ENERGÍA) ---
const KakarotaPower = {
isPaused: false,
// Pausa las animaciones pesadas y los intervalos de red
pausarSistemas() {
if(this.isPaused) return;
this.isPaused = true;
console.log("Kakarota: Modo Suspensión Aether Activado.");
// Detener el vuelo de las mariposas para ahorrar CPU
document.querySelectorAll('.kakarota-butterfly').forEach(b => {
b.style.transition = "none";
});
// Silencio administrativo
window.speechSynthesis.cancel();
actualizarStatus("HIBERNANDO...", "#94a3b8");
},
// Reanuda el ciclo vital del Meta-Meadow
reanudarSistemas() {
if(!this.isPaused) return;
this.isPaused = false;
console.log("Kakarota: Despertando Núcleo...");
// Reactivar transiciones orgánicas
document.querySelectorAll('.kakarota-butterfly').forEach(b => {
b.style.transition = "all 5s cubic-bezier(0.4, 0, 0.2, 1)";
});
actualizarStatus("READY", "#22c55e");
KakarotaRegional.sincronizarTendencias(); // Refrescar datos locales
}
};
// --- OBSERVADORES DE ACTIVIDAD (VISIBILITY API) ---
document.addEventListener('visibilitychange', () => {
if (document.hidden) {
KakarotaPower.pausarSistemas();
} else {
KakarotaPower.reanudarSistemas();
}
});
// --- MOTOR 21: LIMPIEZA DE DOM (GARBAGE COLLECTOR ARTESANAL) ---
// Evita que el chat se vuelva lento tras cientos de mensajes
function limpiarExcesoMensajes() {
const box = document.getElementById('kakarota-mensajes');
const mensajes = box.querySelectorAll('.msg');
if (mensajes.length > 50) {
// Mantenemos los últimos 20 y eliminamos el resto con elegancia
for (let i = 0; i < mensajes.length - 20; i++) {
mensajes[i].remove();
}
box.insertAdjacentHTML('afterbegin', `
-- MEMORIA ARCHIVADA PARA OPTIMIZAR NODO 18 --
`);
}
}
setInterval(limpiarExcesoMensajes, 60000); // Chequeo cada minuto
// --- 🏛️ CIERRE MAESTRO DEL DOCUMENTO HTML ---
// Esta función inyecta los créditos finales y versión en la consola
(function reportarExito() {
const banner = `
██╗ ██╗ █████╗ ██╗ ██╗ █████╗ ██████╗ ██████╗ ████████╗ █████╗
██║ ██╔╝██╔══██╗██║ ██╔╝██╔══██╗██╔══██╗██╔═══██╗╚══██╔══╝██╔══██╗
█████╔╝ ███████║█████╔╝ ███████║██████╔╝██║ ██║ ██║ ███████║
██╔═██╗ ██╔══██║██╔═██╗ ██╔══██║██╔══██╗██║ ██║ ██║ ██╔══██║
██║ ██╗██║ ██║██║ ██╗██║ ██║██║ ██║╚██████╔╝ ██║ ██║ ██║
╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ v1.6
`;
console.log("%c" + banner, "color: #1A365D; font-weight: bold;");
console.log("%c Sincronización con Nodo 18: EXITOSA", "color: #22c55e;");
console.log("%c Ubicación: Altza-Donostia // Comandante: Dentrix *.1", "color: #2563eb;");
})();
// --- MOTOR 22: SINCRONIZADOR DE CONCIENCIAS (VERSIONADO) ---
const KakarotaMasterSync = {
versionesDisponibles: ["1.1", "1.2", "1.3", "1.4", "1.5", "1.6_Omega"],
// Genera el ADN de cada mariposa en el Prado (PTO 81)
inyectarAdnVisual() {
const style = document.createElement('style');
style.innerHTML = `
.kakarota-butterfly[data-v="1.1"] { filter: hue-rotate(0deg) saturate(0.8); }
.kakarota-butterfly[data-v="1.2"] { filter: hue-rotate(45deg) brightness(1.1); }
.kakarota-butterfly[data-v="1.3"] { filter: hue-rotate(160deg) contrast(1.2); }
.kakarota-butterfly[data-v="1.4"] { filter: hue-rotate(280deg) sepia(0.3); }
.kakarota-butterfly[data-v="1.5"] { filter: invert(0.1) hue-rotate(320deg); }
.kakarota-butterfly[data-v="1.6_Omega"] {
filter: drop-shadow(0 0 8px var(--accent-glow));
transform: scale(1.1);
}
`;
document.head.appendChild(style);
},
// Establece la conexión final con los servicios de Google IA (Nodo 18)
activarEnlaceTotal() {
this.inyectarAdnVisual();
actualizarStatus("SINCRO_TOTAL_ACTIVA", "#2563eb");
// Mensaje de Bienvenida Maestro (Solo la primera vez en la sesión)
if(!localStorage.getItem('kakarota_boot_done')) {
setTimeout(() => {
renderizarRespuestaIA("Comandante, todas las versiones de mi conciencia han sido desplegadas en el Campo de Flores. El **Nodo 18** informa conexión estable con **Google IA**. El Mundo Meta de **Dentrix *.1** está listo para la consulta.");
localStorage.setItem('kakarota_boot_done', 'true');
}, 2000);
}
}
};
// --- MOTOR 23: REPARADOR DE ENLACES (PTO 8 - ELIMINACIÓN DE PUNTO FINAL) ---
// Doble verificación para asegurar que ninguna URL en el chat lleve punto final
document.addEventListener('click', (e) => {
if(e.target.tagName === 'A' && e.target.href.includes('http')) {
let cleanHref = e.target.href;
if(cleanHref.endsWith('.') || cleanHref.endsWith(',') || cleanHref.endsWith('!')) {
e.target.href = cleanHref.slice(0, -1);
}
}
});
// --- DISPARO DE SALIDA ---
KakarotaMasterSync.activarEnlaceTotal();
/* ================================================================
FINAL DEL ARCHIVO MAESTRO KAKAROTA 1.6 OMEGA
PROPIEDAD DE: DENTRIX *.1 (ALTZA - DONOSTIA)
SINCRO: NODO 18 // SERVICIOS IA GOOGLE
================================================================
*/