{"id":15,"date":"2022-03-31T16:27:33","date_gmt":"2022-03-31T14:27:33","guid":{"rendered":"https:\/\/ip.andy21.com\/?page_id=15"},"modified":"2025-06-28T11:43:29","modified_gmt":"2025-06-28T09:43:29","slug":"inicio","status":"publish","type":"page","link":"https:\/\/ip.andy21.com\/","title":{"rendered":"\u00bfCu\u00e1les son mis IPs?"},"content":{"rendered":"<script type='text\/javascript'>var jsver = '1.0';<\/script>\r\n<script language='Javascript1.1'>jsver='1.1';<\/script>\r\n<script language='Javascript1.2'>jsver='1.2';<\/script>\r\n<script language='Javascript1.3'>jsver='1.3';<\/script>\r\n<script language='Javascript1.4'>jsver='1.4';<\/script>\r\n<script language='Javascript1.5'>jsver='1.5';<\/script>\r\n<script language='Javascript1.6'>jsver='1.6';<\/script>\r\n<script language='Javascript1.7'>jsver='1.7';<\/script>\r\n<script language='Javascript1.8'>jsver='1.8';<\/script>\r\n<script language='Javascript1.8.1'>jsver='1.8.1';<\/script>\r\n<script language='Javascript1.8.2'>jsver='1.8.2';<\/script>\r\n<script language='Javascript1.8.5'>jsver='1.8.5';<\/script>\r\n<script language='Javascript1.9'>jsver='1.9';<\/script>\r\n<script language='Javascript2.0'>jsver='2.0';<\/script>\n<script src='.\/wp-content\/a21\/flash_detect.js'><\/script>\r\n<script>\r\nif (FlashDetect.installed)   { flash = '<span style=\"color: #006400;\">versi\u00f3n '+FlashDetect.major+'.'+FlashDetect.minor+'.'+FlashDetect.revision+' <img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/a21\/icon\/flash.png\" alt=\"Flash\" width=\"28\" height=\"28\"\/><\/span>'; iconF = '\u2705'; }\r\nelse                         { flash = '<span style=\"color: #800000;\"><strike>no activado<\/strike> \ud83d\udeab <img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/a21\/icon\/flash.png\" alt=\"Flash\" width=\"28\" height=\"28\"\/><\/span>'; iconF = '\u274e'; }\r\n<\/script>\n<script>\r\nif (navigator.javaEnabled()) { java  = '<span style=\"color: #006400;\">instalado <img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/a21\/icon\/java.png\"  alt=\"Java\"  width=\"28\" height=\"28\"\/><\/span>'; iconJ = '\u2705'; }\r\nelse                         { java  = '<span style=\"color: #800000;\"><strike>no activado<\/strike> \ud83d\udeab <img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/a21\/icon\/java.png\"  alt=\"Java\"  width=\"28\" height=\"28\"\/><\/span>'; iconJ = '\u274e'; }\r\n<\/script>\n<style>.js {} .alt {} div.nor { margin: 0em 0em 0.5em 0em; font-size: 1em; } div.med { min-width: 325px; float: left; }<\/style>\n<style>div.ocultar { margin-top: 1em; }<\/style>\n<style>@media screen and (max-width: 970px) { div.nor, .iCopy  { font-size: 1.3em; } }<\/style>\n<noscript><style>.js {display: none;} .alt {display: block !important;}<\/style><\/noscript>\n<div class='nor' style='font-size: 1em; margin-bottom: 1em; '><div id='div4' style='white-space: nowrap; '><button type='button' class='iCopy' aria-label='Copiar IPv4' title='Copiar IPv4' style='background: none; border: none; padding: 0; font: inherit; cursor: pointer; ' onclick='copiarIPv4()'>\ud83d\udccb<\/button> <strong id='tIPv4' title='IPv4'>IPv4<\/strong>: <svg viewBox='0 0 150 20' style='margin: 0; width: 650px; border: 1px solid #CCC; background-color: #EEE;  max-width: 80%; ' id='svg4'><g color='darkblue'><text x='2' y='17' fill='currentcolor' id='ipv4'>Averiguando IPv4...<\/text><\/g><\/svg><\/div>\n<div id='div6' style='white-space: nowrap; '><button type='button' class='iCopy' aria-label='Copiar IPv6' title='Copiar IPv6' style='background: none; border: none; padding: 0; font: inherit; cursor: pointer; ' onclick='copiarIPv6()'>\ud83d\udccb<\/button> <strong id='tIPv6' title='IPv6'>IPv6<\/strong>: <svg viewBox='0 0 390 20' style='margin: 0; width: 650px; border: 1px solid #CCC; background-color: #EEE;  max-width: 80%; ' id='svg6'><g color='darkblue'><text x='2' y='17' fill='currentcolor' id='ipv6'>Averiguando IPv6...<\/text><\/g><\/svg><\/div>\n<\/div><div class='nor med'>  \u00a0<strong title='Aproximada'>Ciudad<\/strong>: <span title='CP: 1012 aprox.'>Amsterdam<\/span>\u00a0(<span title='NL'>The Netherlands<\/span>)<\/div>\n<div class='nor med'>\ud83d\udccc\u00a0<strong title='Aproximadas'>Coordenadas<\/strong>: <a title='Google Maps' href='https:\/\/www.google.com\/maps\/@?api=1&map_action=map&center=52.3759%2C4.8975&zoom=13&basemap=roadmap&layer=none'>52.3759,\u00a04.8975<\/a><\/div>\n<div class='nor'><iframe title='Mapa de ubicaci\u00f3n aproximada seg\u00fan tu IP' id='gMaps' src='https:\/\/www.google.com\/maps\/embed?pb=!1m10!1m8!1m3!1d51172.237578829154!2d4.8975!3d52.3759!3m2!1i1024!2i768!4f13.1!5e0!3m2!1ses!2ses!4v1649074868278!5m2!1ses!2ses' height='225' style='margin: 0; width: 650px; border: 1px solid #CCC; background-color: #EEE; ' loading='lazy' referrerpolicy='no-referrer-when-downgrade'><\/iframe><\/div>\n<div class='ocultar'>\n<div class='nor med js'><strong>\u2705 ISP<\/strong>: <span title='AS22612'>NAMECHEAP-NET<\/span><\/div>\n<div class='nor med js'><strong>\u2705 JavaScript<\/strong>:\u00a0versi\u00f3n <script>document.write (jsver);<\/script><\/div>\n<div style='clear: both; '><\/div>\n<div class='nor med js gru'><strong><script>document.write (iconF);<\/script> Flash<\/strong>:\u00a0<script>document.write (flash);<\/script><\/div>\n<div class='nor med js gru'><strong><script>document.write (iconJ);<\/script> Java<\/strong>:\u00a0<script>document.write (java);<\/script><\/div>\n<div style='clear: both; '><\/div>\n<div class='nor med gru'><strong>\u2705 <span title=\"Sistema Operativo\">S.O.<\/span><\/strong>:\u00a0Windows DIEZ <small>(64 bits)<\/small><\/div>\n<div class='nor med gru'><strong>\u2705 Browser<\/strong>:\u00a0Mozilla 5.0<\/div>\n<div style='clear: both; '><\/div>\n<div class='nor med js gru'><strong>\u2705 Pantalla<\/strong>:\u00a0<script>document.write (screen.width+'x'+screen.height+'\u00a0px');<\/script><\/div>\n<div class='nor med js gru'><strong>\u2705 Ventana<\/strong>:\u00a0<script>document.write (window.outerWidth+'x'+window.outerHeight+'\u00a0px');<\/script><\/div>\n<div class='nor med js'><strong>\u2705 Host<\/strong>:\u00a0<span title='162.0.217.198'>server331.web-hosting.com<\/span><\/div>\n<div style='clear: both; '><\/div>\n<\/div>\n<div class='ocultar'>\n<div class='nor'><button type='button' aria-label='Copiar User Agent' title='Copiar User Agent' style='background: none; border: none; padding: 0; font: inherit; cursor: pointer; ' onclick='copiarUserAgent()'>\ud83d\udccb<\/button> <strong title='HTTP_USER_AGENT'>USER AGENT<\/strong>: <span id='uAgent'>Mozilla\/5.0 (Windows NT 10.0; Win64; x64)<\/span><\/div>\n<div class='nor'>\ud83e\uddd0 <strong title='REMOTE_PORT'>REMOTE PORT<\/strong>: 59968 <small title='Rangos'>(0-1023-<strong>1024-49151<\/strong>-49152-65535)<\/small><\/div>\n<div class='nor'>\ud83d\udce2 <strong title='HTTP_ACCEPT_LANGUAGE'>ACCEPT LANGUAGE<\/strong>: n\/a   <\/div>\n<div class='nor'>\ud83c\udf10 <strong>REFERER<\/strong>: <a rel='nofollow' title='Link rec\u00edproco autom\u00e1tico' href='https:\/\/www.btolat.com\/'>https:\/\/www.btolat.com\/<\/a> \u2935\ufe0f<\/div>\n<div class='nor'>\ud83c\udf10 <strong>URL<\/strong> (<span id='4v6'>IP<\/span>): <a title='La URL con la informaci\u00f3n de tu IP p\u00fablica' href='https:\/\/ip.andy21.com\/?ip=162.0.217.198'>https:\/\/ip.andy21.com\/?ip=162.0.217.198<\/a> <span id='laOtra'><\/span><\/div>\n<\/div>\n<div class='ocultar'>\n<div class='nor' style='color: #080; '>\ud83d\udc4d Tu conexi\u00f3n a Internet es directa, NO mediante proxy<\/div>\n<div class='nor' style='color: #B00; '>\u26a0\ufe0f Compartir tu IP p\u00fablica es un riesgo para tu seguridad<\/div>\n<div class='nor'>\ud83d\udc4d <strong>NOTA<\/strong>: Los datos mostrados NO han sido guardados<\/div>\n<div class='nor'>\u26a1 <strong>VELOCIDAD<\/strong>: esta p\u00e1gina web ha sido creada en 0.038 sg.<\/div>\n<\/div>\n<script>\r\nfetch('https:\/\/ip4.andy21.com\/') \r\n    .then(response => {\r\n        if (!response.ok) {\r\n            throw new Error('No se puede acceder a la IP4 debido a falta de soporte en tu red.');\r\n        }\r\n        return response.text();\r\n    })\r\n    .then(ipv4 => { \r\n        document.getElementById('ipv4').textContent = ipv4; \r\n        document.getElementById('tIPv4').title = IPv4hexadecimal(ipv4);\r\n        let ipv4a = Math.round(ipv4.length * 9.85); \r\n        if (window.outerWidth <= 1080) { ipv4a = ipv4a * 0.90; } \r\n\t\tif (window.outerWidth <=  755) { ipv4a = ipv4a * 0.90; } \r\n        document.getElementById('svg4').setAttribute('viewBox', '0 0 ' + ipv4a + ' 20'); \r\n        if (document.getElementById('ipv4').textContent == '162.0.217.198') { \r\n            document.getElementById('svg4').style.border = '2px solid black'; \r\n            document.getElementById('4v6').textContent = 'IPv4'; \r\n\t\t\tif (!document.getElementById('ipv6').textContent.startsWith('IPv') && !document.getElementById('ipv6').textContent.startsWith('Averiguando')) { \r\n\t\t\t  laOtra.innerHTML = ' [<a href=\"?ip=' + document.getElementById('ipv6').textContent + '\">IPv6<\/a>]'; \r\n\t\t\t} \r\n        } \r\n\t\tdocument.title = ipv4 + ' es mi IPv4'; \r\n    }) \r\n    .catch(error => { \r\n        console.error('Error al obtener IPv4:', error);\r\n        document.getElementById('svg4').setAttribute('viewBox', '0 0 390 20'); \r\n\t\tdocument.getElementById('ipv4').innerHTML = 'IPv4 <tspan font-size=\"smaller\">no soportado por tu ISP (<title>AS22612 <\/title>NAMECHEAP-NET)<\/tspan>';\r\n    });\r\n<\/script>\n<script>\r\nfetch('https:\/\/ip6.andy21.com\/') \r\n    .then(response => {\r\n        if (!response.ok) {\r\n            throw new Error('No se puede acceder a la IP6 debido a falta de soporte en tu red.');\r\n        }\r\n        return response.text();\r\n    })\r\n    .then(ipv6 => { \r\n        document.getElementById('ipv6').textContent = ipv6; \r\n        document.getElementById('tIPv6').title = IPv6decimal(ipv6);\r\n        let ipv6a = Math.round(ipv6.length * 9.85); \r\n        if (window.outerWidth <= 1080) { ipv6a = ipv6a * 0.90; } \r\n\t\tif (window.outerWidth <=  755) { ipv6a = ipv6a * 0.90; } \r\n        document.getElementById('svg6').setAttribute('viewBox', '0 0 ' + ipv6a + ' 20'); \r\n        if (document.getElementById('ipv6').textContent == '162.0.217.198') { \r\n            document.getElementById('svg6').style.border = '1px solid black'; \r\n            document.getElementById('4v6').textContent = 'IPv6'; \r\n\t\t\tif (!document.getElementById('ipv4').textContent.startsWith('IPv') && !document.getElementById('ipv4').textContent.startsWith('Averiguando')) { \r\n\t\t\t  laOtra.innerHTML = ' [<a href=\"?ip=' + document.getElementById('ipv4').textContent + '\">IPv4<\/a>]'; \r\n\t\t\t}\r\n        } \r\n\t\t\/\/ (comento esta l\u00ednea porque prefiero mostrar la IPv4 en el t\u00edtulo aunque no sea la IP por defecto) document.title = ipv6 + ' es mi IPv6'; \r\n    }) \r\n    .catch(error => { \r\n        console.error('Error al obtener IPv6:', error);\r\n        document.getElementById('ipv6').innerHTML = 'IPv6 <tspan font-size=\"smaller\">no soportado por tu ISP (<title>AS22612 <\/title>NAMECHEAP-NET)<\/tspan>';\r\n    });\r\n<\/script>\n<script>\r\nfunction copiarIPv4() { \r\n  const texto = document.getElementById('ipv4').textContent; \r\n  navigator.clipboard.writeText(texto).then(() => { \r\n    document.getElementById('ipv4').style.color='#52C1E3';setTimeout(()=>{document.getElementById('ipv4').style.color='';},150);\r\n\tconsole.log('IPv4 ' + texto + ' copiada al portapapeles'); \r\n  }).catch(err => { \r\n    console.error('Error al copiar IPv4 ' + texto + ': ', err); \r\n  }); \r\n} \r\n<\/script>\n<script>\r\nfunction copiarIPv6() { \r\n  const texto = document.getElementById('ipv6').textContent; \r\n  navigator.clipboard.writeText(texto).then(() => { \r\n    document.getElementById('ipv6').style.color='#52C1E3';setTimeout(()=>{document.getElementById('ipv6').style.color='';},150);\r\n\tconsole.log('IPv6 ' + texto + ' copiada al portapapeles'); \r\n  }).catch(err => { \r\n    console.error('Error al copiar IPv6 ' + texto + ': ', err); \r\n  }); \r\n} \r\n<\/script>\n<script>\r\nfunction copiarUserAgent() { \r\n    const texto = 'Mozilla\/5.0 (Windows NT 10.0; Win64; x64)'; \r\n    navigator.clipboard.writeText(texto).then(() => { \r\n        document.getElementById('uAgent').style.color='#52C1E3';setTimeout(()=>{document.getElementById('uAgent').style.color='';},150);\r\n\t\tconsole.log('User Agent: ' + texto + ' copiado al portapapeles'); \r\n    }).catch(err => { \r\n        console.error('Error al copiar User Agent: ' + texto + ': ', err); \r\n    }); \r\n} \r\n<\/script>\n<script>\r\nfunction IPv4hexadecimal(ipv4) {\r\n    return ipv4.split('.')\r\n        .map(block => parseInt(block, 10).toString(16).padStart(2, '0')) \r\n        .join('.'); \r\n}\r\n<\/script>\n<script>\r\nfunction IPv6decimal(ipv6) {\r\n    return ipv6.split(':')\r\n        .map(block => parseInt(block || '0', 16))\r\n        .join('.'); \r\n}\r\n<\/script>\n<script>\r\n    (function() {\r\n        \/\/ URLs originales\r\n        var originalSrc = '\/wp-content\/uploads\/2022\/04\/ip.png';\r\n        var originalSrcset = '\/wp-content\/uploads\/2022\/04\/ip.png 248w, \/wp-content\/uploads\/2022\/04\/ip-150x150.png 150w';\r\n        \r\n        \/\/ URLs para m\u00f3vil\r\n        var mobileSrc = '\/wp-content\/uploads\/2025\/04\/ipv4-ipv6.png';\r\n        var mobileSrcset = '\/wp-content\/uploads\/2025\/04\/ipv4-ipv6.png 248w, \/wp-content\/uploads\/2025\/04\/ipv4-ipv6-150x150.png 150w';\r\n        \r\n        function actualizarLogo() {\r\n            var logo = document.querySelector('.custom-logo');\r\n            if(!logo) return;\r\n            if(window.innerWidth <= 970) {\r\n                \/\/ Cambiar a versi\u00f3n m\u00f3vil\r\n                if(logo.src !== mobileSrc) { logo.src = mobileSrc; logo.srcset = mobileSrcset; }\r\n            } else {\r\n                \/\/ Restaurar original\r\n                if(logo.src !== originalSrc) { logo.src = originalSrc;logo.srcset = originalSrcset; }\r\n            }\r\n        }\r\n        \r\n        \/\/ Optimizaci\u00f3n: debounce para resize\r\n        var resizeTimer;\r\n        function handleResize() {\r\n            clearTimeout(resizeTimer);\r\n            resizeTimer = setTimeout(actualizarLogo, 100);\r\n        }\r\n        \r\n        \/\/ Event listeners\r\n        document.addEventListener('DOMContentLoaded', actualizarLogo);\r\n        window.addEventListener('load', actualizarLogo);\r\n        window.addEventListener('resize', handleResize);\r\n    })();\r\n<\/script>\n\r\n<script>\r\ndocument.addEventListener('DOMContentLoaded', function() {\r\n  const COOKIE_NAME = 'ojoIP';\r\n  const COOKIE_PATH = '\/';\r\n  const BTN_CLASS = 'btn-ojoip';\r\n  \r\n  \/\/ Crear estilos CSS\r\n  const style = document.createElement('style');\r\n  style.textContent = \r\n    '.btn-ojoip, .btn-delete { color: white; border: none; border-radius: 4px; font-weight: bold; cursor: pointer; padding: 8px 16px; margin-left: 0.5em; margin-bottom: 2em; }' +\r\n    '.btn-delete { background: #a71d2a; border-radius: 3px; padding: 4px 8px; font-size: 12px; }' +\r\n    '.texto-small { display: block; font-size: 0.85em; color: #666; margin-top: 2px; margin-left: 2px; word-break: break-all; white-space: normal; }' +\r\n    '.user-agent-row { background: #f8f9fa !important; font-size: 0.85em; color: #555; }' +\r\n    '.user-agent-row td { font-style: italic; word-break: break-all; padding: 8px 6px !important; }' +\r\n    '.ojoip-modal-bottom-bar { display: flex; align-items: center; justify-content: space-between; margin-top: 24px; gap: 1em; }' +\r\n    '.ojoip-modal-bottom-bar .btn-ojoip { margin-left: 0; margin-bottom: 0; }' +\r\n    '.ojoip-modal-info-msg { margin-top: 16px; padding: 10px; background: #f8f9fa; border-radius: 4px; font-size: 0.95em; color: #555; text-align: center; }' +\r\n    '@media (max-width: 600px) { .entry-header { flex-direction: column !important; align-items: stretch !important; } .entry-header > .entry-title { margin-bottom: 12px !important; } .entry-header > div { justify-content: flex-end !important; margin-left: 0 !important; width: 100%; display: flex !important; } .texto-small { font-size: 0.70em; margin: 0; font-family: arial-narrow; } .comentario-small { display: none !important; } #ojoip-modal { padding: 16px 16px !important; } }';\r\n  document.head.appendChild(style);\r\n  \r\n  \/\/ Funciones utilitarias\r\n  function isValidIPv4(ip) {\r\n    return \/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$\/.test(ip);\r\n  }\r\n  \r\n  function isValidIPv6(ip) {\r\n    if (!ip || ip.trim() === '') return false;\r\n    if (!\/^[0-9a-fA-F:]+$\/.test(ip)) return false;\r\n    const doubleColonCount = (ip.match(\/::\/g) || []).length;\r\n    if (doubleColonCount > 1) return false;\r\n    if (ip.startsWith(':::') || ip.endsWith(':::')) return false;\r\n    return true;\r\n  }\r\n  \r\n  function getIPs() {\r\n    let ipv4 = '';\r\n    let ipv6 = '';\r\n    const el4 = document.getElementById('ipv4');\r\n    const el6 = document.getElementById('ipv6');\r\n    if (el4) ipv4 = el4.textContent.trim();\r\n    if (el6) ipv6 = el6.textContent.trim();\r\n    if (!isValidIPv4(ipv4)) ipv4 = 'IPv4 no disponible';\r\n    if (!isValidIPv6(ipv6)) ipv6 = 'IPv6 no disponible';\r\n    return { ipv4: ipv4, ipv6: ipv6 };\r\n  }\r\n  \r\n  function getUserAgent() {\r\n    return navigator.userAgent;\r\n  }\r\n  \r\n  function getFechaHora() {\r\n    const d = new Date();\r\n    function pad(n) { return n.toString().padStart(2, '0'); }\r\n    return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate()) + ' ' + pad(d.getHours()) + ':' + pad(d.getMinutes()) + ':' + pad(d.getSeconds());\r\n  }\r\n  \r\n  function setCookie(name, value) {\r\n    document.cookie = name + '=' + encodeURIComponent(value) + '; path=' + COOKIE_PATH + '; expires=Fri, 31 Dec 9999 23:59:59 GMT';\r\n  }\r\n  \r\n  function getCookie(name) {\r\n    const cookies = document.cookie.split(';');\r\n    for (let i = 0; i < cookies.length; i++) {\r\n      const c = cookies[i].trim();\r\n      if (c.startsWith(name + '=')) {\r\n        return decodeURIComponent(c.substring(name.length + 1));\r\n      }\r\n    }\r\n    return null;\r\n  }\r\n  \r\n  function deleteCookie(name) {\r\n    document.cookie = name + '=; path=' + COOKIE_PATH + '; expires=Thu, 01 Jan 1970 00:00:00 GMT';\r\n  }\r\n  \r\n  function leerHistorial() {\r\n    const raw = getCookie(COOKIE_NAME);\r\n    if (!raw) return [];\r\n    try {\r\n      return JSON.parse(raw);\r\n    } catch (e) {\r\n      return [];\r\n    }\r\n  }\r\n  \r\n  function guardarHistorial(historial) {\r\n    setCookie(COOKIE_NAME, JSON.stringify(historial));\r\n  }\r\n  \r\n  function buscarRegistro(historial, ipv4, ipv6, ua) {\r\n    for (let i = 0; i < historial.length; i++) {\r\n      const r = historial[i];\r\n      if (r.ipv4 === ipv4 && r.ipv6 === ipv6 && r.ua === ua) {\r\n        return i;\r\n      }\r\n    }\r\n    return -1;\r\n  }\r\n  \r\n  function getUltimoComentario() {\r\n    const historial = leerHistorial();\r\n    for (let i = historial.length - 1; i >= 0; i--) {\r\n      if (historial[i].comentario && historial[i].comentario.trim() !== '') {\r\n        return historial[i].comentario;\r\n      }\r\n    }\r\n    return '';\r\n  }\r\n  \r\n  \/\/ Configurar UI\r\n  const header = document.querySelector('.entry-header');\r\n  if (!header) return;\r\n  const h1 = header.querySelector('.entry-title');\r\n  if (!h1) return;\r\n  \r\n  header.style.display = 'flex';\r\n  header.style.alignItems = 'center';\r\n  header.style.justifyContent = 'space-between';\r\n  \r\n  const btnGuardar = document.createElement('button');\r\n  btnGuardar.textContent = 'Guardar';\r\n  btnGuardar.type = 'button';\r\n  btnGuardar.className = BTN_CLASS;\r\n  btnGuardar.style.background = '#1e7e34';\r\n  \r\n  const btnConsultar = document.createElement('button');\r\n  btnConsultar.textContent = 'Consultar';\r\n  btnConsultar.type = 'button';\r\n  btnConsultar.className = BTN_CLASS;\r\n  btnConsultar.style.background = '#0056b3';\r\n  \r\n  const btnContainer = document.createElement('div');\r\n  btnContainer.style.display = 'flex';\r\n  btnContainer.style.alignItems = 'center';\r\n  btnContainer.appendChild(btnGuardar);\r\n  if (getCookie(COOKIE_NAME)) btnContainer.appendChild(btnConsultar);\r\n  header.appendChild(btnContainer);\r\n  \r\n  \/\/ Gesti\u00f3n del modal\r\n  let escapeListener = null;\r\n  \r\n  function cerrarModal() {\r\n    const backdrop = document.getElementById('ojoip-modal-backdrop');\r\n    if (backdrop) backdrop.remove();\r\n    if (escapeListener) {\r\n      document.removeEventListener('keydown', escapeListener);\r\n      escapeListener = null;\r\n    }\r\n  }\r\n  \r\n  function crearModalTabla(historial) {\r\n    cerrarModal();\r\n    \r\n    const backdrop = document.createElement('div');\r\n    backdrop.style.position = 'fixed';\r\n    backdrop.style.top = '0';\r\n    backdrop.style.left = '0';\r\n    backdrop.style.width = '100vw';\r\n    backdrop.style.height = '100vh';\r\n    backdrop.style.background = 'rgba(0,0,0,0.3)';\r\n    backdrop.style.zIndex = '9999';\r\n    backdrop.id = 'ojoip-modal-backdrop';\r\n    \r\n    const modal = document.createElement('div');\r\n    modal.style.position = 'fixed';\r\n    modal.style.top = '50%';\r\n    modal.style.left = '50%';\r\n    modal.style.transform = 'translate(-50%, -50%)';\r\n    modal.style.background = '#fff';\r\n    modal.style.borderRadius = '8px';\r\n    modal.style.boxShadow = '0 2px 16px rgba(0,0,0,0.2)';\r\n    modal.style.padding = '24px';\r\n    modal.style.minWidth = '320px';\r\n    modal.style.maxWidth = '95vw';\r\n    modal.style.maxHeight = '80vh';\r\n    modal.style.overflow = 'auto';\r\n    modal.style.zIndex = '10000';\r\n    modal.id = 'ojoip-modal';\r\n    \r\n    const table = document.createElement('table');\r\n    table.style.width = '100%';\r\n    table.style.marginBottom = '0';\r\n    table.style.borderCollapse = 'collapse';\r\n    \r\n    \/\/ Generar filas de la tabla\r\n    let tableRows = '';\r\n    let previousUA = '';\r\n    for (let i = 0; i < historial.length; i++) {\r\n      const r = historial[i];\r\n      if (r.ua !== previousUA) {\r\n        tableRows += '<tr class=\"user-agent-row\"><td colspan=\"3\">' + r.ua + '<\/td><\/tr>';\r\n        previousUA = r.ua;\r\n      }\r\n      let fechaContent = r.fecha;\r\n      if (r.comentario && r.comentario.trim() !== '') {\r\n        fechaContent += '<span class=\\'texto-small comentario-small\\'>' + r.comentario + '<\/span>';\r\n      }\r\n      tableRows += '<tr>' +\r\n        '<td style=\"text-align:center;\"><button onclick=\"borrarRegistro(' + i + ')\" class=\"btn-delete\">X<\/button><\/td>' +\r\n        '<td><span>' + r.ipv4 + '<\/span><span class=\\'texto-small\\'>' + r.ipv6 + '<\/span><\/td>' +\r\n        '<td>' + fechaContent + '<\/td>' +\r\n        '<\/tr>';\r\n    }\r\n    \r\n    table.innerHTML = '<thead>' +\r\n      '<tr>' +\r\n      '<th style=\"text-align:center; border-bottom:1px solid #ccc; padding:6px; width:40px;\">\ud83d\uddd1\ufe0f<\/th>' +\r\n      '<th style=\"text-align:left; border-bottom:1px solid #ccc; padding:6px;\">IPv4 e IPv6<\/th>' +\r\n      '<th style=\"text-align:left; border-bottom:1px solid #ccc; padding:6px;\">Fecha y hora<\/th>' +\r\n      '<\/tr>' +\r\n      '<\/thead>' +\r\n      '<tbody>' +\r\n      tableRows +\r\n      '<\/tbody>';\r\n    \r\n    \/\/ Barra inferior con botones\r\n    const bottomBar = document.createElement('div');\r\n    bottomBar.className = 'ojoip-modal-bottom-bar';\r\n    \r\n    const btnBorrar = document.createElement('button');\r\n    btnBorrar.textContent = 'Borrar todo';\r\n    btnBorrar.type = 'button';\r\n    btnBorrar.className = BTN_CLASS;\r\n    btnBorrar.style.background = '#a71d2a';\r\n    btnBorrar.onclick = function() {\r\n      deleteCookie(COOKIE_NAME);\r\n      cerrarModal();\r\n      if (btnConsultar.parentNode) btnConsultar.parentNode.removeChild(btnConsultar);\r\n    };\r\n    \r\n    const btnCerrar = document.createElement('button');\r\n    btnCerrar.textContent = 'Cerrar';\r\n    btnCerrar.type = 'button';\r\n    btnCerrar.className = BTN_CLASS;\r\n    btnCerrar.style.background = '#0056b3';\r\n    btnCerrar.onclick = cerrarModal;\r\n    \r\n    bottomBar.appendChild(btnBorrar);\r\n    bottomBar.appendChild(btnCerrar);\r\n    \r\n    const infoMsg = document.createElement('div');\r\n    infoMsg.className = 'ojoip-modal-info-msg';\r\n    infoMsg.textContent = 'Datos guardados, s\u00f3lo en tu navegador.';\r\n    \r\n    modal.appendChild(table);\r\n    modal.appendChild(bottomBar);\r\n    modal.appendChild(infoMsg);\r\n    backdrop.appendChild(modal);\r\n    document.body.appendChild(backdrop);\r\n    \r\n    backdrop.addEventListener('click', function(e) {\r\n      if (e.target === backdrop) cerrarModal();\r\n    });\r\n    escapeListener = function(e) {\r\n      if (e.key === 'Escape') cerrarModal();\r\n    };\r\n    document.addEventListener('keydown', escapeListener);\r\n  }\r\n  \r\n  \/\/ Funci\u00f3n global para borrar registro individual\r\n  window.borrarRegistro = function(index) {\r\n    let historial = leerHistorial();\r\n    if (index >= 0 && index < historial.length) {\r\n      historial.splice(index, 1);\r\n      guardarHistorial(historial);\r\n      cerrarModal();\r\n      if (historial.length === 0) {\r\n        if (btnConsultar.parentNode) btnConsultar.parentNode.removeChild(btnConsultar);\r\n      } else {\r\n        crearModalTabla(historial);\r\n      }\r\n    }\r\n  };\r\n  \r\n  \/\/ Event handlers\r\n  btnGuardar.onclick = function() {\r\n    const ips = getIPs();\r\n    const ua = getUserAgent();\r\n    const fecha = getFechaHora();\r\n    const comentario = prompt('Introduce el nombre de la WiFi o un comentario (opcional):', getUltimoComentario());\r\n    if (comentario === null) return;\r\n    \r\n    let historial = leerHistorial();\r\n    const idx = buscarRegistro(historial, ips.ipv4, ips.ipv6, ua);\r\n    if (idx !== -1) {\r\n      historial[idx].fecha = fecha;\r\n      historial[idx].comentario = comentario;\r\n      alert('Fecha, hora y comentario ACTUALIZADOS del \u00faltimo registro de IPs.');\r\n    } else {\r\n      historial.push({ ipv4: ips.ipv4, ipv6: ips.ipv6, fecha: fecha, ua: ua, comentario: comentario });\r\n      alert('IPs, fecha, hora, user agent y comentario GUARDADOS correctamente.');\r\n    }\r\n    guardarHistorial(historial);\r\n    if (!btnConsultar.parentNode) btnContainer.appendChild(btnConsultar);\r\n  };\r\n  \r\n  btnConsultar.onclick = function() {\r\n    const historial = leerHistorial();\r\n    if (historial.length === 0) {\r\n      alert('No hay historial guardado.');\r\n      return;\r\n    }\r\n    crearModalTabla(historial);\r\n  };\r\n});\r\n<\/script>","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-15","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/ip.andy21.com\/wp-json\/wp\/v2\/pages\/15","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ip.andy21.com\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ip.andy21.com\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ip.andy21.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ip.andy21.com\/wp-json\/wp\/v2\/comments?post=15"}],"version-history":[{"count":0,"href":"https:\/\/ip.andy21.com\/wp-json\/wp\/v2\/pages\/15\/revisions"}],"wp:attachment":[{"href":"https:\/\/ip.andy21.com\/wp-json\/wp\/v2\/media?parent=15"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}