<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Códice | Entradas sobre «código»</title><description>Feed RSS de publicaciones etiquetadas con código</description><link>https://javguerra.github.io/</link><item><title>Blogeando...</title><link>https://javguerra.github.io/blog/hola-mundo</link><guid isPermaLink="true">https://javguerra.github.io/blog/hola-mundo</guid><description>Un blog con Markdown y Jekyll</description><pubDate>Thu, 21 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/blog.ByH_yChE_ZellLJ.webp&quot; alt=&quot;Blog&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#markdown&lt;/em&gt;, &lt;em&gt;#jekill&lt;/em&gt;, &lt;em&gt;#ssg&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Hola Mundo. Primera entrada del blog.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;note&quot;&gt;&lt;strong&gt;Nota&lt;/strong&gt;: Esta entrada hace referencia a la versión inicial de este blog realizado con Jekill. El repositorio de esa versión del blog es: &lt;a href=&quot;https://github.com/JavGuerra/codice-beautiful-jekyll-es&quot;&gt;blog&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Gracias a &lt;a href=&quot;https://jekyllrb.com/&quot;&gt;Jekill&lt;/a&gt;, un Generador de Sitios Estáticos (&lt;a href=&quot;https://www.cloudflare.com/es-es/learning/performance/static-site-generator/&quot;&gt;SSG&lt;/a&gt;)  y Github pages, hoy ve la luz este blog para volcar en él apuntes de interés sobre los temas que me apasionan.&lt;/p&gt;
&lt;p&gt;Lo he llamado «códice» por su similitud con un conjunto de hojas sueltas cosidas entre si, como eran los libros antes de la encuadernación.&lt;/p&gt;
&lt;p&gt;El tema gráfico empleado en este blog es &lt;a href=&quot;https://beautifuljekyll.com/&quot;&gt;Beautiful Jekyll&lt;/a&gt; del que hice &lt;em&gt;fork&lt;/em&gt; traduje al español y cambié algunas configuraciones para empezar.&lt;/p&gt;
&lt;p&gt;Si quieres crear tu propio blog, en su &lt;a href=&quot;https://github.com/daattali/beautiful-jekyll&quot;&gt;repositorio&lt;/a&gt; tienes las indicaciones necesarias para instalar todo.&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/blog.ByH_yChE_ZellLJ.webp"/><category>código</category><category>markdown</category><category>jekill</category><category>ssg</category><author>JavGuerra</author></item><item><title>Fizz buzz</title><link>https://javguerra.github.io/blog/fizzbuzz</link><guid isPermaLink="true">https://javguerra.github.io/blog/fizzbuzz</guid><description>Prueba de programación</description><pubDate>Fri, 22 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/code.BoBme8u9_ZyVCnB.webp&quot; alt=&quot;Programación&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#algoritmia&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;«Fizz buzz» es un ejercicio que habitualmente se usa como prueba para la selección de candidatos en programación. Su origen es un &lt;a href=&quot;https://en.wikipedia.org/wiki/Fizz_buzz&quot;&gt;juego de niños&lt;/a&gt; para aprender a dividir.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Escribir un programa que muestre en pantalla los números del 1 al 100, sustituyendo los múltiplos de 3 por la palabra “fizz”, los múltiplos de 5 por “buzz” y los múltiplos de ambos, es decir, los múltiplos de 3 y 5 (o de 15), por la palabra “fizzbuzz”.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Este simple enunciado encierra toda una gama de posibilidades en su algoritmo de resolución, y en él es de importancia tanto la rapidez con la que se resuelve el problema como la optimización (u originalidad) del código.&lt;/p&gt;
&lt;p&gt;Esta es mi propuesta de resolución en JavaScript.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 100&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; i&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; value &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) value &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;fizz&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) value &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;buzz&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  result.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(value &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; i);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(result.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;join&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;, &apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;));&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Básicamente el programa comprueba en bucle si cada número del 1 al 100 es divisible por 3 ó por 5. Si lo es, guarda  «fizz», «buzz» o «fizzbuzz» en el caso de ser divisible por los dos (3 y 5). Si no lo es, guarda el número que estoy evaluando y pasa al siguiente número.&lt;/p&gt;
&lt;p&gt;Esta es una versión que además de correcta, es muy legible. Pero si quisiéramos hacer una versión al estilo funcional, por ejemplo para usarla en React, podríamos emplear map.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; result&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Array&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;keys&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; n&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (n &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ?&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;fizz&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (n &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ?&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;buzz&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; n;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;join&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;, &apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(result);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;¿Crees que puede optimizarse más?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/retos-programacion&quot;&gt;Ver el código de este y otros retos de programación en GitHub&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/code.BoBme8u9_ZyVCnB.webp"/><category>código</category><category>javascript</category><category>algoritmia</category><author>JavGuerra</author></item><item><title>Lógica interactiva</title><link>https://javguerra.github.io/blog/logica-interactiva</link><guid isPermaLink="true">https://javguerra.github.io/blog/logica-interactiva</guid><description>Opciones, eventos, disparadores y estados</description><pubDate>Sat, 30 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/decisiones.Dh9wsimN_1ihbMt.webp&quot; alt=&quot;Decisiones&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#algoritmia&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Programar es una diversión difícil. En ocasiones las interacciones entre los disparadores de eventos y los estados de las variables y los objetos interelacionados multiplican sus opciones, haciendo complicado establecer, de memoria, todas las permutaciones posibles para no dejar ninguna de ellas sin implementar en nuestro código.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/ejercicios-web-javascript/12-nodos.html&quot;&gt;&lt;button&gt;Página web de ejemplo&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;En la página que he preparado para ilustrar esta entrada, tenemos cinco botones de un menú de opciones. Cada opción interactúa con los estados de los otros botones mientras se van añadiendo, quitando o cambiando elementos del DOM (en este caso artículos de una sección), y activando o desactivando los botones según sea necesario en cada momento. Es fácil entender la mecánica del ejemplo probándolo.&lt;/p&gt;
&lt;p&gt;Los disparadores son los botones que generan eventos, y algunas condiciones del propio programa, como cuando hemos borrado todos los elementos del DOM o cuando añadimos el primer elemento tras ello. Los estados corresponden a los botones ON/OFF, y al valor de las variables que se emplean para llevar a cabo las acciones asignadas a cada botón.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Decisiones&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/opciones.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt;&lt;/p&gt;
&lt;p&gt;Imaginemos que con el botón «Cambiar» alteramos el contenido del último elemento de la lista de elementos que hemos añadido al DOM (como se ve en la imagen). Esto hará que el botón «Cambiar» se desactive en este momento, porque ya no tenemos que cambiar el elemento recien cambiado, y el botón «Limpiar» se active, si no lo estaba ya, para ofrecer al usuario la opción de limpiar los elementos cambiados. Si borramos seguidamente este último elemento con «Borrar», deberemos comprobar si el botón «Limpiar» debe desactivarse si ya no hay elementos cambiados, y si el botón «Cambiar» debe activarse de nuevo si el que ahora es el último elemento no fue cambiado anteriormente, o mantenerse desactivado en tal caso. Añadir nuevos elementos altera otra vez el estado del botón «Cambiar» que debe activarse ofreciendo la opción de cambiar este nuevo elemento. Estas son algunas de las permutaciones posibles.&lt;/p&gt;
&lt;h2 id=&quot;tabla-disparadoresestados&quot;&gt;Tabla «disparadores/estados»&lt;/h2&gt;
&lt;p&gt;Mediante una tabla en una sencilla hoja de cálculo podemos contabilizar en el eje de las &lt;strong&gt;Y&lt;/strong&gt; (primera columna) todos aquellos disparadores (eventos y condiciones) de nuestra aplicación, y en el eje de las &lt;strong&gt;X&lt;/strong&gt; (filas) todos los estados, tanto de las variables como de los objetos (botones u otros), y ver cómo se interelacionan en tiempo de ejecución. &lt;u&gt;Lo difícil entonces será determinar con claridad cuáles son los disparadores y cuáles los estados&lt;/u&gt;. Si lo hacemos bien, con esta herramienta podemos clarificar, sin olvidar nada, cada interacción lógica derivada de las opciones de la aplicación, de forma similar a como se ve en la siguiente imagen.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Decisiones&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/tabla-disparadores-estados.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt;&lt;/p&gt;
&lt;p&gt;En este ejemplo, «Arranque» se refiere al estado de los botones al inicio. «Click btn…» corresponde a la pulsación de cada uno de los cinco botones. «Sin elementos» corresponde a la situación en la que se han borrado todos los elementos. «Añadir primer elemento» corresponde a los cambios a realizar cuando esta condición se presenta. Por último, «Click de inicio» y «Click de parada» corresponden al estado de los botones cuando los pulsamos y cuando se termina de realizar su tarea asignada. Como se aprecia, los botones son desactivados al pulsarlos para impedir que puedan ser pulsados de nuevo en tanto no terminen su ejecución, momento en el que (algunos de ellos) son reactivados.&lt;/p&gt;
&lt;p&gt;Esta tabla resumida incluye sólo la interacción de estados de los botones, -obviando el estado de las variables para no complicar el ejemplo-, anotando en las celdas de cada columna el estado del botón según los disparadores indicados al principio de cada fila. A la hora de pasar a la fase de codificación de nuestra aplicación, nos será fácil determinar si hemos implementado todas y cada una de las interacciones posibles reflejadas en la tabla simplemente cotejándola. Cuando tengas ante ti un abanico de opciones inabarcables, esta puede ser una solución para salir del atolladero.&lt;/p&gt;
&lt;p&gt;De paso, este ejercicio sirve para mostrar el uso de JavaScript en el manejo de nodos del DOM.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/ejercicios-web-javascript/12-nodos.html&quot;&gt;&lt;button&gt;Ver el ejercicio interactivo on-line&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Descargar la tabla de decisiones completa del ejercicio en formato &lt;a href=&quot;https://javguerra.github.io/ejercicios-web-javascript/12-nodos-tabla.ods&quot;&gt;.ods (Open Document)&lt;/a&gt; o &lt;a href=&quot;https://javguerra.github.io/ejercicios-web-javascript/12-nodos-tabla.xls&quot;&gt;.xls (Excel)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Actualización&lt;/strong&gt;. Ver este ejemplo de uso de botonera aún más complicado: &lt;a href=&quot;/blog/cronometro-js&quot;&gt;Cronómetro en JavaScript&lt;/a&gt;&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/decisiones.Dh9wsimN_1ihbMt.webp"/><category>código</category><category>javascript</category><category>algoritmia</category><author>JavGuerra</author></item><item><title>Un simple efecto Parallax</title><link>https://javguerra.github.io/blog/parallax-simple</link><guid isPermaLink="true">https://javguerra.github.io/blog/parallax-simple</guid><description>Programado con CSS</description><pubDate>Tue, 03 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/css.DvnzabCw_pI0Sy.webp&quot; alt=&quot;CSS&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Parallax es un efecto que se aplica generalmente a las imágenes de fondo de una página web, y que consiste en mantener estático, o mover a una velocidad distinta, el resto de los elementos de la página al hacer &lt;em&gt;scroll&lt;/em&gt;. Parecerá de esa forma que la página tiene profundidad. En mi &lt;a href=&quot;https://javguerra.github.io/conceptos-fswd/index.html&quot;&gt;página de ejemplo&lt;/a&gt; a la que hacía referencia en este &lt;a href=&quot;/blog/conceptos-fswd&quot;&gt;&lt;em&gt;post&lt;/em&gt;&lt;/a&gt;, puede verse aplicado en la portada o zona «&lt;em&gt;Hero&lt;/em&gt;».&lt;/p&gt;
&lt;p&gt;esto se consigue de una forma muy sencilla. Sólo tienes que crear un div en el HTML y ponerle una clase, p. ej. «&lt;code&gt;.parallax&lt;/code&gt;», y luego, en el CSS, en esa clase, incluir la altura que le darás al &lt;code&gt;div&lt;/code&gt; y la imagen de fondo que le vas a poner. Por supuesto, dentro de ese &lt;code&gt;div&lt;/code&gt; puedes incluir texto, imágenes… En el caso del ejemplo mencionado puse el título de la página.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;css&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;min-height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: 100vh;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;background: url(&quot;fondo.jpg&quot;) center/cover &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;no-repeat&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; fixed;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Estas son las dos líneas que he incluido en mi código para lograrlo. La primera le dice al navegador que el &lt;code&gt;div&lt;/code&gt; va a tener la altura de la ventana del navegador, sea esta cual sea. Pero también se puede poner un valor fijo, por ejemplo &lt;code&gt;height: 300px&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;La segunda le dice al navegador que el &lt;code&gt;div&lt;/code&gt; va a tener una imagen de fondo, en este caso &lt;code&gt;fondo.jpg&lt;/code&gt;, y que la tiene que poner centrada vertical y horizontalmente (&lt;code&gt;center&lt;/code&gt;), ocupando todo el ancho del div (&lt;code&gt;cover&lt;/code&gt;), y poniéndola fija (&lt;code&gt;fixed&lt;/code&gt;) para que no se mueva. Este es el efecto que buscamos.&lt;/p&gt;
&lt;p&gt;El &lt;code&gt;fixed&lt;/code&gt; lo hace todo. El fondo  del &lt;code&gt;div&lt;/code&gt; permanecerá estático, y la página lo irá tapando a medida que hacemos &lt;em&gt;scroll&lt;/em&gt; hacia abajo.&lt;/p&gt;
&lt;p&gt;En esta otra &lt;a href=&quot;https://badared.com/conectiva/evento/THTC2021/&quot;&gt;página &lt;em&gt;landing&lt;/em&gt;&lt;/a&gt; que realicé para un evento, puede verse un uso parecido de efecto parallax a modo de cortinilla o separador de sus distintas secciones.&lt;/p&gt;
&lt;p&gt;Este efecto tiene un inconveniente, y es que no funciona bien en el navegador Safari en iOS (iPad/iPhone), como se comenta &lt;a href=&quot;https://css-tricks.com/ios-13-broke-the-classic-pure-css-parallax-technique/&quot;&gt;aquí&lt;/a&gt;, aunque es posible encontrar soluciones más o menos imaginativas buscando por Internet.&lt;/p&gt;
&lt;p&gt;Mis páginas de ejemplo con este efecto Parallax:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/conceptos-fswd/index.html&quot;&gt;&lt;button&gt;página de ejemplo&lt;/button&gt;&lt;/a&gt; - &lt;a href=&quot;/blog/conceptos-fswd&quot;&gt;post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://badared.com/conectiva/evento/THTC2021/&quot;&gt;&lt;button&gt;página &lt;em&gt;landing&lt;/em&gt;&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;El efecto Parallax puede complicarse aún más para conseguir resultados increibles. Puedes encontrar ejemplos con sólo una búsqueda.&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/css.DvnzabCw_pI0Sy.webp"/><category>código</category><category>html</category><category>css</category><author>JavGuerra</author></item><item><title>Accesibilidad Web</title><link>https://javguerra.github.io/blog/accesibilidad</link><guid isPermaLink="true">https://javguerra.github.io/blog/accesibilidad</guid><description>Buenas prácticas explicadas a través de un ejemplo</description><pubDate>Sun, 08 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/accessibility.BH_1lQGp_ZiUkNk.webp&quot; alt=&quot;Accesibilidad web&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#accesibilidad&lt;/em&gt;, &lt;em&gt;#usabilidad&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;blockquote&gt;
&lt;p&gt;«El poder de la Web está en su universalidad. El acceso por cualquier persona, independientemente de la discapacidad que presente es un aspecto esencial.»&lt;/p&gt;
&lt;p&gt;Fuente: &lt;em&gt;&lt;a href=&quot;https://www.w3.org/Press/IPO-announce&quot;&gt;World Wide Web Consortium Launches International Program Office for Web Accessibility Initiative&lt;/a&gt;. &lt;a href=&quot;https://www.w3.org/People/Berners-Lee/&quot;&gt;Tim Berners-Lee&lt;/a&gt;, Director del W3C e inventor de la World Wide Web&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Todos presentaremos en algún momento de nuestra vida alguna discapacidad en menor o mayor grado. El envejecimiento de la población acentúa esto, sumando un número destacable de personas que requieren algún tipo de adaptación (visual, auditiva, cognitiva, motriz) a la hora de acceder a la información en línea, por eso es importante que nuestras webs tengan esto en cuenta para poder llegar a cualquier tipo de público.&lt;/p&gt;
&lt;p&gt;Con ayuda de la página de ejemplo que preparé y reseñe en &lt;a href=&quot;/blog/conceptos-fswd&quot;&gt;esta entrada&lt;/a&gt;, iré describiendo algunas buenas prácticas que suelo emplear en las webs que desarrollo.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/conceptos-fswd/index.html&quot;&gt;&lt;button&gt;Acceder a la página web&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;comprensión-del-contexto&quot;&gt;Comprensión del contexto&lt;/h2&gt;
&lt;p&gt;Para algunas personas el acceso a la web es posible sólo mediante el uso de programas de lectura de pantalla que traducen la página de arriba a abajo, secuencialmente, a mensajes de voz o a líneas de lectura en un teclado Braille.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;note&quot;&gt;Esta entrada no pretende ser un completo compendio de buenas prácticas, sino un acercamiento básico al sentido de la accesibilidad web que permita sensibilizar sobre ello.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Mi primer objetivo es pues dar a conocer adecuadamente el contexto en el que cada elemento de la página se presenta y describir cada cosa que lo necesite, como la misma página, a través de un &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; o las imágenes con el atributo &lt;code&gt;alt&lt;/code&gt; (Los iconos, a no ser que tengan alguna función informativa, no requieren de este atributo). Afortunadamente. esta es una práctica comúnmente usada por los desarrolladores hoy día. Pero hay más.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Redes Sociales&lt;/strong&gt;&lt;br&gt;
Cuando compartimos nuestra web en redes sociales, queremos que esto ayude a generar visitas, por lo que es bueno contar con una descripción y una imagen que referencie adecuadamente su contenido. Mediante el protocolo &lt;a href=&quot;https://ogp.me/&quot;&gt;Open Graph&lt;/a&gt; conseguimos que esta información sea ofrecida de manera automática al publicarla en la red social. Esto se consigue mediante una serie de indicaciones en el &lt;code&gt;head&lt;/code&gt; de la página que contienen la información necesaria debidamente formateada. Pues bien, esto que nace como un recurso para SEO y para conseguir clics de potenciales visitantes, también ayuda a las personas con alguna discapacidad a realizar una mejor navegación informándoles de lo que encontrarán al hacer clic, ahorrándoles incertidumbre y tiempo valioso.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;El lenguaje&lt;/strong&gt;&lt;br&gt;
Hay al menos dos cuestiones de importancia a tener en cuenta en este apartado:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;El contenido debe ser claro, orientado a todo tipo de público, y bien estructurado para que cualquier persona, incluso aquella que presente problemas de comprensión lectora, pueda entenderlo.&lt;/li&gt;
&lt;li&gt;La página debe contar con el atributo &lt;code&gt;lang&lt;/code&gt; en la etiqueta &lt;code&gt;html&lt;/code&gt; (&lt;code&gt;lang=&quot;es&quot;&lt;/code&gt;) que describe el idioma principal de la página. Todos aquellos textos y enlaces que se presenten en otro idioma deben ir debidamente señalizados con la esta etiqueta también. Ver este ejemplo: &lt;code&gt;&amp;lt;span lang=&quot;en&quot;&amp;gt;front end&amp;lt;/span&amp;gt;&lt;/code&gt;. Cuando se escucha una página a través de un sintetizador de voz, se agradece que las palabras en otro idioma no generen confusión.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;El color&lt;/strong&gt;
Para las personas con baja visión o con afecciones en la percepción de los colores, es importante que los textos y el fondo presenten un contraste adecuado para que sean legibles.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ir al contenido&lt;/strong&gt;&lt;br&gt;
Cuando usamos lectores de pantalla se hace tedioso escuchar o leer toda la información del &lt;code&gt;header&lt;/code&gt; (titulo, menú de navegación…) una y otra vez, por lo que es de ayuda contar con un enlace al principio de la página que nos lleve directamente al contenido. Algo como esto: &lt;code&gt;&amp;lt;a href=&quot;#contenido&quot; class=&quot;sr&quot;&amp;gt;Ir al contenido&amp;lt;/a&amp;gt;&lt;/code&gt;. Al hacer clic en el enlace saltaremos directamente al &lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt;, ahorrándonos un tiempo valioso. Pero no querremos que este enlace aparezca en nuestro diseño web visual. Mediante la clase &lt;code&gt;.sr&lt;/code&gt; conseguimos esto. en mi caso, la clase que aplicamos a este enlace contiene lo siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;css&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.sr&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  position&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;absolute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  overflow&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;hidden&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  text-indent&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;-9999&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La clase &lt;code&gt;.sr&lt;/code&gt; hará que la etiqueta exista y pueda ser leída por un lector de pantalla, que no toma en cuenta dónde se ubican visualmente los elementos de la página, pero no se mostrará en nuestro diseño, porque estará oculta en &lt;code&gt;-9999px&lt;/code&gt;, fuera de la pantalla.&lt;/p&gt;
&lt;p&gt;Esta técnica es útil también para incluir comentarios de navegación, información complementaria, incluso, como en el caso del formulario que incluye la web, para mostrar las etiquetas de los campos del formulario que han sido eliminadas del diseño por una cuestión estética.&lt;/p&gt;
&lt;p&gt;Por supuesto, la página debe estar adecuadamente estructurada con las etiquetas semánticas correspondientes (&lt;code&gt;section&lt;/code&gt;, &lt;code&gt;article&lt;/code&gt;, etc.) para poder realizar una navegación secuencial correcta.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Interactividad&lt;/strong&gt;&lt;br&gt;
Al interactuar con la página, botones, enlaces y campos de formulario deben estar adecuadamente identificados, y dotados de un contexto semántico (p.ej. &lt;code&gt;label&lt;/code&gt;). Los enlaces deben ser auto-descriptivos, de tal forma que al leer el texto del enlace sepamos que nos depara hacer clic en él.&lt;/p&gt;
&lt;p&gt;No es muy complicado cuando tomamos conciencia de ello, pero existe una traba mayor, los cambios en la página. Cuando hacemos clic en un menú desplegable, la página cambia para mostrarnos una información que hasta ahora no estaba disponible. Cuando introducimos un valor erróneo en un campo de formulario, el mensaje de error que se muestra es una aparición que debe ser notificada, y el foco de dónde comenzar a escribir para corregir ese dato debe apuntar al campo erróneo.&lt;/p&gt;
&lt;p&gt;Mediante el uso de etiquetas &lt;a href=&quot;https://en.wikipedia.org/wiki/WAI-ARIA&quot;&gt;WAI-ARIA&lt;/a&gt; podemos describir esos eventos y mostrar sus estados correctamente. Veamos el siguiente ejemplo.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;css&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; id=&quot;hamburguesa&quot; &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;aria-controls&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&quot;menu&quot; &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;aria-label&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&quot;Botón de menú&quot; &lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;aria-expanded&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&quot;false&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; class=&quot;barra1&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; class=&quot;barra2&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; class=&quot;barra3&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;nav&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; id=&quot;menu&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;ul&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; href=&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;#descripcion&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Descripción&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; href=&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;#perfiles&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Perfiles&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; href=&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;#tecnologias&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Tecnologías&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; href=&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;#contactar&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Contactar&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;ul&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;nav&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esta pieza de código corresponde al menú de la página. El &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; permite que se despliegue o se repliegue (ON/OFF) el menú del &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt; cuando nuestro dispositivo tiene una pantalla pequeña (es &lt;em&gt;responsive&lt;/em&gt;). Así pues, con &lt;code&gt;aria-controls=&quot;menu&quot;&lt;/code&gt;, establecemos esa relación. Con &lt;code&gt;aria-label=&quot;Botón de menú&quot;&lt;/code&gt; aportamos una descripción de la función del botón. Y con &lt;code&gt;aria-expanded=&quot;false&quot;&lt;/code&gt; indicamos si el botón esta activado o no. En este caso aparece como &lt;code&gt;false&lt;/code&gt;, desactivado, pero esto cambia al hacer clic en él, y es nuestra responsabilidad actualizar esta etiqueta mediante JavaScript, como se hace en el fichero &lt;code&gt;script.js&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; h&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hamburguesa&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;h.onclick &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; hamburguesa;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;h.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &quot;aria-expanded&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    h.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;aria-expanded&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;===&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; true&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ?&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; false&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Al hacer click en el botón del menú (‘&lt;em&gt;hamburguesa&lt;/em&gt;’ llamado así porque su icono de tres líneas &lt;i class=&quot;bi bi-list&quot;&gt;&lt;/i&gt; se asemeja al famoso bocadillo), la etiqueta &lt;code&gt;aria-expanded&lt;/code&gt; cambia su valor de &lt;code&gt;false&lt;/code&gt; a &lt;code&gt;true&lt;/code&gt; o viceversa. Así informaremos al usuario de un lector de pantalla si el botón está pulsado o no en cada momento.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tablas&lt;/strong&gt;&lt;br&gt;
Las páginas pensadas para su uso por terminales móviles primero (&lt;em&gt;responsive&lt;/em&gt;) ayudan mucho a clarificar el flujo del contenido de la navegación, pero si hay algo que rompe con todo ello son las tablas. ¿Cuál es el orden correcto para leer una tabla? ¿fila a fila? ¿Y qué hay de las columnas o filas agrupadas?&lt;/p&gt;
&lt;p&gt;Las etiquetas semánticas nuevamente son de ayuda aquí (&lt;code&gt;&amp;lt;thead&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;tbody&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;tfoot&amp;gt;&lt;/code&gt;, y &lt;code&gt;&amp;lt;tr&amp;gt;&lt;/code&gt; para los encabezados) y algunos atributos de HTML ayudan a paliar esto en cierta medida, como &lt;code&gt;scope=&quot;colgroup&quot;&lt;/code&gt; (columnas) y &lt;code&gt;scope=&quot;rowgroup&quot;&lt;/code&gt; (filas) que indican que las siguientes filas o columnas forman parte de un grupo con un mismo contexto.&lt;/p&gt;
&lt;p&gt;Como se puede ver en la &lt;a href=&quot;https://javguerra.github.io/conceptos-fswd/index.html#perfiles&quot;&gt;tabla&lt;/a&gt; de la web de ejemplo, todas las celdas debajo de la celda del encabezado «&lt;em&gt;Front end&lt;/em&gt;» o del encabezado «&lt;em&gt;Back end&lt;/em&gt;» estarían dentro de un &lt;em&gt;colgroup&lt;/em&gt; y las celdas al lado de las celdas de encabezado «Desarrollo», «Diseño», «Sistemas», etc. estarían dentro de un &lt;code&gt;rowgroup&lt;/code&gt;. No es una solución perfecta, pero definiendo estos bloques, ayudamos a la navegación. Estas etiquetas se suelen aplicar a los elementos &lt;code&gt;&amp;lt;th&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;conclusiones&quot;&gt;Conclusiones&lt;/h2&gt;
&lt;p&gt;Hacer desarrollo web accesible no es más complicado que hacer diseño &lt;em&gt;responsive&lt;/em&gt;, aunque implica dedicarle un poco más tiempo y empatía.&lt;/p&gt;
&lt;p&gt;Para que tus diseños sean exitosos, contempla lo siguiente:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hacer contenido claro, bien estructurado, y definir adecuadamente el contexto de cada cosa que mostremos en la web. Desarrollamos para personas.&lt;/li&gt;
&lt;li&gt;Aportar atajos y ayudas a la navegación si es posible, y sin exagerar.&lt;/li&gt;
&lt;li&gt;Vigilar los eventos interactivos, y señala adecuadamente sus estados.&lt;/li&gt;
&lt;li&gt;Revisar el código con herramientas que nos permitan conocer si hemos pasado algo por alto, y así corregirlo, como el &lt;a href=&quot;https://wave.webaim.org/&quot;&gt;complemento WAVE&lt;/a&gt; para el navegador.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/conceptos-fswd/index.html&quot;&gt;&lt;button&gt;Acceder a la página web&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Enlaces de interés&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.w3.org/WAI/fundamentals/accessibility-intro/es&quot;&gt;Introducción a la accesibilidad web&lt;/a&gt; - W3C&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://es.wikipedia.org/wiki/Accesibilidad_web&quot;&gt;Accesibilidad Web&lt;/a&gt; - Wikipedia&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://administracionelectronica.gob.es/pae_Home/pae_Estrategias/pae_Accesibilidad/pae_normativa/pae_eInclusion_Normas_Accesibilidad.html&quot;&gt;Normas de accesibilidad&lt;/a&gt; - PAE&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.ua.es/es/accesibilidad/&quot;&gt;Unidad de accesibilidad digital&lt;/a&gt; - Universidad de Alicante&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://twitter.com/sergiolujanmora&quot;&gt;Sergio Luján Mora&lt;/a&gt; - Profesor universitario experto&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://olgacarreras.blogspot.com/&quot;&gt;Usable y accesible&lt;/a&gt; - Consultora freelance&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://wave.webaim.org/&quot;&gt;complemento WAVE&lt;/a&gt; - Herramienta&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/WAI-ARIA&quot;&gt;WAI-ARIA&lt;/a&gt; - Estándar&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/accessibility.BH_1lQGp_ZiUkNk.webp"/><category>código</category><category>html</category><category>css</category><category>javascript</category><category>accesibilidad</category><category>usabilidad</category><author>JavGuerra</author></item><item><title>Validación de formularios</title><link>https://javguerra.github.io/blog/validacion</link><guid isPermaLink="true">https://javguerra.github.io/blog/validacion</guid><description>Combinando validaciones propias con las de HTML5</description><pubDate>Fri, 13 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/formulario.DcQ-TXfn_ZQ7Ppf.webp&quot; alt=&quot;Validación de formularios&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#formularios&lt;/em&gt;, &lt;em&gt;#usabilidad&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;¿Cómo procesar un formulario antes de enviarlo, realizando validaciones propias en sus campos y aprovechando simultáneamente la validación de restricciones implícita en HTML5?&lt;/p&gt;
&lt;p&gt;Que ambos tipos de validaciones se den al mismo tiempo es importante, ya que si esto se hiciera consecutivamente, es decir, una a continuación de la otra, llevando a cabo primero nuestra validación y luego la de HTML5, correríamos el riesgo de que los campos propios ya validados pudieran ser alterados por el usuario una vez pasada la primera validación, si en la segunda validación hay campos erróneos que obligan al usuario a editarlos, y por tanto el formulario se enviaría con errores. Veamos cómo se haría.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Validación de formularios&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/validacion.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/ejercicios-web-javascript/validacion.html&quot;&gt;&lt;button&gt;Formulario de ejemplo&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Tenemos un formulario con tres campos requeridos (obligatorios): «nombre», «edad» y «correo», y al campo «edad» le añado una restricción propia, que su valor debe ser mayor o igual a 16, y si esto no se cumple, deberé mostrar un mensaje de error personalizado en el mismo campo (al estilo de los mensajes de error de HTML5). El formulario cuenta con dos botones: «Borrar» y «Enviar».&lt;/p&gt;
&lt;p&gt;Si no tuviésemos que realizar nuestra validación, el proceso sería sencillo, ya que HTML se ocupa de todo por nosotros. Al hacer click en el botón enviar de tipo submit (&lt;code&gt;&amp;lt;button type=&quot;submit&quot;&amp;gt;Enviar&amp;lt;/button&amp;gt;&lt;/code&gt;), se lanza el evento &lt;code&gt;submit()&lt;/code&gt;, y el formulario se envía si no hay errores tras validarlo, o nos muestra los errores de validación de campos implícita en HTML5. Pero para poder realizar nuestras propias validaciones debemos romper este flujo, y tomar el control de la validación.&lt;/p&gt;
&lt;h2 id=&quot;tomando-el-control&quot;&gt;Tomando el control&lt;/h2&gt;
&lt;p&gt;Esto podemos hacerlo de dos formas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Capturamos el evento &lt;code&gt;submit()&lt;/code&gt; asociado al botón «Enviar» con &lt;code&gt;enviar.addEventListener(&apos;click&apos;, validaForm);&lt;/code&gt; en JavaScript, incluyendo en &lt;code&gt;function validaForm(evento)&lt;/code&gt; un &lt;code&gt;evento.preventDefault();&lt;/code&gt; que evite que el &lt;code&gt;action&lt;/code&gt; del formulario se procese, y realizando por nuestra cuenta todas las validaciones (las propias y las de HTML5), usando su (&lt;a href=&quot;https://www.w3.org/TR/html5/forms.html#the-constraint-validation-api&quot;&gt;API&lt;/a&gt;), para terminar lanzando el evento &lt;code&gt;form.submit()&lt;/code&gt; que retomará el curso del formulario.&lt;/li&gt;
&lt;li&gt;Usamos un botón «Enviar» que no incluya el &lt;code&gt;type=&quot;submit&quot;&lt;/code&gt;, y asociamos este botón a un evento que llame a la función de validación &lt;code&gt;validaForm()&lt;/code&gt; desde la cual, al final, lanzaremos también el &lt;code&gt;form.requestSubmit()&lt;/code&gt; si se cumplan las dos condiciones de este ejemplo: edad correcta y campos obligatorios rellenados.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;La opción elegida aquí es la segunda por ser la más simple para cumplir el objetivo marcado de llevar a cabo ambas validaciones. Desde la mencionada función &lt;code&gt;validaForm()&lt;/code&gt; comprobamos la edad con la función &lt;code&gt;validaEdad()&lt;/code&gt; que debe devolver &lt;code&gt;True&lt;/code&gt; o &lt;code&gt;False&lt;/code&gt;, y comprobamos nosotros mismos si el formulario tiene errores con &lt;code&gt;form.checkValidity()&lt;/code&gt;, que también devuelve &lt;code&gt;True&lt;/code&gt; o &lt;code&gt;False&lt;/code&gt;. Si ambas comprobaciones son &lt;code&gt;True&lt;/code&gt;, el formulario se envía.&lt;/p&gt;
&lt;p&gt;Al utilizar &lt;code&gt;form.requestSubmit()&lt;/code&gt;, el navegador se comporta exactamente igual que si el usuario hiciera clic en un botón de envío: ejecuta automáticamente la validación nativa (respetando atributos como required o pattern), muestra los mensajes de error al usuario si algo falla y dispara el evento submit, permitiendo que el formulario se gestione de forma segura y completa.&lt;/p&gt;
&lt;p&gt;Veamos el código JavaScript:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;01&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;. const enviar &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#enviar&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;02&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;. const form   &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.formulario;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;03&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;. &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;04&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;. enviar.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;click&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, validaForm);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;05&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;. &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;06&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;. function &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;validaForm&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(evento) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;07&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.   evento.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;preventDefault&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;08.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;   if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;validaEdad&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; form.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;checkValidity&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;09.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;     alert&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Ambas validaciones son correctas.&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;10.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;     form.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;requestSubmit&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;11.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;   } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;12.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;     alert&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;( &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;El formulario contiene errores.&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;13.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;   }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;14.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;15.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;16.&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; /* Comprueba que el usuario tenga más de 16 años */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;17.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; validaEdad&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;18.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;   const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; edad&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Number&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(form.edad.value);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;19.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;   if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (edad &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 16&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;20.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;     form.edad.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setCustomValidity&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Demasiado joven.&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;21.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;     return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;22.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;   }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;23.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;   form.edad.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setCustomValidity&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;24.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;   return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;25.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Para llegar a esta solución me inspiré en una &lt;a href=&quot;https://stackoverflow.com/questions/45789010/how-to-use-html-form-checkvalidity&quot;&gt;pregunta&lt;/a&gt; realizada en &lt;strong&gt;StackOverflow&lt;/strong&gt;, y en el &lt;a href=&quot;https://www.w3schools.com/js/js_validation_api.asp&quot;&gt;enlace&lt;/a&gt; de &lt;strong&gt;W3Schools&lt;/strong&gt; que aparece en la señalada como mejor respuesta de esa pregunta.&lt;/p&gt;
&lt;p&gt;En caso de tener que llevar a cabo más validaciones propias, bastaría con encadenarlas en el &lt;code&gt;ìf()&lt;/code&gt; de la línea &lt;strong&gt;8&lt;/strong&gt;, o crear una función a parte que incluya todas nuestras validaciones, que sustituya a &lt;code&gt;validaEdad()&lt;/code&gt; y que devuelva &lt;code&gt;True&lt;/code&gt; o &lt;code&gt;False&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;la-función-validaedad&quot;&gt;La función validaEdad()&lt;/h2&gt;
&lt;p&gt;Cuando se ejecuta la función &lt;code&gt;validaEdad()&lt;/code&gt;, pueden pasar dos cosas:&lt;/p&gt;
&lt;p&gt;Si la edad no es la adecuada, se marca el error en la línea &lt;strong&gt;20&lt;/strong&gt;: Al pasar un texto como &lt;code&gt;&apos;Demasiado joven.&apos;&lt;/code&gt;, el navegador marca el campo como inválido. Mientras exista este mensaje, el formulario estará bloqueado y no se podrá enviar.&lt;/p&gt;
&lt;p&gt;Si la edad es la adecuada, se limpiar el error en la línea &lt;strong&gt;23&lt;/strong&gt;: Es imprescindible pasar una cadena vacía &lt;code&gt;&apos;&apos;&lt;/code&gt; cuando el dato sea correcto. Esto indica al navegador que el campo vuelve a ser válido, permitiendo así el envío. Si no “limpias” el mensaje al cumplirse la condición, el campo quedará marcado como erróneo permanentemente.&lt;/p&gt;
&lt;p&gt;Debes aplicar esta misma lógica en cada validación propia que realices.&lt;/p&gt;
&lt;h2 id=&quot;valida--no-valida&quot;&gt;Valida / NO valida&lt;/h2&gt;
&lt;p&gt;¿Qué ocurre si la edad no es correcta o si uno de los campos obligatorios está vacío? Como el formulario no es correcto, se mostrará la alerta de la línea &lt;strong&gt;12&lt;/strong&gt;. Podemos sustituir esta alerta del ejemplo por una serie de acciones de aviso al usuario u otras para informar de que algo no ha ido bien (o no hacer nada, si no necesitamos el &lt;code&gt;else&lt;/code&gt;). En caso contrario, si todo ha ido bien, el formulario será válido, y se llevará a cabo lo estipulado en las líneas &lt;strong&gt;9&lt;/strong&gt; y &lt;strong&gt;10&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;La alerta de la línea &lt;strong&gt;9&lt;/strong&gt; del ejemplo puede sustituirse por cualquier cosa que queramos llevar a cabo antes de enviar el formulario en la línea &lt;strong&gt;10&lt;/strong&gt;, por ejemplo, mostrar los valores de los campos para que el usuario los revise antes de enviar, si estamos realizando una compra, un envío de dinero… Por último, en la línea &lt;strong&gt;10&lt;/strong&gt;, enviamos el formulario con &lt;code&gt;form.requestSubmit()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Eso es todo. Puedes ver el ejemplo empleado en esta entrada y más información relacionada en los siguientes enlaces:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/ejercicios-web-javascript/validacion.html&quot;&gt;&lt;button&gt;Formulario de ejemplo&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.w3.org/TR/html5/forms.html#the-constraint-validation-api&quot;&gt;API de formularios&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.w3schools.com/js/js_validation_api.asp&quot;&gt;Información y ejemplos en W3Schools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/45789010/how-to-use-html-form-checkvalidity&quot;&gt;Información en StackOverflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/formulario.DcQ-TXfn_ZQ7Ppf.webp"/><category>código</category><category>html</category><category>javascript</category><category>formularios</category><category>usabilidad</category><author>JavGuerra</author></item><item><title>Cronómetro en JavaScript</title><link>https://javguerra.github.io/blog/cronometro-js</link><guid isPermaLink="true">https://javguerra.github.io/blog/cronometro-js</guid><description>Gestiona cronometros y guarda sesiones de los cronometrajes</description><pubDate>Sun, 22 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/cronometro-digital.DrsDXeif_Z1xyUJk.webp&quot; alt=&quot;Cronómetro digital&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Ejercicio de programación realizado en el &lt;a href=&quot;/blog/beca-santander-fswd&quot;&gt;bootcamp Full Stack Web Developer&lt;/a&gt; que estoy haciendo.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/CronometroJS/index.html&quot;&gt;&lt;button&gt;Usar el cronómetro&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;enunciado&quot;&gt;Enunciado&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Diseñaremos un HTML que represente un cronómetro con el formato que queramos, por ejemplo: 00:00.&lt;/p&gt;
&lt;p&gt;Añadiremos los botones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Iniciar: Activará el cronómetro, incrementando el contador cada (1) segundo.&lt;/li&gt;
&lt;li&gt;Parar: Detiene el cronómetro.&lt;/li&gt;
&lt;li&gt;Continuar: Vuelve a activar el cronómetro.&lt;/li&gt;
&lt;li&gt;Contar hasta 10: Inicia el cronómetro y lo para a los 10 segundos (y para el crono).&lt;/li&gt;
&lt;li&gt;Guardar: Guarda el estado del crono en localStorage en el momento en que es pulsado (sin parar el crono).&lt;/li&gt;
&lt;li&gt;Ver tiempos: Mostrará el listado de tiempos divido en sesiones que se ha guardado en localStorage.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Queremos guardar en local Storage un conjunto de listados de tiempos divididos por sesiones, si es la primera vez que el usuario accede a la página web, la sesión será la número 1, y así sucesivamente.&lt;/p&gt;
&lt;p&gt;Añadiremos los botones pertinentes para borrar todos los datos de local Storage o solo los datos de una sesión en concreto.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;resolución&quot;&gt;Resolución&lt;/h2&gt;
&lt;p&gt;Este ejercicio es un compendio de todo lo visto hasta ahora en el Bootcamp.&lt;/p&gt;
&lt;p&gt;La aplicación que he desarrollado cumple con el enunciado, haciendo uso de las funciones de manejo de tiempos de JavaScript (&lt;code&gt;setInterval&lt;/code&gt;, &lt;code&gt;setTimeout&lt;/code&gt;, &lt;code&gt;clearInterval&lt;/code&gt;), y las funciones de manejo de &lt;code&gt;localStorage&lt;/code&gt; (&lt;code&gt;.setItem()&lt;/code&gt;, &lt;code&gt;.getItem()&lt;/code&gt;, &lt;code&gt;.clear()&lt;/code&gt;…), e incluye algunas mejoras:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Operativa de la aplicación&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Los botones del cronómetro se activan y desactivan según sean necesarios en cada función de la aplicación. Se recomienda leer mi entrada sobre &lt;a href=&quot;/blog/logica-interactiva&quot;&gt;lógica interactiva&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Implementa cuenta regresiva en el contador hasta 10.&lt;/li&gt;
&lt;li&gt;Al guardar un cronometraje, se muestra la lista de los cronometrajes de la sesión actual. Podemos listar también los cronometrajes de todas las sesiones, incluida la actual. El listado mostrará la sesión, el número del cronometraje dentro de esta sesión, el tiempo guardado (minutos y segundos), la fecha y hora, y el botón de borrar.&lt;/li&gt;
&lt;li&gt;Al borrar una sesión desde la lista de sesiones, si no se trata de la sesión actual, la aplicación reordena las sesiones para no dejar huecos entre ellas. Si tenemos cinco sesiones, y borramos la sesión tres, la sesión cuatro pasará a ser la tres, y la sesión cinco pasará a ser la cuatro.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Desde el punto de vista de la usabilidad&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Web adaptable según el dispositivo.&lt;/li&gt;
&lt;li&gt;Cuidado aspecto visual empleando CSS.&lt;/li&gt;
&lt;li&gt;El formateo básico se realiza mediante una clase CSS llamada &lt;a href=&quot;https://jgthms.com/wysiwyg.css/&quot;&gt;wysiwyg.css&lt;/a&gt; de la que hablé en &lt;a href=&quot;/blog/wysiwyg-css&quot;&gt;este post&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Usa &lt;a href=&quot;https://icons.getbootstrap.com/&quot;&gt;Bootstrap Icons&lt;/a&gt; y fuente personalizada llamada &lt;a href=&quot;https://www.dafont.com/digit.font&quot;&gt;Digit&lt;/a&gt; (&lt;em&gt;sin info del autor&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Es accesible, empleando etiquetas descriptivas y etiquetas &lt;a href=&quot;https://en.wikipedia.org/wiki/WAI-ARIA&quot;&gt;WAI-ARIA&lt;/a&gt; para señalar las regiones de la web que cambian durante la ejecución de la aplicación.&lt;/li&gt;
&lt;li&gt;Ha sido probada en los navegadores web &lt;strong&gt;Firefox&lt;/strong&gt; y &lt;strong&gt;Chrome&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;problemas-resueltos&quot;&gt;Problemas resueltos:&lt;/h2&gt;
&lt;p&gt;La aplicación emplea una serie de funciones para activar y desactivar los botones e incluir las etiquetas WAI-ARIA correspondientes.&lt;/p&gt;
&lt;p&gt;Con dos variables controlo los eventos del cronómetro (&lt;code&gt;cronometro&lt;/code&gt;) y del final de la cuenta atrás (&lt;code&gt;parada10s&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;La variable &lt;code&gt;tiempo&lt;/code&gt; guarda el tiempo en segundos que se llevan contabilizados en el cronometraje en cada momento.&lt;/p&gt;
&lt;p&gt;En &lt;code&gt;sesion&lt;/code&gt; guardo los cronometrajes de la sesión actual. Es un vector o Array de objetos, donde cada objeto es un cronometraje, que se guarda en el formato:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;segundos&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: tiempo, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;fechaHora&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: fechaHora}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En &lt;code&gt;numSesion&lt;/code&gt; guardo el número de sesión actual. Las sesiones se guardan en &lt;strong&gt;localStorage&lt;/strong&gt; con el nombre que corresponde a su número de orden.&lt;/p&gt;
&lt;p&gt;Uso una sesión o clave guardada en &lt;strong&gt;localStorage&lt;/strong&gt; con el nombre &lt;code&gt;ultSesion&lt;/code&gt; que contiene el número de orden de la última sesión guardada. De esta forma puedo consultarla para saber si hay sesiones guardadas, y cuál es el número de orden de la última que se guardó.&lt;/p&gt;
&lt;p&gt;A la hora de guardar y recuperar las sesiones guardadas en &lt;strong&gt;localStorage&lt;/strong&gt; creí erróneamente que estas se guardaban en orden descendiente, que podía recorrer la lista de claves de &lt;strong&gt;localStorage&lt;/strong&gt; con un bucle, como si se tratase de una pila de datos «&lt;strong&gt;LIFO&lt;/strong&gt;» (&lt;em&gt;Last Input - First Output&lt;/em&gt;), de tal forma que la última clave que añadimos a &lt;strong&gt;localStorage&lt;/strong&gt; sería la primera en la lista, y su número de orden sería 0. Así, si recorría la lista con &lt;code&gt;clave = localStorage.key(i)&lt;/code&gt;, obtendría primero la clave 0, la última, luego la 1, la penúltima, la 2, la antepenúltima, etc… pero esto no funciona siempre así.&lt;/p&gt;
&lt;p&gt;Parece que no podemos confiar en este orden, por lo que las sesiones deben guardarse y recuperarse sin tener en cuenta la posición que ocupan en &lt;strong&gt;localStorage&lt;/strong&gt;, lo que me obligó a reescribir la función &lt;code&gt;historLocal()&lt;/code&gt; (listado del historial) y las «delicadas» funciones &lt;code&gt;borraClave(clave)&lt;/code&gt; (borra una sesión) y &lt;code&gt;ordenaClaves(clave, numSesiones)&lt;/code&gt; (ordena las sesiones cuando hay un hueco) que, sinceramente, me llevaron más tiempo del que merecían hasta que volvieron a estar perfectamente ajustadas.&lt;/p&gt;
&lt;p&gt;Otra cuestión que me sorprendió fue la del manejo de los tiempos en los intervalos empleados en la cuenta regresiva (Contar hasta 10). &lt;strong&gt;Firefox&lt;/strong&gt; y &lt;strong&gt;Chrome&lt;/strong&gt; no funcionan igual. Si contamos desde 10 segundos hasta 0, realmente hay 11 segundos. Pues bien, mientras en Firefox esto funcionaba bien empleando &lt;code&gt;parada10s = setTimeout( parateCrono, 11000);&lt;/code&gt; (parateCrono es una función que para el cronómetro) en Chrome el resultado final de la cuenta regresiva, en vez de &lt;code&gt;0&lt;/code&gt; es &lt;code&gt;-1&lt;/code&gt;, así que debí crear la siguiente función para corregir esto:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; limite&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;miliSeg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; navigator.userAgent.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;indexOf&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Firefox&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; miliSeg &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1000&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; miliSeg;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Que comprueba si estamos usando Firefox, entonces devuelve el valor &lt;code&gt;11000&lt;/code&gt; (11 segundos), sino devuelve &lt;code&gt;10000&lt;/code&gt; (10 segundos), para luego poder usarlo de esta forma:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;parada10s &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; setTimeout&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;( parateCrono, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;limite&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;10000&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;));&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Los iconos empleados en los botones inicialmente eran confusos. Con la revisión del compañero del bootcamp &lt;strong&gt;Francesc&lt;/strong&gt; cambié la combinación de iconos para hacer la aplicación más usable.&lt;/p&gt;
&lt;p&gt;Por último, señalar que la aplicación maneja sólo minutos y segundos, hasta un máximo de 3.600 segundos (de 0 a 3.599). Inspirado por la presentación del compañero del bootcamp &lt;strong&gt;Borja&lt;/strong&gt;, incluí el siguiente código dentro de la función que muestra el cronómetro:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (minSeg.minutos &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 59&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; minSeg.segundos &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 59&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    parateCrono&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    btnInactivo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(btnContin, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esto para el cronómetro y pone inactivo el botón de continuar cuando la aplicación llega a 59 minutos y 59 segundos.&lt;/p&gt;
&lt;h2 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/CronometroJS/index.html&quot;&gt;&lt;button&gt;Usar el cronómetro&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/JavGuerra/CronometroJS&quot;&gt;Ver el código fuente&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Referencias&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.w3schools.com/jsref/met_win_settimeout.asp&quot;&gt;setTimeout&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.w3schools.com/jsref/met_win_setinterval.asp&quot;&gt;setInterval&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://es.javascript.info/localstorage&quot;&gt;localStorage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/cronometro-digital.DrsDXeif_Z1xyUJk.webp"/><category>web</category><category>código</category><category>css</category><category>html</category><category>javascript</category><author>JavGuerra</author></item><item><title>Paginación</title><link>https://javguerra.github.io/blog/paginacion</link><guid isPermaLink="true">https://javguerra.github.io/blog/paginacion</guid><description>Cómo hacer una barra de navegación en JavaScript</description><pubDate>Mon, 30 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/paginacion.Ddenk8LV_Zd8315.webp&quot; alt=&quot;Paginación&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#usabilidad&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Imaginemos una lista de entradas de un blog, o una galería de imágenes, con un número de items o elementos alto. Pongamos mil. Esto se hace difícil de manejar, tanto por las dimensiones de las pantallas como por el número de elementos al que el usuario prestará atención, y también existe un problema técnico, el consumo de memoria que implica mostrar todos los items de esa lista, y el tiempo que tarda en hacerlo. Ese retraso entre que se carga la página, se «pinta» y se devuelve el control al usuario supone un tiempo de espera incómodo.&lt;/p&gt;
&lt;p&gt;Paginar es mostrar el contenido separado en páginas para, de esta forma, hacerlo más asequible al usuario, y esta es la solución de la que hablaré en esta entrada.&lt;/p&gt;
&lt;h2 id=&quot;planteamiento&quot;&gt;Planteamiento&lt;/h2&gt;
&lt;p&gt;&lt;span class=&quot;note&quot;&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Para una mejor comprensión de la resolución de este ejercicio, algunas variables que podrían ser globales, como es el caso de &lt;code&gt;longitud&lt;/code&gt; del vector y otras, se repiten en las disitntas funciones.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;En un vector o array tenemos una serie de elementos o items que queremos mostrar paginados, y queremos que estos items se muestren por ejemplo de diez en diez. Para hacerlo necesitaremos el vector, el número de elementos por página y deberemos averiguar el número de páginas que podemos mostrar. Luego recorreremos las páginas ayudandonos de una variable que hará las veces de índice.&lt;/p&gt;
&lt;p&gt;Para mostrar el resultado, el HTML contendrá lo siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;section&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;galeria&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; role&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;region&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; aria-live&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;polite&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;section&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;section&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;navegacion&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;irInic&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; aria-label&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Inicio&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;lt;&amp;amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;anteri&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; aria-label&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Anterior&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;   id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;pagina&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; role&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;region&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; aria-live&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;polite&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;siguie&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; aria-label&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Siguiente&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;irFin&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  aria-label&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Fin&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;gt;&amp;amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;section&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Una sección &lt;code&gt;galeria&lt;/code&gt; donde mostrar los items. en este caso las imágenes.&lt;/p&gt;
&lt;p&gt;Una sección de &lt;code&gt;navegacion&lt;/code&gt; con los botones para recorrer las páginas y donde informar al usuario de la página donde nos econtramos.&lt;/p&gt;
&lt;p&gt;Esto implica la siguiente configuración de valores iniciales en el fichero &lt;code&gt;.js&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; nFotos  &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 10&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; pagina  &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; galeria &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/* Obtener los datos a incluir en galeria */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;elGaleria &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; elemento&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#galeria&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;elPaginac &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; elemento&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#pagina&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;btnIrInic &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; elemento&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#irInic&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;btnAnteri &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; elemento&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#anteri&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;btnSiguie &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; elemento&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#siguie&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;btnIrFin  &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; elemento&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#irFin&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;btnIrInic.onclick &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; inicial;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;btnAnteri.onclick &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; anterior;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;btnSiguie.onclick &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; siguiente;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;btnIrFin.onclick  &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; final;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;paginacion&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(galeria, pagina, nFotos);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/* Devuelve un elemento */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; elemento&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;sel&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) { &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(sel); }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La variable &lt;code&gt;nFotos&lt;/code&gt; contiene el número de elementos por página.
Iniciamos la variable &lt;code&gt;pagina&lt;/code&gt; a &lt;code&gt;1&lt;/code&gt;, y el vector galeria, que contendrá las rutas a las imagenes, a un vector vacío &lt;code&gt;[]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Para cargar la lista de imágenes de la galería en el vector &lt;code&gt;galeria&lt;/code&gt;, podemos usar &lt;code&gt;fetch()&lt;/code&gt; contra una &lt;strong&gt;API&lt;/strong&gt; o un &lt;strong&gt;JSON&lt;/strong&gt; guardado localmente, por ejemplo.&lt;/p&gt;
&lt;p&gt;Seguidamente obtenemos los elementos &lt;code&gt;elGaleria&lt;/code&gt; y &lt;code&gt;elPagina&lt;/code&gt; y los cuatro botones para movernos por las páginas de la galería. A cada uno de ellos le asignamos un evento que ejecutará una función al hacer click que nos llevará a la primera página, a la anterior, a la siguiente o a la última respectivamente, alterando el valor de la variable &lt;code&gt;pagina&lt;/code&gt; y llamando a la función que muestra la galería. Veamos estas funciones:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/* Va a la primera página */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; inicial&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    pagina &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    paginacion&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(galeria, pagina, nFotos);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/* Va a la página anterior */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; anterior&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    pagina&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;--&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    paginacion&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(galeria, pagina, nFotos);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/* Va a la página siguiente */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; siguiente&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    pagina&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    paginacion&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(galeria, pagina, nFotos);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/* Va a la última página */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; final&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; longitud &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; galeria.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    pagina &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Math.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;ceil&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(longitud &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; nFotos);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    paginacion&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(galeria, pagina, nFotos);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cada una de estas cuatro funciones llama a la función &lt;code&gt;paginacion&lt;/code&gt;, para acutalizar el contenido de la galería con tres valores: el vector, la página a mostrar y el número de fotos por página.&lt;/p&gt;
&lt;p&gt;En la función &lt;code&gt;final&lt;/code&gt; calculo el número de páginas posibles atendiendo a la longitud del vector, así, obteniendo el valor entero resultante de dividir la longitud del vector entre el número de imágenes por página devolverá el número de la última página (o el número total de páginas) que guardo en &lt;code&gt;pagina&lt;/code&gt;, valor que necesito para llamar a la función &lt;code&gt;paginacion&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;paginando&quot;&gt;Paginando&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/* Pagina los elementos de un vector en función de página y elementos por página */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; paginacion&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;vector&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;pagina&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;elementos&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; longitud, numPags, inicio;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    longitud &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; vector.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (longitud) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        // Averigua el elemento de inicio&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        numPags &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Math.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;ceil&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(longitud &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; elementos);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (pagina &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; numPags) pagina &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; numPags;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (pagina &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) pagina &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        inicio &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (pagina &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; elementos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        // Ajusta el número de elementos si se requiere&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (longitud &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; elementos) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            elementos &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; longitud;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (longitud &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; inicio &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; elementos) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            elementos &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; longitud &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; inicio;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        // Resuelve&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        ctrlBotonesPag&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(pagina, numPags);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        listaElementos&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(vector, inicio, elementos); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esta es la función donde se produce la «magia». Tras hallar la longitud del vector recibido, si esta es mayor que cero, paso a calcular primeramente el elemento de &lt;code&gt;inicio&lt;/code&gt; de la página que vamos a mostrar. Si la pagina es 1, elemento del vector que guardará &lt;code&gt;inicio&lt;/code&gt; será &lt;code&gt;0&lt;/code&gt; (cero), si la página es la &lt;code&gt;2&lt;/code&gt; el valor será &lt;code&gt;10&lt;/code&gt;, -pues cabe recordar que el número de elementos por página (&lt;code&gt;nFotos&lt;/code&gt;) es &lt;code&gt;10&lt;/code&gt;-, y así sucesivamente.&lt;/p&gt;
&lt;p&gt;Realizo una serie de comprobaciones para obtener el valor de &lt;code&gt;inicio&lt;/code&gt; adecuado: Si la página que recibimos por parámetros es mayor que el número de páginas posibles del vector, la página a mostrar será la última. Si el valor de página es menor que &lt;code&gt;1&lt;/code&gt;, el valor de página será &lt;code&gt;1&lt;/code&gt;, evitando de esta forma que el programa intente mostrar elementos del vector que no existen.&lt;/p&gt;
&lt;p&gt;Una vez tengo el valor de &lt;code&gt;inicio&lt;/code&gt; veo si es necesario ajustar el número de &lt;code&gt;elementos&lt;/code&gt; que se mostrarán en la página. Así, si el número de &lt;code&gt;elementos&lt;/code&gt; por página (&lt;code&gt;nFotos&lt;/code&gt;) es mayor que el número de items del vector, el valor de &lt;code&gt;elementos&lt;/code&gt; se ajusta al número total de items del vector. Sino, se comprueba si el número de items que quedan por mostrarse en esta página &lt;code&gt;(longitud - inicio)&lt;/code&gt; es menor que el número de &lt;code&gt;elementos&lt;/code&gt; (&lt;code&gt;nfotos&lt;/code&gt;), y si es así, se ajusta el valor de &lt;code&gt;elementos&lt;/code&gt;. Este caso ocurre cuando la última página tiene un número de elementos menor que el de &lt;code&gt;nFotos&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Como ya tengo todo lo que necesito, llamo consecutivamente a dos funciones, la encargada de activar o desactivar los botones &lt;code&gt;ctrlBotonesPag(pagina, numPags);&lt;/code&gt; y la encargada de «pintar» la galería &lt;code&gt;listaElementos(vector, inicio, elementos);&lt;/code&gt; mostrando las fotos y la información relativa a la página. Veamos la primera de ellas:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/* Activa o desactiva los botones según la página */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ctrlBotonesPag&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;pagina&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;numPags&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    btnInactivo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(btnIrInic, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    btnInactivo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(btnAnteri, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    btnInactivo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(btnSiguie, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    btnInactivo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(btnIrFin,  &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (pagina &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        btnInactivo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(btnIrInic, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        btnInactivo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(btnAnteri, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (pagina &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; numPags) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        btnInactivo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(btnSiguie, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        btnInactivo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(btnIrFin,  &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esta función primeramente activa todos los botones, por si fuese el caso de que alguno de los ellos hubiera sido desactivado previamente, y luego comprueba si estamos en la primera página, desactivando entonces los botones de &lt;strong&gt;ir al inicio&lt;/strong&gt; de la galería (&lt;code&gt;btnIrInic&lt;/code&gt;) e &lt;strong&gt;ir a la página anterior&lt;/strong&gt; (&lt;code&gt;btnAnteri&lt;/code&gt;) o si estamos en la última página, desactivando entonces &lt;strong&gt;ir al a página siguiente&lt;/strong&gt; (&lt;code&gt;btnSiguie&lt;/code&gt;) e &lt;strong&gt;ir al final&lt;/strong&gt; de la galería (&lt;code&gt;btnIrFin&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Para activar y desactivar los botones, empleo la siguiente función:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/* Cambia el estado de un botón dado */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; btnInactivo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;boton&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;estado&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    boton.disabled &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; estado;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    boton.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;aria-disabled&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, estado);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Recibe como parámetros el botón y el estado que deseamos ponerle: &lt;code&gt;true = inactivo&lt;/code&gt;  o &lt;code&gt;false = activo&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Una vez tengo los botones en sus estados correctos, sólo queda mostrar la galería.&lt;/p&gt;
&lt;h2 id=&quot;mostrando&quot;&gt;Mostrando&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/* Muestra la cantidad de elementos de un vector desde la posición dada */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; listaElementos&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;vector&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;inicio&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;elementos&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; longitud &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; vector.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; primero  &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; inicio &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; fin &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; inicio &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; elementos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    elGaleria.textContent &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    elPaginac.textContent &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    botonera&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    vector.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;slice&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(inicio, fin).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;urlFoto&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            /*&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;             * Código para mostrar la galería&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;             */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    elPaginac.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `Fotos: ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;primero&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;} a ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;fin&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;} de ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;longitud&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    botonera&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Los parámetros que recibimos son el vector (&lt;code&gt;galeria&lt;/code&gt;), el número del item inicial (&lt;code&gt;ìnicio&lt;/code&gt;) y los elementos por página (&lt;code&gt;nFotos&lt;/code&gt;) a mostrar. Con ellos obtengo la &lt;code&gt;longitud&lt;/code&gt;, el número de orden del elemento &lt;code&gt;primero&lt;/code&gt; de la página &lt;code&gt;inicio + 1&lt;/code&gt; y el elemento final del vector que debemos mostrar &lt;code&gt;inicio + elementos&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Seguidamente limpio la página para: el contenido de la galería, el contenido de la info de la paginación, y oculto la botonera. Esto último lo hago con la función &lt;code&gt;botonera(status)&lt;/code&gt; que veremos al finalizar.&lt;/p&gt;
&lt;p&gt;Con &lt;code&gt;vector.slice(inicio, fin).forEach((urlFoto, i) =&amp;gt; { // })&lt;/code&gt; primeramente obtenemos los elementos del vector que necesitamos con &lt;code&gt;.slice(inicio, fin)&lt;/code&gt; y mediante el &lt;code&gt;.forEach()&lt;/code&gt; itero los elementos a mostrar, obteniendo del vector la url de la foto (&lt;code&gt;urlFoto&lt;/code&gt;) y el índice (&lt;code&gt;i&lt;/code&gt;) de elementos del &lt;code&gt;.forEach()&lt;/code&gt;. Dentro de la función flecha se debe incluir el código para mostrar las imágenes dentro del elemento &lt;code&gt;elGaleria&lt;/code&gt; del &lt;strong&gt;HTML&lt;/strong&gt;, por ejemplo:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;elGaleria.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;`&amp;lt;div&amp;gt;&amp;lt;a href=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;urlFoto&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; target=&quot;_blank&quot;&amp;gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&amp;lt;img src=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;urlFoto&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; alt=&quot;Foto ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;primero&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; i&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; /&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;`&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Al terminar de recorrer el vector resultante de aplicar &lt;code&gt;.slice()&lt;/code&gt;, incluyo la información de la página en el elemento &lt;code&gt;elPagina&lt;/code&gt; del &lt;strong&gt;HTML&lt;/strong&gt;, y muestro la botonera que anteriormente oculté. Esta sería la función para hacerlo que mencioné antes:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/* Activa o desactiva la botonera */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; botonera&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;status&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    btnIrInic.style.display &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; status &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;initial&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;none&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    btnAnteri.style.display &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; status &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;initial&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;none&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    btnSiguie.style.display &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; status &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;initial&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;none&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    btnIrFin.style.display  &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; status &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;initial&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;none&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Como se aprecia, &lt;code&gt;true = activa&lt;/code&gt; y &lt;code&gt;false = desactiva&lt;/code&gt; la botonera mostrándola u ocultándola.&lt;/p&gt;
&lt;p&gt;Con esto ya tendríamos presentada la página de la galería con el número de elementos indicado, la información de la página y los botones para movernos por la galería, que era el objetivo de esta entrada.&lt;/p&gt;
&lt;h2 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Podemos ver un caso de uso en esta:&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/ejercicios-web-javascript/17-fetch.html&quot;&gt;&lt;button&gt;galería de perritos&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;El ejemplo anterior usa la API &lt;a href=&quot;https://dog.ceo/dog-api/&quot;&gt;Dog CEO&lt;/a&gt;.&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/paginacion.Ddenk8LV_Zd8315.webp"/><category>código</category><category>css</category><category>html</category><category>javascript</category><category>usabilidad</category><author>JavGuerra</author></item><item><title>Spinner loader asíncrono</title><link>https://javguerra.github.io/blog/spinner-loader-asincrono</link><guid isPermaLink="true">https://javguerra.github.io/blog/spinner-loader-asincrono</guid><description>Mantiene el spinner activo mientras finalizan todos los procesos asíncronos</description><pubDate>Mon, 30 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/spinner-loader.BwuWn1K3_1CpEz3.webp&quot; alt=&quot;Spin&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#usabilidad&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Durante los procesos asíncronos que se llevan a cabo, por ejemplo al usar &lt;code&gt;fetch()&lt;/code&gt; para consumir una &lt;strong&gt;API&lt;/strong&gt; remota, se producen retrasos al mostrar los resultados en el navegador. El uso de &lt;em&gt;spinner loader&lt;/em&gt; ayuda a informar al usuario de que uno o varios procesos están en marcha y se está procesando la información que solicitó tal vez mediante un campo de búsqueda.&lt;/p&gt;
&lt;h2 id=&quot;girando&quot;&gt;Girando…&lt;/h2&gt;
&lt;p&gt;Para mostrar un &lt;em&gt;spinner loader&lt;/em&gt; por pantalla cuando uno o varios de estos procesos se estén ejecutando necesitaré:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Una función que active o desactive el &lt;em&gt;spinner loader&lt;/em&gt; según un valor de status &lt;strong&gt;true/false&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Una función que compruebe si hay o no procesos asíncronos activos aún.&lt;/li&gt;
&lt;li&gt;Ubicar en pantalla el &lt;em&gt;spinner loader&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;El &lt;strong&gt;HTML&lt;/strong&gt; deberá contener la siguiente línea:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;dialog&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;zona&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;spinner&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;dialog&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La etiqueta &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; es relativamente desconocida, pero de gran utilidad. La descubrí en &lt;a href=&quot;https://twitter.com/Manz/status/1529836795130744834&quot;&gt;este twitt&lt;/a&gt; de &lt;a href=&quot;https://twitter.com/Manz&quot;&gt;@Manz&lt;/a&gt;. Esta etiqueta permite crear ventanas modales con &lt;strong&gt;HTML&lt;/strong&gt;. &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; muestra una ventana por encima del contenido de la página y aplica un efecto de fondo sombreado al resto de la página.&lt;/p&gt;
&lt;p&gt;Para dibujar el &lt;em&gt;spinner loader&lt;/em&gt;, seguí las indicaciones de la entrada «&lt;a href=&quot;https://midu.dev/como-crear-un-spinner-con-css/&quot;&gt;Cómo crear un spinner loader con CSS&lt;/a&gt;» Este es el código &lt;strong&gt;CSS&lt;/strong&gt; que incluye también el del diálogo.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;css&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;#zona&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  border&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  background&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;#zona:focus&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  outline&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.spinner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  margin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; auto&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  border&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; solid&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; LightGray&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;36&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;36&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  border-radius&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  border-left-color&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;LightSeaGreen&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  animation&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: spin &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; ease&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; infinite&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@keyframes&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; spin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  0%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;rotate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;deg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  100%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;rotate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;360&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;deg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;El modal identificado como &lt;code&gt;#zona&lt;/code&gt; se mostrará sin fondo y sin borde, osea, totalmente transparente. En él muestro el &lt;em&gt;spinner loader&lt;/em&gt;. &lt;code&gt;#zona&lt;/code&gt; tendrá el tamaño del  &lt;em&gt;spinner loader&lt;/em&gt;, y aparecerá centrado tanto vertical como horizontalmente en la pantalla, manteniéndose centrado aún haciendo &lt;em&gt;scroll&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Con &lt;code&gt;.spinner&lt;/code&gt;se describe el aspecto del &lt;em&gt;spinner loader&lt;/em&gt; y se indicará que debe animarse infinitamente girando 360 grados cada segundo.&lt;/p&gt;
&lt;h2 id=&quot;activando--desactivando&quot;&gt;Activando / desactivando&lt;/h2&gt;
&lt;p&gt;Como estamos trabajando con procesos asíncronos, se puede dar el caso de que, al lanzar un proceso asíncrono, el &lt;em&gt;spinner loader&lt;/em&gt; ya esté mostrado, por tanto no tendremos que mostrarlo. Debo controlar si hay procesos asíncronos en marcha. Esto lo hago con una simple variable &lt;code&gt;spin&lt;/code&gt; que va incrementando o decrementando su valor según el número de procesos asíncronos lanzados.&lt;/p&gt;
&lt;p&gt;Inicializo también la variable &lt;code&gt;intervalo&lt;/code&gt; que usaré para controlar un &lt;code&gt;setInterval()&lt;/code&gt; que comprueba periódicamente el estado de los procesos asíncronos, osea, la variable &lt;code&gt;spin&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Capturo la &lt;code&gt;#zona&lt;/code&gt; donde se mostrará el diálogo modal con el &lt;em&gt;spinner loader&lt;/em&gt;, como se muestra a continuación:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; spin &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; intervalo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;elZona   &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#zona&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Veamos cómo funciona la activación o desactivación asíncronas mediante el siguiente código:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/* Activa o desactiva el spin */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ponSpin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;estado&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    estado &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; spin&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; spin&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;--&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (estado &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;intervalo) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        intervalo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; setInterval&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(compruebaSpin, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;300&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        elZona.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;showModal&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/* Comprueba si el spin ha llegado a cero y desactiva comprobación */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; compruebaSpin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;spin) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        clearInterval&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(intervalo);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        intervalo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        elZona.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cuando iniciamos un proceso asíncrono, se debe llamar a la función &lt;code&gt;ponSpin(true)&lt;/code&gt; con el valor &lt;code&gt;true&lt;/code&gt;, esto incrementará en &lt;code&gt;1&lt;/code&gt; el valor de &lt;code&gt;spin&lt;/code&gt;. Sólo si estoy incrementando &lt;code&gt;spin&lt;/code&gt; (&lt;code&gt;estado = true&lt;/code&gt;), y es la primera vez que se activa (&lt;code&gt;!intervalo&lt;/code&gt;), lanzo &lt;code&gt;compruebaSpin()&lt;/code&gt; cada 300 milisegundos con &lt;code&gt;intervalo = setInterval(compruebaSpin, 300);&lt;/code&gt;y muestro la ventana modal que contiene el &lt;em&gt;spinner loader&lt;/em&gt; con &lt;code&gt;elZona.showModal();&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Es necesario lanzar el &lt;code&gt;setInterval()&lt;/code&gt; porque desconocemos en qué momento los procesos asíncronos terminarán, por lo que se debe comprobar el estado de los procesos cada cierto tiempo.&lt;/p&gt;
&lt;p&gt;Al finalizar un proceso asíncrono debemos llamar de nuevo a la función con &lt;code&gt;ponSpin(false)&lt;/code&gt;, y el valor &lt;code&gt;false&lt;/code&gt; decrementará en &lt;code&gt;1&lt;/code&gt; el valor de &lt;code&gt;spin&lt;/code&gt;, que irá decreciendo hasta llegar a &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;La función &lt;code&gt;compruebaSpin()&lt;/code&gt;, como vimos, es lanzada cada 300 milisegundos, y su función es comprobar si &lt;code&gt;spin&lt;/code&gt; ha llegado a &lt;code&gt;0&lt;/code&gt;, y si es así, desactiva el &lt;code&gt;setInterval()&lt;/code&gt; y oculta la ventana modal que contiene el &lt;em&gt;spinner loader&lt;/em&gt; con &lt;code&gt;elZona.close();&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Importante&lt;/strong&gt;: Hay que ser cuidadoso para indicar tantos cierres del &lt;em&gt;spinner loader&lt;/em&gt; como aperturas se llevan a cabo, es decir, por cada &lt;code&gt;ponSpin(true)&lt;/code&gt; debe haber un &lt;code&gt;ponSpin(false)&lt;/code&gt;, de otra forma, podemos quedarnos con un &lt;em&gt;spinner loader&lt;/em&gt; girando indefinidamente o que se cerró antes de haber concluido todos los procesos asíncronos.&lt;/p&gt;
&lt;p&gt;Este podría ser un ejemplo de código para poner en marcha y concluir un &lt;em&gt;spinner loader&lt;/em&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/* Consulta la API en la ruta dada y ejecuta la función callback() */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; consultaAPI&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;ruta&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;callback&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    ponSpin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    fetch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(ruta)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;respuesta&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// fetch() no maneja errores de conexión, luego...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;respuesta.ok) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(respuesta.statusText);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; respuesta.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;json&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; callback&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(data))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(err);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;finally&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;( &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;ponSpin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Podemos ver un caso de uso en esta &lt;a href=&quot;https://javguerra.github.io/ejercicios-web-javascript/17-fetch.html&quot;&gt;&lt;button&gt;galería de perritos&lt;/button&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El ejemplo anterior usa la API &lt;a href=&quot;https://dog.ceo/dog-api/&quot;&gt;Dog CEO&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Info sobre la etiqueta &lt;a href=&quot;https://twitter.com/Manz/status/1529836795130744834&quot;&gt;&lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Artículo «&lt;a href=&quot;https://midu.dev/como-crear-un-spinner-con-css/&quot;&gt;Cómo crear un spinner loader con CSS&lt;/a&gt;».&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/spinner-loader.BwuWn1K3_1CpEz3.webp"/><category>código</category><category>css</category><category>html</category><category>javascript</category><category>usabilidad</category><author>JavGuerra</author></item><item><title>Contador de resultados</title><link>https://javguerra.github.io/blog/contador-resultados</link><guid isPermaLink="true">https://javguerra.github.io/blog/contador-resultados</guid><description>Gráfica SVG dinámica en JavaScript con aguja indicadora de resultados</description><pubDate>Sat, 04 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/contador.CvHdujvp_ZAoCzg.webp&quot; alt=&quot;Contador&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#svg&lt;/em&gt;, &lt;em&gt;#usabilidad&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;La información visual es percibida con más claridad que la escrita. A la hora de mostrar resultados, por ejemplo los aciertos o fallos de un examen on-line, podemos complementar la información escrita con una gráfica dinámica que muestre los resultados de un vistazo, aportando además valor al resultado.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/ejercicios-web-javascript/contador.html&quot;&gt;&lt;button&gt;Ver contador de ejemplo&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;el-contador&quot;&gt;El contador&lt;/h2&gt;
&lt;p&gt;Para mostrar la información de este ejemplo, he elaborado una gráfica en formato .SVG que contiene un contador en semicírculo con paneles descriptivos. La aguja apunta a los paneles rotulados con el texto: «insuficiente», «regular», «bien» y «excelente» según un resultado numérico entre 0 y 10, donde 0 es ninguna pregunta acertada y diez corresponde a un total de diez sobre diez preguntas contestadas correctamente.&lt;/p&gt;
&lt;p&gt;El fichero SVG lo he creado con &lt;a href=&quot;https://inkscape.org/es/&quot;&gt;InkScape&lt;/a&gt;, una herramienta libre de dibujo vectorial. el diseño asemeja algunas imágenes que encontré haciendo una búsqueda por Internet. Para su elaboración, he tenido en cuenta dos cuestiones importantes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;El tamaño del dibujo tiene las proporciones (ancho x alto) de la imagen que se mostrará en la página. En el caso de este contador, 400px x 240px. Es importante guardar el documento con la medida en píxeles, para poder trabajar después con el tamaño de la imagen desde CSS, si queremos aplicarle distintos tamaños, por ejemplo para la visualización de esta gráfica en diferentes tipos de pantalla (móviles, tablets…).&lt;/li&gt;
&lt;li&gt;La gráfica cuenta con una aguja indicadora. Para poder acceder a ella desde JavaScript y que la aguja apunte adecuadamente, he incluido una etiqueta ID (&lt;code&gt;id=&quot;aguja&quot;&lt;/code&gt;) en el elemento SVG que agrupa las líneas del dibujo que corresponden a la aguja. Esto podemos hacerlo directamente desde InkScape. En este caso, el elemento quedaría así:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;aguja&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;matrix(.28946 0 0 .28839 126 -138.93)&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;El atributo «transform» dentro del SVG indica la posición de la aguja, su tamaño y ángulo de giro. El que se muestra aquí corresponde a la aguja en posición vertical, equivalente a un resultado de 5, entre 0 y 10. Para cubrir todo el rango de puntuaciones, la aguja debe girar 18 grados en un sentido y en otro, es decir, que irá girando de 0 a 180 grados en saltos de 18 grados.&lt;/p&gt;
&lt;p&gt;Calcular los valores de la posición de la aguja en cada uno de esos intervalos no es tarea fácil. Para acortar camino, guardé la misma gráfica con la aguja en las distintas 11 posiciones y obtuve el valor de transform en cada una de ellas. Este será el valor que luego pasaremos a la gráfica para indicar qué posición debe tener la aguja en función de la puntuación obtenida. Esta es la tabla obtenida:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/ejercicios-web-javascript/img/contadores.png&quot; alt=&quot;Contadores&quot;&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;text-align: left&quot;&gt;Puntos&lt;/th&gt;
&lt;th style=&quot;text-align: left&quot;&gt;Valores de la aguja&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;transform=“matrix(0 -.28946 .28839 0 -139.16 -20.501)”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;transform=“matrix(.089449 -.2753 .27428 .089119 -107.1 -76.177)”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;transform=“matrix(.17014 -.23418 .23332 .16951 -59.407 -119.22)”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;transform=“matrix(.23418 -.17014 .16951 .23332 -.74583 -145.42)”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;transform=“matrix(.2753 -.089449 .089119 .27428 63.14 -152.21)”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left&quot;&gt;5&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;transform=“matrix(.28946 0 0 .28839 126 -138.93)”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left&quot;&gt;6&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;transform=“matrix(.2753 .089449 -.089119 .27428 181.67 -106.87)”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left&quot;&gt;7&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;transform=“matrix(.23418 .17014 -.16951 .23332 224.72 -59.174)”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;transform=“matrix(.17014 .23418 -.23332 .16951 250.92 -.51273)”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left&quot;&gt;9&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;transform=“matrix(.089449 .2753 -.27428 .089119 257.71 63.373)”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left&quot;&gt;10&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;transform=“matrix(0 .28946 -.28839 0 244.42 126.23)”&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Teniendo el SVG y esta información, usando JavaScript podemos mostrar una gráfica dinámica de resultados.&lt;/p&gt;
&lt;h2 id=&quot;presentación&quot;&gt;Presentación&lt;/h2&gt;
&lt;p&gt;En el ejemplo, la gráfica aparece con un recuadro de texto debajo que indica también el resultado. Mediante CSS posiciono la gráfica con un valor de margen superior negativo para que esta quede justo por encima del recuadro, lo que consigue el efecto de que la gráfica y el recuadro está unidos por la intersección de la aguja.&lt;/p&gt;
&lt;p&gt;El código html sería el siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;resultados&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; version&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;1.1&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; viewBox&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0 0 105.83 58.208&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; xmlns&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;http://www.w3.org/2000/svg&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Contador con aguja&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;desc&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;La aguja indica los aciertos de 0 a 10 en un contador en forma de semicírculo que tiene cuatro zonas rotuladas con el texto: «insuficiente», «regular», «bien» y «excelente».&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;desc&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;aguja&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;matrix(.28946 0 0 .28839 126 -138.93)&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;nota&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;0&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; de 10 aciertos&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Para no ocupar espacio de esta entrada el SVG no se muestra completo. Los puntos suspensivos corresponden a las etiquetas que deberían estar ahi. El SVG como se aprecia, estaría incrustado, completo, y el elemento que agrupa a los elementos que dibujan la aguja bien identificado.&lt;/p&gt;
&lt;p&gt;En el párrafo se mostraría el resultado de forma textual. ambos, imagen y resultado, están dentro de un DIV contenedor llamado «resultados».&lt;/p&gt;
&lt;p&gt;La gráfica en SVG ocupa lo suyo. Hay técnicas para &lt;a href=&quot;/blog/carga-svg&quot;&gt;cargar dinámicamente la imagen&lt;/a&gt; sin necesidad de colocar el SVG in-line desde el principio. Por ahora el SVG aparecerá incrustado en la página, ya que si lo enlazamos como una imagen (&lt;code&gt;&amp;lt;img src=&quot;contador.svg&quot; alt=&quot;Contador&quot;/&amp;gt;&lt;/code&gt;) no podremos acceder a la etiqueta «aguja» que necesitamos para hacer la gráfica interactiva.&lt;/p&gt;
&lt;p&gt;Deliberadamente he eliminado las etiquetas &lt;code&gt;width&lt;/code&gt; y &lt;code&gt;height&lt;/code&gt; de &lt;code&gt;svg&lt;/code&gt; para poderlas manejar desde CSS.&lt;/p&gt;
&lt;p&gt;Los estilos CSS para mostrar correctamente estos elementos son los siguientes:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;css&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;#resultados&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;480&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    margin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;220&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; auto&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    text-align&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;center&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    background-color&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;lightblue&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    border-radius&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;15&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    border-bottom&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; solid&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; lightslategray&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;#resultados&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt; svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    margin-top&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;-220&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;400&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;220&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;#resultados&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt; p&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    margin-top&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.25&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;em&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    margin-bottom&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;em&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    font-family&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Arial&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Helvetica&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;sans-serif&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    font-size&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: xxx-large;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    color&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;red&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    text-shadow&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; DimGray&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;dinamismo&quot;&gt;Dinamismo&lt;/h2&gt;
&lt;p&gt;Ya disponemos de la gráfica incrustada en el HTML correctamente representada con CSS, y la tabla de posiciones de la aguja, y en esta parte veremos el motivo de toda esta preparación.&lt;/p&gt;
&lt;p&gt;El siguiente código en JavaScript permite obtener el resultado esperado:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; nota&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;nota&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; aciertos &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Math.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;floor&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(Math.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;random&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 10&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;nota.textContent &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; aciertos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;ponAguja&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(aciertos);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ponAguja&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;aciertos&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; aguja&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;aguja&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; posicionAguja&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &apos;0 -.28946 .28839 0 -139.16 -20.501&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &apos;.089449 -.2753 .27428 .089119 -107.1 -76.177&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &apos;.17014 -.23418 .23332 .16951 -59.407 -119.22&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &apos;.23418 -.17014 .16951 .23332 -.74583 -145.42&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &apos;.2753 -.089449 .089119 .27428 63.14 -152.21&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &apos;.28946 0 0 .28839 126 -138.93&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &apos;.2753 .089449 -.089119 .27428 181.67 -106.87&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &apos;.23418 .17014 -.16951 .23332 224.72 -59.174&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &apos;.17014 .23418 -.23332 .16951 250.92 -.51273&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &apos;.089449 .2753 -.27428 .089119 257.71 63.373&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &apos;0 .28946 -.28839 0 244.42 126.23&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    aguja.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;transform&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;`matrix(${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;posicionAguja&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;aciertos&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;})`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Obtengo el elemento «nota» donde pondremos el número de aciertos.&lt;/p&gt;
&lt;p&gt;La variable «aciertos», en este ejemplo, se obtiene aleatoriamente en un rango entero entre 0 y 10.&lt;/p&gt;
&lt;p&gt;Pongo los aciertos y llamo a la función &lt;code&gt;ponAguja(aciertos)&lt;/code&gt; y le paso el parámetro «aciertos».&lt;/p&gt;
&lt;p&gt;La función obtiene el elemento del SVG identificado con «aguja», y contiene un arreglo &lt;code&gt;posicionAguja[]&lt;/code&gt; con todos los valores posibles para la aguja, desde 0 a 10.&lt;/p&gt;
&lt;p&gt;En la última línea, cambiamos el valor del atributo ‘transform’ del SVG con el valor correspondiente a los aciertos guardado en el arreglo &lt;code&gt;posicionAguja[]&lt;/code&gt;;&lt;/p&gt;
&lt;h2 id=&quot;el-código-completo&quot;&gt;El código completo&lt;/h2&gt;
&lt;p&gt;Con cada recarga de la página, la gráfica y el cuadro de texto mostrarán un valor distinto.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;DOCTYPE&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; html&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; lang&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;es&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; charset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;UTF-8&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; http-equiv&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;X-UA-Compatible&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; content&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;IE=edge&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;viewport&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; content&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;width=device-width, initial-scale=1.0&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Contador&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        #resultados&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;480&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            margin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;220&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; auto&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            text-align&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;center&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            background-color&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;lightblue&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            border-radius&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;15&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            border-bottom&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; solid&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; lightslategray&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        #resultados&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt; svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            margin-top&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;-220&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;400&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;220&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        #resultados&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt; p&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            margin-top&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.25&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;em&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            margin-bottom&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;em&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            font-family&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Arial&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Helvetica&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;sans-serif&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            font-size&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: xxx-large;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            color&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;red&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            text-shadow&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; DimGray&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;resultados&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;       &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; version&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;1.1&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; viewBox&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0 0 105.83 58.208&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; xmlns&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;http://www.w3.org/2000/svg&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Contador con aguja&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;desc&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;La aguja indica los aciertos de 0 a 10 en un contador en forma de semicírculo que tiene cuatro zonas rotuladas con el texto: «insuficiente», «regular», «bien» y «excelente».&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;desc&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; clip-path&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;url(#a)&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m52.914-0.001674c-4.7395 0-9.4778 0.63742-14.085 1.9017-0.06321 0.01729-0.12652 0.03416-0.18965 0.05168-0.24752 0.0689-0.49482 0.1388-0.74157 0.21136-0.29501 0.08651-0.58912 0.17555-0.88262 0.26716-0.16716 0.05233-0.33398 0.10566-0.50075 0.15968-0.35229 0.1138-0.70374 0.23024-1.0537 0.3514-0.09768 0.03392-0.19494 0.06936-0.2925 0.10387-0.40857 0.14415-0.81597 0.2918-1.2211 0.44596-0.0026 6.09e-4 -0.0032 0.0015-0.0048 0.0021-2.598 0.98893-5.1231 2.1832-7.5494 3.576-3.2712 1.8893-6.2375 4.028-9.0004 6.5319-10.096 9.0697-16.394 21.745-17.385 35.433-0.01191 0.16487-0.0085 0.32633 0.0026 0.48575-0.07855 1.0993-0.12549 2.2058-0.13951 3.3186l106.09 2.7e-5c-0.01-1.1385-0.0541-2.2702-0.13229-3.3946 6e-3 -0.13439 5e-3 -0.27062-5e-3 -0.40876-0.93929-12.97-6.6434-25.03-15.827-33.976l7e-3 -0.0072c-3.2035-3.1564-6.6655-5.7325-10.563-7.984-4.1446-2.3803-8.5755-4.1793-13.168-5.3666-0.0541-0.01402-0.10813-0.02852-0.16227-0.04237-0.40282-0.10279-0.80713-0.20018-1.2123-0.29352-0.12364-0.02855-0.24725-0.05658-0.37105-0.08423-0.37005-0.08246-0.74075-0.16212-1.1126-0.23668-0.15193-0.03054-0.30417-0.05865-0.4563-0.08785-0.27332-0.05233-0.54692-0.10285-0.82114-0.1509-0.24984-0.04391-0.50001-0.08526-0.75033-0.12557-0.21667-0.03478-0.43346-0.06866-0.65061-0.10077-0.41838-0.06208-0.83732-0.11847-1.2568-0.17053-0.07014-0.0087-0.14015-0.01845-0.21032-0.02687-0.0066-7.93e-4 -0.01323-0.0013-0.01958-0.0021-0.27715-0.03317-0.55448-0.06421-0.832-0.09302-1.8286-0.18982-3.6647-0.28891-5.501-0.28891z&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#fff&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;.26458&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;.28892&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m14.799 16.135c-9.531 9.9166-14.753 22.823-14.928 36.701h31.392c0.09043-5.5163 2.2581-10.797 6.0732-14.796z&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#f97301&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m51.864 0.020187c-8.951 0.16984-17.713 2.594-25.47 7.0468-3.8979 2.2513-7.365 4.8542-10.568 8.0106l22.427 22.033c3.7181-3.4716 8.5272-5.555 13.612-5.8964z&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#ffe900&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m91.031 16.135c9.5273 9.8511 14.813 22.791 14.928 36.701h-31.392c-0.090433-5.5163-2.2581-10.797-6.0732-14.796z&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#0cb200&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m53.271 0.0057678v31.169c5.333 0.1904 10.417 2.2988 14.309 5.9351l22.422-22.06c-3.2035-3.1564-6.6654-5.7323-10.563-7.9838-7.9616-4.5724-16.979-7.0059-26.168-7.0615z&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#9bd701&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m53.118 8.6805c-11.772 0.0020187-23.065 4.6483-31.409 12.922-8.3434 8.2745-13.059 19.504-13.115 31.233h3.1687c-0.0035-0.08667-0.0067-0.17336-0.0097-0.26006 0-10.911 4.3503-21.375 12.094-29.09 7.7436-7.715 18.246-12.049 29.198-12.049 10.951-3.7e-5 21.454 4.3342 29.198 12.049 7.7436 7.715 12.094 18.179 12.094 29.09-3e-3 0.0867-0.0062 0.17339-0.0097 0.26006h3.3207c-0.056473-11.73-4.7727-22.96-13.118-31.236-8.3448-8.2759-19.639-12.92-31.412-12.92z&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#808080&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill-opacity&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;.5&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-linecap&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;.079454&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m53.286 0v8.6857c11.439 0.052083 22.391 4.479 30.636 12.384l6.0792-6.0175c-3.1719-3.091-6.7207-5.773-10.563-7.9838-7.9573-4.577-16.97-7.0047-26.154-7.0684zm-1.3525 0.020101c-8.9701 0.16618-17.759 2.5737-25.538 7.0483-3.9002 2.2434-7.431 4.9511-10.568 8.0106l6.2254 6.2024c8.0259-7.7926 18.696-12.272 29.881-12.571zm-37.062 16.013c-9.4804 9.73-14.999 22.87-14.999 36.804h8.7223c0.055006-11.435 4.5492-22.387 12.506-30.598zm76.125 0.01402-6.0416 6.0193c8.0762 8.2283 12.627 19.261 12.693 30.768h8.3133c-8.6e-4 -13.734-5.3674-26.929-14.964-36.79z&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#e5e5e5&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-linecap&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;.079454&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m12.171 24.438 0.99192-1.3687 0.2474 0.17797-0.77966 1.0758 0.64324 0.46272 0.7471-1.0309 0.2474 0.17797-0.7471 1.0309 0.78733 0.56637 0.79859-1.1019 0.2474 0.17797-1.0108 1.3948zm-1.511 2.3014 1.2275-1.899 0.25655 0.16461-0.51509 0.79688 1.9966 1.281-0.19729 0.30523-1.9966-1.281-0.51509 0.79688zm-1.2563 2.1918 0.24028-0.42344 2.5365 0.06864-1.9517-1.0993 0.17314-0.30514 2.3329 1.314-0.24028 0.42344-2.5365-0.06864 1.9517 1.0993-0.17314 0.30514zm-1.1115 2.2062 0.74762-1.515 0.27384 0.13414-0.58763 1.1908 0.71198 0.34875 0.56309-1.1411 0.27384 0.13413-0.56309 1.1411 0.87148 0.42688 0.60187-1.2197 0.27384 0.13413-0.76186 1.5439zm-0.4834 1.0786 0.14749-0.33 2.4482 1.086-0.14748 0.33zm-0.083943 0.6806 0.3552 0.14092q-0.22616 0.10662-0.38157 0.26826-0.15474 0.15998-0.24107 0.37597-0.16999 0.42535 0.00145 0.75518 0.16984 0.32917 0.66347 0.52498 0.49197 0.19516 0.84409 0.07307 0.35045-0.12275 0.52045-0.54808 0.086326-0.21599 0.084311-0.43815-0.00145-0.22382-0.092045-0.45615l0.35187 0.13959q0.049683 0.22375 0.030697 0.44527-0.018323 0.21987-0.10597 0.43919-0.22511 0.56326-0.6998 0.75028-0.47636 0.18638-1.0751-0.05113-0.60034-0.23817-0.81607-0.69912-0.21738-0.4616 0.00773-1.0249 0.08898-0.22264 0.22737-0.39486 0.13739-0.17456 0.32486-0.30039zm-1.3344 2.8983 0.12082-0.34062 2.5268 0.88968-0.12082 0.34059zm-0.68313 2.0879 0.46418-1.4631 0.29097 0.09163-0.35491 1.1186 0.75306 0.23717 0.32029-1.0095 0.29097 0.09163-0.32029 1.0095 1.2203 0.38431-0.10928 0.34445zm-0.75549 2.7512 0.092676-0.35109 1.5745 0.41254q0.41662 0.10916 0.64037 0.0069 0.22199-0.10271 0.31102-0.43997 0.088566-0.33554-0.05399-0.53375-0.14429-0.19869-0.56092-0.30786l-1.5745-0.41254 0.092676-0.35109 1.6179 0.42393q0.5069 0.13282 0.69936 0.45139 0.19292 0.31683 0.064176 0.80455-0.1292 0.48946-0.45405 0.67247-0.3244 0.18128-0.8313 0.04847zm-0.095522 0.81326 0.34599 0.07269q-0.13919 0.18094-0.22438 0.34947-0.085197 0.16852-0.12038 0.33476-0.061105 0.28874 0.017976 0.46984 0.079448 0.17935 0.2867 0.22289 0.17388 0.03653 0.28531-0.0479 0.11004-0.08655 0.22596-0.36559l0.08909-0.20426q0.15922-0.37961 0.39028-0.52663 0.22969-0.14914 0.54934-0.08199 0.38113 0.08007 0.52378 0.37687 0.14302 0.29505 0.038953 0.78679-0.039254 0.18549-0.12585 0.38662-0.086221 0.19938-0.21617 0.40602l-0.36533-0.07675q0.16674-0.18978 0.27191-0.38336t0.14739-0.39305q0.064066-0.30272-0.020552-0.49231-0.084624-0.18958-0.30593-0.23607-0.1932-0.04059-0.32726 0.05553-0.13371 0.09437-0.24518 0.35241l-0.087706 0.20638q-0.16273 0.37886-0.36874 0.5202-0.20601 0.14132-0.50635 0.07822-0.34776-0.07305-0.49651-0.35835-0.14838-0.28705-0.057652-0.71576 0.038886-0.18374 0.11262-0.36747 0.073737-0.18373 0.1827-0.3692zm-0.90022 4.3749 0.077792-0.48023 2.4026-0.81286-2.2133-0.3559 0.056057-0.34604 2.6457 0.42543-0.077795 0.48023-2.4026 0.81286 2.2133 0.3559-0.05606 0.34604zm-0.14762 1.1651 0.045312-0.35841 2.6589 0.33367-0.045312 0.35841zm97.927-3.1896 0.24568 1.6704-0.30194 0.04407-0.19312-1.3129-0.78501 0.11461 0.18504 1.2581-0.30194 0.04408-0.18504-1.2581-0.96082 0.14028 0.19779 1.3448-0.30194 0.04408-0.25036-1.7022zm-0.49787-2.682 0.42747 2.2182-0.29968 0.05732-0.17938-0.93084-2.3322 0.44611-0.06871-0.35654 2.3322-0.44611-0.17939-0.93084zm-0.58818-2.434 0.11608 0.47247-1.8951 1.681 2.1776-0.5311 0.0836 0.34047-2.6031 0.63486-0.11609-0.47247 1.8951-1.681-2.1776 0.5311-0.08365-0.34047zm-0.6953-2.3561 0.48974 1.6162-0.29212 0.08787-0.38496-1.2703-0.75951 0.22846 0.36886 1.2173-0.29212 0.08787-0.36886-1.2173-0.92966 0.27964 0.3943 1.3012-0.29212 0.08787-0.49909-1.647zm-0.71033-2.0476 0.1211 0.3405-2.2384 0.79025 0.43587 1.2255-0.28762 0.10155-0.55698-1.566zm-0.90804-2.2725 0.64298 1.5619-0.28233 0.11536-0.5054-1.2277-0.73404 0.29993 0.48427 1.1764-0.28233 0.11536-0.48427-1.1764-0.89846 0.36712 0.51764 1.2575-0.28233 0.11536-0.65522-1.5917zm-0.46632-0.55948-0.34509 0.16395q0.07511-0.23777 0.06165-0.46119-0.01271-0.22182-0.11314-0.43166-0.19778-0.41323-0.55724-0.51192-0.35783-0.09945-0.83741 0.12839-0.47796 0.22707-0.62726 0.56746-0.14768 0.33961 0.0501 0.75284 0.10044 0.20985 0.26544 0.3593 0.16577 0.15107 0.3985 0.2426l-0.34185 0.16242q-0.19855-0.11568-0.34883-0.28007-0.1495-0.16276-0.25148-0.37583-0.26191-0.54722-0.07718-1.0213 0.18635-0.47489 0.768-0.75123 0.58326-0.2771 1.0693-0.12167 0.48765 0.15466 0.74959 0.70188 0.10353 0.21631 0.13636 0.43449 0.03523 0.21904 5.78e-4 0.44158zm-1.8763-4.1153 0.18709 0.34039-0.55394 1.0587 1.1954 0.10835 0.18709 0.34039-1.5427-0.13704-0.7803 1.4697-0.18709-0.34039 0.63762-1.2042-1.3644-0.11806-0.18795-0.34194 1.7143 0.15146zm-1.2157-1.9899 0.89293 1.4348-0.25934 0.16021-0.70185-1.1278-0.6743 0.41655 0.67253 1.0807-0.25934 0.16021-0.67253-1.0807-0.82531 0.50984 0.71887 1.1551-0.25934 0.16021-0.90995-1.4621zm-20.071-17.151 0.44154 0.20757 0.11797 2.5253 0.95669-2.0201 0.31818 0.14958-1.1436 2.4147-0.44154-0.20757-0.11797-2.5253-0.9567 2.0201-0.31817-0.14958zm-2.2809-0.94304 1.5694 0.63659-0.11507 0.28158-1.2336-0.50039-0.29919 0.73211 1.182 0.47948-0.11507 0.28158-1.182-0.47948-0.36617 0.89609 1.2635 0.51253-0.11507 0.28158-1.5993-0.64873zm-1.1057-0.40663 0.34052 0.12414-0.92092 2.5074-0.34052-0.12413zm-2.5733 0.60562-0.30266 0.93061 0.55324 0.17861q0.27833 0.089862 0.44861 0.018861 0.17252-0.072138 0.24943-0.30861 0.07746-0.23818-0.0209-0.394-0.09612-0.15699-0.37444-0.24684zm0.33974-1.0446-0.24899 0.76556 0.51055 0.16483q0.25272 0.081588 0.40611 0.027714 0.15564-0.05503 0.21872-0.24897 0.06252-0.19224-0.03114-0.32776-0.09196-0.13496-0.34469-0.21655zm-0.25308-0.39377 0.88112 0.28446q0.39445 0.12734 0.55478 0.35956 0.16033 0.23223 0.06239 0.53335-0.0758 0.23307-0.22991 0.3356-0.1541 0.10252-0.3769 0.068187 0.23672 0.13658 0.32032 0.35533 0.08584 0.21758 0.0017 0.47619-0.11066 0.34024-0.40322 0.45072-0.29253 0.11046-0.72116-0.027916l-0.91523-0.29548zm-25.533-0.24008q0.12254 0.01243 0.25808 0.11367 0.13729 0.10082 0.29618 0.29577l0.5219 0.62961-0.37971 0.086471-0.48742-0.5916q-0.18948-0.23202-0.33158-0.28954-0.14034-0.057935-0.35033-0.010122l-0.38498 0.087665 0.25238 1.1001-0.35349 0.080495-0.59716-2.6029 0.79792-0.18171q0.44797-0.10201 0.71123 0.034324 0.26328 0.13633 0.34967 0.5129 0.05639 0.24582-0.02191 0.43426-0.07655 0.18804-0.28088 0.30062zm-1.1362-0.89147 0.21198 0.924 0.44447-0.10121q0.25548-0.058183 0.35818-0.20448 0.10404-0.14843 0.05165-0.37681-0.0524-0.22838-0.21003-0.31357-0.15629-0.087319-0.41176-0.029139zm-2.0189 0.58866-0.11033 1.412 0.94827-0.26718zm-0.29412-0.28697 0.39555-0.11145 1.7121 2.2923-0.36272 0.1022-0.42198-0.5929-1.1624 0.32752-0.04782 0.72527-0.3679 0.10366zm-2.8118 0.88683 0.34385-0.11462 0.75349 2.2437 1.2375-0.41251 0.09682 0.28831-1.5814 0.52712zm-2.6804 1.0151 0.33936-0.13217 0.59273 1.5107q0.15684 0.39974 0.37155 0.51965 0.21406 0.11825 0.54007-0.00871 0.32434-0.12631 0.40116-0.35783 0.07617-0.2332-0.08067-0.63296l-0.59272-1.5107 0.33936-0.13217 0.60908 1.5523q0.19082 0.48637 0.04578 0.82895-0.14337 0.34194-0.61481 0.52553-0.47312 0.18426-0.81292 0.03048-0.33812-0.15442-0.52893-0.64077zm-0.08394 2.5292-0.30055-0.65162-0.53822 0.24642-0.12442-0.26975 0.86444-0.39579 0.48045 1.0416q-0.12862 0.22225-0.32637 0.3974-0.1985 0.17354-0.45946 0.293-0.57084 0.26136-1.0467 0.07772-0.47495-0.18602-0.74854-0.77914-0.27432-0.59475-0.10591-1.0734 0.16929-0.48098 0.74015-0.74234 0.23813-0.10902 0.47877-0.14834 0.24228-0.040072 0.47579-0.00908l0.16114 0.34938q-0.25388-0.070739-0.49535-0.05465-0.24148 0.016092-0.4682 0.11989-0.4469 0.2046-0.5573 0.55628-0.10878 0.35091 0.11833 0.84328 0.22635 0.49075 0.56448 0.63708 0.33977 0.14557 0.78666-0.059034 0.17452-0.079901 0.29803-0.17188 0.12277-0.093603 0.20281-0.20701zm-4.8108-0.18745 1.4983-0.78852 0.14253 0.26882-1.1777 0.61978 0.37057 0.69894 1.1285-0.59391 0.14253 0.26882-1.1285 0.59391 0.45358 0.85548 1.2062-0.63483 0.14253 0.26882-1.5268 0.80357zm-0.50656 1.9236q0.1204-0.0259 0.28071 0.02861 0.16185 0.05359 0.37343 0.19008l0.69169 0.43804-0.3343 0.19918-0.64709-0.41251q-0.25219-0.1623-0.40519-0.17325-0.15144-0.01185-0.3363 0.09828l-0.3389 0.20194 0.58135 0.96847-0.31117 0.18542-1.3755-2.2915 0.70246-0.41857q0.39436-0.23498 0.68706-0.18641 0.29267 0.04857 0.49168 0.3801 0.1299 0.21641 0.11391 0.41972-0.01444 0.2024-0.17385 0.3724zm-1.3572-0.49788 0.48829 0.81346 0.39129-0.23315q0.22492-0.13401 0.27718-0.30477 0.05289-0.17321-0.0678-0.37427t-0.29704-0.23352q-0.17573-0.03491-0.40064 0.09911z&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;.076444&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;aguja&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;matrix(.28946 0 0 .28839 126 -138.93)&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m-253.45 566.27c-1.858 2e-3 -3.7288 2.2916-3.7828 5.1506l-14.79 85.096c-0.58463 3.3637-0.30092 4.8301-0.31528 8.1508 0 10.432 8.4567 18.888 18.888 18.888 10.432 0 18.888-8.9443 18.888-19.376 0-3.3866 0.21618-4.1153-0.4047-7.5835l-15.237-85.113c1.5e-4 -2.8995-1.4061-5.2129-3.2465-5.213z&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m-253.45 566.27c-1.858 2e-3 -3.7288 2.2916-3.7828 5.1506l-14.79 85.096c-0.58463 3.3637-0.61848 4.7142-0.31528 8.151 0 10.432 8.4567 18.888 18.888 18.888z&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#666&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;circle&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; cx&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;-253.45&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; cy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;664.67&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; r&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;9.7464&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#666&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m-253.45 654.92a9.7464 9.7464 0 0 0-9.7464 9.7464 9.7464 9.7464 0 0 0 9.7464 9.7464z&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;defs&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;clipPath&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m23.149 9.0991c-13.438 9.0736-21.972 23.8-23.14 39.93-0.15217 2.1011 1.5767 3.8119 3.6915 3.8119h23.734c2.1149 0 3.8162-1.7234 4.2038-3.792 1.684-8.9862 8.8444-16.036 17.883-17.606 2.0808-0.36161 5.5414-0.36701 7.6197 7e-3 8.8097 1.5835 15.08 8.6234 16.556 17.595 0.34174 2.0774 2.0454 3.7972 4.1604 3.7972h24.273c2.1149 0 3.8437-1.7107 3.6915-3.8119-1.1682-16.131-9.7021-30.858-23.14-39.931-1.7503-1.1818-4.7243-2.8926-6.6269-3.8119-14.606-7.0578-31.673-7.0578-46.279 0-1.9025 0.91927-4.8765 2.63-6.6269 3.8119z&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#0f0&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-linecap&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;.079454&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;clipPath&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;defs&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;nota&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;0&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; de 10 aciertos&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; nota&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;nota&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; aciertos &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Math.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;floor&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(Math.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;random&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 10&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        nota.textContent &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; aciertos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        ponAguja&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(aciertos);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ponAguja&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;aciertos&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; aguja&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;aguja&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; posicionAguja&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &apos;0 -.28946 .28839 0 -139.16 -20.501&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &apos;.089449 -.2753 .27428 .089119 -107.1 -76.177&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &apos;.17014 -.23418 .23332 .16951 -59.407 -119.22&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &apos;.23418 -.17014 .16951 .23332 -.74583 -145.42&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &apos;.2753 -.089449 .089119 .27428 63.14 -152.21&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &apos;.28946 0 0 .28839 126 -138.93&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &apos;.2753 .089449 -.089119 .27428 181.67 -106.87&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &apos;.23418 .17014 -.16951 .23332 224.72 -59.174&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &apos;.17014 .23418 -.23332 .16951 250.92 -.51273&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &apos;.089449 .2753 -.27428 .089119 257.71 63.373&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &apos;0 .28946 -.28839 0 244.42 126.23&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            ]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            aguja.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;transform&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;`matrix(${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;posicionAguja&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;aciertos&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;})`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;enlace&quot;&gt;Enlace&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/ejercicios-web-javascript/contador.html&quot;&gt;&lt;button&gt;Ver contador de ejemplo&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ver ejemplo de aplicación práctica. &lt;a href=&quot;https://javguerra.github.io/summer-quiz/&quot;&gt;Summer Quiz&lt;/a&gt; Es necesario terminar una partida para obtener resultados.&lt;/li&gt;
&lt;li&gt;Ver también: &lt;a href=&quot;/blog/grafica-lineas&quot;&gt;Creación de gráfica de lineas dinámica con SVG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ver también: &lt;a href=&quot;/blog/carga-svg&quot;&gt;Cargar SVG dinámicamente&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Libro sobre SVG &lt;a href=&quot;https://leanpub.com/scalable/&quot;&gt;SCALABLE&lt;/a&gt; de Jorge Aznar.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/contador.CvHdujvp_ZAoCzg.webp"/><category>código</category><category>css</category><category>html</category><category>javascript</category><category>svg</category><category>usabilidad</category><author>JavGuerra</author></item><item><title>Gráfica de lineas dinámica con SVG</title><link>https://javguerra.github.io/blog/grafica-lineas</link><guid isPermaLink="true">https://javguerra.github.io/blog/grafica-lineas</guid><description>Mostrar resultados gráficos con JavaScript</description><pubDate>Sun, 12 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/graficalineas.BU14jhGg_ZfgmGH.webp&quot; alt=&quot;Gráfica de líneas&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#svg&lt;/em&gt;, &lt;em&gt;#usabilidad&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Como comentaba en el anterior artículo sobre &lt;a href=&quot;/blog/contador-resultados&quot;&gt;la creación de un contador de resultados&lt;/a&gt;, la representación visual ayuda a asumir mejor la información. En este artículo mostraré cómo elaborar una gráfica de líneas dinámica que represente, por ejemplo, las puntuaciones de las últimas cinco jugadas con valores en un rango entre cero y diez.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/ejercicios-web-javascript/graficalineas.html&quot;&gt;&lt;button&gt;Ver gráfica de ejemplo&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;la-gráfica-de-líneas&quot;&gt;La gráfica de líneas&lt;/h2&gt;
&lt;p&gt;Primeramente toca diseñar una gráfica en .SVG que sirva de base para mostrar la línea de resultados que pretendo. Esto lo hago con &lt;a href=&quot;https://inkscape.org/es/&quot;&gt;InkScape&lt;/a&gt;. La gráfica que muestra la imagen es muy sencilla, y de ella destaca la línea roja, que, inicialmente, dibujo en la posición de la línea de puntuación cero. como se puede ver aquí:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/ejercicios-web-javascript/img/graficalineas.svg&quot; alt=&quot;Gráfica de líneas&quot;&gt;&lt;/p&gt;
&lt;p&gt;He rehecho a mano la línea roja para poder acceder a los nodos con más facilidad, empleando el elemento &lt;code&gt;polyline&lt;/code&gt; con los siguientes valores:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;polyline&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;theline&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; points&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;11 73 33.5 73 56 73 78.5 73 101 73&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;none&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; marker-end&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;url(#dotLine)&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; marker-mid&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;url(#dotLine)&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; marker-start&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;url(#dotLine)&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;stroke&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#d8232a&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-linecap&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-linejoin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En &lt;code&gt;points=&quot;11 73 33.5 73 56 73 78.5 73 101 73&quot;&lt;/code&gt; está toda la magia. Este parámetro contiene los valores de los puntos de la linea creada, diez valores en total que corresponden a la posición &lt;strong&gt;x&lt;/strong&gt; e &lt;strong&gt;y&lt;/strong&gt; de cada punto. Si tengo la ubicación de los puntos de la línea, y un identificador &lt;code&gt;id=&quot;theline&quot;&lt;/code&gt; para poder hacer cambios, ya puedo representar valores en la gráfica dinámicamente.&lt;/p&gt;
&lt;p&gt;Para los círculos en los puntos de conexión de la línea, que son referenciados en marker-end, marker-mid y marker-start, hice los siguientes cambios en el SVG:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;marker&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;dotLine&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; overflow&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;visible&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; orient&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;auto&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;circle&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;scale(.2) translate(-8 -8)&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; cx&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;8&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; cy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;8&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; r&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;8&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#f0fff0&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#d8232a&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;4&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;marker&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;presentación&quot;&gt;Presentación&lt;/h2&gt;
&lt;p&gt;Como hicimos en &lt;a href=&quot;/blog/contador-resultados&quot;&gt;la creación de un contador de resultados&lt;/a&gt;, para poder acceder al identificador dentro del SVG, este debe estar disponible en el DOM, por lo que no sería posible acceder a su &lt;strong&gt;id&lt;/strong&gt; haciendo uso del elemento &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; de HTML.&lt;/p&gt;
&lt;p&gt;El código HTML para insertar «en linea» el SVG sería el siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;contenedor&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Gráfica dinámica&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;grafica&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; version&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;1.1&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; viewBox&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0 0 105.83 79.375&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; xmlns&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;http://www.w3.org/2000/svg&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Gráfica de líneas&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;desc&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Muestra una gráfica con dos ejes. En el eje horizontal, se muestran las últimas cinco partidas ordenadas de más antigua a más reciente. En el eje vertical, los ciertos de cada uno de los partidos. La línea une las diferentes puntuaciones del gráfico.&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;desc&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;defs&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;marker&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;dotLine&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; overflow&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;visible&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; orient&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;auto&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;circle&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;scale(.2) translate(-8 -8)&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; cx&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;8&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; cy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;8&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; r&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;8&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#f0fff0&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#d8232a&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;4&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;marker&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;defs&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;polyline&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;laLinea&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; points&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;11 73 33.5 73 56 73 78.5 73 101 73&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;none&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; marker-end&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;url(#dotLine)&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; marker-mid&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;url(#dotLine)&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; marker-start&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;url(#dotLine)&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#d8232a&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-linecap&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-linejoin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;arreglo&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Para no ocupar espacio de esta entrada, el SVG no se muestra completo. Los puntos suspensivos corresponden a las etiquetas que deberían estar ahi. El SVG como se aprecia, estaría incrustado, y el elemento de la línea bien identificado con &lt;code&gt;id=&quot;laLinea&quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;En el párrafo &lt;code&gt;&quot;arreglo&quot;&lt;/code&gt; es donde se mostrarán los valores numéricos que se usarán para representar la gráfica.&lt;/p&gt;
&lt;p&gt;Como dijimos en el anterior artículo, la gráfica en SVG ocupa lo suyo. Hay técnicas para &lt;a href=&quot;/blog/carga-svg&quot;&gt;cargar dinámicamente la imagen&lt;/a&gt; sin necesidad de colocar el SVG &lt;em&gt;in-line&lt;/em&gt; desde el principio.&lt;/p&gt;
&lt;p&gt;Deliberadamente he eliminado los atributos &lt;code&gt;width=&quot;400&quot;&lt;/code&gt; y &lt;code&gt;height=&quot;300&quot;&lt;/code&gt; de la etiqueta &lt;code&gt;svg&lt;/code&gt; porque voy a manejar estos valores desde CSS, aunque dejarlas tampoco sería un problema.&lt;/p&gt;
&lt;p&gt;Los estilos CSS para mostrar correctamente estos elementos son los siguientes:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;css&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;#contenedor&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;text-align&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;center&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;#grafica&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    max-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;400&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;auto&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;#laLinea&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;animation&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: elevador &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; ease&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@keyframes&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; elevador&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    0%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;   {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;translateY&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;73&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;scaleY&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    100%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;translateY&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)    &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;scaleY&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Como se ve, he definido también una animación para mostrar el resultado. Al cargar los nuevos valores de la gráfica, los puntos de la línea estarán en la posición del eje de la puntuación cero, (en la posición 73px) con una escala de 0, es decir la línea estará totalmente aplastada. Durante un segundo, irá tomando su forma original ocupando toda la gráfica con las medidas correctas. Esto hace el efecto de que los nodos de la línea se elevan hasta la posición que debe ocupar en la gráfica. Se entiende mejor &lt;a href=&quot;https://javguerra.github.io/ejercicios-web-javascript/graficalineas.html&quot;&gt;viendo el ejemplo&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;dinamismo&quot;&gt;Dinamismo&lt;/h2&gt;
&lt;p&gt;Ya disponemos de la gráfica incrustada en el HTML, y en esta parte veremos el motivo de toda esta preparación.&lt;/p&gt;
&lt;p&gt;El siguiente código en JavaScript permite obtener el resultado esperado:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; elLinea&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;laLinea&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; elArreg&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;arreglo&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ejesY &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; i&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ejesY.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(Math.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;floor&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(Math.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;random&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 11&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)); &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 0-10&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;elArreg.textContent &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `Valores = [${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ejesY&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}]`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;fijaLinea&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(ejesY);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fijaLinea&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;ordenadas&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; []) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; numOrd &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ordenadas.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(numOrd &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; numOrd; i&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) ordenadas.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ord &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ordenadas.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;slice&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;y&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 73&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; y &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 7.1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    elLinea.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;points&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        `11 ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ord&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;} 33.5 ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ord&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;} 56 ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ord&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;} 78.5 ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ord&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;} 101 ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ord&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Primeramente obtengo los elementos que emplearé en el código &lt;code&gt;elLinea&lt;/code&gt; y &lt;code&gt;elArreg&lt;/code&gt;, y declaro el arreglo &lt;code&gt;ejesY&lt;/code&gt; que contendrá los valores a mostrar. Seguidamente relleno el arreglo con cinco valores al azar en un rango entre 0 y 10. Muestro los valores en la web, llamo a la función &lt;code&gt;fijaLinea(ejesY)&lt;/code&gt; y le paso como parámetro el arreglo. Esta función es la responsable de que la línea tenga la forma deseada.&lt;/p&gt;
&lt;p&gt;En la posición y = 73 está la línea de la puntuación 0. Cada línea de puntuación esta a una distancia de -7.1px. Así: 0 = 73, 1 = 65,9, .. 9 = 9,1, 10 = 2. Con estos datos, la función &lt;code&gt;fijaLinea()&lt;/code&gt; funciona de la siguiente manera: Si el arreglo que le pasamos tiene un número de elementos menor que cinco, rellena a ceros el arreglo. Después toma los últimos cinco elementos del arreglo (pudiera ser que el arreglo recibido tuviese más de cinco elementos).&lt;/p&gt;
&lt;p&gt;A cada elemento del array le aplica el cálculo necesario para convertir la puntuación a la coordenada «&lt;strong&gt;y&lt;/strong&gt;» correspondiente. Con este nuevo arreglo, ya podemos pasar los datos de la línea al SVG con &lt;code&gt;setAttribute&lt;/code&gt;. El valor inicial del atributo &lt;code&gt;points&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;points=&quot;11 73 33.5 73 56 73 78.5 73 101 73&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;pasa a ser:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;`11 ${ord[0]} 33.5 ${ord[1]} 56 ${ord[2]} 78.5 ${ord[3]} 101 ${ord[4]}`&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;siendo los valores del arreglo &lt;code&gt;ord&lt;/code&gt; cada una de las cinco posiciones «&lt;strong&gt;y&lt;/strong&gt;» de los puntos de la polilínea. Esto es todo lo que necesitamos para mostrar los datos.&lt;/p&gt;
&lt;h2 id=&quot;el-código-completo&quot;&gt;El código completo&lt;/h2&gt;
&lt;p&gt;Con cada recarga de la página, la gráfica mostrará valores distintos.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;DOCTYPE&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; html&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; lang&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;es&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; charset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;UTF-8&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; http-equiv&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;X-UA-Compatible&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; content&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;IE=edge&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;viewport&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; content&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;width=device-width, initial-scale=1.0&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Gráfica de líneas&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        #contenedor&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;text-align&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;center&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        #grafica&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            max-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;400&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;auto&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        #laLinea&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;animation&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: elevador &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; ease&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        @keyframes&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; elevador&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            0%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;   {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;translateY&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;73&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;scaleY&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            100%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;translateY&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)    &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;scaleY&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;contenedor&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Gráfica dinámica&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;grafica&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; version&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;1.1&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; viewBox&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0 0 105.83 79.375&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; xmlns&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;http://www.w3.org/2000/svg&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Gráfica de líneas&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;desc&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Muestra una gráfica con dos ejes. En el eje horizontal, se muestran las últimas cinco partidas ordenadas de más antigua a más reciente. En el eje vertical, los ciertos de cada uno de los partidos. La línea une las diferentes puntuaciones del gráfico.&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;desc&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;defs&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;marker&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;dotLine&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; overflow&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;visible&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; orient&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;auto&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;circle&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;scale(.2) translate(-8 -8)&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; cx&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;8&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; cy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;8&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; r&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;8&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#f0fff0&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#d8232a&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;4&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;marker&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;defs&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;matrix(.99339 0 0 .97827 .43246 .039862)&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;none&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#ccc&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;.26839&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m105.57 9.424h-99.395&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m105.57 16.73h-99.408&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m105.57 24.037h-99.309&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m105.57 31.343h-99.438&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m105.57 38.649h-99.515&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m105.57 45.956h-99.435&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m105.57 53.262h-99.416&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m105.57 59.999h-99.416&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m105.57 67.305h-99.469&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m10.957 1.98v72.528&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m100.96 1.9385v72.528&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m33.458 1.98v72.528&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m55.959 1.98v72.528&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m78.461 1.98v72.528&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;rect&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; x&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;6.2237&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; y&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;2.1209&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;99.342&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;72.487&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#3cb371&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-linecap&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;.53688&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;matrix(1.0003 0 0 1.0006 .44383 .038459)&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#3cb371&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;.26458&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; aria-label&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;109876543210&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m1.1672 4.0498h-0.44855v-2.9735l-0.89951 0.33038v-0.40514l1.2781-0.4799h0.069935z&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m4.676 2.5522q0 0.78376-0.26768 1.1648-0.26768 0.38103-0.83681 0.38103-0.5619 0-0.83199-0.37138-0.2701-0.37379-0.27974-1.1141v-0.59566q0-0.77411 0.26768-1.1503 0.26768-0.3762 0.83923-0.3762 0.56672 0 0.8344 0.36415 0.26768 0.36174 0.27492 1.119zm-0.44614-0.61013q0-0.56672-0.15916-0.82476-0.15916-0.26045-0.50402-0.26045-0.34244 0-0.49919 0.25804t-0.16158 0.79341v0.71382q0 0.56913 0.16399 0.84164 0.1664 0.2701 0.50161 0.2701 0.33038 0 0.48955-0.25563 0.16158-0.25563 0.16881-0.80546z&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m4.1841 9.5492q-0.13987 0.1664-0.33521 0.26768-0.19293 0.10129-0.42444 0.10129-0.30386 0-0.53054-0.14952-0.22428-0.14952-0.34727-0.41961-0.12299-0.27251-0.12299-0.60048 0-0.35209 0.13264-0.63424 0.13505-0.28215 0.38103-0.43167t0.57395-0.14952q0.5209 0 0.81993 0.39067 0.30145 0.38826 0.30145 1.0611v0.13022q0 1.0249-0.40514 1.4976-0.40514 0.47026-1.2227 0.48231h-0.086816v-0.3762h0.094051q0.55225-0.0096 0.84887-0.28698 0.29662-0.27974 0.32315-0.88263zm-0.6873 0q0.22428 0 0.41238-0.13746 0.19051-0.13746 0.27733-0.34003v-0.17846q0-0.43891-0.19051-0.71382-0.19051-0.27492-0.48231-0.27492-0.29421 0-0.47267 0.22669-0.17846 0.22428-0.17846 0.59325 0 0.35932 0.17122 0.59325 0.17363 0.23151 0.46302 0.23151z&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m4.6037 15.541q0 0.26286-0.13987 0.46784-0.13746 0.20498-0.37379 0.32074 0.27492 0.11817 0.43408 0.34485 0.16158 0.22669 0.16158 0.51366 0 0.45579-0.30868 0.72588-0.30627 0.2701-0.80788 0.2701-0.50643 0-0.8127-0.2701-0.30386-0.27251-0.30386-0.72588 0-0.28456 0.15434-0.51366 0.15675-0.2291 0.43167-0.34727-0.23392-0.11576-0.36897-0.32074t-0.13505-0.46543q0-0.44373 0.28456-0.70418t0.75-0.26045q0.46302 0 0.74759 0.26045 0.28698 0.26045 0.28698 0.70418zm-0.36415 1.6375q0-0.29421-0.1881-0.4799-0.18569-0.18569-0.48714-0.18569t-0.48472 0.18328q-0.18087 0.18328-0.18087 0.48231t0.17604 0.47026q0.17846 0.17122 0.49437 0.17122 0.3135 0 0.49196-0.17122 0.17846-0.17363 0.17846-0.47026zm-0.67042-2.2355q-0.26286 0-0.42685 0.16399-0.16158 0.16158-0.16158 0.44132 0 0.26768 0.15916 0.43408 0.16158 0.16399 0.42926 0.16399t0.42685-0.16399q0.16158-0.1664 0.16158-0.43408t-0.1664-0.43649-0.42202-0.16881z&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m4.7411 21.918-1.4542 3.2604h-0.46784l1.4494-3.1447h-1.9003v-0.36656h2.373z&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m4.2251 28.707v0.37862h-0.081993q-0.5209 0.0096-0.82958 0.30868-0.30868 0.29903-0.35691 0.84164 0.27733-0.31833 0.75723-0.31833 0.4582 0 0.7307 0.32315 0.27492 0.32315 0.27492 0.8344 0 0.5426-0.29662 0.86816-0.29421 0.32556-0.79099 0.32556-0.50402 0-0.81752-0.38585-0.3135-0.38826-0.3135-0.99839v-0.17122q0-0.96945 0.41238-1.4807 0.41479-0.51366 1.2323-0.52572zm-0.58601 1.582q-0.2291 0-0.42202 0.13746-0.19293 0.13746-0.26768 0.34486v0.16399q0 0.43408 0.19534 0.69936 0.19534 0.26527 0.48714 0.26527 0.30145 0 0.47267-0.22186 0.17363-0.22186 0.17363-0.58119 0-0.36174-0.17604-0.5836-0.17363-0.22428-0.46302-0.22428z&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m2.6793 37.503 0.17846-1.7508h1.799v0.41238h-1.4204l-0.10611 0.95739q0.25804-0.15193 0.58601-0.15193 0.4799 0 0.76206 0.31833 0.28215 0.31592 0.28215 0.85611 0 0.5426-0.29421 0.85611-0.2918 0.31109-0.81752 0.31109-0.46543 0-0.75964-0.25804t-0.33521-0.71382h0.42202q0.040997 0.30145 0.21463 0.45579 0.17363 0.15193 0.4582 0.15193 0.31109 0 0.48714-0.21222 0.17846-0.21222 0.17846-0.58601 0-0.35209-0.19293-0.56431-0.19051-0.21463-0.50884-0.21463-0.2918 0-0.4582 0.12781l-0.11817 0.09646z&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m4.3577 45.127h0.48714v0.36415h-0.48714v0.81511h-0.44855v-0.81511h-1.5989v-0.26286l1.5723-2.4333h0.47508zm-1.541 0h1.0924v-1.7219l-0.053055 0.09646z&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m3.123 51.377h0.33521q0.31592-0.0048 0.49678-0.1664 0.18087-0.16158 0.18087-0.43649 0-0.61736-0.61495-0.61736-0.28939 0-0.46302 0.1664-0.17122 0.16399-0.17122 0.43649h-0.44614q0-0.4172 0.30386-0.69212 0.30627-0.27733 0.77652-0.27733 0.49678 0 0.77894 0.26286 0.28215 0.26286 0.28215 0.7307 0 0.2291-0.14952 0.44373-0.14711 0.21463-0.40273 0.32074 0.28939 0.09164 0.44614 0.30386 0.15916 0.21222 0.15916 0.51849 0 0.47267-0.30868 0.75t-0.80305 0.27733-0.80546-0.26768q-0.30868-0.26768-0.30868-0.70659h0.44855q0 0.27733 0.18087 0.44373t0.48472 0.1664q0.32315 0 0.49437-0.16881t0.17122-0.48472q0-0.30627-0.1881-0.47026t-0.5426-0.16881h-0.33521z&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m4.7749 60.392h-2.3006v-0.32074l1.2154-1.3505q0.2701-0.30627 0.37138-0.49678 0.1037-0.19292 0.1037-0.39791 0-0.27492-0.1664-0.45096t-0.44373-0.17604q-0.3328 0-0.51849 0.19051-0.18328 0.1881-0.18328 0.52572h-0.44614q0-0.48472 0.31109-0.78376 0.3135-0.29903 0.83681-0.29903 0.48955 0 0.77411 0.25804 0.28456 0.25563 0.28456 0.68247 0 0.51849-0.66077 1.2347l-0.94051 1.0201h1.7629z&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m3.9405 67.435h-0.44855v-2.9735l-0.89951 0.33038v-0.40514l1.2781-0.4799h0.069935z&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m4.676 72.98q0 0.78376-0.26768 1.1648-0.26768 0.38103-0.83681 0.38103-0.5619 0-0.83199-0.37138-0.2701-0.37379-0.27974-1.1141v-0.59566q0-0.77411 0.26768-1.1503 0.26768-0.3762 0.83923-0.3762 0.56672 0 0.8344 0.36415 0.26768 0.36174 0.27492 1.119zm-0.44614-0.61013q0-0.56672-0.15916-0.82476-0.15916-0.26045-0.50402-0.26045-0.34244 0-0.49919 0.25804t-0.16158 0.79341v0.71382q0 0.56913 0.16399 0.84164 0.1664 0.2701 0.50161 0.2701 0.33038 0 0.48955-0.25563 0.16158-0.25563 0.16881-0.80546z&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;translate(-.061333 -.081667)&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#3cb371&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;.26458&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;translate(.46707)&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; aria-label&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m11.524 79.312h-0.44855v-2.9735l-0.89952 0.33038v-0.40514l1.2781-0.4799h0.06993z&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#3cb371&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;translate(.33346)&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; aria-label&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;3&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m55.289 77.34h0.33521q0.31592-0.0048 0.49678-0.1664 0.18087-0.16158 0.18087-0.43649 0-0.61736-0.61495-0.61736-0.28939 0-0.46302 0.1664-0.17122 0.16399-0.17122 0.43649h-0.44614q0-0.4172 0.30386-0.69212 0.30627-0.27733 0.77652-0.27733 0.49678 0 0.77894 0.26286t0.28215 0.7307q0 0.2291-0.14952 0.44373-0.1471 0.21463-0.40273 0.32074 0.28939 0.09164 0.44614 0.30386 0.15916 0.21222 0.15916 0.51849 0 0.47267-0.30868 0.75t-0.80305 0.27733-0.80546-0.26768q-0.30868-0.26768-0.30868-0.70659h0.44855q0 0.27733 0.18087 0.44373t0.48472 0.1664q0.32315 0 0.49437-0.16881t0.17122-0.48472q0-0.30627-0.1881-0.47026t-0.5426-0.16881h-0.33521z&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#3cb371&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;translate(.49737)&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; aria-label&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;2&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m34.356 79.312h-2.3006v-0.32074l1.2154-1.3505q0.2701-0.30627 0.37138-0.49678 0.1037-0.19293 0.1037-0.39791 0-0.27492-0.1664-0.45096t-0.44373-0.17604q-0.3328 0-0.51849 0.19051-0.18328 0.1881-0.18328 0.52572h-0.44614q0-0.48472 0.31109-0.78376 0.3135-0.29904 0.83681-0.29904 0.48955 0 0.77411 0.25804 0.28456 0.25563 0.28456 0.68247 0 0.51849-0.66077 1.2347l-0.94051 1.0201h1.7629z&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#3cb371&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;translate(-.47277)&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; aria-label&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m100.22 77.552 0.17846-1.7508h1.799v0.41238h-1.4204l-0.10611 0.95739q0.25804-0.15193 0.58602-0.15193 0.4799 0 0.76205 0.31833 0.28215 0.31592 0.28215 0.85611 0 0.5426-0.29421 0.85611-0.2918 0.31109-0.81752 0.31109-0.46543 0-0.75964-0.25804t-0.33521-0.71382h0.42202q0.041 0.30145 0.21463 0.45579 0.17364 0.15193 0.4582 0.15193 0.31109 0 0.48714-0.21222 0.17845-0.21222 0.17845-0.58601 0-0.35209-0.19292-0.56431-0.19052-0.21463-0.50884-0.21463-0.2918 0-0.4582 0.12781l-0.11817 0.09646z&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#3cb371&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;translate(-.13501)&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; aria-label&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;4&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;m79.29 78.133h0.48714v0.36415h-0.48714v0.81511h-0.44855v-0.81511h-1.5989v-0.26286l1.5723-2.4333h0.47508zm-1.541 0h1.0924v-1.7219l-0.05305 0.09646z&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#3cb371&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;polyline&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;laLinea&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; points&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;11 73 33.5 73 56 73 78.5 73 101 73&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;none&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; marker-end&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;url(#dotLine)&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; marker-mid&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;url(#dotLine)&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; marker-start&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;url(#dotLine)&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#d8232a&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-linecap&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-linejoin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;arreglo&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; elLinea&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;laLinea&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; elArreg&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;arreglo&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ejesY &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; i&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            ejesY.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(Math.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;floor&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(Math.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;random&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 11&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)); &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// 0-10&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        elArreg.textContent &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `Valores = [${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ejesY&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}]`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        fijaLinea&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(ejesY);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fijaLinea&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;ordenadas&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; []) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; numOrd &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ordenadas.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(numOrd &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; numOrd; i&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) ordenadas.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;push&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ord &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ordenadas.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;slice&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;y&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 73&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; -&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; y &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 7.1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            elLinea.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;points&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                `11 ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ord&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;} 33.5 ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ord&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;} 56 ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ord&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;} 78.5 ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ord&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;} 101 ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ord&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con estas indicaciones, hacer tu propia gráfica de líneas no debería ser excesivamente complicado.&lt;/p&gt;
&lt;p&gt;Para conocer más sobre SVG y cómo editarlo, te recomiendo el libro &lt;a href=&quot;https://leanpub.com/scalable/&quot;&gt;SCALABLE&lt;/a&gt; de Jorge Aznar.&lt;/p&gt;
&lt;h2 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/ejercicios-web-javascript/graficalineas.html&quot;&gt;&lt;button&gt;Ver gráfica de ejemplo&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ver ejemplo de aplicación práctica. &lt;a href=&quot;https://javguerra.github.io/summer-quiz/&quot;&gt;Summer Quiz&lt;/a&gt; (Es necesario terminar una partida para obtener resultados.)&lt;/li&gt;
&lt;li&gt;Ver también: &lt;a href=&quot;/blog/contador-resultados&quot;&gt;Creación de un contador de resultados&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ver también: &lt;a href=&quot;/blog/carga-svg&quot;&gt;Cargar SVG dinámicamente&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Libro sobre SVG &lt;a href=&quot;https://leanpub.com/scalable/&quot;&gt;SCALABLE&lt;/a&gt; de Jorge Aznar.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/graficalineas.BU14jhGg_ZfgmGH.webp"/><category>código</category><category>css</category><category>html</category><category>javascript</category><category>svg</category><category>usabilidad</category><author>JavGuerra</author></item><item><title>Cargar SVG dinámicamente</title><link>https://javguerra.github.io/blog/carga-svg</link><guid isPermaLink="true">https://javguerra.github.io/blog/carga-svg</guid><description>Y una función genérica para hacer llamadas con &apos;fetch&apos;</description><pubDate>Tue, 14 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/svg-logo.JHhXWkN6_ZmLAYo.webp&quot; alt=&quot;SVG&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#svg&lt;/em&gt;, &lt;em&gt;#usabilidad&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Esta entrada en el blog complementa el contenido de los artículos &lt;a href=&quot;/blog/contador-resultados&quot;&gt;Creación de un contador de resultados&lt;/a&gt; y &lt;a href=&quot;/blog/grafica-lineas&quot;&gt;Gráfica de lineas dinámica con SVG&lt;/a&gt;, pero puede leerse con independencia de ellos. Veremos cómo cargar un SVG (o cualquier otra cosa que nos propongamos) en el DOM una vez renderizada la página en el navegador apoyándonos en la instrucción &lt;code&gt;fetch()&lt;/code&gt;. Se asume que el lector conoce el uso de esta instrucción.&lt;/p&gt;
&lt;p&gt;La idea la tomé de este repositorio: &lt;a href=&quot;https://github.com/ojgarciab/335841-stackoverflow-es&quot;&gt;Reproducción de acceso a SVG externo con CSS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Como sabemos, podemos cargar imágenes, y también SVG en nuestra página con la etiqueta &lt;code&gt;img&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;img&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; src&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;imagen.svg&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; alt&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Imagen de ejemplo en formato SVG&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;pero esto presenta un inconveniente. Desde el DOM, con JavaScript, no podemos acceder a las etiquetas del fichero SVG, y esto es fundamental para poder aplicar cambios dinámicos a la imagen.&lt;/p&gt;
&lt;p&gt;La alternativa es poner el SVG en línea dentro del HTML, de una forma parecida a:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;imagen&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; version&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;1.1&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; xmlns&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;http://www.w3.org/2000/svg&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En los puntos suspensivos estaría el cuerpo del SVG. Pero esto presentaría otro problema, y es que aumenta el tamaño del HTML de manera considerable, y lo hace menos legible.&lt;/p&gt;
&lt;p&gt;La propuesta de esta entrada es la de hacer la carga del SVG dinámicamente, una vez se ha cargado la página, empleando &lt;code&gt;fetch()&lt;/code&gt; para «traer» la imagen desde el servidor e insertarla en el DOM directamente tomando como referencia un elemento padre del HTML:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;imagen&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Veamos cómo de sencillo es esto.&lt;/p&gt;
&lt;h2 id=&quot;el-código&quot;&gt;El código&lt;/h2&gt;
&lt;p&gt;EL HTML de nuestra página sería pues muy simple:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;DOCTYPE&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; html&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; lang&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;es&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; charset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;UTF-8&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;viewport&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; content&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;width=device-width, initial-scale=1.0&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Ejemplo SVG&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; defer&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; src&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;funciones.js&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;imagen&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Toda la magia se llevaría a cabo en la siguientes funciones para hacer posible la carga dinámica de la imagen:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;01&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;. function &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(el) { &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(el) }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;02&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;. &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;03&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;. function &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;fetchAPI&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(url, callback, tipo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;json&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;04&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.     &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// setSpin(true);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;05&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.     &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;fetch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(url)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;06&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.         .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;respuesta&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;07&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.             &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;respuesta.ok) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(respuesta.statusText);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;08.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;             return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; tipo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;json&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; respuesta.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;json&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; respuesta.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;text&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;09.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;         })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;10.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;         .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;datos&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; callback&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(datos))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;11.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;         .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(err));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;12.&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;         // .finally(setSpin(false));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;13.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;14.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;15.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; urlImagen &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;https://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;16.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; let&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; cargaImagen&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; xml&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#imagen&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; xml;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;17.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fetchAPI&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(urlImagen, cargaImagen, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;text&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Nota&lt;/strong&gt;: La línea &lt;strong&gt;4&lt;/strong&gt; y la línea &lt;strong&gt;12&lt;/strong&gt; llaman a la función &lt;code&gt;setSpin()&lt;/code&gt; que describí en la entrada &lt;a href=&quot;/blog/spinner-loader-asincrono&quot;&gt;Spinner loader asíncrono&lt;/a&gt;, y podemos prescindir de ellas sin problema si no vamos a usarlas.&lt;/p&gt;
&lt;p&gt;Veamos que hace esto. En la línea 1 tenemos una función cuya utilidad es la de acortar la llamada a &lt;code&gt;querySelector()&lt;/code&gt;. Más allá de la estética, simplifica la escritura de código. La usaré en la línea 16.&lt;/p&gt;
&lt;p&gt;La función &lt;code&gt;fetchAPI()&lt;/code&gt; contiene la estructura genérica de una consulta &lt;code&gt;fetch()&lt;/code&gt;, y la usaré en la línea 17, tras haber definido la dirección donde está ubicado el SVG en la línea 15 &lt;code&gt;urlImagen&lt;/code&gt;, y la función que se ocupará de poner la imagen en el DOM de la línea 16 &lt;code&gt;cargaImagen&lt;/code&gt;. Básicamente, la llamada:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;fetchAPI&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(urlImagen, cargaImagen, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;texto&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;lo que hace es pasar a &lt;code&gt;fetch()&lt;/code&gt; la dirección de la imagen SVG y mediante la función &lt;em&gt;callback&lt;/em&gt; &lt;code&gt;cargaImagen()&lt;/code&gt;, que es una función flecha asignada a una variable, una vez fetch obtenga la imagen, ponerla dentro del contenedor &lt;code&gt;div&lt;/code&gt; que describimos en el HTML. El parámetro &lt;code&gt;&apos;texto&apos;&lt;/code&gt; sirve para indicar que lo que vamos a cargar debe ser leído como texto, y no como un json. Realmente podríamos poner cualquier cosa aquí: ‘text’, ‘false’… lo que se nos ocurriese,  ya que la función fechAPI consulta si lo que estamos indicando que debe devolver es &lt;strong&gt;‘json’&lt;/strong&gt; en la línea 8:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; tipo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;json&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; respuesta.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;json&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; respuesta.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;text&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;y cualquier otra opción será entendida como que debe devolver la dos datos de tipo &lt;code&gt;text()&lt;/code&gt; en vez de &lt;code&gt;json()&lt;/code&gt;, que es el formato que requiere el contenido &lt;code&gt;xml&lt;/code&gt; que describe el SVG que estamos cargando. por defecto, esta función devolverá un json si no indicamos este parámetro en la llamada.&lt;/p&gt;
&lt;p&gt;En la línea 13 comprobamos que la petición &lt;code&gt;fetch(url)&lt;/code&gt; no ha devuelto ningún error. &lt;code&gt;fetch()&lt;/code&gt; no realiza esta comprobación por nosotros, y si se obtiene respuesta del servidor, así sea un error, entenderá que la petición se ha llevado a cabo, y devolverá la respuesta obtenida. Con esta línea nos aseguramos de que todo ha ido bien, si no es así, lanzo un error que será capturado en la línea 17 y mostrado por consola, parando la ejecución de la función.&lt;/p&gt;
&lt;p&gt;Una vez devueltos los datos desde la línea 8, es en la línea 10 donde se procesa la función &lt;em&gt;callback&lt;/em&gt;_ &lt;code&gt;cargaImagen&lt;/code&gt; que paso como parámetro:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;xml&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#imagen&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; xml;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esta función flecha toma los datos &lt;code&gt;xml&lt;/code&gt; recibidos de &lt;code&gt;fetch()&lt;/code&gt;, que deben estar en formato &lt;code&gt;.text()&lt;/code&gt; y los inserta en el div que identificamos con el &lt;code&gt;id=&quot;imagen&quot;&lt;/code&gt; usando &lt;code&gt;.innerHTML&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Desde ese momento ya disponemos de acceso completo al .SVG mediante el DOM.&lt;/p&gt;
&lt;h2 id=&quot;código-completo&quot;&gt;Código completo&lt;/h2&gt;
&lt;p&gt;Puedes copiar y pegar este código para hacer pruebas:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;DOCTYPE&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; html&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; lang&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;es&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; charset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;UTF-8&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;viewport&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; content&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;width=device-width, initial-scale=1.0&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Ejemplo SVG&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;imagen&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) { &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(el) }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fetchAPI&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;callback&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;tipo&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;json&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // setSpin(true);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            fetch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(url)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;respuesta&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;respuesta.ok) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(respuesta.statusText);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; tipo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;json&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; respuesta.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;json&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; respuesta.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;text&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;datos&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; callback&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(datos))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(err));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;                // .finally(setSpin(false));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; urlImagen &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;https://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        let&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; cargaImagen&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; xml&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#imagen&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; xml;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        fetchAPI&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(urlImagen, cargaImagen, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;text&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ver ejemplo de aplicación práctica. &lt;a href=&quot;https://javguerra.github.io/summer-quiz/&quot;&gt;Summer Quiz&lt;/a&gt;. El SVG inicial de la gráfica y el SVG final de resultados se cargan mediante este método. Es necesario terminar una partida para obtener resultados que se muestren en la gráfica.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/contador-resultados&quot;&gt;Creación de un contador de resultados&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/grafica-lineas&quot;&gt;Gráfica de lineas dinámica con SVG&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/spinner-loader-asincrono&quot;&gt;Spinner loader asíncrono&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Libro sobre SVG &lt;a href=&quot;https://leanpub.com/scalable/&quot;&gt;SCALABLE&lt;/a&gt; de Jorge Aznar.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ojgarciab/335841-stackoverflow-es&quot;&gt;Reproducción de acceso a SVG externo con CSS&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg&quot;&gt;Imagen SVG de prueba en Wikipedia&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/svg-logo.JHhXWkN6_ZmLAYo.webp"/><category>código</category><category>css</category><category>html</category><category>javascript</category><category>svg</category><category>usabilidad</category><author>JavGuerra</author></item><item><title>Mosaico JS</title><link>https://javguerra.github.io/blog/mosaico-js</link><guid isPermaLink="true">https://javguerra.github.io/blog/mosaico-js</guid><description>Juego de colorear pixel art</description><pubDate>Mon, 27 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/mosaico.BiJ60OK-_Zo8LIn.webp&quot; alt=&quot;Mosaico JS&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#dom&lt;/em&gt;, &lt;em&gt;#juego&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Ejercicio que combina lógica de programación en JavaScript, y el uso de eventos asociados a los elementos del DOM que consiste en elegir un pincel y pintar las celdas de una tabla para construir un mosaico de colores.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/MosaicoJS/&quot;&gt;&lt;button&gt;Probar el juego&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;el-juego&quot;&gt;El juego&lt;/h1&gt;
&lt;p&gt;La página muestra ocho botones redondos de otros tantos colores de una gama que va de los colores oscuros, empezando por el negro, a los colores claros, terminando con el blanco. Al hacer clic en cada botón elegimos el color deseado.&lt;/p&gt;
&lt;p&gt;Debajo de estos botones está la tabla de 16x16 celdas sobre las que vamos a pintar con el color seleccionado. Al hacer clic sobre una celda, esta cambia su color de fondo al nuevo color. Podemos componer dibujos con esta técnica como el que se ve en la imagen.&lt;/p&gt;
&lt;p&gt;Para borrar emplearemos el color blanco, ya que este es el color por defecto de cada celda de la tabla, o bien podemos corregir errores pintando con otro color distinto.&lt;/p&gt;
&lt;p&gt;Para borrar todo el dibujo deberemos recargar la página. Dada la simplicidad del ejemplo, no se han implementado opciones para guardar y cargar los mosaicos creados.&lt;/p&gt;
&lt;h1 id=&quot;lo-básico-el-html&quot;&gt;Lo básico, el HTML&lt;/h1&gt;
&lt;p&gt;El código html es una fuente de información para la aplicación que voy a desarrollar.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;header&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;img&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;logo&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; src&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;assets/img/mosaico.png&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; alt&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;logo&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;Mosaico&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;small&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;¡Elije un color y haz clic en el mosaico para pintar!&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;small&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;nav&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;btnNegro&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;negro&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;btnAzul&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;azul&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;btnRojo&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;rojo&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;btnMagen&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;magen&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;btnVerde&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;verde&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;btnCian&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;cian&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;btnAmari&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;amari&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;btnBlanc&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;blanc&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;nav&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;header&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;main&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Dentro de &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt; indico el identificador &lt;code&gt;id&lt;/code&gt; y la clase &lt;code&gt;class&lt;/code&gt; que definirá el color de cada botón &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;. Esta clase me va a servir para simplificar la codificación del juego, ya que, como veremos más adelante, voy a aprovechar esta información para seleccionar el color del pincel con el que pintaremos, es decir, cuando hagamos clic en cada uno de los botones, dispararemos un evento que me permitirá ejecutar una función que leerá la clase asociada a este. Como la clase indica el color del botón, podemos usarla para saber qué color hemos elegido. Al pulsar el botón rojo estaremos obteniendo la clase &lt;code&gt;.rojo&lt;/code&gt; que luego podemos aplicar en las celdas del mosaico.&lt;/p&gt;
&lt;p&gt;Por supuesto, en el CSS cada clase definirá el color, por ejemplo:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;css&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.rojo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  background-color&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;#f00&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sencillo, ¿verdad? Veamos cómo funciona.&lt;/p&gt;
&lt;h1 id=&quot;el-programa-en-js&quot;&gt;El programa en JS&lt;/h1&gt;
&lt;p&gt;Básicamente el programa hará lo siguiente:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Asociará un evento que llama a la función &lt;code&gt;color()&lt;/code&gt; en cada uno de los ocho botones para poder elegir el color con el que pintar.&lt;/li&gt;
&lt;li&gt;Dibujará una tabla con las dimensiones deseadas (inicialmente 16x16, pero se puede cambiar), y a cada celda de la tabla le asociará un evento que llama a la función &lt;code&gt;pinta()&lt;/code&gt; cuya tarea es cambiar el color de la celda sobre la que se ha echo clic.&lt;/li&gt;
&lt;li&gt;Inicializará las dos variables que usaremos en el juego.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Esto último paso es simple:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; btnSel &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#btnNegro&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; pincel &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; btnSel.className;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Estas variables servirán para:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;text-align: left&quot;&gt;Variable&lt;/th&gt;
&lt;th style=&quot;text-align: left&quot;&gt;Uso&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;btnSel&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;Contendrá la referencia al botón que hemos seleccionado. Esto nos permitirá mostrar el botón como seleccionado y desmarcar el botón cuando cambiemos nuestra selección por otro botón seleccionado.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left&quot;&gt;&lt;code&gt;pincel&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;Contendrá la clase relativa al color seleccionado que hemos obtenido al hacer clic en alguno de los botones de la barra de navegación.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;asociando-el-evento-de-la-función-color&quot;&gt;Asociando el evento de la función color&lt;/h2&gt;
&lt;p&gt;Para que los ocho botones de colores funcionen, debo asociarles un evento de tal forma que, al hacer clic en ellos, realicen su función, nunca mejor dicho:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#btnNegro&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).onclick &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; color;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#btnAzul&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ).onclick &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; color;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#btnRojo&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ).onclick &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; color;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#btnMagen&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).onclick &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; color;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#btnVerde&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).onclick &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; color;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#btnCian&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ).onclick &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; color;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#btnAmari&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).onclick &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; color;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#btnBlanc&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).onclick &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; color;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La función &lt;code&gt;el()&lt;/code&gt; es una forma de abreviar:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) { &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(el); }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Como se aprecia, lo que hace la función &lt;code&gt;el()&lt;/code&gt;  es devolver un elemento de nuestro HTML tomando como referencia su selector, usando para ello la función &lt;code&gt;querySelector()&lt;/code&gt;;&lt;/p&gt;
&lt;p&gt;Como ya tenemos el elemento HTML que corresponde a cada botón, podemos asignarle un escuchador de evento con &lt;code&gt;.onclick&lt;/code&gt; que llame a la función &lt;code&gt;color()&lt;/code&gt; al hacer click en ese botón.&lt;/p&gt;
&lt;p&gt;¿Y qué hace la función &lt;code&gt;color()&lt;/code&gt;?&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; color&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    btnSel.classList.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;remove&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;seleccion&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    btnSel &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    pincel &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; this&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.className;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    btnSel.classList.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;seleccion&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Primeramente elimina la clase &lt;code&gt;.seleccion&lt;/code&gt; que es la encargada de dar el efecto hundido del botón seleccionado (&lt;code&gt;btnSel&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Seguidamente obtiene la referencia del botón que acabamos de seleccionar haciendo uso de &lt;code&gt;this&lt;/code&gt;. Aquí &lt;code&gt;this&lt;/code&gt; hace referencia al objeto que llama a la función, es decir, al botón que lanzó el evento. Ahora ya sabemos cual es el botón sobre el que hemos hecho clic.&lt;/p&gt;
&lt;p&gt;Para obtener el color del &lt;code&gt;pincel&lt;/code&gt; con el que vamos a pintar, leo la clase asociada al botón con &lt;code&gt;.className&lt;/code&gt;. Esta clase, como vimos cuando creamos el HTML, es la encargada de definir el color de fondo del botón, y es la que usaremos para pintar las celdas a partir de ahora cuando llamemos a la función &lt;code&gt;pinta()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Para indicar visualmente al usuario el color que ha seleccionado, ponemos la clase &lt;code&gt;.seleccion&lt;/code&gt; en el nuevo botón.&lt;/p&gt;
&lt;p&gt;En resumen, como sabemos cual fue el botón que seleccionamos anteriormente, quitamos la clase que indica visualmente que el botón está seleccionado, porque ya ha dejado de estarlo, asociamos a la variable &lt;code&gt;btnSel&lt;/code&gt; el nuevo botón, y a la variable &lt;code&gt;pincel&lt;/code&gt; la clase asociada al botón que indica su color, y finalmente ponemos la marca de selección en el nuevo botón seleccionado.&lt;/p&gt;
&lt;h2 id=&quot;dibujando-la-tabla-con-las-celdas-sobre-las-que-pintaremos&quot;&gt;Dibujando la tabla con las celdas sobre las que pintaremos&lt;/h2&gt;
&lt;p&gt;Creo la tabla y la conecto al DOM mediante:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;main&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;appendChild&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;( &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;creaTabla&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(numCols, numFils) );&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La función &lt;code&gt;creaTabla()&lt;/code&gt; recibe dos parámetros que indican su altura y anchura en celdas. Si lo deseamos, podemos cambiar el valor de estas variables para hacer que el mosaico tenga otras dimensiones cambiando los valores en:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; numCols&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 16&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; numFils&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 16&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esta función &lt;code&gt;creaTabla()&lt;/code&gt; no destaca especialmente si no es por dos cosas:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; creaTabla&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;numCols&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;numFils&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; table, tbody, tr, td;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    tbody &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; creaEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;tbody&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; numFils; i&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        tr &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; creaEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;tr&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; numCols; i&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            td &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; creaEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;td&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            td.classList.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;blanc&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            td.onclick &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; pinta; &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// ¡Magia!&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            tr.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;appendChild&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(td);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        tbody.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;appendChild&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(tr);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    table &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; creaEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;table&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    table.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;appendChild&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(tbody);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; table;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hago uso de la función &lt;code&gt;.creaEl()&lt;/code&gt; para acortar la instrucción encargada de la creación de elementos del DOM:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; creaEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) { &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;createElement&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(el); }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cada vez que creo un &lt;code&gt;&amp;lt;td&amp;gt;&lt;/code&gt; (celda) le asigno un evento que llama a la función &lt;code&gt;pinta()&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    td &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; creaEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;td&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    td.classList.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;blanc&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    td.onclick &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; pinta; &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// ¡Magia!&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Estas tres líneas dentro del bucle anidado crean las celdas de cada fila, les asignan la clase &lt;code&gt;.blanc&lt;/code&gt; que pone el fondo de las celdas de color blanco por defecto, y luego asocia la función &lt;code&gt;pinta()&lt;/code&gt; al evento &lt;code&gt;.onclick&lt;/code&gt; de cada celda de forma que al hacer click en ella su fondo se pintará del color que indique &lt;code&gt;pincel&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; pinta&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() { &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.className &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; pincel; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;De nuevo aquí &lt;code&gt;this&lt;/code&gt; es fundamental para poder trabajar con la celda seleccionada, que es la que lanzó el evento. Al hacer clic en la celda, cambiamos de color esa misma celda. Así de simple.&lt;/p&gt;
&lt;h1 id=&quot;en-resumen&quot;&gt;En resumen&lt;/h1&gt;
&lt;p&gt;Esto sería todo. Resumiendo la operativa de la aplicación, partiendo de un HTML con las clases que indican el color de cada uno de los botones del juego que sirven para seleccionar el color, asocio un evento a cada botón para saber el color del pincel con el que vamos a pintar las celdas. Inicialmente, el color seleccionado es el negro, y el botón seleccionado es el que corresponde a ese color.&lt;/p&gt;
&lt;p&gt;Al hacer clic en cada celda, hacemos que el fondo de esta cambie al color seleccionado.&lt;/p&gt;
&lt;p&gt;Puedes jugar al juego y ver el código completo en el repositorio haciendo clic en los siguientes enlaces.&lt;/p&gt;
&lt;p&gt;¿Te animas a hacer tus propios dibujos pixel art?&lt;/p&gt;
&lt;h1 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/MosaicoJS/&quot;&gt;&lt;button&gt;Probar el juego&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Repositorio &lt;a href=&quot;https://github.com/JavGuerra/MosaicoJS&quot;&gt;JavGuerra/MosaicoJS &lt;/a&gt;&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/mosaico.BiJ60OK-_Zo8LIn.webp"/><category>web</category><category>código</category><category>css</category><category>html</category><category>javascript</category><category>dom</category><category>juego</category><author>JavGuerra</author></item><item><title>Filtrado múltiple</title><link>https://javguerra.github.io/blog/filtrado-multiple</link><guid isPermaLink="true">https://javguerra.github.io/blog/filtrado-multiple</guid><description>Como simplificar la búsqueda de información</description><pubDate>Fri, 15 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/filtrado.0LXC88F8_lExjy.webp&quot; alt=&quot;Filtrado&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#node.js&lt;/em&gt;, &lt;em&gt;#express&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;En programación es habitual trabajar con datos de entrada. Un caso común son los campos (obligatorios o no) que recibimos de un formulario para realizar búsquedas en una base de datos y devolver datos al usuario, o para dar de alta nueva información… pero estos datos de entrada, según las circunstancias, pueden variar. Para un mismo formulario, podemos recibir uno o varios campos, lo que complica la forma en que hacemos las búsquedas de información. En esta entrada veremos como simplificar el filtrado para hacer consultas a los datos.&lt;/p&gt;
&lt;h1 id=&quot;supuesto-práctico&quot;&gt;Supuesto práctico&lt;/h1&gt;
&lt;p&gt;Tenemos una lista de &lt;strong&gt;productos&lt;/strong&gt; almacenados en un arreglo o lista de objetos. Cada objeto tiene las propiedades &lt;strong&gt;nombre&lt;/strong&gt;, &lt;strong&gt;tipo&lt;/strong&gt; y &lt;strong&gt;precio&lt;/strong&gt;, y deseamos hacer búsquedas sobre esta lista, devolviendo los objetos que cumplan con los datos recibidos desde un formulario. Los datos recibidos pueden ser todos ellos, es decir, valores para cada una de las tres propiedades, o sólo el dato de búsqueda de uno de ellos o dos de ellos (faltando un dato en este último caso). Veamos primeramente la estructura de datos:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; productos &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;nombre&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;LAVADORA SECAMAS&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;tipo&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hogar&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;precio&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;700&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;nombre&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;TELEVISOR TV&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;tipo&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;video&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;precio&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1200&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;nombre&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;ARMARIO RIO&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;tipo&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hogar&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;precio&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;300&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Una búsqueda &lt;code&gt;nombre: &apos;LAVADORA&apos;&lt;/code&gt; me devolvería el primer objeto. Si busco por &lt;code&gt;tipo: &apos;hogar&apos;&lt;/code&gt; me devolverá el primer y el tercer objeto… Y si busco por &lt;code&gt;tipo: &apos;video&apos; y precio: menor que 1500&lt;/code&gt; me devolverá el segundo objeto.&lt;/p&gt;
&lt;h2 id=&quot;comunmente&quot;&gt;Comunmente…&lt;/h2&gt;
&lt;p&gt;Para hacer una búsqueda sobre esta lista, tendría que comprobar si he recibido un valor para cada uno de las propiedades de los objetos de la lista, y si es así, realizar el filtrado por el primer valor para obtener el primer resultado, pasar al siguiente valor si lo hubiese, para obtener el siguiente resultado filtrado, y así con tantos valores como haya recibido del formulario. El código sería algo como esto:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; resultados &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; productos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (nombre &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; tipo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; precio) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (nombre) resultados &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; resultados.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;filter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;producto&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; producto.nombre.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;includes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(nombre));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (tipo)   resultados &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; resultados.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;filter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;producto&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; producto.tipo.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;includes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(tipo));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (precio) resultados &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; resultados.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;filter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;producto&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; producto.precio &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; precio);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;} &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    resultados &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(resultados);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Este encadenado de filtrados me obliga a realizar tres filtrados e ir guardando el resultado para el siguiente filtro, si la entrada de formulario, por tanto la variable que guarda su valor, existe.&lt;/p&gt;
&lt;p&gt;Como se aprecia en el código, primeramente copio el contenido de &lt;code&gt;productos&lt;/code&gt; a &lt;code&gt;resultados&lt;/code&gt;, para ir filtrando el resultado. Esto lo hago porque no sé qué valores recibiré, por lo tanto no sabré donde empezará &lt;code&gt;productos.filter&lt;/code&gt;, si en el primer, segundo o tercer &lt;code&gt;if&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Seguidamente compruebo si tengo valores en las variables &lt;code&gt;nombre&lt;/code&gt;, &lt;code&gt;tipo&lt;/code&gt; y &lt;code&gt;precio&lt;/code&gt;. Si alguna de ellas existe, realizo el filtrado sobre los datos, sino, devuelvo un arreglo o lista vacía. Así pues, si existe nombre, filtro por nombre, si existe tipo, filtro por tipo y si existe precio filtro por precio, consecutivamente.&lt;/p&gt;
&lt;h2 id=&quot;otra-manera-de-hacerlo&quot;&gt;Otra manera de hacerlo&lt;/h2&gt;
&lt;p&gt;Es posible hacer un sólo filtrado que incluya las tres condiciones. Para ello usaré el operador condicional ternario (&lt;code&gt;?&lt;/code&gt;):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; resultados&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (nombre &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; tipo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; precio)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; productos.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;filter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;producto&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    (nombre &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; producto.nombre.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;includes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(nombre) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    (tipo   &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; producto.tipo.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;includes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(tipo) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    (precio &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; producto.precio &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; precio &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [];&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La lista &lt;code&gt;resultados&lt;/code&gt; tendrá el valor del filtro o una lista vacía según reciba o no reciba alguno de los valores para filtrar.&lt;/p&gt;
&lt;p&gt;Dentro de &lt;code&gt;filter&lt;/code&gt; incluimos ahora los tres criterios de filtrado de una vez, pero igualmente debemos comprobar si cada uno de las variables que recibimos tiene o no valores para filtrar, es decir, si el dato de entrada existe.&lt;/p&gt;
&lt;p&gt;Si una variable tiene valor, osea, si hemos recibido sus datos del formulario, entonces se incluirá la condición de filtrado, sino se incluirá un &lt;code&gt;true&lt;/code&gt;. Nos fijamos en una de las líneas:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    (nombre &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; producto.nombre.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;includes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(nombre) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si la variable &lt;code&gt;nombre&lt;/code&gt; tiene datos, entonces se incluirá la comprobación &lt;code&gt;producto.nombre.includes(nombre)&lt;/code&gt; en el filtrado, de otra forma se incluirá un &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Como estamos filtrando por un total de hasta tres condiciones que tienen que ser verdaderas (&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;), si alguna de ellas no se cumple, el &lt;code&gt;filter&lt;/code&gt; pasará al siguiente elemento de la lista, y no devolverá este elemento.&lt;/p&gt;
&lt;p&gt;Imaginemos que sólo hemos recibido el &lt;code&gt;nombre&lt;/code&gt; del producto. ¿Qué pasa con las otras dos condiciones derivadas de &lt;code&gt;tipo&lt;/code&gt; y &lt;code&gt;precio&lt;/code&gt;?. Devolverán &lt;code&gt;true&lt;/code&gt;, condicionando la respuesta de filtrado a lo que devuelva la condición de &lt;code&gt;nombre&lt;/code&gt;. Por ello los &lt;code&gt;true&lt;/code&gt; que no sean resultado de la condición de una o varias de las variables no tendrán ninguna influencia en el valor de la comprobación.&lt;/p&gt;
&lt;p&gt;Si tenemos dos variables, la tercera será &lt;code&gt;true&lt;/code&gt;, y la condición de filtrado funcionará sólo si las dos condiciones con valores de entrada son &lt;code&gt;true&lt;/code&gt; si han pasado la comprobación asociada a esa variable.&lt;/p&gt;
&lt;h1 id=&quot;otra-manera-más&quot;&gt;Otra manera más&lt;/h1&gt;
&lt;p&gt;En programación no hay un único camino para hacer las cosas. Tras la lectura de esta entrada, &lt;strong&gt;Marcos&lt;/strong&gt;, de un foro de Discord, me propuso una alternativa aún más simple. Vamos a ver cómo funciona:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; resultados&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (nombre &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; tipo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; precio)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; productos.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;filter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;producto&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;nombre &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; producto.nombre.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;includes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(nombre)) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;tipo   &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; producto.tipo.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;includes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(tipo)) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;precio &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; producto.precio &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; precio))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [];&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La lógica de fondo no deja de ser la misma, se basa en un booleano que nos dice si se va a tener en cuenta la condición o se va a incluir un &lt;code&gt;true&lt;/code&gt;, pero esta refinada forma de hacerlo consiste en «jugar» con el valor inverso del contenido de una variable, de tal forma que si la variable existe, su valor será &lt;code&gt;false&lt;/code&gt; (Ej. &lt;code&gt;!nombre&lt;/code&gt;) debiendo aplicar entonces la condición de filtrado (&lt;code&gt;||&lt;/code&gt;), y si no existe, el valor de la variable será &lt;code&gt;true&lt;/code&gt;. Elegante.&lt;/p&gt;
&lt;h1 id=&quot;un-poco-más-allá&quot;&gt;Un poco más allá&lt;/h1&gt;
&lt;p&gt;La siguiente es una función basada en la codificación anterior y devuelve un objeto que incluye un código de respuesta y el listado de objetos resultante.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; respuesta&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;nombre&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; undefined&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;tipo&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; undefined&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;precio&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; undefined&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; codigo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (nombre &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; tipo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; precio) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; resultados&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (codigo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        ?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; productos.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;filter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;producto&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;nombre &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; producto.nombre.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;includes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(nombre)) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;tipo   &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; producto.tipo.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;includes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(tipo)) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;precio &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; producto.precio &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; precio))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        :&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (codigo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) codigo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (resultados.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { codigo, resultados };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La variable &lt;code&gt;codigo&lt;/code&gt; va a contener tres posibles valores:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;text-align: center&quot;&gt;Valor&lt;/th&gt;
&lt;th style=&quot;text-align: left&quot;&gt;Significado&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center&quot;&gt;0&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;Datos encontrados.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;No se han encontrado datos.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;No se han recibido datos de entrada.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;De tal forma que en:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; codigo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (nombre &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; tipo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; precio) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;se determina si se ha recibido alguna de las variables, asignándole el código correspondiente, y en la línea:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (codigo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) codigo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (resultados.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;se determina si se ha obtenido algún resultado tras la búsqueda, si el código era 0, es decir, si había datos de entrada.&lt;/p&gt;
&lt;p&gt;por último en la línea:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { codigo, resultados };&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Devolvemos el objeto con la información de lo sucedido y el resultado de la búsqueda.&lt;/p&gt;
&lt;p&gt;La línea anterior es equivalente a:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { codigo: codigo, resultados: resultados };&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esta función puede ser útil para, por ejemplo, trabajar con rutas en Node.js/express:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;router.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;nombre&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;tipo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;precio&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; req.query;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    res.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;json&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;( &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;respuesta&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(nombre, tipo, precio) );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/filtrado.0LXC88F8_lExjy.webp"/><category>código</category><category>javascript</category><category>node.js</category><category>express</category><author>JavGuerra</author></item><item><title>Conexión persistente a MongoDB en Node.js</title><link>https://javguerra.github.io/blog/mongodb-connect</link><guid isPermaLink="true">https://javguerra.github.io/blog/mongodb-connect</guid><description>Abrir una única conexión a la base de datos a través de los distintos módulos de la aplicación</description><pubDate>Sun, 24 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/mongodb.B38n9K_s_1aeGYn.webp&quot; alt=&quot;MongoDB&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#node.js&lt;/em&gt;, &lt;em&gt;#express&lt;/em&gt;, &lt;em&gt;#mongodb&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Esta semana tocó aprender sobre &lt;strong&gt;MongoDB&lt;/strong&gt;. Una de las cuestiones que me llamaron la atención en los ejercicios que realizamos era la necesidad de abrir y cerrar la conexión a la Base de Datos (en adelante «BBDD») en cada consulta, algo que supone una sobrecarga importante para el servidor, así que me puse a investigar la manera de hacer que la conexión a la BBDD permaneciese abierta y dando servicio a través de los distintos módulos de la aplicación. Esto es lo que descubrí, con ayuda de la comunidad.&lt;/p&gt;
&lt;h2 id=&quot;cambiando-el-chip&quot;&gt;Cambiando el chip&lt;/h2&gt;
&lt;p&gt;Pasar de manejar datos embebidos en módulos como en el caso de la publicación sobre &lt;a href=&quot;/blog/filtrado-multiple&quot;&gt;filtrado múltiple&lt;/a&gt; a consultar una base de datos como &lt;strong&gt;MongoDB&lt;/strong&gt; presenta retos importantes. el principal es que debo establecer la conexión al servicio y esperar una respuesta. Una consulta típica a MongoDB tendría esta forma:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;NODE_ENV&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;production&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;dotenv&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;config&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; mongoClient&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;mongodb&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).MongoClient;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_HOST&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}:${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_PORT&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}/`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; db_name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_DATABASE&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; collection&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;products&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(url, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;database&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (err) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; err;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; db&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; database.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;db&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(db_name);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    db.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;collection&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(collection).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;find&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toArray&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;result&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (err) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; err;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(result);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        database.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En la primera línea, en función de si la aplicación está funcionando en local, en modo desarrollo, o bien en producción en el servidor, cargo o no el módulo &lt;code&gt;dotenv&lt;/code&gt; que me permite tener las variables globales que luego usaré en url y db_name por ejemplo definidas en un fichero &lt;code&gt;.env&lt;/code&gt;. Puedes ampliar conocimientos sobre este asunto en &lt;a href=&quot;https://www.npmjs.com/package/dotenv&quot;&gt;.dovenv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Tras importar mongoClient, y definir las variables que se emplearán en la conexión (url a la BBDD, nombre de la BBDD y nombre de la colección) lanzo un &lt;code&gt;mongoClient.connect()&lt;/code&gt; que devuelve bien un error de conexión o abre la conexión (cliente) al gestor de BBDD MongoDB. Luego, con  &lt;code&gt;const db = database.db(db_name);&lt;/code&gt; obtengo acceso a la BBDD, y seguidamente hago una consulta con &lt;code&gt;db.collection(collection).find()&lt;/code&gt;. Una vez obtengo el resultado de la búsqueda (en este caso todos los documentos dentro de la colección de la BBDD), los muestro por consola y cierro la base de datos con &lt;code&gt;database.close();&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Pero si deseo hacer otra búsqueda, o en el módulo tengo una serie de rutas, todas ellas apuntando a una consulta a la BBDD, el número de aperturas y cierres de la conexión se multiplica por el número de consultas. Esto en una página personal o con poco tráfico es sostenible, pero no lo es para grandes flujos de acceso o incluso para situaciones de picos concretos de acceso al servidor (horas de más tráfico, momentos del año donde las consultas se incrementan, por ejemplo cuando se solicitan los resultados de un evento, las notas de fin de curso, una noticia que ha tenido popularidad o alcance…).&lt;/p&gt;
&lt;p&gt;Mantener la conexión abierta para distintas consultas en un módulo es fácil, pero, ¿cómo abrirla a través de los distintos módulos de la aplicación?&lt;/p&gt;
&lt;h2 id=&quot;primer-acercamiento-importar-y-conectar&quot;&gt;Primer acercamiento: Importar y conectar&lt;/h2&gt;
&lt;p&gt;Mi primera opción fue que si voy a emplear la conexión en distintos módulos debía extraer el proceso de conexión a un módulo a parte y luego importarlo allá donde lo necesite, y dicho y hecho:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;NODE_ENV&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;production&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;dotenv&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;config&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; MongoClient&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;mongodb&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).MongoClient;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_HOST&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}:${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_PORT&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}/`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; db_name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_DATABASE&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; loadDB&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; client&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; MongoClient.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;connect&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(url);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; db&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; client.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;db&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(db_name);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; db;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (err) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(err);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;exports&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; loadDB;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Este módulo realiza lo mismo que en el ejemplo anterior, es decir, abre una conexión a MongoDB, pero lo hace exportando la función asíncrona &lt;code&gt;loadDB&lt;/code&gt; para que pueda ser llamada desde otros módulos con:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; loadDB&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;../services/DB&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; db;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; collection&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;products&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; db &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; loadDB&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;())();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;db.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;collection&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(collection).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;find&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toArray&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;result&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (err) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; err;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(result);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tras cargar &lt;code&gt;loadDB&lt;/code&gt;, declaro la variable de ámbito global &lt;code&gt;db&lt;/code&gt; que contendrá la conexión a la BBDD, y en la línea:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; db &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; loadDB&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;())();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ejecuto la función asíncrona &lt;code&gt;loadDB()&lt;/code&gt; para obtener la conexión que se guardará en &lt;code&gt;db&lt;/code&gt;, y ya puedo hacer la consulta con &lt;code&gt;db.collection(collection).find()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Esta consulta podría formar parte de una ruta de &lt;strong&gt;express&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; express&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; router&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; express.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Router&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; loadDB&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;../services/DB&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; db;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; collection&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;products&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; db &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; loadDB&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;())();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;router.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;/ejemplo&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    db.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;collection&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(collection).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;find&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toArray&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;result&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (err) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; err;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        res.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;json&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(result);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;exports&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; router;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pero claro, esta forma de proceder implica abrir una conexión por cada módulo de rutas que use la función loadDB. No es lo que busco.&lt;/p&gt;
&lt;h1 id=&quot;alternativa-función-callback-al-rescate&quot;&gt;Alternativa: función &lt;em&gt;callback&lt;/em&gt; al rescate&lt;/h1&gt;
&lt;p&gt;¿Qué tal si, en vez de intentar traer a cada módulo la conexión a la BBDD llevo las rutas a la función que abre la conexión directamente mediante una función &lt;em&gt;callback&lt;/em&gt;? Veamos…&lt;/p&gt;
&lt;p&gt;Para que todas las rutas puedan usar la variable &lt;code&gt;db&lt;/code&gt; que se declara cuando se lleva a cabo la conexión, podría establecer una única conexión a la base de datos desde index.js (o app.js) osea, desde el fichero principal de la aplicación &lt;strong&gt;Node.js&lt;/strong&gt;, y referenciar las rutas dentro de una función &lt;em&gt;callback&lt;/em&gt; que le pase al módulo encargado de abrir la conexión.&lt;/p&gt;
&lt;p&gt;Esta idea fue la que me propuso &lt;strong&gt;ZeroBl&lt;/strong&gt;, que se tomó el tiempo de responder a mis preguntas en un foro de Discord, y tras pasarme el código que él usa para establecer su conexión, y buscar un poco más de información en StackOverflow, el resultado fue el siguiente:&lt;/p&gt;
&lt;h2 id=&quot;módulo-de-conexión-a-la-bbdd&quot;&gt;Módulo de conexión a la BBDD&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;NODE_ENV&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;production&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;dotenv&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;config&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; MongoClient&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;mongodb&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).MongoClient;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_HOST&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}:${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;process&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;env&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_PORT&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}/`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; db_name&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_DATABASE&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; _db;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; _client;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; connectDB&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;callback&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        MongoClient.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;connect&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(url, {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            useNewUrlParser: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            useUnifiedTopology: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            _client &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; client;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            _db &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; client.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;db&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(db_name);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; callback&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(err, client);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (err) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        throw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; err;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getDB&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (_db) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; _db;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    throw&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;BBDD no encontrada.&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; disconnectDB&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (_db) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; _client.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    throw&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;BBDD no encontrada.&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;exports&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { connectDB, getDB, disconnectDB };&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Como se aprecia, este módulo devuelve tres funciones: &lt;code&gt;connectDB&lt;/code&gt; que abre la conexión, &lt;code&gt;getDB&lt;/code&gt; que obtiene la conexión a la BBDD, y &lt;code&gt;disconnectDB&lt;/code&gt;, que cierra la conexión a la BBDD.&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;connectDB&lt;/code&gt; le paso un &lt;code&gt;callback&lt;/code&gt; que se ejecutará en el ámbito donde está viva la conexión. Igual deberemos obtener la referencia a &lt;code&gt;_db&lt;/code&gt; en cada módulo que usemos. Lo voy a explicar enseguida.&lt;/p&gt;
&lt;p&gt;Con &lt;code&gt;disconnectDB&lt;/code&gt; puedo cerrar la conexión a la BBDD desde cualquier parte del programa, pero también debo importarlo si queremos usarlo.&lt;/p&gt;
&lt;h2 id=&quot;el-indexjs&quot;&gt;El index.js&lt;/h2&gt;
&lt;p&gt;O cualquier otro js que haga las veces de inicio de nuestra app:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;NODE_ENV&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;production&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;dotenv&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;config&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; express&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; app&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; express&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; port&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;PORT&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; mongoDB&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;./services/DB&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;mongoDB.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;connectDB&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (err) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; err;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Ej. http:localhost:3000/ejemplo&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; RouteEjemplo&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;./routes/ejemplo&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    app.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;/ejemplo&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, RouteEjemplo);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // otras rutas...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Ej. http:localhost:3000/exit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    app.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;/exit&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        client.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        res.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;end&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Fin&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        process.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;kill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(process.pid, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;SIGTERM&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    app.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        res.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;status&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;404&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;send&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Error 404: No encontrado.&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    app.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(err.stack);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; status&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; err.status &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 500&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        res.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;status&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(status).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;send&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;`Error ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;status&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}: ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}.`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; server&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; app.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;listen&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(port, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;`Servidor levantado en el puerto ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}.`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    process.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;SIGTERM&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        server.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Proceso terminado.&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Importo el módulo de &lt;code&gt;mongoDB&lt;/code&gt; y conecto a la BBDD con:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;mongoDB.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;connectDB&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;client&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Función callback&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Función a la que le paso como &lt;em&gt;callback&lt;/em&gt; todo el manejo de rutas, e incluso levanto el servidor. Recuerda que esta función se ejecutará tras establecer la conexión en la línea:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; callback&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(err, client);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Al ejecutar la función obtengo dos posibles valores, o bien un error, o bien el cliente para la conexión. Esto me va a permitir hacer uso del cliente desde la misma función &lt;em&gt;callback&lt;/em&gt;, para, por ejemplo, cerrar la conexión, como ocurre en la ruta &lt;code&gt;/exit&lt;/code&gt; en:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;client.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Usar una ruta para cerrar la aplicación por supuesto es un ejemplo ilustrativo, y no es la mejor forma de hacerlo. ;)&lt;/p&gt;
&lt;p&gt;Si quiero cerrar la aplicación desde dentro de un módulo de, por ejemplo, una ruta, debo usar &lt;code&gt;disconnectDB()&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;la-ruta-de-ejemplo&quot;&gt;La ruta de ejemplo&lt;/h2&gt;
&lt;p&gt;Como dije, para poder utilizar la BBDD en las distintas rutas o en los módulos de la aplicación, debo importar la referencia a &lt;code&gt;db&lt;/code&gt; en cada módulo con:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; mongoDB&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;../services/DB&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; db&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; mongoDB.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getDB&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;y a partir de ahí puedo usar &lt;code&gt;db&lt;/code&gt; en todo el módulo. Así de simple.&lt;/p&gt;
&lt;p&gt;Esto es posible porque, como hemos visto, estamos llamado a esta ruta dentro del &lt;em&gt;callback&lt;/em&gt; que pasamos a la función que abre la conexión.&lt;/p&gt;
&lt;h1 id=&quot;en-resumen&quot;&gt;En resumen&lt;/h1&gt;
&lt;p&gt;Mediante un módulo que devuelve tres funciones podemos abrir la conexión a la BBDD (recibiendo y ejecutando un &lt;em&gt;callback&lt;/em&gt;) obtener la referencia a la BBDD y cerrar la conexión a la BBDD.&lt;/p&gt;
&lt;p&gt;Dentro del &lt;em&gt;callback&lt;/em&gt; definimos las rutas (&lt;code&gt;app.use&lt;/code&gt;) que van a hacer uso de la BBDD, y en cada módulo donde se defina la ruta o las sub-rutas, deberemos obtener la referencia a la BBDD para poder usarla.&lt;/p&gt;
&lt;p&gt;En este &lt;a href=&quot;https://stackoverflow.com/questions/24621940/how-to-properly-reuse-connection-to-mongodb-across-nodejs-application-and-module&quot;&gt;enlace a StackOverflow&lt;/a&gt; (&lt;em&gt;en inglés&lt;/em&gt;) podrás obtener más información y alternativas a esta solución.&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/mongodb.B38n9K_s_1aeGYn.webp"/><category>código</category><category>javascript</category><category>node.js</category><category>express</category><category>mongodb</category><author>JavGuerra</author></item><item><title>Kit básico para manejo del DOM</title><link>https://javguerra.github.io/blog/kit-dom</link><guid isPermaLink="true">https://javguerra.github.io/blog/kit-dom</guid><description>Colección de utilidades para no depender de librerías externas.</description><pubDate>Mon, 25 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/code.BoBme8u9_ZyVCnB.webp&quot; alt=&quot;Código&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#dom&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;El uso del DOM desde JavaScript ha mejorado mucho en los últimos años. Librerías como jQuery facilitaron enormemente la tarea del programador a la hora de acceder a identificadores, clases y etiquetas, y aunque ahora disponemos de nuevas formas de acceso en JavaScript que han hecho olvidar en parte aquella librería, la forma en que trabajamos con el DOM aún se puede mejorar. En esta entrada veremos unas pocas funciones que nos ayudarán en el día a día.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;note&quot;&gt;&lt;strong&gt;Nota&lt;/strong&gt;: Este artículo ha sido publicado también en &lt;a href=&quot;https://ifgeekthen.nttdata.com/s/post/kit-basico-para-manejo-del-dom-MC33VANXA4HFFARH6TCP3P7DTPZY&quot;&gt;IfGeekThen&lt;/a&gt;, el blog de NTT Data, el 24 de abril de 2026.&lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&quot;selección-al-estilo-jquery&quot;&gt;Selección al estilo jQuery&lt;/h1&gt;
&lt;p&gt;Para empezar, un canto a la nostalgia. Si usabas la famosa librería y echas de menos su forma tan simple de funcionar, aquí tienes una aproximación a la selección de elementos del DOM.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; $&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) { &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(el); };&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;o en versión función flecha, como más te guste:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; $&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; el&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(el);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La función &lt;code&gt;$(el)&lt;/code&gt; seleccionará un elemento (&lt;code&gt;el&lt;/code&gt;) del DOM que podemos asignar a una variable o con el que podemos usar propiedades, por ejemplo:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#aviso&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).classList.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;add&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;rojo&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;que añadirá la clase &lt;code&gt;.rojo&lt;/code&gt; al elemento con el id &lt;code&gt;aviso&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;El uso de &lt;code&gt;querySelector()&lt;/code&gt; ha venido a simplificar mucho el acceso a los elementos del DOM, pero con esta función &lt;code&gt;$()&lt;/code&gt;, seleccionar elementos es aún más simple, y va a ser de ayuda en las siguientes funciones.&lt;/p&gt;
&lt;p&gt;Podemos mejorar esta función dándole la posibilidad de buscar dentro de un elemento específico.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; $&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;parent&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; parent.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(el);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Podríamos usarla de esta forma:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; fila&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; $&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#fila3&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, tabla);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Donde &lt;code&gt;tabla&lt;/code&gt; es el elemento padre. De no indicarlo, el elemento padre será todo el documento (document).&lt;/p&gt;
&lt;p&gt;También podemos seleccionar varios elementos con &lt;code&gt;$$()&lt;/code&gt; con esta función:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; $$&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; el&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;querySelectorAll&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(el);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;E igualmente podemos mejorar esto:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; $$&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;parent&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;parent.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;querySelectorAll&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(el)];&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Aquí, además de poder indicar el nodo padre, obtendremos automáticamente el NodeList en un array ([…]).&lt;/p&gt;
&lt;h1 id=&quot;crear-nuevos-elementos-y-conectarlos-al-dom&quot;&gt;Crear nuevos elementos y conectarlos al DOM&lt;/h1&gt;
&lt;p&gt;La creación de nuevos elementos del DOM requiere de varios pasos. Crear el elemento, introducir la información en el elemento si es necesario y conectarlo al elemento padre. ¿Qué tal si lo simplificamos con una función?&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; createEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;parent&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;tag&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; el&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;createElement&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(tag);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (content) el.textContent &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; content;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    parent.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;appendChild&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(el);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; el;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con la función &lt;code&gt;createEl()&lt;/code&gt; cubrimos los tres pasos necesarios para crear, completar y conectar un nuevo elemento, y la función nos devolverá el nuevo elemento para que podamos trabajar con él:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; $titulo&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; createEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;body&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;), &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;h1&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Hola Mundo&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con esta línea crearemos un elemento &lt;code&gt;H1&lt;/code&gt; dentro del &lt;code&gt;body&lt;/code&gt; que contendrá el texto &lt;code&gt;&apos;Hola Mundo&apos;&lt;/code&gt;, y la referencia al nuevo elemento está contenida en la variable &lt;code&gt;$titulo&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;El &lt;code&gt;$&lt;/code&gt; de la variable &lt;code&gt;titulo&lt;/code&gt; no es necesario (ni que estuviésemos programando en PHP…), pero recordando el uso de jQuery, es una buena forma de identificar aquellas variables que hacen referencia a elementos del DOM para diferenciarlas de las otras.&lt;/p&gt;
&lt;p&gt;Esta versión puede mejorarse mucho para, por ejemplo, añadir atributos (attrs) e hijos (children)… hasta donde te de la imaginación.&lt;/p&gt;
&lt;h2 id=&quot;uso-práctico-creación-de-tablas-básicas-con-createel&quot;&gt;Uso práctico: Creación de tablas básicas con createEl()&lt;/h2&gt;
&lt;p&gt;Esta nueva función es muy potente, y simplifica mucho las líneas de código que tenemos que usar para crear estructuras del DOM complejas con JavaScript. Un ejemplo de ello son las tablas y sus etiquetas anidadas. Veamos cómo sería una función que crease una tabla simple con &lt;code&gt;createEl()&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; createTable&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;parent&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;headers&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;footers&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; table&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; createEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(parent, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;table&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    table.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;id&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, id);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; thead&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; createEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(table, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;thead&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; tr &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; createEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(thead, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;tr&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; header&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; headers) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; th&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; createEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(tr, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;th&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, header);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        th.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;scope&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;col&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (footers) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; tfoot&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; createEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(table, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;tfoot&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        tr &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; createEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(tfoot, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;tr&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; footer&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; of&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; footers) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            createEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(tr, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;td&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, footer);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; createEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(table, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;tbody&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La función &lt;code&gt;createTable()&lt;/code&gt; crea una tabla dentro de un elemento padre, le asigna un identificador, y crea las cabeceras y pies que le indiquemos, devolviendo la referencia al elemento &lt;code&gt;tbody&lt;/code&gt; de la tabla para que podamos rellenarla con filas y columnas.&lt;/p&gt;
&lt;p&gt;Un ejemplo sencillo de uso sería:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$tBody &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; createTable&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#section&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;), &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;miTabla&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, [&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;núm.&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;producto&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$tBody.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;1&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;vegetales&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;que mostrará la siguiente tabla a la que podemos seguir añadiendo elementos:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;text-align: center&quot;&gt;núm&lt;/th&gt;
&lt;th style=&quot;text-align: left&quot;&gt;producto&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;text-align: left&quot;&gt;vegetales&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Fácil y cómodo. ¿verdad?&lt;/p&gt;
&lt;h1 id=&quot;vaciar-un-elemento-de-forma-eficiente&quot;&gt;Vaciar un elemento de forma eficiente&lt;/h1&gt;
&lt;p&gt;Vaciar un contenedor con &lt;code&gt;innerHTML = &quot;&quot;&lt;/code&gt; funciona, pero la siguiente función es más eficiente y segura, porque no reemplaza el contenedor entero y no rompe event listeners internos, lo que puede provocar pérdida o duplicación de eventos.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; emptyEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    while&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (el.firstChild) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        el.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;removeChild&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(el.firstChild);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Un ejemplo para borrar el contenido de una lista:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;emptyEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#lista&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;));&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;añadir-o-quitar-una-clase-css&quot;&gt;Añadir o quitar una clase CSS&lt;/h1&gt;
&lt;p&gt;La función:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; toggleClass&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;className&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; el.classList.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toggle&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(className);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;aprovecha el.classList.toggle() para:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Añadir una clase si el elemento no la tiene.&lt;/li&gt;
&lt;li&gt;Quitar una clase si el elemento ya la tiene.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;y devuelve &lt;code&gt;true&lt;/code&gt; si la clase se añadió y &lt;code&gt;false&lt;/code&gt; si la clase se eliminó.&lt;/p&gt;
&lt;p&gt;Esta función es ideal para interacciones de usuario tipo click para abrir/cerrar, expandir/contraer, activar/desactivar.&lt;/p&gt;
&lt;h1 id=&quot;establecer-una-clase-según-un-estado-booleano&quot;&gt;Establecer una clase según un estado booleano&lt;/h1&gt;
&lt;p&gt;La función &lt;code&gt;setClass()&lt;/code&gt; permite añadir o quitar una clase según un booleano, garantizando que el elemento queda exactamente en el estado indicado. A diferencia de &lt;code&gt;toggleClass()&lt;/code&gt;, no alterna: fuerza el estado.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; setClass&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;className&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;active&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    el.classList.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toggle&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(className, active);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ejemplos:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setClass&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(menu, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;open&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// añade la clase&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setClass&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(menu, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;open&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// la quita&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setClass&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(input, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;error&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;isValid&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(input.value)); &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// Estado de error en un formulario&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;tabs.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;tab&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    setClass&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(tab, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;active&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, tab.id &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;===&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; selectedId); &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// Pestaña activa según ID&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esta función es perfecta para sincronizar la UI con estados lógicos (isOpen, hasError, isActive, etc.).&lt;/p&gt;
&lt;h1 id=&quot;mostrar-u-ocultar-elementos-del-dom&quot;&gt;Mostrar u ocultar elementos del DOM&lt;/h1&gt;
&lt;p&gt;Una función que nos aporte una forma simple de hacer visible u ocultar cualquier elemento del DOM, por ejemplo las secciones de una página web de una única página (&lt;strong&gt;SPA&lt;/strong&gt;) sería la siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; showEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;visible&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    visible&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        ?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; el.style.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;removeProperty&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;display&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        :&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; el.style.display &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;none&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La función &lt;code&gt;showEl()&lt;/code&gt; requiere dos parámetros: elemento del DOM con el que vamos a trabajar y si va a estar visible (&lt;code&gt;true&lt;/code&gt;) o invisible (&lt;code&gt;false&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Digamos que en una &lt;strong&gt;SPA&lt;/strong&gt; hemos completado un formulario, y ahora queremos mostrar los resultados. con esta función podríamos:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;showEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#form&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;), &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;showEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#results&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;), &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Partimos de la base de que el elemento con identificador &lt;code&gt;results&lt;/code&gt; estaba oculto, y el elemento con identificador &lt;code&gt;form&lt;/code&gt; visible. De esta forma el formulario se ocultaría y serían visibles los datos derivados de la gestión de formulario.&lt;/p&gt;
&lt;h1 id=&quot;comprobar-si-un-elemento-está-visible&quot;&gt;Comprobar si un elemento está visible&lt;/h1&gt;
&lt;p&gt;Esta función permite saber si un elemento está realmente visible en la página.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; isVisible&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;el&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(el.offsetWidth &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;          el.offsetHeight &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;          el.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getClientRects&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La función &lt;code&gt;showEl()&lt;/code&gt; e &lt;code&gt;isVisible()&lt;/code&gt; se complementan perfectamente porque la primera controla si un elemento se muestra u oculta, y la segunda detecta si un elemento está actualmente visible.&lt;/p&gt;
&lt;p&gt;Veamos un ejemplo de uso conjunto:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;isVisible&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(panel)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    showEl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(panel, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);   &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// lo muestra solo si está oculto&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;activar-o-desactivar-un-botón&quot;&gt;Activar o desactivar un botón&lt;/h1&gt;
&lt;p&gt;Es una buena práctica desactivar un botón cada vez que se dispare un evento asociado a este. Nada más fácil con la siguiente función:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; setInactiveBtn&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;inactive&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    button.disabled &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; inactive;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    inactive&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        ?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; button.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;aria-disabled&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;true&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        :&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; button.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;removeAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;aria-disabled&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con &lt;code&gt;setInactiveBtn()&lt;/code&gt; cambiamos el estado &lt;code&gt;disabled&lt;/code&gt; del botón que indiquemos pasándole los valores &lt;code&gt;true&lt;/code&gt; o &lt;code&gt;false&lt;/code&gt;. Un ejemplo:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; setInactiveBtn&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#submit&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;), &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La función desactivará el botón con el identificador &lt;code&gt;submit&lt;/code&gt; (&lt;code&gt;disabled = true&lt;/code&gt;). Para volver a activarlo, será suficiente con usar la misma función con el status &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;comprobar-si-un-botón-está-activo&quot;&gt;Comprobar si un botón está activo&lt;/h1&gt;
&lt;p&gt;También podemos necesitar conocer el estado de un botón, si este está activo o inactivo.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; isInactiveBtn&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; button.disabled &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;===&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Un ejemplo de uso con &lt;code&gt;setInactiveBtn()&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setInactiveBtn&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(btn, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;isInactiveBtn&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(btn));&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Activa o desactiva el botón invirtiendo su estado actual (si está activo lo desactiva, y si está inactivo lo activa).&lt;/p&gt;
&lt;h1 id=&quot;decodificar-entidades-html-con-ayuda-del-dom&quot;&gt;Decodificar entidades HTML con ayuda del DOM&lt;/h1&gt;
&lt;p&gt;Pasemos ahora a cosas más específicas a modo de bonus.&lt;/p&gt;
&lt;p&gt;Aunque JavaScript incluye funciones como &lt;code&gt;encodeURIComponent()&lt;/code&gt; y &lt;code&gt;decodeURIComponent()&lt;/code&gt;, estas se utilizan exclusivamente para codificar y decodificar URLs, no entidades HTML. Por tanto, una función como esta resulta práctica cuando recibimos cadenas que contienen entidades como &lt;code&gt;&amp;amp;amp;&lt;/code&gt; o &lt;code&gt;&amp;amp;quot;&lt;/code&gt;, ya que el lenguaje no ofrece un método nativo para convertirlas en texto legible. Podemos apoyarnos en el motor del DOM para conseguirlo.&lt;/p&gt;
&lt;p&gt;La siguiente función crea un nodo temporal, asigna su contenido usando &lt;code&gt;innerHTML&lt;/code&gt; y obtiene el texto decodificado mediante &lt;code&gt;textContent&lt;/code&gt;. Es un ejemplo interesante de cómo el DOM puede ayudarnos más allá de la manipulación visual de la página.&lt;/p&gt;
&lt;p&gt;Cuando la función recibe la información codificada con entidades HTML, por ejemplo, a través de una API, y queremos reconducir esa información a, por ejemplo, un fichero de &lt;em&gt;logs&lt;/em&gt; en texto plano, o tal vez enviarla a consola, la información no se muestra correctamente. Una forma de convertir a un &lt;em&gt;string&lt;/em&gt; la información que incluye entidades HTML sería la siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; decodeHTMLEntities&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;typeof&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; html &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; div&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;createElement&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;div&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    div.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; html;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; div.textContent &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La función recibe la cadena a «decodificar» y devuelve la cadena en texto simple. Para ello obliga al DOM a trabajar para nosotros creando un elemento &lt;code&gt;div&lt;/code&gt; en el que se incluye el texto «codificado» y del que se lee luego el texto «decodificado» para devolverlo con &lt;code&gt;return&lt;/code&gt;. Como se ve, el elemento &lt;code&gt;div&lt;/code&gt; nunca llega a conectarse al árbol DOM.&lt;/p&gt;
&lt;p&gt;Tomemos el siguiente ejemplo:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; texto &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; decodeHTMLEntities&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Los%20ni%C3%B1os%20com%C3%ADan%20y%20daban%20migajas%20a%20la%20cig%C3%BCe%C3%B1a.&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;El valor de &lt;code&gt;texto&lt;/code&gt; resultante será: ‘&lt;code&gt;Los niños comían y daban migajas a la cigüeña.&lt;/code&gt;’.&lt;/p&gt;
&lt;h1 id=&quot;iniciar-si-el-dom-está-cargado&quot;&gt;Iniciar si el DOM está cargado&lt;/h1&gt;
&lt;p&gt;Concluyo con una función primordial.&lt;/p&gt;
&lt;p&gt;Con &lt;code&gt;onReady()&lt;/code&gt;, si el DOM ya está cargado, se ejecutará la función de inicio que le pasemos inmediatamente. Si el DOM aún se está cargando, añade un listener a DOMContentLoaded.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; onReady&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;fn&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (document.readyState &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;loading&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        fn&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;DOMContentLoaded&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, fn);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Veamos un ejemplo de uso:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;onReady&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; btn&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; $&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;#btnStart&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    setClass&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(btn, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;ready&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La función &lt;code&gt;onReady()&lt;/code&gt; permite escribir inicialización limpia sin preocuparte por dónde está ubicado el script o de qué forma se carga.&lt;/p&gt;
&lt;h1 id=&quot;tu-propio-kit&quot;&gt;Tu propio kit&lt;/h1&gt;
&lt;p&gt;Espero que alguna de estas funciones te resulte útil, te hagan la vida más agradable y, sobre todo, que te animen a experimentar por tu cuenta.&lt;/p&gt;
&lt;p&gt;El DOM ofrece muchísimas posibilidades, y a veces basta con probar una idea para descubrir una utilidad nueva que encaje contigo y ampliar de esta forma tu kit de herramientas. ¡Diviértete explorando!&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/code.BoBme8u9_ZyVCnB.webp"/><category>código</category><category>javascript</category><category>dom</category><author>JavGuerra</author></item><item><title>Conocer el ancho y alto de una imagen con JavaScript antes de usarla en HTML</title><link>https://javguerra.github.io/blog/ancho-alto</link><guid isPermaLink="true">https://javguerra.github.io/blog/ancho-alto</guid><description>Ideas para evitar el «FOUC» de contenido cuando desconocemos las medidas de las imágenes</description><pubDate>Mon, 01 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/img.BrQ752_Z_Z2rMVCO.webp&quot; alt=&quot;Imagen&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#node.js&lt;/em&gt;, &lt;em&gt;#imágenes&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Cuando una web está cargando, se producen cambios en el diseño conocidos como &lt;em&gt;Flash Of Unestiled Content&lt;/em&gt; (FOUC) que son visualmente molestos para el usuario y le hacen perder su punto de referencia en la página. Las imágenes son uno de los principales causantes de estos cambios. Hasta que no son cargadas no se conoce su ancho y alto, por lo que es un buen criterio de diseño indicar el ancho y alto de la imagen en el HTML. Pero ¿qué ocurre cuando no conocemos las medidas de las imágenes que vamos a cargar? Pongamos como ejemplo una galería de fotos que tomamos mediante fetch. En esta entrada veremos como afrontarlo.&lt;/p&gt;
&lt;h1 id=&quot;el-código&quot;&gt;El código&lt;/h1&gt;
&lt;p&gt;Pongamos que tenemos un arreglo con un listado de URLs de fotos de adorables perritos que queremos mostrar en una galería de fotos. Este arreglo podemos definirlo u obtenerlo mediante &lt;code&gt;fetch&lt;/code&gt; desde una API u otro lugar. Cada imagen tiene un tamaño distinto, osea, unas medidas para los valores &lt;code&gt;width&lt;/code&gt; y &lt;code&gt;height&lt;/code&gt; diferentes. Nuestro objetivo es conocer estos valores antes de mostrar las fotos en la galería, para asignarles su ancho y alto correctos y evitar de esa manera el FUOC. De otra forma, a medida que se carguen las imágenes en la galería, estas irán abriéndose hueco para ocupar su espacio «empujando» el diseño.&lt;/p&gt;
&lt;p&gt;Con este código que seguramente encontré y adapté de StackOverflow o un sitio similar podemos hacerlo. Lo describo más abajo.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; galeria&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;galeria&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; fotos&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &apos;https://images.dog.ceo/breeds/dachshund/Stretched_Dachshund.jpg&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &apos;https://images.dog.ceo/breeds/cattledog-australian/IMG_1211.jpg&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &apos;https://images.dog.ceo/breeds/dachshund/dachshund-7.jpg&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; medidas&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;urlFoto&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; Promise&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;resolve&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;reject&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; img&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Image&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        img.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;onload&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            resolve&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;({ ancho: img.width, alto: img.height });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        img.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;onerror&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            reject&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Imagen no encontrada.&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        img.src &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; urlFoto;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;fotos.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;urlFoto&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    medidas&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(urlFoto)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;mide&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            galeria.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&amp;lt;img src=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;urlFoto&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `width=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;mide&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ancho&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; height=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;mide&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;alto&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `alt=&quot;Foto ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; title=&quot;Foto ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; /&amp;gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(err));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Para usar este código, debemos tener algo como esto en el HTML:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;galeria&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Vamos con JavaScript. Primero defino las variables con las que voy a trabajar. La referencia al elemento del DOM y el arreglo de URLs de fotos de perritos:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; galeria&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;galeria&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; fotos&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &apos;https://images.dog.ceo/breeds/dachshund/Stretched_Dachshund.jpg&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &apos;https://images.dog.ceo/breeds/cattledog-australian/IMG_1211.jpg&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &apos;https://images.dog.ceo/breeds/dachshund/dachshund-7.jpg&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;obtener-las-medidas&quot;&gt;Obtener las medidas&lt;/h2&gt;
&lt;p&gt;Aquí es donde se produce la magia. Veamos como:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; medidas&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;urlFoto&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; Promise&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;resolve&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;reject&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; img&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Image&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        img.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;onload&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            resolve&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;({ ancho: img.width, alto: img.height });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        img.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;onerror&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            reject&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Imagen no encontrada.&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        img.src &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; urlFoto;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esta función recibe como parámetro la URL de la imagen a calcular y envuelve una promesa que resolverá un objeto con las medidas &lt;code&gt;ancho&lt;/code&gt; y &lt;code&gt;alto&lt;/code&gt; o bien un error.&lt;/p&gt;
&lt;p&gt;Para hacerlo, instancio una nueva imagen con &lt;code&gt;const img = new Image();&lt;/code&gt; y declaro dos eventos asociados a &lt;code&gt;img&lt;/code&gt;, un evento que se disparará cuando se cargue la imagen en &lt;code&gt;img&lt;/code&gt; con &lt;code&gt;img.src = urlFoto;&lt;/code&gt; (&lt;code&gt;img.onload&lt;/code&gt;), y otro que se disparará si se produce un error al cargar la imagen (&lt;code&gt;img.onerror&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Es decir, cuando cargo la imagen con &lt;code&gt;img.src = urlFoto;&lt;/code&gt; pueden pasar dos cosas, que se lance el evento &lt;code&gt;onload&lt;/code&gt; si todo fue bien, o el evento &lt;code&gt;onerror&lt;/code&gt; si algo falló.&lt;/p&gt;
&lt;p&gt;Si todo fue bien, la imagen estará «cargada» en &lt;code&gt;img&lt;/code&gt;, y podemos obtener su ancho y alto. Mediante &lt;code&gt;resolve({ ancho: img.width, alto: img.height });&lt;/code&gt; devuelvo estos valores dentro de un objeto.&lt;/p&gt;
&lt;p&gt;Si algo falló, devuelvo un error con &lt;code&gt;reject(new Error(&apos;Imagen no encontrada.&apos;));&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;poner-las-imágenes-en-la-galería&quot;&gt;Poner las imágenes en la galería&lt;/h2&gt;
&lt;p&gt;Si tenemos la función &lt;code&gt;medidas()&lt;/code&gt; a la que podemos pasarle una URL, podemos recorrer el arreglo &lt;code&gt;fotos&lt;/code&gt; y poner en nuestro HTML cada foto con sus medidas exactas:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;fotos.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;urlFoto&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    medidas&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(urlFoto)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;mide&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            galeria.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&amp;lt;img src=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;urlFoto&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `width=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;mide&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ancho&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; height=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;mide&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;alto&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `alt=&quot;Foto ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; title=&quot;Foto ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; /&amp;gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        })&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(err));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mediante un &lt;code&gt;.forEach()&lt;/code&gt; recorro cada elemento del arreglo. De él obtengo dos valores, cada una de las URLs y el índice que ocupa en el arreglo cada URL.&lt;/p&gt;
&lt;p&gt;Llamo a la función &lt;code&gt;medidas()&lt;/code&gt; a la que le paso como parámetro la URL de una foto (&lt;code&gt;urlFoto&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;La función devuelve una promesa que debe ser resuelta. Así mediante &lt;code&gt;.then()&lt;/code&gt; obtengo el objeto &lt;code&gt;mide&lt;/code&gt; que contiene el ancho y el alto de la imagen que indiqué mediante la URL, que es el resultado del &lt;code&gt;resolve&lt;/code&gt; de la promesa. De otra forma, con &lt;code&gt;.catch()&lt;/code&gt; se captura el error resultante del &lt;code&gt;reject&lt;/code&gt; de la promesa.&lt;/p&gt;
&lt;p&gt;Si tenemos las medidas de ancho y alto de la imagen a mostrar, ya podemos conectarla al DOM con:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;galeria.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&amp;lt;img src=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;urlFoto&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `width=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;mide&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;ancho&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; height=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;mide&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;alto&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `alt=&quot;Foto ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; title=&quot;Foto ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot; /&amp;gt;`&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esto insertará en el elemento del DOM identificado con &lt;code&gt;#galeria&lt;/code&gt; una imagen (&lt;code&gt;img&lt;/code&gt;) con el enlace a la foto (&lt;code&gt;src&lt;/code&gt;), su ancho (&lt;code&gt;width&lt;/code&gt;), alto (&lt;code&gt;height&lt;/code&gt;) y una etiqueta &lt;code&gt;alt&lt;/code&gt; que «describe» (vagamente) la foto. Con &lt;code&gt;title&lt;/code&gt; podemos obtener la misma descripción al pasar con el ratón sobre la imagen.&lt;/p&gt;
&lt;p&gt;Por supuesto a la imagen podemos aplicarle las clases CSS que deseemos para, por ejemplo, que aparezca correctamente si usamos flexbox o similar para mostrar la galería…&lt;/p&gt;
&lt;h1 id=&quot;el-módulo-image-size&quot;&gt;El módulo image-size&lt;/h1&gt;
&lt;p&gt;Si realizamos el test &lt;a href=&quot;https://pagespeed.web.dev/&quot;&gt;Page Speed de Google&lt;/a&gt; a nuestra página y no indicamos el ancho y alto de las imágenes, esto nos penalizará en la puntuación de viabilidad en el apartado &lt;em&gt;&lt;code&gt;Cumulative Layout Shift&lt;/code&gt;&lt;/em&gt; o &lt;code&gt;CLS&lt;/code&gt;. El «movimiento inesperado de contenido» en español, mide la estabilidad visual cuantificando la frecuencia con la que los usuarios experimentan cambios de diseño inesperados. Así pues, cuanto más bajo sea el CLS, mejor.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Manz&lt;/strong&gt;, de &lt;a href=&quot;https://manz.dev/&quot;&gt;manz.dev&lt;/a&gt;, en su canal de &lt;a href=&quot;https://discord.manz.dev/&quot;&gt;Discord&lt;/a&gt;, cuenta lo siguiente:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;El navegador nunca va a saber las dimensiones (ancho y alto) de la imagen hasta descargar la imagen. Si la imagen es pesada va a tardar un rato y no es posible “reservar” ese espacio en la web porque no lo conoce. La única forma de evitar el CLS es indicarle tú previamente el tamaño para que no haya “salto”.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Mediante la opción propuesta, podemos resolver este problema si somos nosotros los que desarrollamos todo el código, pero si estamos trabajando con &lt;em&gt;frameworks&lt;/em&gt;, también hay soluciones disponibles. &lt;strong&gt;Manz&lt;/strong&gt; sigue diciendo:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hay una forma de evitarlo, si estás usando SSG (eleventy, astro, next, etc…) y es que en la fase de “compilación” le pases algún plugin que vaya mirando las imágenes y sacando sus dimensiones con node y añadiendo automáticamente el width y height. Yo, por ejemplo, uso este: &lt;a href=&quot;https://www.npmjs.com/package/image-size&quot;&gt;image-size&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Como indica &lt;strong&gt;Manz&lt;/strong&gt;, &lt;a href=&quot;https://www.npmjs.com/package/image-size&quot;&gt;image-size&lt;/a&gt; es una opción que permite obtener las dimensiones de una imagen y que podemos instalar con npm.&lt;/p&gt;
&lt;h1 id=&quot;un-truco&quot;&gt;Un truco&lt;/h1&gt;
&lt;p&gt;Em Twitter &lt;strong&gt;Manz&lt;/strong&gt; contaba:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Otras soluciones más simples e ingeniosas pueden ser establecer un alto máximo para el contenedor, de modo que no haga reflow de elementos inferiores, y los items del interior (galería) los vas haciendo aparecer a medida que se carguen con CSS/JS.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Esta, sin duda, es otra opción.&lt;/p&gt;
&lt;h1 id=&quot;resumen&quot;&gt;Resumen&lt;/h1&gt;
&lt;p&gt;En Twitter, &lt;strong&gt;Manz&lt;/strong&gt; proponía también estas tres opciones para evitar el &lt;em&gt;reflow&lt;/em&gt; que podemos tomar a modo de resumen:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;Establecer siempre el width y height (tedioso)&lt;/li&gt;
&lt;li&gt;Usar aspect-ratio de CSS (&lt;a href=&quot;https://caniuse.com/mdn-css_properties_aspect-ratio&quot;&gt;https://caniuse.com/mdn-css_properties_aspect-ratio&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Automatizar con alguna herramienta de preprocesado. Yo en 11ty uso image-size o soluciones parecidas&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Ejemplo de uso de la solución propuesta: &lt;a href=&quot;https://javguerra.github.io/ejercicios-web-javascript/17-fetch.html&quot;&gt;Galería de perritos&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Módulo &lt;a href=&quot;https://www.npmjs.com/package/image-size&quot;&gt;image-size&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pagespeed.web.dev/&quot;&gt;Page Speed de Google&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.itdo.com/blog/que-es-el-cumulative-layout-shift-cls/&quot;&gt;¿Qué es el Cumulative Layout Shift (CLS)?&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Twitter de @Manz: &lt;a href=&quot;https://twitter.com/Manz/status/1527681719964512256&quot;&gt;¿Qué es «FUOC»?&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Web de @Manz: &lt;a href=&quot;https://manz.dev/&quot;&gt;manz.dev&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/img.BrQ752_Z_Z2rMVCO.webp"/><category>código</category><category>javascript</category><category>node.js</category><category>imágenes</category><author>JavGuerra</author></item><item><title>Mastermind en PHP</title><link>https://javguerra.github.io/blog/mastermind</link><guid isPermaLink="true">https://javguerra.github.io/blog/mastermind</guid><description>Programado en una sola página web, sin usar librerías</description><pubDate>Sat, 06 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/mastermind.C8GKrbMY_hnLY5.webp&quot; alt=&quot;Mastermind&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#php&lt;/em&gt;, &lt;em&gt;#juego&lt;/em&gt;, &lt;em&gt;#formularios&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Este juego interactúa con el usuario y pasa parámetros mediante POST a través de un formulario. El reto es hacerlo de tal forma que esos parámetros sean recibidos y procesados en la misma página que los envió, por lo tanto, la página debe contener toda la operativa de los distintos escenarios posibles del juego: al iniciar el juego, tras una tirada, si se producen errores, si se termina el juego… Veamos cómo.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://badared.com/javguerra/daw/mastermind/&quot;&gt;&lt;button&gt;Probar el juego&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;el-juego&quot;&gt;El juego&lt;/h1&gt;
&lt;p&gt;Mastermind es un juego simple. Se trata de adivinar un número de 4 dígitos distintos (no repetidos). Cada dígito tendrá un valor entre 0 y 9. A través de un formulario, introducimos los cuatro dígitos. Al enviar el formulario recibiremos la respuesta de cuantos dígitos hemos acertado, o si hemos acertado el número completo con los dígitos en su orden correcto.&lt;/p&gt;
&lt;p&gt;Si un dígito está en su posición correcta dentro del número, se contabilizará como un «muerto». Con cuatro muertos ganamos el juego, es decir, habremos acertado el número.&lt;/p&gt;
&lt;p&gt;Si un dígito forma parte del número de cuatro dígitos, pero su posición en él no es la correcta, se contabilizará como un «herido». Esto nos permitirá sospechar que vamos por buen camino, y podremos probar nuevas combinaciones.&lt;/p&gt;
&lt;p&gt;Para enviar el formulario debemos completar las casillas con los cuatro dígitos.&lt;/p&gt;
&lt;p&gt;Para iniciar otra partida, ya sea a mitad de jugada o tras haber ganado, es suficiente con recargar la página sin enviar el formulario.&lt;/p&gt;
&lt;h1 id=&quot;escenarios&quot;&gt;Escenarios&lt;/h1&gt;
&lt;p&gt;Dado que tenemos un juego en una SPA (&lt;em&gt;Simple Page Aplication&lt;/em&gt;), la lógica del juego tiene que estar contenida en ella al completo, y mediante condicionales, actuar de una forma u otra según sea el caso. Estos casos son:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;La primera vez que accedemos a la página del juego.&lt;/li&gt;
&lt;li&gt;La recepción de datos y comprobaciones tras una tirada.&lt;/li&gt;
&lt;li&gt;Cuando el juego ha terminado: Se ha averiguado el número.&lt;/li&gt;
&lt;li&gt;Enviar datos y comprobar si hay errores en el formulario.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Puedes ver el código del juego completo al final de esta entrada.&lt;/p&gt;
&lt;p&gt;Veamos cada escenario y su correspondiente código. Obviaré en esta entrada los estilos CSS que son incluidos en el &lt;code&gt;head&lt;/code&gt; de la página. Pero antes, vamos con el formulario.&lt;/p&gt;
&lt;h2 id=&quot;formulario&quot;&gt;Formulario&lt;/h2&gt;
&lt;p&gt;El formulario es simple. Emplea una serie de campos ocultos, que veremos después, para pasar la información recabada del formulario (los 4 dígitos) y de las tiradas anteriores en el juego. Su estructura será:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;input&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; action&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;?php echo $_SERVER[&apos;PHP_SELF&apos;];?&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; method&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;post&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    // Campos ocultos&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    // Campos de formulario (4 input)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    // Comprobaciones de error de cada campo input&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;submit&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;enviar&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;boton&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Enviar&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con &lt;code&gt;&amp;lt;?php echo $_SERVER[&apos;PHP_SELF&apos;];?&amp;gt;&lt;/code&gt; indico la dirección donde debo enviar (mediante POST) el resultado del formulario, en este caso la misma página (&lt;code&gt;PHP_SELF&lt;/code&gt;), esté en la ruta que esté.&lt;/p&gt;
&lt;p&gt;Con &lt;code&gt;name=&quot;enviar&quot;&lt;/code&gt; podré indicar si estoy enviando los datos del formulario. Empleando el botón &lt;code&gt;submit&lt;/code&gt; tengo esa garantía, ya que es el medio de que dispongo (el botón) para hacer justamente el envío.&lt;/p&gt;
&lt;h2 id=&quot;1-empezando-a-jugar&quot;&gt;1. Empezando a jugar&lt;/h2&gt;
&lt;p&gt;Empiezo averiguando si he recibido algún dato del formulario. Si no es así es que estamos ante la primera tirada.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;php&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$enviado &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; isset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($_POST[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;enviar&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$muertos &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$mostrarNum &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ($enviado) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Procesar los datos recibidos del formulario&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;} &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Generar un número al azar de cuatro dígitos no repetidos&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    $numero &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; range&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    shuffle&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numero);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    $numero &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; array_slice&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numero, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    $numero &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; implode&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numero);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con &lt;code&gt;isset($_POST[&apos;enviar&apos;])&lt;/code&gt; obtengo &lt;code&gt;true&lt;/code&gt; si he recibido datos del formulario (el valor asociado al botón submit) o &lt;code&gt;false&lt;/code&gt; en caso contrario. La variable &lt;code&gt;$enviado&lt;/code&gt; contendrá ese valor booleano que determinará que rumbo tomará el programa. &lt;code&gt;$_POST[&apos;enviar&apos;]&lt;/code&gt; nos lo dirá si contiene el valor &lt;code&gt;&quot;Enviar&quot;&lt;/code&gt; recibido del formulario (&lt;code&gt;value=&quot;Enviar&quot;&lt;/code&gt;) o no.&lt;/p&gt;
&lt;p&gt;Inicializo la variable &lt;code&gt;$muertos&lt;/code&gt; que contendrá el número de dígitos acertados en su posición correcta. Al principio será 0, porque aún no hay aciertos. Usaré esta variable como condicional más adelante.&lt;/p&gt;
&lt;p&gt;La variable &lt;code&gt;$mostrarNum&lt;/code&gt; es un &lt;em&gt;swich&lt;/em&gt; que me provee de una característica del juego, la de mostrar o no un interrogante en pantalla. Al pasar con el ratón sobre este interrogante puedo comprobar el número que estoy intentando acertar. Esta opción se implementó para hacer comprobaciones durante el desarrollo, pero ha quedado como una característica. Pon la variable en &lt;code&gt;false&lt;/code&gt; si sientes que vas a tener la tentación de hacer trampas…&lt;/p&gt;
&lt;p&gt;Esta ayuda se mostrará en el programa con la siguiente línea:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;php&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ($mostrarNum) &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&amp;lt;dfn id=&apos;numero&apos; title=&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$numero&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;&amp;gt;?&amp;lt;/dfn&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\n\n&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con la comprobación &lt;code&gt;if ($enviado)&lt;/code&gt;, como decía, discrimino si debo procesar los datos recibidos del formulario o por el contrario debo inicializar el juego. El número de cuatro dígitos a averiguar es lo que necesito en este caso. Para obtenerlo al azar, empleo lo siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;php&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$numero &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; range&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;shuffle&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numero);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$numero &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; array_slice&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numero, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$numero &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; implode&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numero);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En el arreglo &lt;code&gt;$numero&lt;/code&gt; introduzco los dígitos del 0 al 9 con &lt;code&gt;range()&lt;/code&gt;, y luego los mezclo (altero su posición en el arreglo) con &lt;code&gt;shuffle()&lt;/code&gt;. Con &lt;code&gt;array_slice()&lt;/code&gt; recorto el arreglo para que contenga sólo los cuatro primeros elementos, osea, los cuatro dígitos al azar. Finalmente, con &lt;code&gt;implode()&lt;/code&gt; concateno esos cuatro elementos en uno, siendo ahora &lt;code&gt;$numero&lt;/code&gt; una cadena de cuatro caracteres.&lt;/p&gt;
&lt;p&gt;Podría haber obtenido un número al azar entre &lt;code&gt;0&lt;/code&gt; y &lt;code&gt;9999&lt;/code&gt; con &lt;code&gt;rand()&lt;/code&gt; o incluso con &lt;code&gt;mt_rand()&lt;/code&gt;, pero esto conllevaría conversiones de número a cadena, rellenado de &lt;code&gt;0&lt;/code&gt; a la izquierda si el número obtenido al azar es menor que 1000, y comprobar que cada dígito sea distinto. Esta solución propuesta es más divertida e imaginativa, ¿verdad?&lt;/p&gt;
&lt;h2 id=&quot;2-recibiendo-datos-del-formulario&quot;&gt;2. Recibiendo datos del formulario&lt;/h2&gt;
&lt;p&gt;Desde el formulario recibimos los siguientes valores:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;El número que estamos intentando averiguar para poder hacer comprobaciones&lt;/li&gt;
&lt;li&gt;Los cuatro dígitos que hemos introducido en el formulario.&lt;/li&gt;
&lt;li&gt;El arreglo con las tiradas que hemos realizado hasta ahora. En la primera tirada no contendrá nada.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Veamos cómo recuperar y procesar los datos recibidos:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;php&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ($enviado) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Recuperar número&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;isset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($_POST[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;numero&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;])) $numero &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $_POST[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;numero&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Recuperar dígitos&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;isset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($_POST[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;d1&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;])) $d1 &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $_POST[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;d1&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;isset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($_POST[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;d2&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;])) $d2 &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $_POST[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;d2&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;isset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($_POST[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;d3&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;])) $d3 &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $_POST[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;d3&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;isset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($_POST[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;d4&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;])) $d4 &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $_POST[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;d4&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Recuperar $tiradas[]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;isset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($_POST[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;tiradas&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;])) $tiradas &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $_POST[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;tiradas&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;validaEntero&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($d1) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; validaEntero&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($d2) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; validaEntero&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($d3) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; validaEntero&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($d4)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        $numEnviado &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $d1 &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $d2 &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $d3 &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $d4;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        // Comprobar datos entrantes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        $muertos &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; numMuertos&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numero, $numEnviado);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        $heridos &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; numHeridos&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numero, $numEnviado, $muertos);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        // Añadir tirada&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        $tiradas[] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; array&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numEnviado, $muertos, $heridos);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;} &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Generar un número al azar de cuatro dígitos no repetidos&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si cierta variable está presente, obtengo su valor. Por ejemplo con:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;php&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;isset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($_POST[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;numero&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;])) $numero &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $_POST[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;numero&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cuando he recuperado el resto de valores, hago una comprobación básica por cada uno de los 4 dígitos recibidos con la función &lt;code&gt;validaEntero()&lt;/code&gt;. Esta función hace lo siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;php&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// Validar un número entero entre 0 y 9, ambos inclusive&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; validaEntero&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numero) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; isset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numero) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; ctype_digit&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numero) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $numero &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 9&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $numero &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Devuelve &lt;code&gt;true&lt;/code&gt; o &lt;code&gt;false&lt;/code&gt; si el dígito que le pasamos es un número entre 0 y 9 o no.&lt;/p&gt;
&lt;p&gt;De esta forma, podemos usarlo para tratar y obtener el número enviado:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;php&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;validaEntero&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($d1) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; validaEntero&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($d2) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; validaEntero&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($d3) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; validaEntero&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($d4)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        $numEnviado &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $d1 &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $d2 &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $d3 &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $d4;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        // Comprobar datos entrantes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        // Añadir tirada&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si los cuatro dígitos validan, en la cadena &lt;code&gt;$numEnviado&lt;/code&gt; guardo el número de cuatro dígitos que estoy probando en esta jugada.&lt;/p&gt;
&lt;p&gt;Compruebo a continuación el total de muertos y heridos a partir de ese dato.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;php&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// Comprobar datos entrantes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$muertos &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; numMuertos&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numero, $numEnviado);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$heridos &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; numHeridos&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numero, $numEnviado, $muertos);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Las funciones &lt;code&gt;numMuertos()&lt;/code&gt; y &lt;code&gt;numHeridos()&lt;/code&gt; calcularán los aciertos:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;php&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// Calcular el número de muertos&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; numMuertos&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numero, $numEnviado) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    $contador &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    $l &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; strlen&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numero);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; $i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $l; $i&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;substr&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numero, $i, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; substr&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numEnviado, $i, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)) $contador&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $contador;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// Calcular el número de heridos&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; numHeridos&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numero, $numEnviado, $muertos) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    $contador &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    $l &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; strlen&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numero);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; $i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $l; $i&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;strpos&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numEnviado, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;substr&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numero, $i, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) $contador&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $contador &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $muertos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La función &lt;code&gt;numMuertos()&lt;/code&gt; comparará los valores de cada posición de los caracteres de cada una de las dos cadenas, el número que intentamos averiguar y el numero que hemos enviado por el formulario. Con cada coincidencia,el &lt;code&gt;$contador&lt;/code&gt; se incrementa en 1. La función devuelve el número de coincidencias exactas, osea, el número de muertos.&lt;/p&gt;
&lt;p&gt;La función &lt;code&gt;numHeridos()&lt;/code&gt; por otra parte, recorre los caracteres del número que hemos enviado y comprueba si están contenido en el número que debemos acertar. Si es así el &lt;code&gt;$contador&lt;/code&gt; se incrementa en 1. La función devuelve la diferencia entre el número de heridos y el número de muertos, ya que los aciertos en esta función no discriminan si los valores coincidentes están en su posición correcta o no, y los contabiliza como heridos, cuando puede que realmente estos valores sean muertos, y estos ya estaban contabilizados en la variable &lt;code&gt;$muertos&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Cuando tenemos los datos, ya podemos añadir el resultado a la lista de tiradas:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;php&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// Añadir tirada&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;$tiradas[] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; array&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($numEnviado, $muertos, $heridos);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;El arreglo &lt;code&gt;$tiradas[]&lt;/code&gt; contendrá un arreglo por cada tirada que almacenará el número que enviamos, el numero de muertos y el número de heridos obtenido.&lt;/p&gt;
&lt;h2 id=&quot;3-el-juego-terminó&quot;&gt;3. ¿El juego terminó?&lt;/h2&gt;
&lt;p&gt;Pero ¿habremos acertado el número? Vamos a comprobarlo.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;php&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ($enviado &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $muertos &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 4&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) { &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Partida finalizada&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    echo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\t\t&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;lt;br /&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\n\t\t&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&amp;lt;h3&amp;gt;¡¡¡Enhorabuena!!! Has acertado el número &quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $numero &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot; en &quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; count&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($tiradas) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot; jugadas.&amp;lt;/h3&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;} &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Seguir jugando&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;isset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($tiradas)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    foreach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ($tiradas &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $indice &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $valor) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;        echo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\t\t&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&amp;lt;p&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ($indice &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;. Con el número introducido: &quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $valor[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;, tienes &quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $valor[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot; muertos y &quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $valor[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot; heridos.&amp;lt;/p&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// Formulario&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si tengo cuatro muertos, ¡he ganado!. habré acertado el número en una serie de intentos que muestro con &lt;code&gt;count($tiradas)&lt;/code&gt;. En caso contrario, sigo jugando.&lt;/p&gt;
&lt;p&gt;Si hay tiradas &lt;code&gt;if (isset($tiradas))&lt;/code&gt; muestro los datos de cada una de ellas con un &lt;code&gt;foreach&lt;/code&gt;: número introducido, muertos y heridos de cada tirada, y a continuación muestro el formulario para seguir intentándolo.&lt;/p&gt;
&lt;h2 id=&quot;4-el-formulario-completo-y-sus-comprobaciones&quot;&gt;4. El formulario completo y sus comprobaciones&lt;/h2&gt;
&lt;p&gt;Aquí el código que iré desgranado y que va dentro de la comprobación anterior, en el &lt;code&gt;else&lt;/code&gt;, en caso de que no acertara el número:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Introduce tu número:&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;input&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; action&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;?php echo $_SERVER[&apos;PHP_SELF&apos;];?&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; method&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;post&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    &amp;lt;!-- Campos ocultos --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;?php&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        echo &apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hidden&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;numero&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&apos; . $numero . &apos;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&apos; . &quot;\n&quot;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        if ($enviado &amp;amp;&amp;amp; !empty($tiradas)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            foreach ($tiradas as $indice =&amp;gt; $valor){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                echo &quot;\n\t\t\t&quot; .&apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hidden&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;tiradas[&apos; . $indice . &apos;][0]&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&apos; . $valor[0] . &apos;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&apos; . &quot;\n&quot;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                echo &quot;\t\t\t&quot; .&apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hidden&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;tiradas[&apos; . $indice . &apos;][1]&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&apos; . $valor[1] . &apos;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&apos; . &quot;\n&quot;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                echo &quot;\t\t\t&quot; .&apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hidden&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;tiradas[&apos; . $indice . &apos;][2]&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&apos; . $valor[2] . &apos;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&apos; . &quot;\n&quot;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ?&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    &amp;lt;!-- Dígito 1 --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;d1&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;campo&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; min&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; max&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;9&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; validaEntero($d1)) echo $d1; ?&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; required&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; !validaEntero($d1)) echo &apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alerta&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;larr;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&apos;.&quot;\n&quot; ?&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    &amp;lt;!-- Dígito 2 --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;d2&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;campo&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; min&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; max&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;9&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; validaEntero($d2)) echo $d2; ?&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; required&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; !validaEntero($d2)) echo &apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alerta&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;larr;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&apos;.&quot;\n&quot; ?&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    &amp;lt;!-- Dígito 3 --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;d3&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;campo&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; min&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; max&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;9&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; validaEntero($d3)) echo $d3; ?&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; required&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; !validaEntero($d3)) echo &apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alerta&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;larr;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&apos;.&quot;\n&quot; ?&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    &amp;lt;!-- Dígito 4 --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;d4&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;campo&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; min&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; max&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;9&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; validaEntero($d4)) echo $d4; ?&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; required&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; !validaEntero($d4)) echo &apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alerta&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;larr;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&apos;.&quot;\n&quot; ?&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    &amp;lt;!-- Enviar --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    &amp;amp;nbsp;&amp;amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;submit&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;enviar&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;boton&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Enviar&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ya expliqué, más arriba, los parámetros de &lt;code&gt;form&lt;/code&gt; y el envío del formulario. Entendido esto, el formulario tiene tres cuestiones de interés.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Preparar los datos que se enviarán en el formulario, incluyendo los que llegaron a través del anterior formulario.&lt;/li&gt;
&lt;li&gt;Recibir los datos en los cuatro campos &lt;code&gt;input&lt;/code&gt; para ser enviados. En cada campo deberá estar el valor de cada dígito recibido del formulario anterior. Las características de HTML se ocupan de que los valores introducidos estén en rango antes de enviarse, pero aún así podemos recibir datos alterados por &lt;code&gt;POST&lt;/code&gt;, luego:&lt;/li&gt;
&lt;li&gt;Comprobar que los datos recibidos sean los correctos, y si no, reseñar el error.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;41-campos-ocultos&quot;&gt;4.1. Campos ocultos&lt;/h3&gt;
&lt;p&gt;En esta parte del formulario, completo los distintos campos ocultos con información necesaria para la siguiente tirada: el número a acertar, y cada uno de los arreglos de cada tirada anterior, conteniendo el número que enviamos en la tirada, el número de muertos y el número de heridos.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;php&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;!--&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; Campos&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; ocultos&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;php&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;    echo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&amp;lt;input type=&quot;hidden&quot; name=&quot;numero&quot; value=&quot;&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $numero &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&quot; /&amp;gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ($enviado &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;empty&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($tiradas)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        foreach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ($tiradas &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $indice &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $valor){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            echo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\n\t\t\t&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;&amp;lt;input type=&quot;hidden&quot; name=&quot;tiradas[&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $indice &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;][0]&quot; value=&quot;&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $valor[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&quot; /&amp;gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            echo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\t\t\t&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;&amp;lt;input type=&quot;hidden&quot; name=&quot;tiradas[&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $indice &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;][1]&quot; value=&quot;&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $valor[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&quot; /&amp;gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            echo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\t\t\t&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;&amp;lt;input type=&quot;hidden&quot; name=&quot;tiradas[&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $indice &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;][2]&quot; value=&quot;&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $valor[&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&quot; /&amp;gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Véase que cada tirada debe incluirse con sus correspondientes valores como &lt;code&gt;input&lt;/code&gt;  ocultos por separado en el cuerpo de la página, ya que no podemos pasar un arreglo como valor de un campo de un formulario. Afortunadamente, sí podemos recibir estas tiradas como un arreglo para tratarlas. Recuerda, como vimos antes:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;php&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// Recuperar $tiradas[]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;isset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($_POST[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;tiradas&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;])) $tiradas &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $_POST[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;tiradas&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;];&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;42-recibir-los-datos-de-los-input&quot;&gt;4.2. Recibir los datos de los input&lt;/h3&gt;
&lt;p&gt;El código para los cuatro campos &lt;code&gt;input&lt;/code&gt; es el siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;&amp;lt;!-- Dígito 1 --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;d1&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;campo&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; min&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; max&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;9&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; validaEntero($d1)) echo $d1; ?&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; required&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; !validaEntero($d1)) echo &apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alerta&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;larr;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&apos;.&quot;\n&quot; ?&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;&amp;lt;!-- Dígito 2 --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;d2&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;campo&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; min&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; max&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;9&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; validaEntero($d2)) echo $d2; ?&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; required&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; !validaEntero($d2)) echo &apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alerta&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;larr;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&apos;.&quot;\n&quot; ?&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;&amp;lt;!-- Dígito 3 --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;d3&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;campo&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; min&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; max&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;9&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; validaEntero($d3)) echo $d3; ?&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; required&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; !validaEntero($d3)) echo &apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alerta&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;larr;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&apos;.&quot;\n&quot; ?&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;&amp;lt;!-- Dígito 4 --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;d4&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;campo&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; min&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; max&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;9&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; validaEntero($d4)) echo $d4; ?&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; required&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; !validaEntero($d4)) echo &apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alerta&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;larr;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&apos;.&quot;\n&quot; ?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mediante este código, repetido en cada &lt;code&gt;input&lt;/code&gt; (convenientemente modificado), muestro el valor de cada dígito recibido de la jugada anterior, si esta se produjo. Sino no muestro nada.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;value=&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; validaEntero($d1)) echo $d1; ?&amp;gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;43-si-hay-error-en-los-datos-recibidos-resaltarlo&quot;&gt;4.3. Si hay error en los datos recibidos, resaltarlo&lt;/h3&gt;
&lt;p&gt;Para asegurarnos que los dígitos que recibimos del formulario anterior son correctos, es necesario comprobarlos de nuevo del lado del servidor (ahora con PHP), aunque ya lo hiciéramos con las funcionalidades de HTML. Esto garantiza que los datos no fueron alterados en el envío mediante, tal vez, una modificación de la fuente HTML a través de las herramientas del navegador.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;php&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ($enviado &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;validaEntero&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;($d1)) &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&amp;lt;span class=&quot;alerta&quot;&amp;gt; &amp;amp;larr;&amp;lt;/span&amp;gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con este código tras cada campo, señalaremos aquellos campos &lt;code&gt;input&lt;/code&gt; que contengan un error, en este caso añadiendo una flecha (←) y pintándola de color rojo con la clase CSS &lt;code&gt;alerta&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Completado el formulario, con sus campos ocultos y los datos de todos los input, -que son campos obligatorios y tienen rangos numéricos definidos-, ya podemos enviarlo (botón &lt;code&gt;sent&lt;/code&gt;) a la misma página para ser procesados tal como se indicó en el &lt;strong&gt;punto 2&lt;/strong&gt; de esta entrada, y así hasta acertar el número o hasta que recarguemos la página, caso en el que empezaremos de cero, en el &lt;strong&gt;punto 1&lt;/strong&gt; de esta entrada.&lt;/p&gt;
&lt;h1 id=&quot;el-programa-completo&quot;&gt;El programa completo&lt;/h1&gt;
&lt;p&gt;El HTML con el código PHP completo es el siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;DOCTYPE&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; html&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; lang&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;es&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; charset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;UTF-8&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;viewport&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; content&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;width=device-width, user-scalable=no&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Mastermind&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; content&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Mastermind&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;keywords&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; content&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;DWES, DAW, Juego, Tarea 2&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;author&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; content&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Javier Guerra&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;license&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; content&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;CC-BY&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; content&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;2019-01-31&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; scheme&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;YYYY-MM-DD&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;        html&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;padding&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;margin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;font-family&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;sans-serif&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;font-weight&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;300&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;background-color&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;#efeffb&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.contenedor&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;margin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;25&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; auto&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;padding&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 20&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 20&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;max-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;border-radius&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;background-color&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;#FFF&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;-webkit-box-shadow&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; rgba&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.10&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;-moz-box-shadow&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; rgba&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.10&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;box-shadow&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; rgba&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.10&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)}&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@media&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;min-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1023&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;){&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.contenedor&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;padding&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 30&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 30&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;67&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}}&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@media&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;min-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1215&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;){&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.contenedor&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;padding&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 40&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 40&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}}&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;#numero&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;display&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;block&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;text-align&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;right&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;margin-top&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;margin-bottom&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;color&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;#1883ba&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;margin-top&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;margin-bottom&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;color&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;#1883ba&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;margin-top&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;margin-bottom&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;hr&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;border&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;margin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;background-image&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;linear-gradient&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;to&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; right&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;rgba&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0.50&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;rgba&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;))}&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.campo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.boton&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;margin-top&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;padding&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;font-weight&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;600&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;font-size&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;16&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;border-radius&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;border&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; solid&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; #1883ba&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;color&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;#1883ba&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.campo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;64&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.boton&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;128&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;text-decoration&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;color&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;#fff&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;background-color&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;#1883ba&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.boton:hover&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;color&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;#1883ba&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;background-color&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;#efeffb&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;#autor&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;display&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;block&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;text-align&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;center&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;font-size&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;small&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;margin-bottom&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;25&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.alerta&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;color&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;red&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;contenedor&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;?php&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        $enviado = isset($_POST[&apos;enviar&apos;]);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        $muertos = 0;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        $mostrarNum = true;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        // Calcular el número de muertos&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        function numMuertos($numero, $numEnviado) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            $contador = 0;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            $l = strlen($numero);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            for($i = 0; $i &lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $l; $i++) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                if (substr($numero, $i, 1) == substr($numEnviado, $i, 1)) $contador++;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            return $contador;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        // Calcular el número de heridos&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        function numHeridos($numero, $numEnviado, $muertos) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            $contador = 0;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            $l = strlen($numero);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            for($i = 0; $i &lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; $l; $i++) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                if (strpos($numEnviado, substr($numero, $i, 1)) !== false) $contador++;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            return $contador - $muertos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        // Validar un número entero entre 0 y 9, ambos inclusive&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        function validaEntero($numero) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            return isset($numero) &amp;amp;&amp;amp; ctype_digit($numero) &amp;amp;&amp;amp; $numero &lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;= 9 &amp;amp;&amp;amp; $numero &amp;gt;= 0;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;         &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        if ($enviado) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            // Recuperar número&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            if (isset($_POST[&apos;numero&apos;])) $numero = $_POST[&apos;numero&apos;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            // Recuperar dígitos&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            if (isset($_POST[&apos;d1&apos;])) $d1 = $_POST[&apos;d1&apos;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            if (isset($_POST[&apos;d2&apos;])) $d2 = $_POST[&apos;d2&apos;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            if (isset($_POST[&apos;d3&apos;])) $d3 = $_POST[&apos;d3&apos;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            if (isset($_POST[&apos;d4&apos;])) $d4 = $_POST[&apos;d4&apos;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            // Recuperar $tiradas[]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            if (isset($_POST[&apos;tiradas&apos;])) $tiradas = $_POST[&apos;tiradas&apos;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            if (validaEntero($d1) &amp;amp;&amp;amp; validaEntero($d2) &amp;amp;&amp;amp; validaEntero($d3) &amp;amp;&amp;amp; validaEntero($d4)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                $numEnviado = $d1 . $d2 . $d3 . $d4;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                // Comprobar datos entrantes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                $muertos = numMuertos($numero, $numEnviado);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                $heridos = numHeridos($numero, $numEnviado, $muertos);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                // Añadir tirada&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                $tiradas[] = array($numEnviado, $muertos, $heridos);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        } else {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            // Generar un número al azar de cuatro dígitos no repetidos&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            $numero = range(0, 9);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            shuffle($numero);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            $numero = array_slice($numero, 0, 4);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            $numero = implode($numero);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        if ($mostrarNum) echo &quot;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;dfn&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;numero&apos;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;$numero&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;?&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;dfn&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&quot; . &quot;\n\n&quot;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        echo &quot;\t\t&quot; . &quot;&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;&amp;lt;!-- Encabezado --&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;\n&quot;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        echo &lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; CADENA&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;24&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;24&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;circle&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; cx&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;6&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; cy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;6&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; r&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;6&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;red&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;circle&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; cx&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;18&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; cy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;6&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; r&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;6&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;yellow&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;circle&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; cx&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;6&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; cy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;18&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; r&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;6&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;yellow&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;circle&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; cx&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;18&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; cy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;18&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; r&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;6&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;lawngreen&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; Mastermind&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;El juego de los muertos y heridos&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h2&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;\n&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;         &amp;lt;!-- Jugadas --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;br&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;hr&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;\n&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;CADENA;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        if ($enviado &amp;amp;&amp;amp; $muertos == 4) { &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            // Partida finalizada&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            echo &quot;\t\t&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;br&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;\n\t\t&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;¡¡¡Enhorabuena!!! Has acertado el número &quot; . $numero . &quot; en &quot; . count($tiradas) . &quot; jugadas.&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;\n&quot;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        } else {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        // Seguir jugando&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        if (isset($tiradas)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        foreach ($tiradas as $indice =&amp;gt; $valor) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            echo &quot;\t\t&quot; . &quot;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&quot; . ($indice + 1) . &quot;. Con el número introducido: &quot; . $valor[0] . &quot;, tienes &quot; . $valor[1] . &quot; muertos y &quot; . $valor[2]. &quot; heridos.&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&quot; . &quot;\n&quot;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        echo &quot;\t\t&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;hr&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;\n\t\t&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;br&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;\n&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        ?&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        &amp;lt;!-- Formulario --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Introduce tu número:&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;input&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; action&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;?php echo $_SERVER[&apos;PHP_SELF&apos;];?&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; method&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;post&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            &amp;lt;!-- Campos ocultos --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;?php&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                echo &apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hidden&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;numero&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&apos; . $numero . &apos;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&apos; . &quot;\n&quot;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                if ($enviado &amp;amp;&amp;amp; !empty($tiradas)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                    foreach ($tiradas as $indice =&amp;gt; $valor){&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                        echo &quot;\n\t\t\t&quot; .&apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hidden&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;tiradas[&apos; . $indice . &apos;][0]&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&apos; . $valor[0] . &apos;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&apos; . &quot;\n&quot;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                        echo &quot;\t\t\t&quot; .&apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hidden&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;tiradas[&apos; . $indice . &apos;][1]&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&apos; . $valor[1] . &apos;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&apos; . &quot;\n&quot;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                        echo &quot;\t\t\t&quot; .&apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hidden&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;tiradas[&apos; . $indice . &apos;][2]&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&apos; . $valor[2] . &apos;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&apos; . &quot;\n&quot;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                }}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            ?&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            &amp;lt;!-- Dígito 1 --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;d1&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;campo&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; min&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; max&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;9&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; validaEntero($d1)) echo $d1; ?&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; required&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; !validaEntero($d1)) echo &apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alerta&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;larr;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&apos;.&quot;\n&quot; ?&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            &amp;lt;!-- Dígito 2 --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;d2&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;campo&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; min&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; max&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;9&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; validaEntero($d2)) echo $d2; ?&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; required&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; !validaEntero($d2)) echo &apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alerta&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;larr;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&apos;.&quot;\n&quot; ?&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            &amp;lt;!-- Dígito 3 --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;d3&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;campo&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; min&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; max&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;9&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; validaEntero($d3)) echo $d3; ?&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; required&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; !validaEntero($d3)) echo &apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alerta&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;larr;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&apos;.&quot;\n&quot; ?&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            &amp;lt;!-- Dígito 4 --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;d4&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;campo&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; min&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; max&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;9&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; validaEntero($d4)) echo $d4; ?&amp;gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; required&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;required&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;?php if ($enviado &amp;amp;&amp;amp; !validaEntero($d4)) echo &apos;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alerta&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;larr;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&apos;.&quot;\n&quot; ?&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            &amp;lt;!-- Enviar --&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;            &amp;amp;nbsp;&amp;amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;submit&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;enviar&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;boton&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Enviar&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;?php } ?&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;autor&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;2019 (CC-BY) Javier Guerra&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://badared.com/javguerra/daw/mastermind/&quot;&gt;&lt;button&gt;Probar el juego&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/mastermind.C8GKrbMY_hnLY5.webp"/><category>web</category><category>código</category><category>php</category><category>juego</category><category>formularios</category><author>JavGuerra</author></item><item><title>Conexiones asíncronas a MySQL en Node.js</title><link>https://javguerra.github.io/blog/mysql-connect</link><guid isPermaLink="true">https://javguerra.github.io/blog/mysql-connect</guid><description>Usando util.promisify() para convertir en promesas conexiones síncronas de BBDD</description><pubDate>Wed, 14 Sep 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/mysql.CIjIICAX_2rcnGP.webp&quot; alt=&quot;MySQL&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#node.js&lt;/em&gt;, &lt;em&gt;#mysql&lt;/em&gt;, &lt;em&gt;#bbdd&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;El módulo &lt;code&gt;mysql&lt;/code&gt; de Node.js lleva a cabo conexiones a la BBDD empleando &lt;em&gt;callback&lt;/em&gt; para obtener los datos de las consultas SQL y no permite, por defecto, el uso de async/await. Al abrir la conexión, el resultado de estas consultas permanecerá dentro de la función &lt;em&gt;callback&lt;/em&gt;. En este artículo mostraré cómo convertir conexiones MySQL de Node.js en promesas que permitan el uso de async/await, pudiendo así extraer de la función el resultado de la consulta.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;note&quot;&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Esta entrada es un ejercicio sin un sentido práctico específico en el que se hace uso del módulo mysql de Node.js. Para producción se recomienda el uso de mysql2, que incluye soporte para promesas, o el uso de un ORM como Sequelize.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Poder obtener los datos de la consulta SQL, en el flujo de nuestro programa, nos facilita la tarea de observar buenas prácticas que permitan separar las rutas de los controladores y los servicios. Con un módulo de conexión podemos realizar las consultas desde los servicios, y estos a su vez devolver el resultado al controlador que fue llamado desde la ruta.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;txt&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── controllers&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   └── searchControllers.js&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── modules&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   ├── connection.js&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   └── utils.js&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── routes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   └── searchRoutes.js&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── services&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   └── searchServices.js&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;├── index.js&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pongamos que llega una consulta a la ruta de nuestra API que es gestionada por &lt;code&gt;searchRoutes.js&lt;/code&gt;, esta emplea una función del controlador que importa de &lt;code&gt;searchControllers.js&lt;/code&gt; que procesa la consulta, y que a su vez llama a una función del servicio &lt;code&gt;searchServices.js&lt;/code&gt; que se encarga de hacer la petición SQL a la BBDD.&lt;/p&gt;
&lt;p&gt;Dado que todas las peticiones a la BBDD son análogas (abrir conexión, hacer petición, devolver resultado) he creado una función llamada &lt;code&gt;getMysqlDbList()&lt;/code&gt; que he colocado en un módulo llamado &lt;code&gt;utils.js&lt;/code&gt; que importo y uso en &lt;code&gt;searchServices.js&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;La función &lt;code&gt;getMysqlDbList()&lt;/code&gt; se encargará de hacer la conexión a la base de datos, realizar la consulta y cerrar la conexión, apoyándose en el módulo &lt;code&gt;connection.js&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;un-ejemplo&quot;&gt;Un ejemplo&lt;/h1&gt;
&lt;p&gt;Pongamos que tenemos un frontal desde el que queremos obtener todos los productos de la BBDD. Veamos ejemplos de cada uno de los ficheros mencionados sin tener mucho en cuenta en este caso las pertinentes comprobaciones de los datos recibidos para simplificar el código.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;searchRoutes.js&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; express&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; router&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; express.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;Router&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; getAllProducts&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;../controllers/searchControllers&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;router.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;/&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, getAllProducts);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;exports&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; router;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Por supuesto, este módulo será importado en &lt;code&gt;index.js&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;searchControllers.js&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; searchServices&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;../services/searchServices&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getAllProducts&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; products&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; searchServices.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAllProducts&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    res.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;json&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(products);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;exports&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; getAllProducts;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;searchServices.js&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;getMysqlDbList&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;../modules/utils&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getAllProducts&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; request&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;SELECT * FROM products&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getMysqlDbList&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(request);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;exports&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { getAllProducts };&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;la-consulta&quot;&gt;La consulta&lt;/h2&gt;
&lt;p&gt;Para que esta línea &lt;code&gt;return getMysqlDbList(request);&lt;/code&gt; en &lt;code&gt;searchServices.js&lt;/code&gt; funcione, la función &lt;code&gt;getMysqlDbList()&lt;/code&gt; en &lt;code&gt;utils.js&lt;/code&gt; debe devolver el resultado de la consulta. El código debería ser algo como esto:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;utils.js&lt;/code&gt; (no lo usaremos de esta forma)&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; client&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;../modules/connection&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getMysqlDbList&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;request&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; list&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; client.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;query&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(request);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; list;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (err) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(err);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;El problema es que la consultas a mysql en Node.js no soportan async/await. Una conexión mysql entonces tendría esta forma, empleando una función &lt;em&gt;callback&lt;/em&gt;:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;utils.js&lt;/code&gt; (no lo usaremos de esta forma)&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; connection&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;../modules/connection&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getMysqlDbList&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;request&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    connection.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;query&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(request, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;results&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;fields&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (error) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; error;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        results.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;result&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(result);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Como se aprecia, &lt;code&gt;results&lt;/code&gt; está dentro de la función &lt;em&gt;callback&lt;/em&gt; que obtiene los datos de la consulta y desde dentro de esta función no puedo hacer un &lt;code&gt;return&lt;/code&gt; para devolver los productos como resultado de la función &lt;code&gt;getMysqlDbList()&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;la-conexión&quot;&gt;La conexión&lt;/h2&gt;
&lt;p&gt;Una conexión típica a la BBDD, cuyo código estaría en &lt;code&gt;connection.js&lt;/code&gt;, podría ser:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;connection.js&lt;/code&gt; (no lo usaremos de esta forma)&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; mysql&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;mysql&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;NODE_ENV&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;production&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;dotenv&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;config&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; connection&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; mysql.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;createConnection&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;({&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    host : process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_HOST&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    database : process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_DATABASE&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    user : process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_USERNAME&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    password : process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_PASSWORD&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    port : process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_PORT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;connection.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;connect&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (err) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Error de conexión: &apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; err.stack);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Conectado con el identificador &apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; connection.threadId);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;exports&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; connection;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A continuación mostraré los cambios que sufrirá este fichero.&lt;/p&gt;
&lt;h1 id=&quot;promisificación&quot;&gt;Promisificación&lt;/h1&gt;
&lt;p&gt;Node.js tiene un módulo &lt;code&gt;util&lt;/code&gt; con algunas funciones, entre ellas &lt;code&gt;promisify()&lt;/code&gt; que permite la conversión de una función que acepta un &lt;em&gt;callback&lt;/em&gt; a una función que devuelve una promesa. A este cambio se le conoce con el aparatoso y extraño nombre de &lt;code&gt;Promisificación&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Con esta función podemos convertir nuestra consulta a la base de datos basada en &lt;em&gt;callback&lt;/em&gt; a una promesa que puede usar async/await para devolver la info resultante de la consulta, pero esto no está exento de inconvenientes. Como necesito cerrar la conexión tras la consulta SQL, lo que haré es crear una función en &lt;code&gt;connection.js&lt;/code&gt; que exportaré junto con los datos de conexión para ser usados por &lt;code&gt;getMysqlDbList()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;connection.js&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; util&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;util&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; mysql&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;mysql&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;NODE_ENV&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;production&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;dotenv&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;config&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; config&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    host: process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_HOST&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    database: process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_DATABASE&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    user: process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_USERNAME&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    password: process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_PASSWORD&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    port: process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DB_PORT&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; makeDb&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;config&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; connection&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; mysql.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;createConnection&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(config);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        query&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;sql&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;args&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; util.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;promisify&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(connection.query)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;call&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(connection, sql, args);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        close&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; util.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;promisify&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(connection.end).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;call&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(connection);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;module&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;exports&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {config, makeDb};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Como se aprecia, importo el módulo &lt;code&gt;util&lt;/code&gt; del que utilizaré su función &lt;code&gt;promisify()&lt;/code&gt;. Nótese que este &lt;code&gt;util&lt;/code&gt; no se refiere a mi módulo &lt;code&gt;utils.js&lt;/code&gt; en la carpeta &lt;code&gt;modules&lt;/code&gt;, sino al módulo por defecto de Node.js.&lt;/p&gt;
&lt;p&gt;Defino los datos de configuración en un objeto, y creo una función &lt;code&gt;makeDb()&lt;/code&gt; que recibe como parámetro la configuración para establecer la conexión (&lt;code&gt;mysql.createConnection(config)&lt;/code&gt;) y que devuelve mediante &lt;em&gt;return&lt;/em&gt; dos funciones en un objeto: &lt;code&gt;query()&lt;/code&gt; y &lt;code&gt;close()&lt;/code&gt;. Con &lt;code&gt;.call()&lt;/code&gt; indico los parámetros de la función que va a ser convertida en promesa.&lt;/p&gt;
&lt;p&gt;Con la exportación de &lt;code&gt;config&lt;/code&gt; y &lt;code&gt;makeDb()&lt;/code&gt; tengo lo necesario para realizar una consulta a la BBDD desde &lt;code&gt;getMysqlDbList()&lt;/code&gt; en &lt;code&gt;utils.js&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;la-función-getmysqldblist&quot;&gt;La función getMysqlDbList()&lt;/h1&gt;
&lt;p&gt;{: .box-warning}
&lt;strong&gt;Advertencia:&lt;/strong&gt; En líneas generales no es buena idea conectar y desconectar a la BBDD en cada &lt;em&gt;request&lt;/em&gt; ya que se introduce esa latencia en cada solicitud, por tanto esta es una solución que puede y debe ser mejorada en el futuro.&lt;/p&gt;
&lt;p&gt;El siguiente código muestra cómo ha quedado la función &lt;code&gt;getMysqlDbList()&lt;/code&gt; dentro del fichero &lt;code&gt;utils.js&lt;/code&gt; definitivo (Obviar los anteriores ejemplos de utils.js):&lt;/p&gt;
&lt;p&gt;&lt;code&gt;utils.js&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;config&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;makeDb&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; require&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;./connection&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/**&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; * Obtiene un listado de la BBDD MySQL mediante consulta SQL.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@param&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; {String}&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; request&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@returns&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; Object&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getMysqlDbList&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;request&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    let&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; list &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; db&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; makeDb&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(config);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        list &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; db.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;query&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(request);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (err) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(err);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;finally&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; db.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; list;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Importo &lt;code&gt;config&lt;/code&gt; y &lt;code&gt;makeDb()&lt;/code&gt; para poder establecer la conexión a la BBDD mediante: &lt;code&gt;const db = makeDb(config);&lt;/code&gt;. Al llamar a &lt;code&gt;makeDb()&lt;/code&gt; pasándole el parámetro &lt;code&gt;config&lt;/code&gt; se inicia la conexión a la BBDD, y en &lt;code&gt;db&lt;/code&gt; se guarda el objeto con las funciones &lt;code&gt;query()&lt;/code&gt; y &lt;code&gt;close()&lt;/code&gt; que uso a continuación.&lt;/p&gt;
&lt;p&gt;Con &lt;code&gt;list = await db.query(request);&lt;/code&gt; realizo la consulta a la BBDD. Por supuesto &lt;code&gt;request&lt;/code&gt; es un parámetro que nos llega desde el servicio en &lt;code&gt;searchServices.js&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Por último, con &lt;code&gt;await db.close()&lt;/code&gt; cierro la conexión a la BBDD.&lt;/p&gt;
&lt;p&gt;Ahora, con &lt;code&gt;return list&lt;/code&gt; puedo devolver el resultado obtenido de la BBDD al servicio;&lt;/p&gt;
&lt;h1 id=&quot;resumiendo&quot;&gt;Resumiendo&lt;/h1&gt;
&lt;p&gt;Al hacer una petición a la ruta de nuestra API, esta llama a una función en el controlador encargada de procesar los datos recibidos en la petición que a su vez llama a una función en el servicio encargado de hacer la consulta a la BBDD.&lt;/p&gt;
&lt;p&gt;La función del servicio llama a una función en el fichero utils.js que se ocupa de establecer la conexión, realizar la consulta a la BBDD y cerrar la conexión. Esta función se externaliza porque, generalmente, su funcionalidad es la misma para cada consulta a la BBDD en cada servicio, cambiando sólo la consulta SQL a realizar.&lt;/p&gt;
&lt;p&gt;Para poder ejecutar esta función en el fichero utils.js se requiere del módulo de conexión que exporta tanto los datos de conexión como una función que permite realizar la conexión a la BBDD, la consulta y el cierre de la conexión, de tal forma que pueda usarse con async/await.&lt;/p&gt;
&lt;h1 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Página de la que he obtenido la pista para resolver esta cuestión &lt;a href=&quot;https://codeburst.io/node-js-mysql-and-async-await-6fb25b01b628&quot;&gt;Node.js, MySQL and async/await&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;La función util.promisify() en Node.js &lt;a href=&quot;https://nodejs.org/dist/latest-v8.x/docs/api/util.html#util_util_promisify_original&quot;&gt;util.promisify()&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Usando el método .call &lt;a href=&quot;https://dev.to/imsergiobernal/para-que-sirven-los-metodos-call-y-apply-en-javascript-4bj2&quot;&gt;¿Para qué sirven los métodos .call() y .apply() en JavaScript?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Libreria alternativa que incluye promesas (Aportada por borja) &lt;a href=&quot;https://www.npmjs.com/package/mysql2&quot;&gt;Node MySQL 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ORM: &lt;a href=&quot;https://sequelize.org/&quot;&gt;Sequelize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ejemplo de uso de pool de conexiones mysql, aportado por Jose, de «Desarrollo útil». &lt;a href=&quot;https://github.com/bezkoder/nodejs-express-mysql&quot;&gt;Node.js Rest APIs with Express &amp;amp; MySQL example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/mysql.CIjIICAX_2rcnGP.webp"/><category>código</category><category>javascript</category><category>node.js</category><category>mysql</category><category>bbdd</category><author>JavGuerra</author></item><item><title>Usando populate con paginate y filtrando los resultados</title><link>https://javguerra.github.io/blog/populate-paginate-fitrado</link><guid isPermaLink="true">https://javguerra.github.io/blog/populate-paginate-fitrado</guid><description>Cómo relacionar colecciones cuando se usa mongoose-paginate-v2</description><pubDate>Sat, 29 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/mongoose.yK9gFAu8_Z1xJtaI.webp&quot; alt=&quot;mongoose-paginate-v2&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#node.js&lt;/em&gt;, &lt;em&gt;#mongodb&lt;/em&gt;, &lt;em&gt;#mongoose&lt;/em&gt;, &lt;em&gt;#paginate&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Si bien mongodb tiene formas de obtener resultados paginados (limit, skip), el módulo mongoose-paginate-v2 de mongoose nos ahorra tiempo y código a la hora de preparar y usar los datos paginados obtenidos de las búsquedas en nuestras bases de datos, devolviendo información complementaria muy cómoda, pero ¿cómo podemos usar la paginación cuando tenemos relaciones entre colecciones? En esta entrada explicaré cómo paginar resultados agregados entre colecciones como si usásemos aggregate en mongodb o populate en mongoose, y además cómo filtrar búsquedas agregadas y paginadas con este módulo.&lt;/p&gt;
&lt;h1 id=&quot;el-ejemplo&quot;&gt;El ejemplo&lt;/h1&gt;
&lt;p&gt;Imaginemos que tenemos dos colecciones en una BBDD mongodb, una de &lt;code&gt;libros&lt;/code&gt; y otra de &lt;code&gt;autores&lt;/code&gt;, y un dato en cada documento de la colección libros llamado &lt;code&gt;autor&lt;/code&gt; que sirve para contener la información agregada del autor en la colección libros. En el &lt;em&gt;schema&lt;/em&gt;, el dato &lt;code&gt;autor&lt;/code&gt; podría tener esta forma:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    autor&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        ref&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: Schema.Types.ObjectId, &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;ref&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Autor&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        nombre&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: String&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La propiedad &lt;code&gt;ref&lt;/code&gt; es la que «tenderá el puente» entre ambas colecciones, y contendrá el &lt;code&gt;_id&lt;/code&gt; del documento a relacionar de la colección &lt;code&gt;autores&lt;/code&gt;. La propiedad &lt;code&gt;nombre&lt;/code&gt; contendrá, como se espera, el nombre del autor. Si bien este dato estará también en la colección &lt;code&gt;autores&lt;/code&gt;, y puede ser redundante cuando agregamos los resultados, el dato tiene su utilidad, pues nos permite realizar el filtrado de libros por autor incluso sin realizar la agregación.&lt;/p&gt;
&lt;p&gt;Una búsqueda haciendo uso de populate tendría esta forma:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Libro.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;find&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;( filtro ).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;populate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;( &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;autor.ref&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;exec&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;donde &lt;code&gt;filtro&lt;/code&gt; es un objeto que contendrá los criterios de búsqueda, y &lt;code&gt;autor.ref&lt;/code&gt; es la necesaria referencia para poder llevar a cabo la agregación de datos de la colección &lt;code&gt;autores&lt;/code&gt; en &lt;code&gt;libros&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Si queremos emplear el módulo &lt;code&gt;mongoose-paginate-v2&lt;/code&gt; para paginar los resultados de la búsqueda, esta quedaría de la siguiente forma:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Libro.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;paginate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(filtro, { page, limit });&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;donde &lt;code&gt;page&lt;/code&gt; indica la página de resultados a obtener y &lt;code&gt;limit&lt;/code&gt; el número de resultados por página.&lt;/p&gt;
&lt;p&gt;Pero sólo nos devolverá los datos de la colección &lt;code&gt;autores&lt;/code&gt;, sin agregar los datos de la colección &lt;code&gt;libros&lt;/code&gt;. ¿Cómo se haría esto?&lt;/p&gt;
&lt;h1 id=&quot;agregando-y-paginando&quot;&gt;Agregando y paginando&lt;/h1&gt;
&lt;p&gt;Hemos visto que paginate acepta dos parámetros, los criterios de búsqueda (filtro) y las opciones (page, limit). Otra opción que podemos añadir a paginate es &lt;code&gt;populate&lt;/code&gt;. Para hacer una búsqueda agregada como la del ejemplo, usaríamos:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Libro.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;paginate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(filtro, { page, limit, populate: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;autor.ref&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; });&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;de esta forma podemos obtener un resultado con la información de ambas colecciones.&lt;/p&gt;
&lt;p&gt;La opción populate permite también otras opciones. Imaginemos que en la agregación queremos obviar el dato &lt;code&gt;nombre&lt;/code&gt; de la colección &lt;code&gt;autores&lt;/code&gt; que ya tenemos en la colección &lt;code&gt;libros&lt;/code&gt;. Podemos pasarle a &lt;code&gt;populate&lt;/code&gt; un objeto de la siguiente forma:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Libro.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;paginate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(filtro, { page, limit, populate: {path: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;autor.ref&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, select: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;-nombre&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos; })&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;donde &lt;code&gt;select: &apos;-nombre&apos;&lt;/code&gt;, que va con un signo menos (-) delante, indica que ese dato no será requerido. Véase también que, para incluir la referencia a la colección, dentro del objeto se usa &lt;code&gt;path: &apos;autor.ref&apos;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Puedes obtener más información sobre las &lt;a href=&quot;https://mongoosejs.com/docs/api.html#query_Query-populate&quot;&gt;opciones de populate&lt;/a&gt; en el manual on-line.&lt;/p&gt;
&lt;h1 id=&quot;filtrando&quot;&gt;Filtrando&lt;/h1&gt;
&lt;p&gt;Decía más arriba que nos puede interesar hacer un filtrado en la búsqueda sobre nuestra base de datos por el nombre del autor, que es un dato dentro de otro dato, pero antes recordaré cómo buscar por uno o varios datos de la colección.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; filtro&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (titulo) filtro.titulo &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { $regex: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;`.*${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;titulo&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}.*`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (precio) filtro.precio &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { $lte: precio };&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Este código creará un objeto &lt;code&gt;filtro&lt;/code&gt; que permitirá que busquemos en la colección &lt;code&gt;libros&lt;/code&gt; por título y precio, ya que, si estos datos de búsqueda existen, con &lt;code&gt;filtro.titulo&lt;/code&gt; y &lt;code&gt;filtro.precio&lt;/code&gt; añadimos ambas propiedades al objeto filtro que usaremos en la búsqueda de la forma en que hemos visto en todos los ejemplos anteriores. (Nota: entiéndase que podríamos tener libros con el mismo título y distinto precio según la editorial o la colección editorial).&lt;/p&gt;
&lt;p&gt;Con &lt;code&gt;{ $regex: `.*${titulo}.*/` }&lt;/code&gt; buscamos por la expresión regular dada, en cambio con &lt;code&gt;$lte: precio&lt;/code&gt; buscamos por un valor igual o menor al proporcionado. Ver más información sobre &lt;a href=&quot;https://www.mongodb.com/docs/manual/reference/operator/&quot;&gt;operadores de búsqueda en mongodb&lt;/a&gt; en el manual on-line.&lt;/p&gt;
&lt;p&gt;Esto permitirá que:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Libro.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;paginate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(filtro, { page, limit, populate: {path: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;autor.ref&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, select: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;-nombre&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos; })&lt;/span&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;devuelva aquellos documentos de la colección &lt;code&gt;libros&lt;/code&gt; que tengan coincidencias con el &lt;code&gt;filtro&lt;/code&gt; indicado, es decir, que contengan en el título el texto &lt;code&gt;titulo&lt;/code&gt; indicado y cuyo precio sea igual o menor al &lt;code&gt;precio&lt;/code&gt; indicado.&lt;/p&gt;
&lt;h2 id=&quot;consulta-sobre-datos-anidados&quot;&gt;Consulta sobre datos anidados&lt;/h2&gt;
&lt;p&gt;Teniendo claro lo anterior, acceder al dato &lt;code&gt;nombre&lt;/code&gt; dentro de &lt;code&gt;autor&lt;/code&gt; no es complicado, pero para referenciar el dato tendremos que usar lo siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; filtro&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (nombre) filtro[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;autor.nombre&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { $regex: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;`.*${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;nombre&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}.*`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; };&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Uso aquí los corchetes &lt;code&gt;[]&lt;/code&gt; porque para poder usar el filtro en mongodb debo pasarle la propiedad al objeto filtro de esta forma: &lt;code&gt;{ &quot;autor.nombre&quot; : { $regex: `.*${nombre}.*` } }&lt;/code&gt; como se indica en la sección &lt;a href=&quot;https://www.mongodb.com/docs/manual/tutorial/query-embedded-documents/&quot;&gt;consulta sobre documentos incrustados/anidados&lt;/a&gt; del manual online.&lt;/p&gt;
&lt;p&gt;Este filtro devolverá aquellos documentos de la colección &lt;code&gt;libros&lt;/code&gt; que, dentro del dato &lt;code&gt;autor&lt;/code&gt;, contengan el nombre dado dentro del dato anidado &lt;code&gt;nombre&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/mongoose-paginate-v2&quot;&gt;mongoose-paginate-v2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mongoosejs.com/docs/api.html#query_Query-populate&quot;&gt;Opciones de populate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.mongodb.com/docs/manual/reference/operator/&quot;&gt;Operadores de búsqueda en mongodb&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.mongodb.com/docs/manual/tutorial/query-embedded-documents/&quot;&gt;Consulta sobre documentos incrustados/anidados&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/mongoose.yK9gFAu8_Z1xJtaI.webp"/><category>código</category><category>javascript</category><category>node.js</category><category>mongodb</category><category>mongoose</category><category>paginate</category><author>JavGuerra</author></item><item><title>Generar enlaces dinámicos de imágenes almacenadas en MongoDB</title><link>https://javguerra.github.io/blog/rutas-dinamicas-imagenes-mongodb</link><guid isPermaLink="true">https://javguerra.github.io/blog/rutas-dinamicas-imagenes-mongodb</guid><description>Conseguir que nuestros datos no dependan de una ubicación estática</description><pubDate>Sun, 06 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/dynamic_links.BDCzFkfb_1Co5pD.webp&quot; alt=&quot;Enlaces dinámicos&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#node.js&lt;/em&gt;, &lt;em&gt;#mongodb&lt;/em&gt;, &lt;em&gt;#imágenes&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Las bases de datos a menudo contienen referencias a recursos que no son almacenados en su misma estructura. Un claro ejemplo de ello son las fotografías o imágenes que acompañan a los productos de un catálogo. En tal caso, guardar la información es sencillo, es suficiente con almacenar la ruta completa al recurso en un campo de tipo &lt;em&gt;String&lt;/em&gt;, pero, ¿que ocurre si, presumiblemente, nuestros datos van a cambiar de ubicación, o van a correr en distintas instancias o en diferentes hospedajes? En ese caso, lo recomendable es almacenar la información del nombre del recurso en la BBDD, y entonces tendremos dos alternativas para generar el enlace completo: modificar los datos de la BBDD mediante un &lt;em&gt;script&lt;/em&gt; para que la url al recurso sea la adecuada cada vez que cambiamos de ubicación los datos, o bien generar la ruta al recurso de forma dinámica, al vuelo, cuando se realizan las consultas. Vamos a ver aquí la segunda.&lt;/p&gt;
&lt;h1 id=&quot;el-ejemplo&quot;&gt;El ejemplo&lt;/h1&gt;
&lt;p&gt;Partimos de la siguiente premisa. En las variables globales del sistema tenemos almacenadas la ruta y el puerto del servidor donde están ubicadas las imágenes, que es la información susceptible de cambiar de lugar. Tal vez estos datos estén disponibles mediante &lt;a href=&quot;https://www.npmjs.com/package/dotenv&quot;&gt;dotenv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Tomemos como referencia el ejemplo de la &lt;a href=&quot;/blog/populate-paginate-fitrado&quot;&gt;entrada anterior&lt;/a&gt;. Dos colecciones relacionadas, &lt;code&gt;libros&lt;/code&gt; y &lt;code&gt;autores&lt;/code&gt;, y en las que queremos incluir un dato en cada documento de la colección libros con la foto de portada del libro, y un dato con la foto del autor en cada documento de la colección autores. Algo como:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;libro&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    portada&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;don-quijote.png&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;autor&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    foto&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;cervantes.jpg&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;obviamente, tanto la colección libros como la conección autores tendrán otros datos, no sólo la portada o la foto.&lt;/p&gt;
&lt;h1 id=&quot;la-ruta&quot;&gt;La ruta&lt;/h1&gt;
&lt;p&gt;Para poder acceder a la portada del libro, necesitamos completar la ruta a la imagen. En este ejemplo usaremos el dominio &lt;code&gt;lalibreria2022.com&lt;/code&gt; al que se accede por el porto &lt;code&gt;80&lt;/code&gt;. Esta información la tenemos almacenada en un fichero &lt;code&gt;.env&lt;/code&gt; de nuestra aplicación de la siguiente forma:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;HOST=&apos;https://lalibreria2022.com&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;PORT=80&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Y asumo que las portadas se almacenan en una carpeta llamada &lt;code&gt;portadas&lt;/code&gt;, y las fotos en otra llamada &lt;code&gt;fotos&lt;/code&gt;.
De esta forma, para acceder a la imagen &lt;code&gt;don-quijote.png&lt;/code&gt; debemos completar la siguiente ruta:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;HOST + &apos;:&apos; + PORT + &apos;/&apos; + &apos;portadas&apos; + &apos;/&apos; + &apos;don-quijote.png&apos;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;y obtendríamos:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;https://lalibreria2022.com:80/portadas/don-quijote.png&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;alterando-los-resultados&quot;&gt;Alterando los resultados&lt;/h1&gt;
&lt;p&gt;Cuando llevamos a cabo las búsquedas de información sobre la BBDD, esta nos devolverá, como ya sabemos, el nombre del recurso (‘don-quijote.png’), pero queremos que la BBDD devuelva dinámicamente la ruta antes mencionada. Para ello hay que recorrer el resultado obtenido y hacer cambios sobre los datos. Un &lt;code&gt;forEach()&lt;/code&gt; es suficiente.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; insertarRutas&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; datos&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;HOST&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;:&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;PORT&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;/&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    datos.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;( &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;elemento&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; elemento.portada &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; url &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;portadas/&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; elemento.portada );&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; data;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tras cada búsqueda, aplicando esta función al resultado, recorro todos los documentos de la colección (&lt;code&gt;datos&lt;/code&gt;) y cambio el valor del dato &lt;code&gt;portada&lt;/code&gt; en cada documento.&lt;/p&gt;
&lt;h1 id=&quot;también-con-resultados-agregados&quot;&gt;También con resultados agregados&lt;/h1&gt;
&lt;p&gt;Cuando llevamos a cabo consultas agregadas, el proceso es similar. En una consulta donde obtenemos los libros y las referencias a sus respectivos autores, debemos repetir el proceso también para el dato &lt;code&gt;foto&lt;/code&gt; de la colección &lt;code&gt;autores&lt;/code&gt;, pero hay que tener en cuenta lo siguiente:&lt;/p&gt;
&lt;p&gt;{: .box-note}
&lt;strong&gt;Nota:&lt;/strong&gt; Cuando recorremos una colección agregada lo hacemos sobre una colección y sobre referencias a otra colección, es decir, si hay varios libros de un mismo autor, aunque los datos del autor se muestren en varios libros agregados, solo están almacenados una vez.&lt;/p&gt;
&lt;p&gt;Esto tiene importancia porque, al realizar el cambio de la ruta de la foto del autor, estaríamos cambiándola tantas veces como libros existan, y generando entonces una url errónea con rutas repetidas. Si tenemos dos libros de Cervantes, la ruta a la foto podría verse así:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;https://lalibreria2022.com:80/fotos/https://lalibreria2022.com:80/fotos/cervantes.jpg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Para evitar esto, debemos implementar el siguiente código, en el que se incluyen ambos casos, el de la portada del libro y el de la foto del autor:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; insertarRutas&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; datos&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;HOST&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;:&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; process.env.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;PORT&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;/&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    datos.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;elemento&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        elemento.portada &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; url &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;portadas/&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; elemento.portada;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;elemento.autor.ref.foto.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;includes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(url)) &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;             elemento.autor.ref.foto &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; url &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;fotos/&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; elemento.autor.ref.foto;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; data;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con el condicional (&lt;code&gt;if&lt;/code&gt;) me aseguro de que la foto no contiene ya la ruta completa, y si no es así, la completa.&lt;/p&gt;
&lt;h1 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/populate-paginate-fitrado&quot;&gt;Usando populate con paginate y filtrando los resultados&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/dynamic_links.BDCzFkfb_1Co5pD.webp"/><category>código</category><category>javascript</category><category>node.js</category><category>mongodb</category><category>imágenes</category><author>JavGuerra</author></item><item><title>El algoritmo de Karaca</title><link>https://javguerra.github.io/blog/karaca</link><guid isPermaLink="true">https://javguerra.github.io/blog/karaca</guid><description>Solución en JavaScript al reto semanal n. 50 de @MoureDev</description><pubDate>Thu, 15 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/cifrado.Hb5hRkab_Z2qxri.webp&quot; alt=&quot;Cifrado&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#criptografía&lt;/em&gt;, &lt;em&gt;#ciberseguridad&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;En este post resuelvo, en JavaScript el &lt;a href=&quot;https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge50.kt&quot;&gt;reto de programación&lt;/a&gt; consistente en desarrollar una función que es capaz de encriptar y desencriptar texto utilizando el algoritmo de encriptación de Karaca.&lt;/p&gt;
&lt;p&gt;Descubrí esta semana, un poco tarde, los &lt;a href=&quot;https://retosdeprogramacion.com/semanales2022&quot;&gt;retos de programación semanales de Mouredev para 2022&lt;/a&gt; y me atrajo el enunciado de este ejercicio.&lt;/p&gt;
&lt;p&gt;Busqué información en Internet sobre el algoritmo, encontrando lo siguiente:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Make a function that encrypts a given input with these steps:&lt;br&gt;
Input: “apple”&lt;br&gt;
Step 1: Reverse the input: “elppa”&lt;br&gt;
Step 2: Replace all vowels using the following chart:&lt;br&gt;
a =&amp;gt; 0, e =&amp;gt; 1, i =&amp;gt; 2, o =&amp;gt; 3, u =&amp;gt; 4  # “1lpp0”&lt;br&gt;
Step 3: Add “aca” to the end of the word: “1lpp0aca”&lt;br&gt;
Output: “1lpp0aca”&lt;br&gt;
All inputs are strings, no uppercases and all output must be strings.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Y me tomé la libertad de corregir la relación entre vocales y números que, en &lt;a href=&quot;https://edabit.com/challenge/JzBLDzrcGCzDjkk5n&quot;&gt;la fuente original&lt;/a&gt; publicada por Furkan Karaca, en el &lt;a href=&quot;https://edabit.com/&quot;&gt;portal de retos Edabit&lt;/a&gt; parece no ser correcta.&lt;/p&gt;
&lt;p&gt;El algoritmo, sin una aparente utilidad práctica, es un buen ejercicio de programación que combina el uso de expresiones regulares, uso de arreglos y cadenas y lógica.&lt;/p&gt;
&lt;h1 id=&quot;entendiendo-el-problema&quot;&gt;Entendiendo el problema&lt;/h1&gt;
&lt;p&gt;Lo que pide el ejercicio es que nuestra función debe poder codificar y decodificar un texto, en minúsculas, que le pasemos por parámetro. Este texto, lógicamente, no puede estar vacío.&lt;/p&gt;
&lt;p&gt;Cualquier dato que le pasemos que no sea texto debe impedir la ejecución de la codificación/decodificación. La función puede devolver un error, o bien el dato original suministrado. Opto por esta segunda posibilidad.&lt;/p&gt;
&lt;p&gt;La cadena de caracteres suministrada a la función puede tener espacios al inicio y/o al final, incluso puede contener sólo espacios, por lo que amerita limpiar la cadena, y que esta contenga algo más que sólo espacios.&lt;/p&gt;
&lt;p&gt;La cadena no puede contener sólo números, esto equivaldría a suministrar un número entero a la función. De hecho, el algoritmo presenta un problema importante con esto. Si se le suministra un frase que contenga dígitos en el rango del mapeo de vocales (0-1-2-3-4) no realizará bien el cifrado, pues tomará estos dígitos como parte del descifrado, mostrando un galimatías. Ej. «100 horas» -&amp;gt; «s0r3h 001aca» -&amp;gt; «eaa horas».&lt;/p&gt;
&lt;p&gt;Para saber si se puede decodificar una cadena proporcionada, es decir, para saber si está codificada con el algoritmo de Karaca, se debe cumplir que esta termine con un «aca», que contenga algún número entre el 0 y el 4, y que su longitud sea mayor que la de la cadena de control «aca». De no cumplirse esto, se entiende que la cadena que se proporciona a la función no está codificada, y entonces puede ser codificada.&lt;/p&gt;
&lt;p&gt;Para realizar la conversión, se debe recorrer la cadena teniendo en cuenta el mapeo de vocales del enunciado (a =&amp;gt; 0, e =&amp;gt; 1, i =&amp;gt; 2, o =&amp;gt; 3, u =&amp;gt; 4) y viceversa.&lt;/p&gt;
&lt;h1 id=&quot;resolución&quot;&gt;Resolución&lt;/h1&gt;
&lt;p&gt;El algoritmo de Karaca en JavaScript, atendiendo a las consideraciones anteriores, es el siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;01&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;. &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/**&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;02.  * Función en JavaScript que encripta y desencripta texto en minúsculas en &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;03.  * inglés, sin números, utilizando el algoritmo de encriptación de Karaca.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;04.  * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@param&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; {String}&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;05.  * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@returns&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; String&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;06.  * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@author&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Javier Guerra&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;07.  */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;08.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; karacaAlgorithm&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;09.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;10.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;??&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;11.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;12.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;typeof&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;===&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;string&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;match&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\D&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;13.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;14.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toLowerCase&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;reverse&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;join&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;15.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;16.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; vowels&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;aeiou&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;17.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; control&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;aca&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;18.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;19.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;20.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;startsWith&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(control) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;21.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;match&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;\d&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;22.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            str.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; control.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;23.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        ) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;24.&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // decode&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;25.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;slice&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(control.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;26.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            vowels.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;chr&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;27.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;includes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(i)) str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;replaceAll&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(i, chr);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;28.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;29.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;30.&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // encode&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;31.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            vowels.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;forEach&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;chr&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;32.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;includes&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(chr)) str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;replaceAll&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(chr, i);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;33.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;34.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; control;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;35.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;36.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;37.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;38.&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toString&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;39.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En la línea 8, con el valor por defecto &lt;code&gt;&quot;&quot;&lt;/code&gt; del parámetro se evita el error si llamemos a la función sin ningún parámetro, devolviendo una cadena vacía.&lt;/p&gt;
&lt;p&gt;en la línea 10 se comprueba que el parámetro recibido no está colando un valor &lt;code&gt;null&lt;/code&gt; o &lt;code&gt;undefined&lt;/code&gt; con el operador coalescente nulo (&lt;code&gt;??&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;En la línea 12 se comprueba que el dato recibido es una cadena, que tiene al menos un carácter, y cuenta con alguna consonante. De no ser así, se devuelve el parámetro recibido.&lt;/p&gt;
&lt;p&gt;En la línea 14 se realizan varias conversiones al parámetro recibido: se limpian los espacios iniciales y/o finales, se pasa la  cadena a minúsculas, y se invierte la cadena. Esto último se hace mediante la concatenación de varios métodos: &lt;code&gt;split&lt;/code&gt;, para convertir la cadena en un arreglo, &lt;code&gt;reverse&lt;/code&gt; para invertir el orden del contenido del arreglo y &lt;code&gt;join&lt;/code&gt; para unir el contenido del arreglo en una cadena.&lt;/p&gt;
&lt;p&gt;Las líneas 16 y 17 definen las variables que usaremos en el algoritmo.&lt;/p&gt;
&lt;p&gt;En la comprobación de las líneas de la 19 a la 23 se decide si se va a decodificar la cadena recibida, es decir, si se cumple que la cadena termina en «aca», contiene algún dígito y su longitud es mayor que la longitud de «aca». Si es así, se lleva a cabo la codificación a partir de la línea 25. en caso contrario, se lleva a cabo la codificación a partir de la línea 31.&lt;/p&gt;
&lt;p&gt;Para la decodificación, primero se elimina el control «aca» y luego se recorre el arreglo de vocales con forEach, de tal forma que si alguno de los elementos del arreglo es encontrado en la cadena a decodificar, este se sustituye por la vocal correspondiente.&lt;/p&gt;
&lt;p&gt;Para la codificación se lleva a cabo el proceso contrario. Al recorrer el arreglo de vocales, se sustituye el dígito por la vocal correspondiente. Luego se añade la cadena de control «aca».&lt;/p&gt;
&lt;p&gt;Por último, se devuelve el resultado de las operaciones sobre la cadena recibida convertida a cadena, por si el valor recibido fue un número, ya que la función debe devolver una cadena.&lt;/p&gt;
&lt;h1 id=&quot;prueba&quot;&gt;Prueba&lt;/h1&gt;
&lt;p&gt;El siguiente código de prueba debe poder codificar y decodificar la cadena original suministrada obteniendo la cadena original como resultado.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// Testing&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; str&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;Solving an equation produces, instantly, great euphoria.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;karacaAlgorithm&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(str));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;karacaAlgorithm&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;karacaAlgorithm&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(str)));&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;El resultado esperado debe ser:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;text&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;.02r3hp41 t01rg ,yltn0tsn2 ,s1c4d3rp n32t04q1 n0 gn2vl3saca&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;solving an equation produces, instantly, great euphoria.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La frase, en inglés, incluye las palabras &lt;code&gt;equation&lt;/code&gt; y &lt;code&gt;euphoria&lt;/code&gt; que cuentan con todas las vocales.&lt;/p&gt;
&lt;h1 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://retosdeprogramacion.com/semanales2022&quot;&gt;Retos de programación semanales de Mouredev para 2022&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/mouredev/Weekly-Challenge-2022-Kotlin/blob/main/app/src/main/java/com/mouredev/weeklychallenge2022/Challenge50.kt&quot;&gt;Reto de programación semanal n. 50 de Mouredev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://edabit.com/challenge/JzBLDzrcGCzDjkk5n&quot;&gt;La fuente original del reto por Furkan Karaca&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://edabit.com/&quot;&gt;Portal de retos Edabit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/retos-programacion&quot;&gt;Ver el código de este y otros retos de programación en GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/cifrado.Hb5hRkab_Z2qxri.webp"/><category>código</category><category>javascript</category><category>criptografía</category><category>ciberseguridad</category><author>JavGuerra</author></item><item><title>ConsoleInput kit</title><link>https://javguerra.github.io/blog/clase-scanner-java</link><guid isPermaLink="true">https://javguerra.github.io/blog/clase-scanner-java</guid><description>Una clase en Java para lectura de datos por consola</description><pubDate>Tue, 31 Jan 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/java-logo.Bk_jUffp_Z7fmbt.webp&quot; alt=&quot;Logo de Java&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#java&lt;/em&gt;, &lt;em&gt;#consola&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Cuando se emplea la clase Scanner en Java surgen multitud de inconvenientes a la hora de solicitar datos por consola. Algunos errores están asociados a la introducción de tipos de datos no solicitados, pero hay un problema especialmente incómodo, el de las pulsaciones de tecla Intro que quedan en el &lt;em&gt;buffer&lt;/em&gt; del Scanner. En esta entrada muestro cómo solucionar esto con algunos métodos básicos de ejemplo.&lt;/p&gt;
&lt;h1 id=&quot;lo-primero-abrir-y-cerrar&quot;&gt;Lo primero: abrir y cerrar&lt;/h1&gt;
&lt;p&gt;Voy a crear una clase de utilidad &lt;code&gt;ConsoleInput&lt;/code&gt; que no permite ser instanciada.&lt;/p&gt;
&lt;p&gt;Para poder leer por consola, necesitaré usar la clase &lt;code&gt;Scanner&lt;/code&gt; dentro de mi clase &lt;code&gt;ConsoleInput&lt;/code&gt;, y también crearé un método para poder cerrar el Scanner.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; final&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ConsoleInput&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    private&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Scanner IN &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Scanner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(System.in);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; closeScanner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (IN &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;isClosed&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    private&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ensureScannerOpen&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (IN &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;isClosed&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            IN &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Scanner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(System.in);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; resetScanner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        closeScanner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        IN &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Scanner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(System.in);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Como se aprecia, dentro de un paquete llamado &lt;code&gt;utilities&lt;/code&gt; creo la clase &lt;code&gt;ConsoleInput&lt;/code&gt;, el objeto &lt;code&gt;IN&lt;/code&gt; de tipo &lt;code&gt;Scanner&lt;/code&gt; que debe importarse de &lt;code&gt;java.util.Scanner&lt;/code&gt; y creo un método que, cuando sea llamado, cerrará el Scanner &lt;code&gt;IN&lt;/code&gt; con el método &lt;code&gt;.close()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;También he añadido dos métodos más relacionados con cerrar el scanner: &lt;code&gt;ensureScannerOpen()&lt;/code&gt; para cerciorarme de que el scanner esté abierto y &lt;code&gt;resetScanner()&lt;/code&gt; para cerrarlo y abrir uno nuevo si fuera necesario en nuestra aplicación.&lt;/p&gt;
&lt;p&gt;El método &lt;code&gt;ensureScannerOpen()&lt;/code&gt; se incluye en cada método que espera datos por consola para evitar problemas si el scanner no está abierto. Si no lo está, lo abre de forma transparente al usuario.&lt;/p&gt;
&lt;h1 id=&quot;introducir-datos-por-consola&quot;&gt;Introducir datos por consola&lt;/h1&gt;
&lt;h2 id=&quot;el-problema-next-vs-nextline&quot;&gt;El problema: .next() vs. .nextLine()&lt;/h2&gt;
&lt;p&gt;Cuando queremos leer un dato por consola, podemos usar el método &lt;code&gt;.next()&lt;/code&gt; o &lt;code&gt;.nextLine()&lt;/code&gt;, siendo &lt;code&gt;IN&lt;/code&gt; el objeto de la clase Scanner instanciado para leer por teclado.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Introduce una palabra&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;String entrada1 &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(entrada1);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Introduce una frase&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;String entrada2 &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(entrada2);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En &lt;code&gt;entrada1&lt;/code&gt; se guardará el dato introducido hasta encontrar un espacio en blanco.
En &lt;code&gt;entrada2&lt;/code&gt; se guardará el dato introducido hasta encontrar Intro, incluidos los espacios en blanco.&lt;/p&gt;
&lt;p&gt;Pero hay un problema en este código. Tras escribir la palabra que se solicita y pulsar &lt;code&gt;Intro&lt;/code&gt;, se guarda en &lt;code&gt;entrada1&lt;/code&gt; la palabra, pero en el &lt;em&gt;buffer&lt;/em&gt; del Scanner queda almacenado el &lt;code&gt;Intro&lt;/code&gt;, y este será leído por &lt;code&gt;entrada2&lt;/code&gt; y no nos permitirá escribir la frase solicitada.&lt;/p&gt;
&lt;p&gt;No ocurre lo mismo si invertimos el orden, es decir, si primero pedimos la frase con &lt;code&gt;.nexLine()&lt;/code&gt; y después la palabra con &lt;code&gt;.next()&lt;/code&gt;, ya que &lt;code&gt;.nextLine()&lt;/code&gt; lee específicamente el Intro tras introducir la frase y este no queda almacenado en el &lt;em&gt;buffer&lt;/em&gt;, pudiendo entonces introducir la palabra solicitada tras la frase.&lt;/p&gt;
&lt;p&gt;La solución pasa por poner siempre un &lt;code&gt;.nextLine()&lt;/code&gt; tras un &lt;code&gt;.next()&lt;/code&gt; para evitar problemas, de esta forma:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Introduce una palabra&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;String entrada1 &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(); &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// Lee el intro del buffer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(entrada1);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Introduce una frase&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;String entrada2 &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(entrada2);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Y ahora sí, la frase podrá ser introducida en &lt;code&gt;entrada2&lt;/code&gt; y luego mostrada.&lt;/p&gt;
&lt;p&gt;Esta solución aplica también a &lt;code&gt;.nextInt()&lt;/code&gt;, &lt;code&gt;.nextLong()&lt;/code&gt;, &lt;code&gt;.nextDouble()&lt;/code&gt; y otros métodos &lt;code&gt;.next()&lt;/code&gt; de entrada de la clase Scanner.&lt;/p&gt;
&lt;h2 id=&quot;pulse-intro-para-continuar&quot;&gt;Pulse Intro para continuar&lt;/h2&gt;
&lt;p&gt;La primera aplicación práctica de esto puede ser el método siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt; public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getEnter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    ensureScannerOpen&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;El método &lt;code&gt;.getEnter()&lt;/code&gt; es útil cuando queremos esperar que el usuario pulse la tecla &lt;code&gt;Intro&lt;/code&gt; para continuar.&lt;/p&gt;
&lt;h2 id=&quot;obtener-un-número-largo-entero-positivo&quot;&gt;Obtener un número largo, entero, positivo&lt;/h2&gt;
&lt;p&gt;Ahora quiero leer un número por consola que sea entero, largo (&lt;code&gt;long&lt;/code&gt;) y positivo. Emplearé el método &lt;code&gt;.nextLong()&lt;/code&gt; para obtener el dato, y lo acompañaré de un &lt;code&gt;.nextLine()&lt;/code&gt; como mostré antes.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;num &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLong&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(); &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Como puede que el dato introducido no sea un número largo, envolveré estas sentencias con un &lt;code&gt;try-catch&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    num &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLong&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ...  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;} &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (InputMismatchException &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Tipo de dato no reconocido.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;} &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La excepción &lt;code&gt;InputMismatchException&lt;/code&gt; será la encargada de probar (&lt;code&gt;try&lt;/code&gt;) si el tipo de dato introducido fue erróneo y de esta forma se llevarían a cabo las instrucciones del bloque &lt;code&gt;catch&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;En el bloque &lt;code&gt;catch&lt;/code&gt; también se incluye &lt;code&gt;IN.nextLine()&lt;/code&gt; ya que, cuando salta la excepción,  la línea &lt;code&gt;IN.nextLine();&lt;/code&gt; debajo del &lt;code&gt;IN.nextLong()&lt;/code&gt; no llega a ejecutarse.&lt;/p&gt;
&lt;p&gt;Si no se incluye esta línea en el &lt;code&gt;catch&lt;/code&gt; y estamos solicitando el dato por consola desde un bucle, como en el código que se ve a continuación, la aplicación entrará en un bucle infinito que mostrará el mensaje &lt;code&gt;&quot;Tipo de dato no reconocido.&quot;&lt;/code&gt;, ya que con cada nueva petición del dato, leería el &lt;code&gt;Intro&lt;/code&gt; del &lt;em&gt;buffer&lt;/em&gt; no pudiendo introducir el dato solicitado.&lt;/p&gt;
&lt;p&gt;Aquí el código completo del método &lt;code&gt;.getLongIntPos()&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Long &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getLongIntPos&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(String message) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    ensureScannerOpen&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    while&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(message);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            long&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; num &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLong&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (num &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; num;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Valor fuera de rango.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (InputMismatchException &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Tipo de dato no reconocido. Ingrese un número entero.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;El bucle &lt;code&gt;while&lt;/code&gt; se asegura de que, hasta que no se introduzca un dato válido, se esté solicitando el dato por consola. La condición de salida es si &lt;code&gt;num &amp;gt;= 0&lt;/code&gt;, momento en el que la función ejecutará el &lt;code&gt;return&lt;/code&gt; con el dato &lt;code&gt;num&lt;/code&gt; obtenido.&lt;/p&gt;
&lt;p&gt;Por parámetro recibimos el mensaje que dará versatilidad a esta función, y que será mostrado por consola antes de requerir el dato. Esta función se podrá usar de esta forma desde otra parte de nuestra aplicación:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Long numero &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getLongIntPos&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Introduce un número entero: &quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(numero);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;obtener-un-número-largo-entero-positivo-por-rango&quot;&gt;Obtener un número largo, entero, positivo por rango&lt;/h2&gt;
&lt;p&gt;Dado el método anterior, es fácil hacer cambios para que el valor recibido se encuentre entre un rango determinado.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Long &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getLongIntPosByRange&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(String message, Long min, Long max) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    ensureScannerOpen&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();   &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (min &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; max) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Long temp &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; min;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        min &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; max;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        max &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; temp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    while&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(message);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            long&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; num &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLong&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (num &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; min &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; num &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; max) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; num;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Valor fuera de rango.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (InputMismatchException &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Tipo de dato no reconocido.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;El método &lt;code&gt;.getLongIntPosByRange()&lt;/code&gt; solicita esta vez tres parámetros, el mensaje a mostrar (&lt;code&gt;message&lt;/code&gt;), el valor del rango mínimo (&lt;code&gt;min&lt;/code&gt;) y el máximo (&lt;code&gt;max&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Para evitar errores y complicar el código, asumo que si el valor máximo es menor que el valor mínimo, es que deben cambiarse, pero esta no sería la mejor forma de hacerlo.&lt;/p&gt;
&lt;p&gt;La otra diferencia con &lt;code&gt;.getLongIntPos()&lt;/code&gt; es que la condición de salida ahora es que el número que recibimos por consola debe estar entre los valores mínimo y máximo indicados (&lt;code&gt;num &amp;gt;= min &amp;amp;&amp;amp; num &amp;lt;= max&lt;/code&gt;).&lt;/p&gt;
&lt;h2 id=&quot;obtener-una-palabra&quot;&gt;Obtener una palabra&lt;/h2&gt;
&lt;p&gt;El código del método &lt;code&gt;.getWord()&lt;/code&gt; obtiene una palabra.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; String &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getWord&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(String message) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    ensureScannerOpen&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    while&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(message);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            String str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Cadena no válida.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (InputMismatchException &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Tipo de dato no reconocido.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La diferencia con los métodos anteriores es la condición de salida.&lt;/p&gt;
&lt;p&gt;Si la palabra introducida no tiene al menos tres caracteres (&lt;code&gt;str.length() &amp;gt;= 3&lt;/code&gt;), te la volverá a pedir. A la palabra introducida le limpio los posibles espacios al inicio y final con &lt;code&gt;.trim()&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;obtener-una-cadena-de-caracteres&quot;&gt;Obtener una cadena de caracteres&lt;/h2&gt;
&lt;p&gt;En la línea de los casos anteriores, el código del método &lt;code&gt;.getString()&lt;/code&gt; obtiene una cadena de caracteres (una frase) sería:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; String &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getString&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(String message) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    ensureScannerOpen&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    while&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(message);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            String str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Cadena no válida.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (InputMismatchException &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Tipo de dato no reconocido.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Aquí no sería necesario poner el &lt;code&gt;IN.nextLine()&lt;/code&gt; en el bloque &lt;code&gt;try&lt;/code&gt;, y todo lo demás es muy similar. La diferencia es, una vez más, la condición de salida.&lt;/p&gt;
&lt;p&gt;Si la cadena introducida no tiene al menos tres caracteres (&lt;code&gt;str.length() &amp;gt;= 3&lt;/code&gt;), te la volverá a pedir. A la cadena introducida le limpio los posibles espacios al inicio y final con &lt;code&gt;.trim()&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;obtener-un-sí-o-no&quot;&gt;Obtener un Sí o No&lt;/h2&gt;
&lt;p&gt;Con el método &lt;code&gt;getYesNo()&lt;/code&gt; obtengo un &lt;code&gt;true&lt;/code&gt; para ‘sí’ o un &lt;code&gt;false&lt;/code&gt; para ‘no’. El código es el siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Boolean &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getYesNo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(String message) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;    ensureScannerOpen&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    while&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(message);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            char&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; chr &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;charAt&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (chr &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;S&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; chr &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;s&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (chr &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;N&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; chr &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;n&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Carácter no válido.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (InputMismatchException &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Tipo de dato no reconocido.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();   &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lo destacable de este método es la línea:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;chr &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;charAt&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;); &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Que permite que, de los datos introducidos, sólo se almacene un carácter.&lt;/p&gt;
&lt;p&gt;En este método vuelve a ser necesario el uso de &lt;code&gt;IN.nextLine()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;En muy raras ocasiones, si un usuario presiona &lt;code&gt;Ctrl+D&lt;/code&gt; (EOF) en lugar de escribir algo o si se produce corrupción del stream de entrada, se puede recibir un &lt;code&gt;null&lt;/code&gt; en &lt;code&gt;chr&lt;/code&gt;. Por si acaso, para hacer la clase más robusta, podemos hacer una comprobación para evitarlo:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    String input &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// ← SEPARADO&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (input &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; input.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;isEmpty&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()) {  &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// ← PROTECCIÓN&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Entrada vacía no válida.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        continue&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    char&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; chr &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; input.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;charAt&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;bonus-limpiar-la-consola&quot;&gt;Bonus: limpiar la consola&lt;/h2&gt;
&lt;p&gt;Buscando por Internet, encontré este sencillo código para limpiar la consola:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; clearConsole&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 50&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; i&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Realmente &lt;code&gt;clearConsole()&lt;/code&gt; no limpia la consola. Sólo empuja las líneas hacia arriba. Concretamente, 50 líneas hacia arriba. Esto permite que este simple método funcione en cualquier IDE o sistema operativo, y a efectos prácticos, despeja la consola, que es lo que se persigue.&lt;/p&gt;
&lt;h1 id=&quot;la-clase-consoleinput-completa&quot;&gt;La clase ConsoleInput completa&lt;/h1&gt;
&lt;p&gt;El código es el siguiente (cambia el «package» según te interese):&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;package&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; utilities;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; java.util.InputMismatchException;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; java.util.Scanner;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;/**&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; * Clase para leer datos por consola.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@author&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; JavGuerra&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@version&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; 1.1 - 2026-02-13&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@since&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; 2023-01-31&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; * @requires Java 5.0 (1.5) or higher&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@see&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; &amp;lt;a href=&quot;https://javguerra.github.io/blog/clase-scanner-java/&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; *         «ConsoleInput kit» Descripción en el blog del autor.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; *     &amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@see&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; &amp;lt;a href=&quot;https://youtu.be/HSq3rRfBmDg&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; *         Video: Entrada de datos en Java - Clase Scanner.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; *         Mega curso Java desde 0, Aula en la nube.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; *     &amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; final&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ConsoleInput&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    /**&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * Constructor privado que evita la instanciación de la clase. &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    private&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ConsoleInput&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        throw&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; AssertionError&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;No se puede instanciar ConsoleInput&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    /** &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * Instancia de la clase Scanner.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    private&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Scanner IN &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Scanner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(System.in);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    /**&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * Cierra el Scanner.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; closeScanner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (IN &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;isClosed&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    /**&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * Verifica que el Scanner esté abierto y funcionando.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * Si está cerrado, lo reabre automáticamente.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    private&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ensureScannerOpen&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (IN &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;isClosed&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            IN &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Scanner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(System.in);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    /**&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * Reinicia el Scanner (cierra y abre uno nuevo).&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; resetScanner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        closeScanner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        IN &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Scanner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(System.in);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    /**&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * Espera la pulsación de la tecla Intro.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getEnter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() { &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        ensureScannerOpen&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    /**&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * Solicita con un mensaje por consola, y comprueba que se introduzca,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * un número largo, entero, positivo (&amp;gt;=0).&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@param&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; message&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; String Pregunta del usuario.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@return&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; Long Número introducido.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Long &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getLongIntPos&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(String &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        ensureScannerOpen&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        while&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(message);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                long&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; num &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLong&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (num &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; num;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Valor fuera de rango.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (InputMismatchException &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Tipo de dato no reconocido.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    /**&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * Solicita con un mensaje por consola, y comprueba que se introduzca,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * un número largo, entero, positivo (&amp;gt;=0), cuyo rango esté entre&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * el valor mínimo y el valor máximo recibido, ambos inclusive.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@param&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; message&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; String Pregunta del usuario.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@param&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; min&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; Long Valor mínimo.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@param&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; max&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; Long Valor máximo.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@return&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; Long Número introducido.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Long &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getLongIntPosByRange&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(String &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, Long &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;min&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, Long &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;max&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        ensureScannerOpen&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (min &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; max) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            Long temp &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; min;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            min &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; max;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            max &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; temp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        } &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        while&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(message);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                long&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; num &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLong&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (num &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; min &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; num &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; max) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; num;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Valor fuera de rango.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (InputMismatchException &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Tipo de dato no reconocido.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    /**&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * Solicita con un mensaje por consola, y comprueba que se introduzca,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * una palabra de, al menos, 3 caracteres.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@param&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; message&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; String Pregunta del usuario.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@return&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; String Palabra introducida.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; String &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getWord&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(String &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) { &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        ensureScannerOpen&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        while&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(message);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                String str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Cadena no válida.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (InputMismatchException &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Tipo de dato no reconocido.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();   &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }   &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    /**&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * Solicita con un mensaje por consola, y comprueba que se introduzca,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * una cadena de texto de, al menos, 3 caracteres.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@param&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; message&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; String Pregunta del usuario.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@return&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; String Cadena de texto introducida.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; String &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getString&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(String &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        ensureScannerOpen&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        while&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(message);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                String str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                str &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (str.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; str;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Cadena no válida.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (InputMismatchException &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Tipo de dato no reconocido.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();   &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    /**&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * Solicita con un mensaje por consola, y comprueba que se introduzca,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * un carácter para confirmar (&apos;S&apos;, &apos;s&apos;) o (&apos;N&apos;, &apos;n&apos;).&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@param&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; message&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; String Pregunta del usuario.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@return&lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt; Boolean true/Sí o false/No.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Boolean &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getYesNo&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(String &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;message&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        ensureScannerOpen&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        while&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(message);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                String input &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (input &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; input.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;isEmpty&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                    System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Entrada vacía no válida.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                    continue&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                char&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; chr &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; input.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;charAt&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (chr &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;S&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; chr &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;s&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (chr &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;N&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; chr &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;n&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Carácter no válido.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (InputMismatchException &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Tipo de dato no reconocido.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                IN.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;nextLine&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();   &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }   &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    /**&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * Limpia la consola (desplaza el contenido hacia arriba).&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     * Funciona en TODOS los sistemas e IDEs.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;     */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; clearConsole&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        for&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; i &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 50&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;; i&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    } &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esta clase puede crecer con nuevos métodos para otros tipos numericos como int o double… que tú mismo puedes hacer.&lt;/p&gt;
&lt;h1 id=&quot;puntos-fuertes-de-esta-clase&quot;&gt;Puntos fuertes de esta clase&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;No instanciable - Constructor privado + final class.&lt;/li&gt;
&lt;li&gt;Auto-reparable - Scanner se reabre solo.&lt;/li&gt;
&lt;li&gt;Robusta - Maneja entradas incorrectas sin caer.&lt;/li&gt;
&lt;li&gt;Null-safe - &lt;code&gt;getYesNo()&lt;/code&gt; protegido.&lt;/li&gt;
&lt;li&gt;Consistente - Todos los métodos usan &lt;code&gt;ensureScannerOpen()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Compatible - Funciona desde Java 1.5.&lt;/li&gt;
&lt;li&gt;Documentada - JavaDoc completo.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;un-ejemplo-de-uso&quot;&gt;Un ejemplo de uso&lt;/h1&gt;
&lt;p&gt;Para finalizar, veamos un caso práctico para la gestión de clientes.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    private&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; static&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; selectOptions&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        long&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; totalOpts &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 6L&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        String optMsg &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;Seleccione una opción (0-6): &quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        String menuList &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        -------------------&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;           CRUD Customer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        -------------------&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        1. Listar clientes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        2. Mostrar un cliente&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        3. Crear un nuevo cliente&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        4. Actualizar un cliente&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        5. Eliminar un cliente&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        6. Eliminar los clientes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        0. Salir&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &quot;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        byte&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; opt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        while&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            clearConsole&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(menuList);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            opt &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getLongIntPosByRange&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(optMsg, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0L&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, totalOpts).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;byteValue&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (opt &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;break&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            switch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (opt) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                case&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; controller.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;listCustomers&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                case&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; controller.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;listCustomerById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                case&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; controller.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;newCustomer&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                case&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 4&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; controller.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;updateCustomerById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                case&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; controller.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;deleteCustomerById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                case&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 6&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; -&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; controller.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;deleteAllCustomers&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            System.out.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;println&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Pulse &amp;lt;Intro&amp;gt; para continuar.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;            getEnter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        closeScanner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://youtu.be/HSq3rRfBmDg&quot;&gt;Video: Entrada de datos en Java - Clase Scanner&lt;/a&gt; - Mega curso Java desde 0, Aula en la nube&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/java-logo.Bk_jUffp_Z7fmbt.webp"/><category>java</category><category>consola</category><category>código</category><author>JavGuerra</author></item><item><title>Reto navideño</title><link>https://javguerra.github.io/blog/reto-navidad</link><guid isPermaLink="true">https://javguerra.github.io/blog/reto-navidad</guid><description>Cinco ejercicios de programación muy festivos</description><pubDate>Sun, 24 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/reto-navidad.FKCpLWfX_Z1lvJEa.webp&quot; alt=&quot;Arbolito&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Cinco ejercicios de programación navideños de dificultad progresiva que puedes realizar en el lenguaje de programación que desees y subir a tu repositorio.&lt;/p&gt;
&lt;h2 id=&quot;ejercicios&quot;&gt;Ejercicios&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;¿Cuánto queda para año nuevo?&lt;/strong&gt; Imprime por consola el tiempo que queda hasta el día 1 de enero. Puedes mostrar el tiempo en meses, días, horas y minutos. ¿Y qué pasará si ya hemos sobrepasado la fecha? Piensa cómo resolverlo.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Arbolito&lt;/strong&gt;. Dibuja por consola un árbol de navidad con caracteres ASCII de colores. El árbol puede ser tan completo como quieras, ser un triángulo o tener ramas de las que cuelguen objetos decorativos o generar el árbol aleatoriamente, pero siempre usando caracteres.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Calendario mensual&lt;/strong&gt;. Pide por consola un número del 1 al 12 y genera, con tu propio código, el calendario de ese mes del nuevo año. Incluye el nombre del mes, y en la fila superior del calendario pon las iniciales de los días de la semana. Para complicarlo aún más, puedes colorear los domingos y festivos si lo deseas.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Amigo invisible&lt;/strong&gt;. Crea un programa al que le puedes facilitar una lista de nombres. El programa deberá asignar aleatoriamente el amigo invisible, y guardar el resultado. La segunda parte del programa será para consultar. Escribiendo tu nombre recibirás por pantalla la persona a la que te ha tocado regalar.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;To do&lt;/strong&gt;. Crea un programa que guarde una lista de propósitos para año nuevo y te permita listar, añadir, editar, tachar y/o borrar cada uno de los items de la lista. Puedes incluso usar una base de datos como respaldo.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Recuerda compartir el enlace al código de cada ejercicio en tu repositorio para que otros vean el resultado y aprendan de tu solución&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;bonus&quot;&gt;Bonus&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;¡Inventa!&lt;/strong&gt;. Cambia el enunciado de estos ejercicios a tu gusto o crea tus propios ejercicios en torno a esta temática festiva.&lt;/p&gt;
&lt;p&gt;¡Felices programas!&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/reto-navidad.FKCpLWfX_Z1lvJEa.webp"/><category>código</category><author>JavGuerra</author></item><item><title>Sinclair QL SCR Viewer</title><link>https://javguerra.github.io/blog/ql-scr-viewer</link><guid isPermaLink="true">https://javguerra.github.io/blog/ql-scr-viewer</guid><description>Muestra pantallas del ordenador Sinclair QL</description><pubDate>Sat, 10 Feb 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/qlscrview.CzONMBZX_1QXhLE.webp&quot; alt=&quot;QL SCR Viewer&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#herramienta&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#retro&lt;/em&gt;, &lt;em&gt;#sinclair ql&lt;/em&gt;, &lt;em&gt;#software libre&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;El QL original tiene dos modos de pantalla, el modo de 256×256 pixels a 8 colores, y el modo de 512×256 pixels a 4 colores.&lt;/p&gt;
&lt;p&gt;La aplicación Sinclair QL SCR Viewer es un HTML que permite cargar en el navegador un archivo de imagen en estos formatos ubicado en local o en remoto, mediante un botón INPUT, para mostrar su contenido sin que ocurran errores de CORS, y sin usar un servidor.&lt;/p&gt;
&lt;p&gt;La imagen resultante puede descargarse en formato PNG con un tamaño de 1024×768 pixels.&lt;/p&gt;
&lt;p&gt;Se escribió un &lt;a href=&quot;https://sinclairqles.wordpress.com/2024/02/10/ql-scr-viewer-en-linea/&quot;&gt;artículo para QBlog&lt;/a&gt; con más información de cuál es la estructura de codificación de las pantallas en estos dos modos que puedes consultar.&lt;/p&gt;
&lt;p&gt;El desarrollo se ha llevado a cabo a ratos, durante una semana, y se ha hecho uso de la IA &lt;a href=&quot;https://www.phind.com/&quot;&gt;Phind&lt;/a&gt; para consultas técnicas que han sido de gran utilidad. La aplicación acrtualmente está en la versión 1.0.&lt;/p&gt;
&lt;p&gt;Hice uso de GitHub pages para alojar el desarrollo y también la aplicación que está disponible en:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/Sinclair-QL-SCR-viewer/&quot;&gt;&lt;button&gt;QL SCR Viewer&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;objetivo-de-la-aplicación&quot;&gt;Objetivo de la aplicación&lt;/h2&gt;
&lt;p&gt;Hagamos un poco de arqueología. En los tiempos del QL (años 80) era muy normal cargar y salvar a y desde memoria de pantalla las imágenes que querían mostrarse. Solía usarse para mantener al usuario atento con una pantalla colorida mientras terminaba la carga del programa desde algún medio de almacenamiento. ¡Esto podía demorar minutos!&lt;/p&gt;
&lt;p&gt;Dado que las imágenes de pantalla del QL son datos con estructura, pero sin cabecera, es complicado poder visualizarlas en un PC si no se lleva a cabo una conversión, y eso es justamente lo que hace esta aplicación, además de permitir descargar la pantalla en formato PNG.&lt;/p&gt;
&lt;p&gt;La idea era crear una herramienta que no dependiera de ningún sistema host, para que pudiera ser usada en cualquier sistema operativo actual. Emplear HTML + JavaScript era una opción interesante que permitía hacer uso de la aplicación en local, pero también ofrecer la aplicación como un servicio en línea.&lt;/p&gt;
&lt;h2 id=&quot;características&quot;&gt;Características&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Maneja pantallas en modos 8 y 4.&lt;/li&gt;
&lt;li&gt;Detecta automáticamente el modo de pantalla.&lt;/li&gt;
&lt;li&gt;Permite el cambio de modo de la imagen cargada.&lt;/li&gt;
&lt;li&gt;Funciona en local evitando errores de CORS.&lt;/li&gt;
&lt;li&gt;Descarga la imagen visualizada en PNG.&lt;/li&gt;
&lt;li&gt;Es responsive.&lt;/li&gt;
&lt;li&gt;Es accesible.&lt;/li&gt;
&lt;li&gt;Detecta errores de carga.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;info-sobre-el-funcionamiento-de-la-aplicación&quot;&gt;Info sobre el funcionamiento de la aplicación&lt;/h2&gt;
&lt;p&gt;El desarrollo inicialmente se centró en el &lt;em&gt;parser&lt;/em&gt; o analizador sintáctico que debía «entender» los dos modos. Mediante un botón de carga y un evento asociado se accede al fichero, y luego se procesa.&lt;/p&gt;
&lt;p&gt;Igualmente se asocian eventos al botón de cambiar de modo y al botón de descargar archivos. Estos eventos llaman a sus correspondientes funciones.&lt;/p&gt;
&lt;p&gt;El código ha sido optimizado para poder funcionar en local sin que se generen errores de CORS (Cross-Origin Resource Sharing en inglés), una funcionalidad de los navegadores que ayudan a evitar problemas relacionados con la seguridad de la información.&lt;/p&gt;
&lt;p&gt;Para visualizar correctamente la imagen se hace uso de una función que revisa los datos cargados y determina si la imagen está en modo 8 o en modo 4 y, si corresponde, cambia el modo de visualización.&lt;/p&gt;
&lt;p&gt;A la hora de visualizar la imagen se han empelado dos canvas, uno donde se dibuja la imagen y otro que contiene este primer canvas que lo muestra en la escala adecuada para que se vea completo y proporcional en cualquier dispositivo. La proporción de la imagen es 4:3 y el tamaño de la imagen es de 1024x768.&lt;/p&gt;
&lt;p&gt;Se ha elegido esta resolución porque es múltiplo de las resoluciones de ambos modos. De hecho, para representar correctamente las imágenes de los modos 8 y 4, un pixel de una imagen en modo 8 ocupará cuatro pixeles de ancho y tres de alto en la imagen resultante, y un pixel de una imagen en modo 4 ocupará dos píxeles de ancho y tres píxeles de alto en la imagen resultante.&lt;/p&gt;
&lt;p&gt;La representación de color de los modos se realiza de la siguiente forma: el modo 8 usa cuatro bits por pixel para representar cada color (GFRB - Green, Flash, Red, Blue), con una profundidad de color de 8 (negro, azul, rojo, magenta, verde, cian, amarillo, blanco). Hay un bit que no se usa, que corresponde al flash (F) o parpadeo, una característica que tiene este ordenador. El modo 4 usa 2 bits por pixel (GR - Green, Reed), con una profundidad de color de 4 (negro, rojo, verde, blanco). Pues bien, para poder mostrar los colores en formato RGB, si un bit R, G o B está a cero, el valor de su componente RGB será 0, si es 1, el valor de su componente RGB será 255. En el modo 4, para obtener el valor de B, si los valores G y R están a 1, el valor B será 1, y el valor de su componente, 255, en caso contrario, será 0.&lt;/p&gt;
&lt;p&gt;La pantalla del QL clásica tiene un tamaño de 32.768 bytes en ambos modos. Al cargar la imagen esto se comprueba, así como si el archivo está vacío o si no se ha podido acceder al medio.&lt;/p&gt;
&lt;p&gt;Con el botón de intercambio de modo, podemos cambiar el modo de visualización de la imagen, caso que puede ser de utilidad si la detección automática no terminó de funcionar correctamente. Esto se hace sin necesidad de volver a acceder a la imagen, aprovechando los datos que están almacenados en el &lt;em&gt;buffer&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;La descarga en PNG permite obtener una imagen que se guardará con el formato nombre + sufijo + extensión. El &lt;code&gt;nombre&lt;/code&gt; corresponde al nombre del archivo original. La extensión será &lt;code&gt;_QL8&lt;/code&gt; o &lt;code&gt;_QL4&lt;/code&gt; según corresponda, y la extensión será &lt;code&gt;.png&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Para el desarrollo se ha tenido en cuenta el uso accesible de la aplicación, mediante la incorporación de etiquetas WAI-ARIA en el código.&lt;/p&gt;
&lt;h2 id=&quot;saber-más&quot;&gt;Saber más&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://javguerra.github.io/Sinclair-QL-SCR-viewer/&quot;&gt;QL SCR Viewer en línea&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sinclairqles.wordpress.com/2024/02/10/ql-scr-viewer-en-linea/&quot;&gt;Artículo sobre QL SCR Viewer para QBLog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/Sinclair-QL-SCR-viewer&quot;&gt;Repositorio de QL SCR Viewer en GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/sinclair-ql&quot;&gt;Info sobre Sinclair QL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/qlscrview.CzONMBZX_1QXhLE.webp"/><category>web</category><category>html</category><category>javascript</category><category>herramienta</category><category>código</category><category>retro</category><category>sinclair ql</category><category>software libre</category><author>JavGuerra</author></item><item><title>Notificaciones con Thymeleaft</title><link>https://javguerra.github.io/blog/notificaciones-thymeleaft</link><guid isPermaLink="true">https://javguerra.github.io/blog/notificaciones-thymeleaft</guid><description>Cómo incluir avisos en Spring Boot</description><pubDate>Wed, 03 Jul 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/notificaciones.DrEXfhr5_Z1sRXMQ.webp&quot; alt=&quot;Notificaciones&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#java&lt;/em&gt;, &lt;em&gt;#spring boot&lt;/em&gt;, &lt;em&gt;#bootstrap&lt;/em&gt;, &lt;em&gt;#thymeleaft&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Cuando una aplicación realiza operaciones potencialmente críticas como editar, guardar o borrar datos de una base de datos, es conveniente notificar al usuario el éxito o fracaso de las operaciones. Esta entrada presenta una solución básica de cómo mostrar notificaciones en la plantilla Thymeleaft.&lt;/p&gt;
&lt;p&gt;Se asume que el lector tiene conocimientos generales de Spring Boot, Thymeleaft y Bootstrap para aplicar el contenido.&lt;/p&gt;
&lt;h1 id=&quot;planteamiento&quot;&gt;Planteamiento&lt;/h1&gt;
&lt;p&gt;La idea es destinar una área de la visualización en la aplicación para las notificaciones, y activar este área sólo cuando se deban mostrar, dando opción al usuario a cerrarlas una vez leídas. Este área puede crearse como un fragmento (th:fragment) e incluirse en las plantillas en las que se requiera, o en todas las plantillas asociadas a las vistas de la aplicación.&lt;/p&gt;
&lt;p&gt;Será necesaria una variable que sirva de «llave» para mostrar estas notificaciones o no, y otra para indicar el tipo de mensaje (&lt;em&gt;info&lt;/em&gt;, &lt;em&gt;danger&lt;/em&gt;…). Como enviar el mensaje desde cada método de erutado de nuestros controladores es algo trabajoso, lo adecuado es usar un filtro de sesión http que me permitirá crear las variables donde guardaré el contenido del mensaje y el tipo de mensaje a mostrar.&lt;/p&gt;
&lt;p&gt;Por último, gestionaré el borrado del contenido de la notificación para que esta deje de mostrarse al cambiar de página Para ello necesitaremos otra variable que indique si la notificación ya se ha mostrado.&lt;/p&gt;
&lt;h1 id=&quot;programando-notificaciones&quot;&gt;Programando notificaciones&lt;/h1&gt;
&lt;p&gt;Para crear las notificaciones, necesitaremos:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Crear un fragmento que servirá para incluir el texto de la notificación en nuestras vistas.&lt;/li&gt;
&lt;li&gt;Inicializar las variables de sesión que contendrán la notificación y el tipo de notificación.&lt;/li&gt;
&lt;li&gt;Actualizar el valor de las variables de notificación para que estas se muestren.&lt;/li&gt;
&lt;li&gt;Eliminar la notificación al cambiar de página.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;el-fragmento&quot;&gt;El fragmento&lt;/h2&gt;
&lt;p&gt;He creado un fragmento de código llamado &lt;code&gt;messageAlert.html&lt;/code&gt; que he incluido en mi carpeta &lt;code&gt;fragments&lt;/code&gt; dentro de templates en resources. Este es un ejemplo que puede modificarse a voluntad para adaptar su diseño a la aplicación donde se usará.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:fragment&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageAlert&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;${session.message != &apos;&apos;}&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;container&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alert alert-dismissible fade show&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; role&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alert&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;        th:classappend&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;${session.messageType} == &apos;danger&apos;? &apos;alert-danger&apos; : &apos;alert-info&apos;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; xmlns&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;http://www.w3.org/2000/svg&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;none&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; viewBox&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0 0 24 24&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;1.5&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;currentColor&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;24&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;24&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-linecap&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-linejoin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;M14.857 17.082a23.848 23.848 0 0 0 5.454-1.31A8.967 8.967 0 0 1 18 9.75V9A6 6 0 0 0 6 9v.75a8.967 8.967 0 0 1-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 0 1-5.714 0m5.714 0a3 3 0 1 1-5.714 0M3.124 7.5A8.969 8.969 0 0 1 5.292 3m13.416 0a8.969 8.969 0 0 1 2.168 4.5&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;nbsp;&amp;amp;nbsp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;align-middle&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:text&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;${session.message}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;btn-close&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; data-bs-dismiss&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alert&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; aria-label&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Cerrar&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con &lt;code&gt;th:if=&quot;${session.message != &apos;&apos;}&quot;&lt;/code&gt;determino si este fragmento se mostrará o no. Si el valor de la variable de sesión llamada &lt;code&gt;message&lt;/code&gt; está vacío, es que no hay nada que mostrar, de otra forma, el fragmento se mostrará.&lt;/p&gt;
&lt;p&gt;Con &lt;code&gt;th:classappend=&quot;${session.messageType} == &apos;danger&apos;? &apos;alert-danger&apos; : &apos;alert-info&apos;&quot;&lt;/code&gt; determino qué tipo de alerta de Boostrap mostrar, si una destinada a informar (recuadro con fondo azul) o una destinada a alertar de un fallo (recuadro con fondo rojo). Esto lo consigo mediante la variable de sesión &lt;code&gt;messageType&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Tras el icono SVG que se mostrará en el aviso, se incluye el mensaje de la notificación con &lt;code&gt;th:text=&quot;${session.message}&quot;&lt;/code&gt; dentro de la etiqueta &lt;code&gt;span&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Con el &lt;code&gt;button&lt;/code&gt;, ayudado por Bootstrap, el usuario puede cerrar la notificación.&lt;/p&gt;
&lt;p&gt;Para incluir este fragmento en la vista donde deseo que se muestre la notificación, uso:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:replace&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;~{fragments/messageAlert :: messageAlert}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;inicializando-las-variables-message-y-messagetype&quot;&gt;Inicializando las variables message y messageType&lt;/h2&gt;
&lt;p&gt;Como he comentado, voy a usar variables de sesión http para guardar el contenido del mensaje y el tipo de mensaje. Para ello creo un filtro de sesión que compruebe, por cada petición http, si existe una sesión y si las variables de sesión están creadas.&lt;/p&gt;
&lt;p&gt;He incluido el siguiente componente en &lt;code&gt;/Utils/SessionFilter.java&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Component&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SessionFilter&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; implements&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Filter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; init&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(FilterConfig &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;filterConfig&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throws&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ServletException {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; doFilter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(ServletRequest &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;request&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, ServletResponse &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;response&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, FilterChain &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;chain&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            throws&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IOException, ServletException {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        HttpServletRequest httpRequest &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (HttpServletRequest) request;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        HttpServletResponse httpResponse &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (HttpServletResponse) response;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        HttpSession session &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; httpRequest.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getSession&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // Variables para las notificaciones&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageType&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageType&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;                // Valores: &quot;danger&quot; u otro cualquiera = &quot;info&quot;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        chain.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;doFilter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(request, response);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; destroy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con &lt;code&gt;HttpSession session = httpRequest.getSession(true);&lt;/code&gt; Obtengo la sesión, y si no existe, se creará una nueva. Esto ocurre porque he incluido el valor &lt;code&gt;true&lt;/code&gt; en &lt;code&gt;.getSession(true)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Si existe la sesión (que, salvo error, ya debería existir), compruebo que las variables &lt;code&gt;message&lt;/code&gt; y &lt;code&gt;messageType&lt;/code&gt; estén inicializadas, y si no lo están las inicializo a &lt;code&gt;&quot;&quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Tras esto, ya podremos usar &lt;code&gt;session.getAttribute()&lt;/code&gt; y &lt;code&gt;session.setAttribute()&lt;/code&gt; para leer y para actualizar el valor de las variables de sesión desde nuestros servicios o controladores, como veremos.&lt;/p&gt;
&lt;h2 id=&quot;usando-mensajes&quot;&gt;Usando mensajes&lt;/h2&gt;
&lt;p&gt;Pensemos en un servicio que guarde el contenido de un formulario para crear un cine. Sería algo similar a esto:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Slf4j&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;RequiredArgsConstructor&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Service&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; CinemaServiceImpl&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; implements&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ICinemaService&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    private&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; final&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; CinemaRepository cinemaRepo;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Otras propiedades y métodos de la clase aquí&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Transactional&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Cinema &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;save&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(Cinema &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;cinema&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        log.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;save {}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, cinema);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; cinemaRepo.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;save&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(cinema);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (Exception &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            log.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Error al guardar el cine: &quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, e);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Como se ve, la clase &lt;code&gt;CinemaServiceImpl&lt;/code&gt; implementa la interfaz &lt;code&gt;ICinemaService&lt;/code&gt;, inyecta el repositorio &lt;code&gt;CinemaRepository&lt;/code&gt; y tiene un método que guarda un cine. &lt;code&gt;cinema&lt;/code&gt; es enviado al método &lt;code&gt;save&lt;/code&gt; desde el controlador que lo usa, y el método devuelve el cine guardado o null si se produjo un error.&lt;/p&gt;
&lt;p&gt;A continuación muestro cómo se verá el método al incluir los mensajes de éxito o error:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Slf4j&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;RequiredArgsConstructor&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Service&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; CinemaServiceImpl&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; implements&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; ICinemaService&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    private&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; final&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; HttpSession session;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    private&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; final&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; CinemaRepository cinemaRepo;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Otras propiedades y métodos de la clase aquí&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Transactional&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Cinema &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;save&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(Cinema &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;cinema&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        log.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;save {}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, cinema);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            Cinema newCinema &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; cinemaRepo.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;save&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(cinema);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            String message &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;Cine &quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; newCinema &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot; guardado.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, message);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageType&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;info&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; newCinema;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (Exception &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            log.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Error al guardar el cine: &quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, e);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;El cine no ha podido guardarse.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageType&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;danger&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con &lt;code&gt;session.setAttribute(&quot;message&quot;, message);&lt;/code&gt; se cambia el valor de la variable &lt;code&gt;message&lt;/code&gt;, y con &lt;code&gt;session.setAttribute(&quot;messageType&quot;, &quot;info&quot;);&lt;/code&gt; se hace lo propio con la variable &lt;code&gt;messageType&lt;/code&gt;. Lo mismo ocurre en caso de error.&lt;/p&gt;
&lt;p&gt;A tener en cuenta: en &lt;code&gt;String message = &quot;Cine &quot; + newCinema + &quot; guardado correctamente.&quot;;&lt;/code&gt; hay que estar seguro de que la entidad &lt;code&gt;Cinema&lt;/code&gt; sobrescribe (@Override) el método &lt;code&gt;toString()&lt;/code&gt; para poder usarlo como String.&lt;/p&gt;
&lt;p&gt;El resultado es algo como lo que se muestra a continuación.&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Notificación activa&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/notificaciones.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt;&lt;/p&gt;
&lt;p&gt;Lo que se ve es lo que hemos definido en el fragmento &lt;code&gt;messageAlert.html&lt;/code&gt; que hemos incluido en la plantilla de la vista.&lt;/p&gt;
&lt;h2 id=&quot;mensajes-encadenados&quot;&gt;Mensajes encadenados&lt;/h2&gt;
&lt;p&gt;Si realizamos más de una gestión crítica desde un mismo controlador, como, por ejemplo, actualizar la información de un cine, y si este no está está operativo (p.ej. si ha cerrado temporalmente), entonces desactivar todas las salas de ese cine para que no se muestren en la aplicación, podemos encadenar los mensajes de ambos servicios. Para ello debemos leer el valor de la variable &lt;code&gt;message&lt;/code&gt; en el segundo servicio, el que se ocupe de desactivar las salas, y añadir el aviso al nuevo mensaje, ya que sólo disponemos de un mensaje que puede ser mostrado a la vez:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;String message &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (String) session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, message &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot; Salas desactivadas correctamente.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;cerrando-la-notificación-al-cambiar-de-página&quot;&gt;Cerrando la notificación al cambiar de página&lt;/h2&gt;
&lt;p&gt;Como sabemos, la notificación puede cerrarse haciendo clic en la &lt;code&gt;X&lt;/code&gt; de cierre, o bien cerrarse cuando cambiamos de página. Al cambiar de página, el filtro &lt;code&gt;SessionFilter&lt;/code&gt; se ejecutará, y para que ocurra lo que queremos es necesario incluir una nueva variable y mas comprobaciones, como se muestra a continuación:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Component&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SessionFilter&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; implements&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Filter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; init&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(FilterConfig &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;filterConfig&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throws&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ServletException {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; doFilter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(ServletRequest &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;request&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, ServletResponse &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;response&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, FilterChain &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;chain&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            throws&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IOException, ServletException {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        HttpServletRequest httpRequest &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (HttpServletRequest) request;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        HttpServletResponse httpResponse &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (HttpServletResponse) response;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        HttpSession session &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; httpRequest.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getSession&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // Variables para las notificaciones&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageType&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageType&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;                // Valores: &quot;danger&quot; u otro cualquiera = &quot;info&quot;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // Cierre de notificaciones al cambiar de página&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ((&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;boolean&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Objects.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;equals&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((String) session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;), &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        chain.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;doFilter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(request, response);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; destroy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En estos tres nuevos bloques de sentencias &lt;code&gt;if&lt;/code&gt; , primero compruebo que la variable de sesión &lt;code&gt;messageActivated&lt;/code&gt; está inicializada, como hacía con las otras variables de sesión, y si no lo está, la inicializo a false.&lt;/p&gt;
&lt;p&gt;Como cada vez que se muestra una página en la aplicación se lanza &lt;code&gt;SessionFilter&lt;/code&gt;, en el siguiente bloque de sentencias compruebo si &lt;code&gt;messageActivated&lt;/code&gt; está activado (&lt;code&gt;true&lt;/code&gt;), y si lo está, la desactivo, y vacío &lt;code&gt;message&lt;/code&gt; para que no vuelva a mostrarse la notificación. Recordemos que el fragment &lt;code&gt;messageAlert.html&lt;/code&gt; sólo muestra la notificación si su contenido no es &lt;code&gt;&quot;&quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;En el último bloque, si &lt;code&gt;message&lt;/code&gt; contiene texto y es la primera vez que se va a mostrar la notificación, el bloque anterior no la habrá borrado. Entonces activo &lt;code&gt;messageActivated&lt;/code&gt; para que la notificación pueda ser eliminada la siguiente vez que se muestre una página.&lt;/p&gt;
&lt;p&gt;Como se aprecia, &lt;code&gt;messageActivated&lt;/code&gt; actúa como indicador de borrado, y en este proceso es determinante el orden en el que se hacen las comprobaciones.&lt;/p&gt;
&lt;p&gt;Con esto, ya tenemos activo nuestro propio sistema de notificaciones para Thymeleaft.&lt;/p&gt;
&lt;p&gt;Adaptando este método sería posible, por ejemplo, generar notificaciones que permitan consultar al usuario si quiere llevar a cabo o no una tarea determinada, como p.ej. &lt;code&gt;&quot;¿Desea borrar el cine? [Sí] [No]&quot;&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;bonus-aviso-de-cookies&quot;&gt;BONUS: Aviso de cookies&lt;/h1&gt;
&lt;p&gt;Es fácil realizar los cambios para, por ejemplo, notificar un aviso de cookies con un botón de aceptar que permanezca abierto hasta que el usuario lo cierre, o incluso poner un banner, o cualquier aviso temporal que requiera nuestra aplicación. Hagamos el proceso de ejemplo de un aviso de cookies.&lt;/p&gt;
&lt;p&gt;El planteamiento cambia un poco. Si vamos a emplear ambos métodos, el de notificar lo que ocurre en la aplicación y el aviso de cookies, debemos usar una variable propia que actúe de «llave» para la cookie.&lt;/p&gt;
&lt;p&gt;La notificación estará disponible en la vista actual y en todas aquellas vistas que tengan el fragmento de código de la cookie incluido en la plantilla hasta que se lo indiquemos. Como no podemos eliminar el contenido de la notificación desde Thymeleaft, y no sabemos el momento en el que el usuario eliminará la ventana de notificación, la variable de sesión que guarda la notificación se manejará desde el &lt;em&gt;backend&lt;/em&gt;, mediante un controlador y una ruta que nos permita cambiar su valor.&lt;/p&gt;
&lt;h2 id=&quot;el-filtro&quot;&gt;El filtro&lt;/h2&gt;
&lt;p&gt;Comienzo añadiendo la nueva variable &lt;code&gt;cookieWarning&lt;/code&gt; de sesión al filtro:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Component&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SessionFilter&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; implements&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Filter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; init&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(FilterConfig &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;filterConfig&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throws&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ServletException {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; doFilter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(ServletRequest &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;request&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, ServletResponse &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;response&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, FilterChain &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;chain&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            throws&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; IOException, ServletException {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        HttpServletRequest httpRequest &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (HttpServletRequest) request;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        HttpServletResponse httpResponse &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (HttpServletResponse) response;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        HttpSession session &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; httpRequest.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getSession&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // Variables para las notificaciones&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageType&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageType&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;); &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;                // Valores: &quot;danger&quot; u otro cualquiera = &quot;info&quot;.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // Cierre de notificaciones al cambiar de página&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; ((&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;boolean&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;Objects.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;equals&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;((String) session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;), &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;messageActivated&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // Gestión de la cookie&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;cookieWarning&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;cookieWarning&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        chain.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;doFilter&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(request, response);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Override&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; void&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; destroy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En este caso, la variable tendrá valor &lt;code&gt;true&lt;/code&gt; por defecto, lo que indica que el fragmento de aviso de cookies debe mostrarse. Cuando la cerremos, este valor cambiará a &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;el-fragmento-1&quot;&gt;El fragmento&lt;/h2&gt;
&lt;p&gt;Podemos llamar al fragmento que mostrará la notificación &lt;code&gt;cookieWarnig.html&lt;/code&gt;, e incluirlo en todas nuestras páginas mediante:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:replace&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;~{fragments/cookieWarning :: cookieWarning}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Este es su código:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:fragment&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;cookieWarning&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;${session.cookieWarning}&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;container mt-3 sticky-top&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:action&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;@{/cookie}&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; method&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;POST&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;hidden&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;returnUrl&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:value&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;${returnUrl}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alert alert-warning alert-dismissible fade show shadow d-flex justify-content-between&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; role&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alert&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; xmlns&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;http://www.w3.org/2000/svg&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fill&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;none&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; viewBox&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;0 0 24 24&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;1.5&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;currentColor&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;24&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;24&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-linecap&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; stroke-linejoin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; d&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;M10.34 15.84c-.688-.06-1.386-.09-2.09-.09H7.5a4.5 4.5 0 1 1 0-9h.75c.704 0 1.402-.03 2.09-.09m0 9.18c.253.962.584 1.892.985 2.783.247.55.06 1.21-.463 1.511l-.657.38c-.551.318-1.26.117-1.527-.461a20.845 20.845 0 0 1-1.44-4.282m3.102.069a18.03 18.03 0 0 1-.59-4.59c0-1.586.205-3.124.59-4.59m0 9.18a23.848 23.848 0 0 1 8.835 2.535M10.34 6.66a23.847 23.847 0 0 0 8.835-2.535m0 0A23.74 23.74 0 0 0 18.795 3m.38 1.125a23.91 23.91 0 0 1 1.014 5.395m-1.014 8.855c-.118.38-.245.754-.38 1.125m.38-1.125a23.91 23.91 0 0 0 1.014-5.395m0-3.46c.495.413.811 1.035.811 1.73 0 .695-.316 1.317-.811 1.73m0-3.46a24.347 24.347 0 0 1 0 3.46&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;amp;nbsp;&amp;amp;nbsp;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;align-middle&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;strong&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Atención:&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;strong&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; Este sitio usa cookies. Lea la Política de privacidad.&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;span&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;submit&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;btn btn-sm btn-outline-primary&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; data-bs-dismiss&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;alert&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; aria-label&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Confirmar&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;OK&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nuestra notificación de cookie se verá así:&lt;/p&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Notificación de cookie&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/notificaciones-cookie.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt;&lt;/p&gt;
&lt;p&gt;La comprobación &lt;code&gt;th:if=&quot;${session.cookieWarning}&quot;&lt;/code&gt; hará que se muestre o no este fragmento, osea, que se muestre o no la notificación de cookies.&lt;/p&gt;
&lt;p&gt;Como se aprecia, se incluye un formulario que actuará cuando el usuario cierre la notificación. Con el botón &lt;code&gt;button type=&quot;submit&quot;&lt;/code&gt;, mediante el formulario, llamo al controlador que va a desactivar la notificación de cookie a través la ruta indicada en el formulario: &lt;code&gt;&amp;lt;form th:action=&quot;@{/cookie}&quot; method=&quot;POST&quot;&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Con &lt;code&gt;&amp;lt;input type=&quot;hidden&quot; th:name=&quot;returnUrl&quot; th:value=&quot;${returnUrl}&quot;&amp;gt;&lt;/code&gt; indico, a través de la respuesta de formulario al controlador, a qué página debo dirigirme después de realizar la operación, pues, como dije, no sabemos en qué momento el usuario cerrará la notificación. Esto me permitirá volver a la página donde estaba una vez se procese el cambio del valor de la variable de sesión de la cookie.&lt;/p&gt;
&lt;p&gt;Suelo usar de forma genérica &lt;code&gt;returnUrl&lt;/code&gt; para indicar la ruta porque es útil para, por ejemplo, cuando llamo a un formulario y quiero saber dónde debo ir una vez enviado el contenido del formulario, como en este caso. Por ejemplo, si nuestra aplicación maneja cines, y añadimos, editamos o borramos un cine, mediante &lt;code&gt;returnUrl&lt;/code&gt; puedo indicar al método &lt;code&gt;@PostMapping&lt;/code&gt; qué vista mostrar tras realizar estas operaciones. Para poder hacerlo, cuando usé las vistas de crear, editar o borrar mencionadas, añado esta variable al modelo con:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;model.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;addAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;returnUrl&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;cinemas&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;donde cinemas es la ruta a la que se debe llegar una vez el formulario de la ruta a la que vamos se procese. El método se vería así:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;GetMapping&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;/create&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; String &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;createForm&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(Model model) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    model.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;addAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;cinema&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Cinema&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    model.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;addAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;returnUrl&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;cinemas&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;cinema/cinema-form&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;cerrando-la-notificación-de-cookie&quot;&gt;Cerrando la notificación de cookie&lt;/h2&gt;
&lt;p&gt;En la carpeta &lt;code&gt;controllers&lt;/code&gt;, creo el controlador &lt;code&gt;CookieController&lt;/code&gt; siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Controller&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; CookieController&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;PostMapping&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;/cookie&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; String &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;closeCookiePolicy&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(HttpSession &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;session&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;RequestParam&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;returnUrl&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;required&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) String &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;returnUrl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        session.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAttribute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;cookieWarning&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;stringIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(returnUrl)) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;redirect:&quot;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; returnUrl;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;redirect:/&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Así, a través de la ruta &lt;code&gt;/cookie&lt;/code&gt; puedo cambiar el valor de &lt;code&gt;cookieWarning&lt;/code&gt; con: &lt;code&gt;session.setAttribute(&quot;cookieWarning&quot;, false);&lt;/code&gt; y luego volver a la ruta deseada si hemos pasado el parámetro &lt;code&gt;returnUrl&lt;/code&gt;. Ahora la notificación ya no se mostrará más.&lt;/p&gt;
&lt;p&gt;Es importante que la ruta &lt;code&gt;/cookie&lt;/code&gt; esté definida en nuestra configuración de seguridad. Si estamos usando Spring Security, en &lt;code&gt;SecurityConfig.class&lt;/code&gt; debe haber algo como esto:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Bean&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; SecurityFilterChain &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;securityFilterChain&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(HttpSecurity http) throws Exception {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    http&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;authorizeHttpRequests&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(authRequest &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; authRequest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // otras configuraciones&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;requestMatchers&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(HttpMethod.POST, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;/cookie&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;permitAll&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;            // otras configuraciones&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;anyRequest&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;authenticated&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        // otras configuraciones&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; http.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;build&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con &lt;code&gt;.requestMatchers(HttpMethod.POST, &quot;/cookie&quot;).permitAll()&lt;/code&gt; la ruta &lt;code&gt;/cookie&lt;/code&gt; es ahora visible y ya podemos usarla desde el fragmento para cerrar nuestra notificación.&lt;/p&gt;
&lt;h1 id=&quot;un-ejemplo&quot;&gt;Un ejemplo&lt;/h1&gt;
&lt;p&gt;Puedes ver el código que implementan estos métodos, tanto las notificaciones como los mensajes fijos de cookies, en el repositorio de la aplicación &lt;a href=&quot;/blog/cartelera-daw&quot;&gt;Cartelera DAW&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/cartelera-daw&quot;&gt;Repositorio de Cartelera DAW&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/notificaciones.DrEXfhr5_Z1sRXMQ.webp"/><category>código</category><category>java</category><category>spring boot</category><category>bootstrap</category><category>thymeleaft</category><author>JavGuerra</author></item><item><title>Spinner loader en Thymeleaft</title><link>https://javguerra.github.io/blog/loader-thymeleaft</link><guid isPermaLink="true">https://javguerra.github.io/blog/loader-thymeleaft</guid><description>Esperando la respuesta del backend</description><pubDate>Mon, 08 Jul 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/spinner-loader.BwuWn1K3_1CpEz3.webp&quot; alt=&quot;Spin&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#java&lt;/em&gt;, &lt;em&gt;#spring boot&lt;/em&gt;, &lt;em&gt;#thymeleaft&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;A veces, el tiempo de respuesta del servidor es alto, y el usuario puede sentir que la aplicación web no está funcionando bien. Aquí explico cómo usar un spinner loader o animación de carga propia, generada con CSS, que se active al cargar la página y permanezca activa hasta que se muestre completamente.&lt;/p&gt;
&lt;p&gt;Esta entrada hace uso y adapta los contenidos ya explicados anteriormente en este blog en &lt;a href=&quot;/blog/spinner-loader-asincrono&quot;&gt;Spinner loader asíncrono&lt;/a&gt;, pero en este caso se simplifica el proceso al plantear una solución que no se basa en eventos asíncronos.&lt;/p&gt;
&lt;h1 id=&quot;manos-a-la-obra&quot;&gt;Manos a la obra&lt;/h1&gt;
&lt;p&gt;Lo que voy a hacer es mostrar el cargador cada vez que entramos en una página, y hasta que esta se carga completamente. Usaré JavaScript para activarlo y desactivarlo.&lt;/p&gt;
&lt;p&gt;Necesitaré un espacio donde mostrar la animación de carga y el CSS que defina esta animación.&lt;/p&gt;
&lt;h2 id=&quot;el-fragmento&quot;&gt;El fragmento&lt;/h2&gt;
&lt;p&gt;Para incluir el código necesario en nuestras vistas con Thymeleaft, creo un fragmento que llamo &lt;code&gt;spinner.html&lt;/code&gt; como este:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:fragment&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;spinner&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;dialog&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;zone&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;spinner&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; aria-label&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Cargando...&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;dialog&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; zone&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;querySelector&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;#zone&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        // Activa la ventana modal&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        let&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; domContentLoadedCallback&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            zone.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;showModal&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;removeEventListener&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;DOMContentLoaded&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, domContentLoadedCallback);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        // Desactiva la ventana modal&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        let&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; loadCallback&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            zone.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            window.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;removeEventListener&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;load&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, loadCallback);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        };&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;DOMContentLoaded&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, domContentLoadedCallback);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        window.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;load&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, loadCallback);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Puedo incluir este fragmento en cualquier parte de la plantilla Thymeleaft con:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:replace&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;~{fragments/spinner :: spinner}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Realmente no importa en qué parte de la plantilla incluyamos el fragmento, pues va a hacer uso de &lt;code&gt;dialog&lt;/code&gt;, una etiqueta HTML que define una ventana modal que se muestra en el centro exacto de la ventana del navegador.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;dialog&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;zone&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;spinner&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; aria-label&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Cargando...&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;dialog&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Este simple código define una ventana modal identificada como &lt;code&gt;zone&lt;/code&gt; y un div que servirá para mostrar el cargador definido a través de la clase &lt;code&gt;spinner&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Mediante el código JavaScript posterior, selecciono la ventana modal &lt;code&gt;zone&lt;/code&gt; sobre la que voy a actuar, y luego defino dos eventos, el primero hará que se muestre el cargador y el segundo que se desactive.&lt;/p&gt;
&lt;p&gt;El primer evento se dispara cuando el HTML se ha cargado completamente (&lt;code&gt;DOMContentLoaded&lt;/code&gt;), y el segundo cuando todos los contenidos referenciados en la página son cargados (&lt;code&gt;load&lt;/code&gt;). Entre el primer y el segundo evento, el cargador es visible.&lt;/p&gt;
&lt;p&gt;Con &lt;code&gt;zone.showModal();&lt;/code&gt; se activa la ventana modal, y con &lt;code&gt;zone.close();&lt;/code&gt; se desactiva. En realidad, el cargador está ahí en todo momento, pero no está visible en todo momento.&lt;/p&gt;
&lt;p&gt;Dentro de cada función que gestiona el evento he incluido también el código para quitar el evento una vez usado.&lt;/p&gt;
&lt;h2 id=&quot;el-css&quot;&gt;El CSS&lt;/h2&gt;
&lt;p&gt;Con el siguiente código:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;css&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;#zone&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  border&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  background&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;#zone:focus&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  outline&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.spinner&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  margin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; auto&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  border&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; solid&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; moccasin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;36&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;36&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  border-radius&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;50&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  border-left-color&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;DarkOrange&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  animation&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: spin &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; ease&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; infinite&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;@keyframes&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt; spin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  0%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;rotate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;deg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;); }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  100%&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;transform&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;rotate&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;360&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;deg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;); }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;No debemos olvidar incluir algo como:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; rel&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;stylesheet&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; href&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;/css/estilo.css&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;en el &lt;code&gt;head&lt;/code&gt; de las plantillas donde vayamos a usar el cargador, cambiando &lt;code&gt;estilo.css&lt;/code&gt; y su ruta según corresponda.&lt;/p&gt;
&lt;p&gt;El modal identificado como &lt;code&gt;#zone&lt;/code&gt; se verá sin fondo y sin borde, osea, totalmente transparente. En él es donde se muestra el cargador. &lt;code&gt;#zone&lt;/code&gt; tendrá el tamaño del cargador, y aparecerá centrado tanto vertical como horizontalmente en la pantalla, manteniéndose centrado aún haciendo &lt;em&gt;scroll&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Con &lt;code&gt;.spinner&lt;/code&gt; describo el aspecto del &lt;em&gt;spinner loader&lt;/em&gt;, e indico que debe animarse infinitamente girando 360 grados cada segundo.&lt;/p&gt;
&lt;p&gt;Realmente se trata de colorear el borde a un div, poner un color distinto al borde de uno de sus lados, redondear sus esquinas para que el div parezca un círculo y luego hacerlo girar constantemente. Simple y efectivo.&lt;/p&gt;
&lt;p&gt;Y no necesitamos nada más. Ahora, cada vez que se cargue una página, veremos el cargador durante el tiempo que tarda en cargarse completamente.&lt;/p&gt;
&lt;p&gt;No se recomienda abusar del cargador, ya que este puede centrar la atención del usuario, por lo que usado con moderación, en las páginas que son susceptibles de retrasar su carga, añadimos un efecto interesante y útil a nuestra aplicación y damos información al usuario de lo que ocurre.&lt;/p&gt;
&lt;h1 id=&quot;uso-en-formularios&quot;&gt;Uso en formularios&lt;/h1&gt;
&lt;p&gt;Cuando enviamos un formulario o hacemos una petición que el backend va a tardar en procesar, también podemos activar la visualización del cargador hasta que cambie la vista. Para ello podemos añadir un evento a nuestro formulario de la siguiente manera:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;myForm&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; th:action&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;@{/setCity}&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; method&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;POST&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;send&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;submit&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Guardar&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;button&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;send&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;click&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;event&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        event.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;preventDefault&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        zone.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;showModal&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;myForm&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;submit&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Una vez identificados el formulario &lt;code&gt;myForm&lt;/code&gt; y el botón de enviar &lt;code&gt;send&lt;/code&gt;, mediante JavaScript asocio un evento que permitirá que, al hacer click en el botón de guardar, se active la ventana modal.&lt;/p&gt;
&lt;p&gt;Con &lt;code&gt;event.preventDefault();&lt;/code&gt; capturo el evento de envío del formulario para poder intercalar la activación de la ventana modal con &lt;code&gt;zone.showModal();&lt;/code&gt; antes de enviar el formulario definitivamente con &lt;code&gt;document.getElementById(&apos;myForm&apos;).submit();&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Es necesario que el fragmento &lt;code&gt;spinner.html&lt;/code&gt; se haya incluido en la página. De otra forma podemos incluir el código del cargador ya mencionado en cualquier parte de nuestra página:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;dialog&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;zone&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;spinner&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; aria-label&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Cargando...&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;dialog&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Como ya sabemos que vamos a cambiar de vista al enviar el formulario, no es necesario desactivar el evento &lt;code&gt;click&lt;/code&gt; del formulario, pero si estamos haciendo comprobaciones el en &lt;code&gt;frontend&lt;/code&gt;, es posible que necesitemos hacerlo cunado mostremos errores, lo que implica código de comprobaciones adicional. Si estamos usando &lt;code&gt;@Valid&lt;/code&gt; en nuestro &lt;code&gt;backend&lt;/code&gt;, esto no será necesario.&lt;/p&gt;
&lt;h1 id=&quot;un-ejemplo&quot;&gt;Un ejemplo&lt;/h1&gt;
&lt;p&gt;Puedes ver el código que implementa esta solución en el repositorio de la aplicación &lt;a href=&quot;/blog/cartelera-daw&quot;&gt;Cartelera DAW&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://cartelera-daw.up.railway.app/&quot;&gt;Aplicación web Cartelera DAW&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/cartelera-daw&quot;&gt;Repositorio de Cartelera DAW&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;enlaces-recomendados&quot;&gt;Enlaces recomendados&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Info sobre la etiqueta &lt;a href=&quot;https://twitter.com/Manz/status/1529836795130744834&quot;&gt;&lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Artículo «&lt;a href=&quot;https://midu.dev/como-crear-un-spinner-con-css/&quot;&gt;Cómo crear un spinner loader con CSS&lt;/a&gt;»&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/spinner-loader.BwuWn1K3_1CpEz3.webp"/><category>código</category><category>java</category><category>spring boot</category><category>thymeleaft</category><author>JavGuerra</author></item><item><title>Logout personalizado con Spring Security</title><link>https://javguerra.github.io/blog/logout-spring-security</link><guid isPermaLink="true">https://javguerra.github.io/blog/logout-spring-security</guid><description>Limpiando el contexto de seguridad sin borrar la cookie</description><pubDate>Sat, 13 Jul 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/cookies.CQlbddQu_TNB6F.webp&quot; alt=&quot;cookies&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#java&lt;/em&gt;, &lt;em&gt;#spring boot&lt;/em&gt;, &lt;em&gt;#spring security&lt;/em&gt;, &lt;em&gt;#ciberseguridad&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;En un &lt;a href=&quot;/blog/notificaciones-thymeleaft&quot;&gt;artículo anterior&lt;/a&gt; he usado variables de sesión para guardar información de la aplicación: mensajes para el usuario, aviso de cookies… Puede que, cuando el usuario salga de su sesión, queramos conservar estos datos que seguirán siendo útiles aunque no esté autenticado. En esta entrada muestro mi solución usando Spring Security.&lt;/p&gt;
&lt;p&gt;Se asume que el lector tiene conocimientos generales de Spring Boot y Spring Security para aplicar el contenido.&lt;/p&gt;
&lt;h1 id=&quot;el-contexto-de-seguridad&quot;&gt;El contexto de seguridad&lt;/h1&gt;
&lt;p&gt;El primer paso en el proceso de logout que lleva a cabo Spring Security es invalidar la sesión del usuario. Esto significa que Spring Security elimina cualquier información asociada con la sesión del usuario, como datos de estado de sesión almacenados en el servidor o en cookies (borra la información, pero no la cookie). Al invalidar la sesión, se asegura de que el usuario ya no pueda acceder a la aplicación como si estuviera autenticado.&lt;/p&gt;
&lt;p&gt;Después de invalidar la sesión, Spring Security también limpia el contexto de seguridad actual. Esto incluye eliminar cualquier token de Authentication que represente al usuario autenticado, asegurando que el usuario ya no sea reconocido como autenticado en la aplicación.&lt;/p&gt;
&lt;p&gt;Pero en este caso no interesa ese borrado completo, sino sólo la información de autenticación. Para ello debo codificar mi propio logout limpiando el contexto de seguridad pero sin invalidar la sesión.&lt;/p&gt;
&lt;h1 id=&quot;tomando-el-control-de-logout&quot;&gt;Tomando el control de Logout&lt;/h1&gt;
&lt;p&gt;Como sabemos, para configurar Spring Security se usa la clase &lt;code&gt;SecurityConfig.class&lt;/code&gt;, que generalmente incluye el componente &lt;code&gt;SecurityFilterChain&lt;/code&gt;, fundamental para establecer filtros a las peticiones HTTP que se reciben en la aplicación. En este ejemplo me centraré en la parte de su configuración relativa al logout.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Configuration&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;EnableWebSecurity&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;  SecurityConfig&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Bean&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; SecurityFilterChain &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;securityFilterChain&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(HttpSecurity &lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;http&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)  &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throws&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Exception {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        http.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;authorizeHttpRequests&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(authRequest &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; authRequest&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;requestMatchers&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(HttpMethod.POST, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;/logout&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;permitAll&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;anyRequest&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;authenticated&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;logout&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(logout &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; logout&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;logoutUrl&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;/logout&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;                .&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;permitAll&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            )&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; http.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;build&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con &lt;code&gt;...&lt;/code&gt; indico que el código puede ser más amplio y contener otras configuraciones.&lt;/p&gt;
&lt;p&gt;En la línea &lt;code&gt;.requestMatchers(HttpMethod.POST, &quot;/logout&quot;).permitAll()&lt;/code&gt; estoy permitiendo el acceso a la ruta personalizada para llevar a cabo el logout. Realmente, esto no sería necesario al incluir &lt;code&gt;.permitAll()&lt;/code&gt; después de &lt;code&gt;logoutUrl(&quot;/logout&quot;)&lt;/code&gt;. Tampoco sería necesario porque la ruta &lt;code&gt;/logout&lt;/code&gt; está disponible por defecto. No obstante, esto puede ser útil si decidimos usar otra ruta distinta a &lt;code&gt;/logout&lt;/code&gt; en la aplicación.&lt;/p&gt;
&lt;p&gt;Para la gestión del token del usuario, será necesario definir un controlador propio para la ruta &lt;code&gt;logout&lt;/code&gt;. Algo similar a esto:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Slf4j&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Controller&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; LogoutController&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;RequestMapping&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;/logout&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; String &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;logout&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        log.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;logout&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        SecurityContextHolder.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getContext&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAuthentication&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        // cosas que hacer tras el cierre de sesión aquí&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;logout&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La información de sesión se guarda en una cookie llamada &lt;code&gt;JSESSIONID&lt;/code&gt;, que contendrá las variables de sesión, incluido el token de autenticación.&lt;/p&gt;
&lt;p&gt;Con &lt;code&gt;SecurityContextHolder.getContext().setAuthentication(null);&lt;/code&gt; elimino el token de autenticación, pero sin borrar toda la información de la cookie, como las variables de sesión.&lt;/p&gt;
&lt;p&gt;Después de esto, puedo realizar algunas acciones asociadas al cierre y redirigir al login, o como en este caso, mostrar la vista &lt;code&gt;logout&lt;/code&gt; para mostrar un mensaje de despedida.&lt;/p&gt;
&lt;h1 id=&quot;refinando-el-logout&quot;&gt;Refinando el logout&lt;/h1&gt;
&lt;p&gt;Al usar &lt;code&gt;null&lt;/code&gt; elimino el token de autenticación del usuario, pero puede que, en la plantilla que devuelvo con return (&lt;code&gt;logout&lt;/code&gt; en el caso anterior), sea necesario usar el contexto de seguridad, por ejemplo mostrando una información u otra en un fragmento de la plantilla si estamos autenticados o no. Con este método, ni &lt;code&gt;sec:authorize=&quot;isAnonymous()&quot;&lt;/code&gt; ni &lt;code&gt;sec:authorize=&quot;isAuthenticated()&quot;&lt;/code&gt; funcionarán en Thymeleaft, ya que ahora no existe el token que indique si el usuario es anónimo o está autenticado.&lt;/p&gt;
&lt;p&gt;Esto ocurre sólo para la vista asociada al controlador que es llamada tras borrar el token, pero no ocurre así para las siguientes vistas, en las que parece que el token es regenerado como anónimo.&lt;/p&gt;
&lt;p&gt;Entonces, si en la siguiente vista no vamos a usar la autenticación, será suficiente con usar &lt;code&gt;null&lt;/code&gt;, pero si no es así, entonces hay que cambiar el token en vez de eliminarlo, pero Spring Boot no tiene un token por defecto que pueda usar, así que debo construir uno.&lt;/p&gt;
&lt;p&gt;Primeramente añado el siguiente código en&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Bean&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; AnonymousAuthenticationToken &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;anonymousAuthenticationToken&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    List&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;GrantedAuthority&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt; authorities &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; Collections.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;singletonList&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; SimpleGrantedAuthority&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;ROLE_ANONYMOUS&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; AnonymousAuthenticationToken&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;ANONYMOUS_USER&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;ANONYMOUS_USER&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, authorities);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Que me permitirá crear &lt;code&gt;anonymousAuthenticationToken&lt;/code&gt; como un &lt;code&gt;Bean&lt;/code&gt;. Este método es responsable de crear e inicializar el objeto &lt;code&gt;AnonymousAuthenticationToken&lt;/code&gt;. Este token es utilizado por Spring Security para representar la autenticación de usuarios anónimos dentro de una aplicación.&lt;/p&gt;
&lt;p&gt;El método realiza las siguientes acciones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Inicialización de Autoridades&lt;/strong&gt;: Primero, creo una lista (&lt;code&gt;List&amp;lt;GrantedAuthority&amp;gt;&lt;/code&gt;) con un solo elemento, que es una instancia de &lt;code&gt;SimpleGrantedAuthority&lt;/code&gt; con el rol &lt;code&gt;&quot;ROLE_ANONYMOUS&quot;&lt;/code&gt;. Las autoridades (o roles) determinan los privilegios que tiene un usuario dentro de la aplicación. En este caso, asigno al usuario anónimo el rol de &lt;code&gt;ROLE_ANONYMOUS&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Creación del Token&lt;/strong&gt;: Luego, utilizo esta lista de autoridades para construir un nuevo &lt;code&gt;AnonymousAuthenticationToken&lt;/code&gt;, pasando también dos cadenas de texto (&lt;code&gt;&quot;ANONYMOUS_USER&quot;&lt;/code&gt;) como nombre y detalles del usuario. Estos valores pueden ser personalizados según sea necesario.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ya puedo usar el token en el controlador, como se muestra:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;java&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Slf4j&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;RequiredArgsConstructor&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;Controller&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;public&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; LogoutController&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    private&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; final&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; AnonymousAuthenticationToken anonymousAuthenticationToken;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    @&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;RequestMapping&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;/logout&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    public&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; String &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;logout&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        log.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;info&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;logout&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        SecurityContextHolder.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getContext&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;().&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;setAuthentication&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(anonymousAuthenticationToken);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;        // cosas que hacer tras el cierre de sesión aquí&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;logout&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ahora sí, el usuario será anónimo, y cualquier comprobación en la plantilla Thymeleaft que incluya &lt;code&gt;sec:authorize=&quot;isAnonymous()&quot;&lt;/code&gt; permitirá que la etiqueta HTML que lo use sea mostrada.&lt;/p&gt;
&lt;h1 id=&quot;consideraciones&quot;&gt;Consideraciones&lt;/h1&gt;
&lt;p&gt;Tal vez podría crearse un servicio al que llamar desde el controlador para gestionar el logout, o un manejador propio &lt;code&gt;CustomLogoutHandler&lt;/code&gt; que realice esta función de cierre de sesión sin la necesidad de crear un controlador, y que se use directamente desde &lt;code&gt;SecurityConfig.class&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Se han de tener en cuenta las consideraciones de seguridad relacionadas con este método. Mantener información de la sesión de usuario una vez se lleva a cabo el logout no siempre es seguro, y se deben controlar las posibles fugas de información para evitar problemas.&lt;/p&gt;
&lt;h1 id=&quot;un-ejemplo&quot;&gt;Un ejemplo&lt;/h1&gt;
&lt;p&gt;Puedes ver el código que implementan esta funcionalidad en el repositorio de la aplicación &lt;a href=&quot;/blog/cartelera-daw&quot;&gt;Cartelera DAW&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/cartelera-daw&quot;&gt;Repositorio de Cartelera DAW&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mira también el artículo donde se usan las variables de sesión que quiero preservar:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/notificaciones-thymeleaft&quot;&gt;Notificaciones con Thymeleaft&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/cookies.CQlbddQu_TNB6F.webp"/><category>código</category><category>java</category><category>spring boot</category><category>spring security</category><category>ciberseguridad</category><author>JavGuerra</author></item><item><title>Accediendo a la API de Mastodon</title><link>https://javguerra.github.io/blog/api-mastodon</link><guid isPermaLink="true">https://javguerra.github.io/blog/api-mastodon</guid><description>Cómo obtener y mostrar las publicaciones de esta red social</description><pubDate>Wed, 18 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/mastodon.Dc7cm57i_1rPUNx.webp&quot; alt=&quot;Logo Mastodon&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#api&lt;/em&gt;, &lt;em&gt;#servidor&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;En este artículo vamos a ver cómo se puede acceder a la API de Mastodon, un servicio que nos permite, entre otras cosas, obtener las últimas publicaciones de un usuario concreto.&lt;/p&gt;
&lt;p&gt;Recientemente la he usado para mostrar, en el apartado &lt;a href=&quot;/social&quot;&gt;social&lt;/a&gt; de esta página, las publicaciones que escribo en la red social, empleando JavaScript del lado del cliente en Astro, es decir, que en una página .astro he incluido un script que lee y muestra las publicaciones actualizadas de mi cuenta de Mastodon.&lt;/p&gt;
&lt;p&gt;Me centraré en la parte de JavaScript y no tanto en la integración con Astro, ya que, de esta forma, será posible aprovechar la información para que pueda ser usada en otros frameworks o aplicaciones propias.&lt;/p&gt;
&lt;p&gt;El lector debe conocer las funciones avanzadas de JavaScript como asincronía y llamadas a APIs para seguir correctamente esta entrada.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;note&quot;&gt;&lt;strong&gt;Nota&lt;/strong&gt;: Este artículo ha sido publicado también en &lt;a href=&quot;https://ifgeekthen.nttdata.com/s/post/accediendo-a-la-api-de-mastodon-MCKLT5EQTUINBVBMVGH7W6S2MYXM&quot;&gt;IfGeekThen&lt;/a&gt;, el blog de NTT Data, el 18 de marzo de 2026.&lt;/span&gt;&lt;/p&gt;
&lt;h1 id=&quot;api-de-mastodon&quot;&gt;API de Mastodon&lt;/h1&gt;
&lt;p&gt;Realizaré la consulta a la &lt;a href=&quot;https://docs.joinmastodon.org/api/&quot;&gt;API de Mastodon&lt;/a&gt; mediante la función &lt;code&gt;fetch&lt;/code&gt; de JavaScript.&lt;/p&gt;
&lt;p&gt;Las consultas a la API no requieren autenticación (aunque es posible), por lo que podemos acceder a ella sin ningún tipo de token, pero voy a necesitar:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;La url de la instancia de Mastodon, es decir el servidor.&lt;/li&gt;
&lt;li&gt;El id de la cuenta de usuario que quiero consultar.&lt;/li&gt;
&lt;li&gt;El número que indique la cantidad de publicaciones que quiero obtener.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cuando tengamos estos datos, podremos construir el &lt;code&gt;endpoint&lt;/code&gt; o url de la API de Mastodon, que será la siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;https://&amp;lt;server&amp;gt;/api/v1/accounts/&amp;lt;accountId&amp;gt;/statuses?limit=&amp;lt;limit&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Donde:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;server&amp;gt;&lt;/code&gt; es el nombre de dominio de la instancia de Mastodon, por ejemplo &lt;code&gt;mastodon.social&lt;/code&gt; o la de tu propia instancia.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;accountId&amp;gt;&lt;/code&gt; es el id de la cuenta que queremos consultar, por ejemplo &lt;code&gt;1234567890&lt;/code&gt;. Este id se obtendría de la url de la cuenta, ej.: &lt;code&gt;https://mastodon.social/@usuario&lt;/code&gt;, como se verá enseguida.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;limit&amp;gt;&lt;/code&gt; es el número de publicaciones que queremos consultar, por ejemplo &lt;code&gt;10&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Para obtener el id de la cuenta, debo usar la siguiente url:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;https://&amp;lt;server&amp;gt;/api/v1/accounts/lookup?acct=&amp;lt;username&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Donde hay que sustituir &lt;code&gt;&amp;lt;server&amp;gt;&lt;/code&gt; por el nombre de la instancia de Mastodon y &lt;code&gt;&amp;lt;username&amp;gt;&lt;/code&gt; por el nombre de usuario de la cuenta que queremos consultar.&lt;/p&gt;
&lt;p&gt;Obtengo un json con el id de la cuenta, entre otros datos, como por ejemplo:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;json&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  &quot;id&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;1234567890&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  &quot;username&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;usuario&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#FDAEB7;font-style:italic&quot;&gt;  ...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si queremos consultar las 10 últimas publicaciones de la cuenta ficticia &lt;code&gt;@usuario&lt;/code&gt;, que tiene el id ficticio: &lt;code&gt;1234567890&lt;/code&gt;, en la instancia de Mastodon &lt;code&gt;mastodon.social&lt;/code&gt;, tendríamos que usar la siguiente url:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;https://mastodon.social/api/v1/accounts/1234567890/statuses?limit=10&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;fetch&quot;&gt;Fetch&lt;/h2&gt;
&lt;p&gt;Ya tenemos formado el endpoint de la API de Mastodon, y, para llevar a cabo la consulta, usaré la función &lt;code&gt;fetch&lt;/code&gt; de JavaScript, que permite realizar peticiones HTTP, y obtener el resultado como un objeto &lt;code&gt;json&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; server&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;https://mastodon.social&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; profileId&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;1234567890&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; limit&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 10&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; route&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;server&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}/api/v1/accounts/${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;profileId&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}/statuses?limit=${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;limit&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getLatestPosts&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;route&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; response&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fetch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(route);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;response.ok) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(response.statusText);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; response.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;json&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (error) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(error);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Como se aprecia, se trata de una función asíncrona con una estructura de lo más común, que se ejecutará de manera independiente, y cuando se haya terminado de ejecutar, me permitirá seguir con la ejecución del código.&lt;/p&gt;
&lt;p&gt;Para llamar a la función, uso:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; posts&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getLatestPosts&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(route);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con &lt;code&gt;await&lt;/code&gt;, se espera a que la función &lt;code&gt;getLatestPosts&lt;/code&gt; termine de ejecutarse, y luego es posible usar el array &lt;code&gt;posts&lt;/code&gt; para mostrar las publicaciones en nuestra página, siempre que no se haya producido ningún error.&lt;/p&gt;
&lt;h2 id=&quot;mostrando-las-publicaciones&quot;&gt;Mostrando las publicaciones&lt;/h2&gt;
&lt;p&gt;Allí donde vamos a mostrar las publicaciones, voy a usar un elemento &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; con el &lt;code&gt;id=&quot;posts&quot;&lt;/code&gt; para definir una lista de publicaciones, un &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt;, y un elemento &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; para cada publicación.&lt;/p&gt;
&lt;p&gt;Incluyo el siguiente código HTML en la página:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;posts&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Cargando...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Y luego, mediante el script de JavaScript, sustituiré el contenido del elemento &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; con las publicaciones obtenidas y formateadas:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; displayPosts&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;posts&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; postsElement&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;posts&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;posts &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; posts.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    postsElement.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&amp;lt;p&amp;gt;No se encontraron posts.&amp;lt;/p&amp;gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  postsElement.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &amp;lt;h2&amp;gt;Últimas publicaciones&amp;lt;/h2&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &amp;lt;ul&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;posts&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;post&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; isReblog&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; post&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;reblog&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; originalPost&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; isReblog&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; post&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;reblog&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; post&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; contentIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;replace&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#DBEDFF&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;^&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;gt;]&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#DBEDFF&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;===&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; hasMedia&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;media_attachments&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;media_attachments&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; multimediaLink&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; hasMedia&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ?&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&amp;lt;small&amp;gt;Incluye contenido multimedia &amp;lt;a href=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot;&amp;gt;👁️ Ver en origen →&amp;lt;/a&amp;gt;&amp;lt;/small&amp;gt;&amp;lt;br /&amp;gt;`&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      return&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &amp;lt;li class=&quot;post&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;isReblog&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            ?&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;} &amp;lt;small&amp;gt;♻️ Republicado &amp;lt;/small&amp;gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            :&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; contentIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; hasMedia&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;              ?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; multimediaLink&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;              :&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; multimediaLink&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          &amp;lt;a href=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &amp;lt;small&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;              📢 ${&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Date&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;created_at&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toLocaleString&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;es-ES&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;, {dateStyle: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;medium&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;, timeStyle: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;short&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;})&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &amp;lt;/small&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          &amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &amp;lt;/li&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;      }).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;join&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &amp;lt;/ul&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;  `&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}   &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Vamos por partes.&lt;/p&gt;
&lt;p&gt;Primero obtengo el elemento &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; con el id &lt;code&gt;posts&lt;/code&gt; del DOM, y lo guardo en una variable &lt;code&gt;postsElement&lt;/code&gt; para poder referirme a él en el script.&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; postsElement&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;posts&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Compruebo que hay publicaciones y que el array &lt;code&gt;posts&lt;/code&gt; no esté vacío. Si no es así, defino el contenido del elemento &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; con el siguiente código:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;postsElement.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&amp;lt;p&amp;gt;No se encontraron posts.&amp;lt;/p&amp;gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si hemos obtenidos publicaciones, hago uso de la siguiente estructura:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;postsElement.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &amp;lt;h2&amp;gt;Últimas publicaciones&amp;lt;/h2&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &amp;lt;ul&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;posts&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;post&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        // código para mostrar cada publicación&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    `&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;join&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &amp;lt;/ul&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;  `&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con la función &lt;code&gt;map&lt;/code&gt; puedo iterar sobre cada elemento del objeto &lt;code&gt;posts&lt;/code&gt; y acceder a cada una de las publicaciones, y luego puedo juntar todos los elementos formateados en una cadena de texto mediante la función &lt;code&gt;join&lt;/code&gt;. El resultado se incluirá en el elemento &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; con el id &lt;code&gt;posts&lt;/code&gt; mediante el método &lt;code&gt;innerHTML&lt;/code&gt; de &lt;code&gt;postElement&lt;/code&gt;. Es decir, obtengo cada publicación, esta se formatea, y se concatena o añade a la cadena de texto que conforma el contenido del elemento &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;; las publicaciones.&lt;/p&gt;
&lt;h2 id=&quot;pintando&quot;&gt;Pintando…&lt;/h2&gt;
&lt;p&gt;Para formatear las publicaciones, voy a usar una estructura de elementos &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; por cada publicación, como dije, y un elemento &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; para enlazar a la publicación original. Lo que quiero conseguir se parece a esto:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;post&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  Este es un ejemplo de una publicación en Mastodon.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; href&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;https://mastodon.social/@usuario/109292343224519197&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;small&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;18 sep 2024, 1:23:45&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;small&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;De cada publicación obtengo el contenido de la publicación, y el enlace a la publicación. Con esta información defino una serie de variables:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; isReblog&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; post.reblog &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; originalPost&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; isReblog &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; post.reblog &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; post;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; contentIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost.content &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost.content.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;replace&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#DBEDFF&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;^&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;gt;]&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#DBEDFF&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;===&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; hasMedia&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost.media_attachments &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost.media_attachments.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; multimediaLink&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; hasMedia &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&amp;lt;small&amp;gt;Incluye contenido multimedia &amp;lt;a href=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot;&amp;gt;👁️ Ver en origen →&amp;lt;/a&amp;gt;&amp;lt;/small&amp;gt;&amp;lt;br /&amp;gt;`&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Como las publicaciones pueden ser republicaciones, es decir, publicaciones compartidas de otros usuarios o propias, compruebo si este es el caso.&lt;/p&gt;
&lt;p&gt;Si es una republicación, obtengo su contenido, sino, obtengo el contenido de la publicación original.&lt;/p&gt;
&lt;p&gt;Compruebo si el texto de la publicación está verdaderamente vacío, es decir, si no contiene, por ejemplo, alguna etiqueta HTML.&lt;/p&gt;
&lt;p&gt;Compruebo también si la publicación tiene contenido multimedia.&lt;/p&gt;
&lt;p&gt;Por último, si la publicación tiene contenido multimedia, preparo el enlace a la publicación original, y si no lo tiene, dejo el aviso vacío.&lt;/p&gt;
&lt;p&gt;Seguidamente, formateo el texto de la publicación mediante el siguiente código:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;post&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ${isReblog &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      ?&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;} &amp;lt;small&amp;gt;♻️ Republicado &amp;lt;/small&amp;gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      :&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; contentIsEmpty &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; hasMedia&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        ?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; multimediaLink&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        :&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost.content &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; multimediaLink}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; href&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;${originalPost.url}&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;small&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        📢 ${&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Date&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(originalPost.created_at).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toLocaleString&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;es-ES&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, {dateStyle: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;medium&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, timeStyle: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;short&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;})}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;small&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;¿Se trata de una republicación?, entonces publico el texto de la republicación con el aviso de &lt;code&gt;♻️ Republicado&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;En caso contrario, compruebo si el texto de la publicación está vacío y si tiene contenido multimedia.&lt;/p&gt;
&lt;p&gt;Si ambas condiciones se cumplen, entonces publico el aviso de ver &lt;code&gt;👁️ Ver en origen →&lt;/code&gt; con su enlace, ya que será una publicación sin texto pero con video o imagen…&lt;/p&gt;
&lt;p&gt;Si no se cumple alguna o ambas condiciones, entonces publico el contenido de la publicación y el aviso de ver &lt;code&gt;👁️ Ver en origen →&lt;/code&gt; con su enlace, pues o bien la publicación tiene contenido, tiene texto y contenido multimedia o sólo texto.&lt;/p&gt;
&lt;p&gt;Para mostrar la fecha, uso la función &lt;code&gt;toLocaleString&lt;/code&gt; de JavaScript, que me permite obtener la fecha en formato local.&lt;/p&gt;
&lt;p&gt;Es posible llamar a la función &lt;code&gt;displayPosts&lt;/code&gt; mediante:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;js&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;displayPosts&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(posts);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Siendo &lt;code&gt;posts&lt;/code&gt; el objeto de publicaciones en json obtenido de la API de Mastodon.&lt;/p&gt;
&lt;h2 id=&quot;una-advertencia&quot;&gt;Una advertencia&lt;/h2&gt;
&lt;p&gt;Si bien las instancias de Mastodon se encargan de limpiar las publicaciones de los usuarios ante potenciales peligros, no estaría de más implementar una función propia que se ocupe de limpiar el contenido de las publicaciones antes de hacer uso de &lt;code&gt;originalPost.content&lt;/code&gt; para evitar sorpresas por la inclusión de etiquetas o atributos dañinos que pudieran llegar de publicaciones de instancias de Mastodon poco confiables.&lt;/p&gt;
&lt;h1 id=&quot;el-código-completo&quot;&gt;El código completo&lt;/h1&gt;
&lt;p&gt;El código siguiente incluye el contenido mostrado hasta ahora en el artículo:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;html&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;DOCTYPE&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; html&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; lang&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;es&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; charset&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;UTF-8&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;viewport&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; content&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;width=device-width, initial-scale=1.0&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Publicaciones de Mastodon&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;link&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; rel&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;stylesheet&quot;&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; href&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;style.css&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;Mastodon&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;h1&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; id&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;posts&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        Cargando...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    &amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;    // Sustituye los valores siguientes para adaptarlo a tu propio uso&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; server&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;https://mastodon.social&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; profileId&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;1234567890&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; limit&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 10&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; route&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;server&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}/api/v1/accounts/${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;profileId&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}/statuses?limit=${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;limit&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    async&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getLatestPosts&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;route&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        try&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; response&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; fetch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(route);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;response.ok) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(response.statusText);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; response.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;json&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        } &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (error) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;            console.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(error);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;            return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;    function&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; displayPosts&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;posts&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; postsElement&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;getElementById&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;posts&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      if&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;posts &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; posts.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ===&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;        postsElement.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&amp;lt;p&amp;gt;No se encontraron posts.&amp;lt;/p&amp;gt;&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;        return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;      postsElement.innerHTML &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &amp;lt;h2&amp;gt;Últimas publicaciones&amp;lt;/h2&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &amp;lt;ul&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;posts&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;post&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;          const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; isReblog&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; post&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;reblog&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !=&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;          const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; originalPost&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; isReblog&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; post&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;reblog&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; post&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;          const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; contentIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;replace&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#DBEDFF&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;^&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;&amp;gt;]&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:#DBEDFF&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;g&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;() &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;===&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;          const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; hasMedia&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;media_attachments&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;media_attachments&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;          const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; multimediaLink&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; hasMedia&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ?&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&amp;lt;small&amp;gt;Incluye contenido multimedia &amp;lt;a href=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot;&amp;gt;👁️ Ver en origen →&amp;lt;/a&amp;gt;&amp;lt;/small&amp;gt;&amp;lt;br /&amp;gt;`&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; :&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;          return&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &amp;lt;li class=&quot;post&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;              ${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;isReblog&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                ?&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; `${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;} &amp;lt;small&amp;gt;♻️ Republicado &amp;lt;/small&amp;gt;`&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                :&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; contentIsEmpty&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; hasMedia&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                  ?&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; multimediaLink&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;                  :&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;content&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; +&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; multimediaLink&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;              &amp;lt;a href=&quot;${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &amp;lt;small&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                  📢 ${&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Date&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;originalPost&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;created_at&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;toLocaleString&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;es-ES&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;, {dateStyle: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;medium&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;, timeStyle: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;short&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;})&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;                &amp;lt;/small&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;              &amp;lt;/a&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            &amp;lt;/li&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;            `&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;          }).&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;join&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;        &amp;lt;/ul&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;      `&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    document.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;DOMContentLoaded&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;async&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; () &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;      const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; posts&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; getLatestPosts&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(route);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;      displayPosts&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(posts);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;No olvides sustituir los valores de &lt;code&gt;server&lt;/code&gt;, &lt;code&gt;profileId&lt;/code&gt; y &lt;code&gt;limit&lt;/code&gt; con los que correspondan a tu propio perfil de Mastodon o el del perfil que desees consultar.&lt;/p&gt;
&lt;h1 id=&quot;cargando-las-publicaciones&quot;&gt;Cargando las publicaciones&lt;/h1&gt;
&lt;p&gt;Aquí confluye todo. Mediante el evento asociado a la carga de la página &lt;code&gt;DOMContentLoaded&lt;/code&gt;, que se incluye al final del script, se inicia la petición asíncrona a la API de Mastodon con &lt;code&gt;getLatestPosts(route)&lt;/code&gt; y se muestran las publicaciones con &lt;code&gt;displayPosts(posts)&lt;/code&gt;.&lt;/p&gt;
&lt;h1 id=&quot;estilos&quot;&gt;Estilos&lt;/h1&gt;
&lt;p&gt;Para que el contenido se vea correctamente, es recomendable definir algunos estilos en el archivo &lt;code&gt;style.css&lt;/code&gt;. Un ejemplo:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;css&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.invisible&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  display&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;inline-block&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  font-size&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  line-height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  position&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;absolute&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.invisible&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt; img&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.invisible&lt;/span&gt;&lt;span style=&quot;color:#85E89D&quot;&gt; svg&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  border&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !important&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  height&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !important&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  margin&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !important&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  padding&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !important&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  width&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; !important&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;.ellipsis:after&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;  content&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;…&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Los estilos aquí mostrados son los que usa el propio Mastodon para presentar las publicaciones en su página.&lt;/p&gt;
&lt;p&gt;La clase &lt;code&gt;.invisible&lt;/code&gt; se aplica a los elementos que quiero que no se vean. Esto es necesario para evitar saltos de línea y espacios en blanco en el contenido de las publicaciones debido a su formateo original.&lt;/p&gt;
&lt;p&gt;Se incluye también la clase &lt;code&gt;.invisible&lt;/code&gt; para imágenes y vectores SVG. Si bien no se usa en este ejemplo, pueden ser de utilidad si decides mostrar el contenido multimedia de las publicaciones.&lt;/p&gt;
&lt;p&gt;Por su parte, la clase &lt;code&gt;.ellipsis&lt;/code&gt; se usa para mostrar puntos suspensivos &lt;code&gt;…&lt;/code&gt; al final de los enlaces acortados.&lt;/p&gt;
&lt;p&gt;A partir de estos estilos es posible aplicar estilos propios al contenido mostrado.&lt;/p&gt;
&lt;h1 id=&quot;experimenta-por-tu-cuenta&quot;&gt;Experimenta por tu cuenta&lt;/h1&gt;
&lt;p&gt;Como has podido comprobar a lo largo de este artículo, acceder a la API de Mastodon es un proceso sencillo que nos permite integrar el contenido de una cuenta en nuestros propios proyectos mediante código JavaScript. Desde la construcción del endpoint y la gestión de la respuesta asíncrona con fetch, hasta el formateo final de los datos considerando casos como las republicaciones o el contenido multimedia, has visto los fundamentos para crear tu propio visor de publicaciones.&lt;/p&gt;
&lt;p&gt;Te animo a que tomes el código completo, lo adaptes con tus propios datos y experimentes modificando la lógica de displayPosts y el css para personalizar aún más la presentación. Y si te surgen dudas o mejoras, no dudes en explorar la documentación oficial de la API, donde encontrarás muchas más posibilidades.&lt;/p&gt;
&lt;h1 id=&quot;saber-más&quot;&gt;Saber más&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://es.wikipedia.org/wiki/Mastodon_(red_social)&quot;&gt;Mastodon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.joinmastodon.org/api/&quot;&gt;Mastodon API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ejemplo de uso: &lt;a href=&quot;/social&quot;&gt;Social&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/mastodon.Dc7cm57i_1rPUNx.webp"/><category>javascript</category><category>código</category><category>api</category><category>servidor</category><author>JavGuerra</author></item><item><title>Visor para banco de preguntas</title><link>https://javguerra.github.io/blog/visor-preguntas</link><guid isPermaLink="true">https://javguerra.github.io/blog/visor-preguntas</guid><description>Aplicación web para recorrer y estudiar exámenes a través de sus preguntas y respuestas</description><pubDate>Thu, 12 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/visor-preguntas.BQ4EG9V__1YC5uz.webp&quot; alt=&quot;Screenshot&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#herramienta&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Recientemente me presenté a una certificación en mi trabajo, y contábamos con un banco de preguntas y respuestas para repasar. Es frecuente también que, en nuevos exámenes se incluyan preguntas de exámenes anteriores, por lo que decidi prepararme una aplicación para estudiar y aprender las respuestas a las preguntas. En esta entrada verás cómo funciona y podrás acceder al código para descargarlo.&lt;/p&gt;
&lt;h2 id=&quot;el-programa-visor&quot;&gt;El programa visor&lt;/h2&gt;
&lt;p&gt;El programa visor se ejecuta en un navegador web, y sirve para mostrar, de forma consecutiva o aleatoriamente, un conjunto de preguntas y respuestas para estudiarlas. Para ello:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Usa &lt;code&gt;←&lt;/code&gt; / &lt;code&gt;→&lt;/code&gt; para navegar por las preguntas.&lt;/li&gt;
&lt;li&gt;Pulsa &lt;code&gt;S&lt;/code&gt; para mostrar/ocultar la solución.&lt;/li&gt;
&lt;li&gt;Pulsa &lt;code&gt;R&lt;/code&gt; para barajar las preguntas.&lt;/li&gt;
&lt;li&gt;Recarga la página para ordenarlas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mediante este programa es posible repasar las respuestas a las preguntas de los exámenes si mantienes activada la función de mostrar solución, reteniendo de esta forma la respuesta correcta, o bien recorrer las preguntas para intentar acertar las respuestas y ver inmediatamente el resultado mostrando/ocultando la solución a la pregunta.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/JavGuerra/visor-preguntas&quot;&gt;&lt;button&gt;Descargar el visor de preguntas&lt;/button&gt;&lt;/a&gt; | &lt;a href=&quot;https://javguerra.github.io/visor-preguntas/&quot;&gt;&lt;button&gt;Ver el programa visor en linea&lt;/button&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;El programa requiere que esté habilitado el soporte JavaScript en el navegador.&lt;/p&gt;
&lt;p&gt;Eres libre de usarlo, modificarlo y redistribuirlo bajo las condiciones de la licencia es GPL v.3.&lt;/p&gt;
&lt;h2 id=&quot;estructura-de-los-datos&quot;&gt;Estructura de los datos&lt;/h2&gt;
&lt;p&gt;Al abrir la aplicación, esta importa un fichero llamado &lt;code&gt;bancoDePreguntas.js&lt;/code&gt; que contiene:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cada una de las preguntas del banco de preguntas&lt;/li&gt;
&lt;li&gt;Las respuestas posibles asociadas a cada pregunta&lt;/li&gt;
&lt;li&gt;El número de respuesta correcta de entre las respuestas&lt;/li&gt;
&lt;li&gt;El número de examen al que corresponde la pregunta (opcional)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La estructura de los datos es la siguiente:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;window.bancoDePreguntas &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &quot;pregunta&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;Texto de la pregunta&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &quot;opciones&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: [&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;      &quot;Respuesta 1.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;      &quot;Respuesta 2.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;      &quot;Respuesta 3.&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;      &quot;Respuesta 4.&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;    ],&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &quot;correcta&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;    &quot;examen&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  ...&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;otras preguntas aquí&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;El valor &lt;code&gt;correcta&lt;/code&gt; indica la opción correcta de ente las opciones posibles. En el ejemplo, la primera opción es la 0 y la cuarta es la 3 (índice 0).&lt;/p&gt;
&lt;p&gt;Cada pregunta debe tener, al menos, dos respuestas posibles.&lt;/p&gt;
&lt;h2 id=&quot;bancos-de-preguntas&quot;&gt;Bancos de preguntas&lt;/h2&gt;
&lt;p&gt;Se pueden incorporar nuevas preguntas al banco de preguntas o también intercambiar el fichero &lt;code&gt;bancoDePreguntas.js&lt;/code&gt; con otras temáticas de estudio, en ese caso:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;El fichero &lt;code&gt;bancoDePreguntas.js&lt;/code&gt; debe estar en la carpeta donde se encuentre el programa &lt;code&gt;visor.html&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;El nuevo banco de preguntas debe tener el nombre &lt;code&gt;bancoDePreguntas.js&lt;/code&gt;, por lo que se deberá renombar el fichero del banco de preguntas actual.&lt;/li&gt;
&lt;li&gt;El banco de preguntas debe tener al menos una pregunta con sus correspondientes opciones, e indicar la respuesta correcta.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;todo&quot;&gt;ToDo&lt;/h2&gt;
&lt;p&gt;Como todo programa, puede ser mejorado. Aquí algunas propuestas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Añadir un título, no obligatorio, al banco de preguntas en bancoDePreguntas.js.&lt;/li&gt;
&lt;li&gt;Desordenar las posibles respuestas.&lt;/li&gt;
&lt;li&gt;Añadir un selector interactivo de examen.&lt;/li&gt;
&lt;li&gt;Opción para mantener o no la solución a las preguntas al cambiar de pregunta.&lt;/li&gt;
&lt;li&gt;Opción para mostrar el resultado tras un tiempo determinado.&lt;/li&gt;
&lt;li&gt;Añadir notas no obligatorias a las preguntas.&lt;/li&gt;
&lt;li&gt;Opción para indicar que una pregunta no debe ser mostrada, aunque esté en el banco de preguntas.&lt;/li&gt;
&lt;li&gt;Seleccionar uno o varios exámenes para mostrar, excluyendo el resto, o bien seleccionar exámenes a excluir, mostrando el resto.&lt;/li&gt;
&lt;li&gt;Incluir un fichero de configuración para personalizar el visor.&lt;/li&gt;
&lt;li&gt;Hoja de estilos externa para posibilitar el cambio de diseño del visor.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;consideración&quot;&gt;Consideración&lt;/h2&gt;
&lt;p&gt;Para su desarrollo básico se ha empleado la IA Copilot, y posteriormente ha sido modificado manualmente para añadir nuevas funcionalidades, para que sea accesible y para que se adapte a la ventana del dispositivo donde es abierto.&lt;/p&gt;
&lt;h1 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://javguerra.github.io/visor-preguntas/&quot;&gt;Programa visor en linea&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/visor-preguntas&quot;&gt;Repositorio GitHub para descargar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/visor-preguntas.BQ4EG9V__1YC5uz.webp"/><category>javascript</category><category>html</category><category>css</category><category>código</category><category>herramienta</category><author>JavGuerra</author></item><item><title>De Thunder a Postman</title><link>https://javguerra.github.io/blog/conversor-thunder-postman</link><guid isPermaLink="true">https://javguerra.github.io/blog/conversor-thunder-postman</guid><description>Conversor universal para migrar colecciones API sin perder estructura</description><pubDate>Thu, 02 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/thunder-postman.JGQ6N9Pq_ZW8Q9F.webp&quot; alt=&quot;Logos Thunder Client, Postman y Bruno&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#api&lt;/em&gt;, &lt;em&gt;#json&lt;/em&gt;, &lt;em&gt;#herramienta&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#node.js&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Necesitaba migrar colecciones de API desde &lt;strong&gt;Thunder Client&lt;/strong&gt; (una extensión de VS Code) a &lt;strong&gt;Bruno&lt;/strong&gt; (cliente API), pero Bruno no importa directamente colecciones de Thunder Client. Sin embargo, Bruno sí importa colecciones de Postman. Así que creé este script que convierte cualquier colección exportada de Thunder Client al formato estándar de &lt;strong&gt;Postman Collection v2.1.0&lt;/strong&gt;, permitiendo importarla en Bruno (o Postman) sin perder carpetas, autenticación, archivos ni estructura. En esta entrada te explico cómo funciona el script.&lt;/p&gt;
&lt;h2 id=&quot;qué-es-bruno&quot;&gt;¿Qué es Bruno?&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.usebruno.com/&quot;&gt;Bruno&lt;/a&gt; es un cliente de API de código abierto, offline y respetuoso con la privacidad. A diferencia de otras herramientas, no requiere cuenta, no sincroniza tus colecciones en la nube y todos los datos se guardan localmente en tu ordenador. Es rápido, ligero y perfecto para equipos que priorizan la seguridad y el control de sus propios archivos.&lt;/p&gt;
&lt;h2 id=&quot;planteamiento&quot;&gt;Planteamiento&lt;/h2&gt;
&lt;p&gt;Thunder Client exporta las colecciones en un formato JSON propio. Postman y Bruno usan otro formato diferente. El script actúa como un “traductor” que lee el JSON de Thunder Client, lo interpreta y genera un JSON válido para Postman, conservando:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Las peticiones (GET, POST, PUT, DELETE, etc.)&lt;/li&gt;
&lt;li&gt;Las carpetas y subcarpetas&lt;/li&gt;
&lt;li&gt;Los headers, autenticación y cuerpos de las peticiones&lt;/li&gt;
&lt;li&gt;Los archivos adjuntos en formularios&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Puedes descargar el script desde el: &lt;a href=&quot;https://github.com/JavGuerra/conversor-thunder-postman&quot;&gt;&lt;button&gt;Repositorio del conversor&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;dificultades-de-la-conversión&quot;&gt;Dificultades de la conversión&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Estructura inconsistente del JSON de Thunder Client&lt;/strong&gt;&lt;br&gt;
Las exportaciones no siguen un formato fijo: las peticiones pueden estar en &lt;code&gt;requests&lt;/code&gt;, en &lt;code&gt;items&lt;/code&gt;, en &lt;code&gt;tests&lt;/code&gt; o en arrays con nombres personalizados como &lt;code&gt;requests_carpeta_auth&lt;/code&gt;. El script tuvo que aprender a buscar en cualquier lugar.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Carpetas anidadas sin un identificador claro&lt;/strong&gt;&lt;br&gt;
Thunder Client a veces usa &lt;code&gt;parentId&lt;/code&gt;, otras veces &lt;code&gt;_parentId&lt;/code&gt;, o simplemente anida objetos. Reconstruir la jerarquía a cualquier nivel requirió una función recursiva robusta.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Variables en URLs&lt;/strong&gt;&lt;br&gt;
Thunder Client permite &lt;code&gt;{{variables}}&lt;/code&gt; en las URLs. Si intentas parsear la URL con &lt;code&gt;new URL()&lt;/code&gt;, el script falla. Hubo que detectar y proteger estos casos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Autenticación dispersa&lt;/strong&gt;&lt;br&gt;
La autenticación puede venir en un bloque &lt;code&gt;auth&lt;/code&gt; o directamente en los headers. Además, hay que soportar Bearer, Basic y API Key (que puede ir en header o en query param).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Archivos en formdata&lt;/strong&gt;&lt;br&gt;
Los archivos no se representan como strings simples, sino como objetos con ruta o strings especiales (&lt;code&gt;@/ruta&lt;/code&gt;). Hay que identificarlos y convertirlos al formato que espera Postman.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Headers con espacios&lt;/strong&gt;&lt;br&gt;
Algunos headers exportados tenían espacios al inicio o final del nombre, lo que provocaba errores en Bruno. Hubo que limpiarlos con &lt;code&gt;trim()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;BOM en archivos Windows&lt;/strong&gt;&lt;br&gt;
Los archivos exportados desde Windows incluyen una marca de orden de bytes (BOM) invisible que rompe el parseo JSON. Hubo que detectarla y eliminarla.&lt;/p&gt;
&lt;h2 id=&quot;el-script-paso-a-paso&quot;&gt;El script paso a paso&lt;/h2&gt;
&lt;h3 id=&quot;1-lee-el-archivo-de-entrada&quot;&gt;1. Lee el archivo de entrada&lt;/h3&gt;
&lt;p&gt;El script recibe como parámetro el archivo JSON exportado desde Thunder Client. Verifica que el archivo existe y que es un JSON válido. Si el archivo tiene BOM (marca de orden de bytes típica de Windows), lo elimina automáticamente para evitar errores.&lt;/p&gt;
&lt;h3 id=&quot;2-extrae-todas-las-peticiones&quot;&gt;2. Extrae todas las peticiones&lt;/h3&gt;
&lt;p&gt;Busca las peticiones en &lt;strong&gt;cualquier lugar&lt;/strong&gt; del JSON: en la raíz, dentro de carpetas, en arrays con nombres personalizados, etc. No importa cómo haya estructurado Thunder Client la exportación.&lt;/p&gt;
&lt;h3 id=&quot;3-extrae-la-estructura-de-carpetas&quot;&gt;3. Extrae la estructura de carpetas&lt;/h3&gt;
&lt;p&gt;Identifica las carpetas y subcarpetas, detectando sus identificadores (&lt;code&gt;folderId&lt;/code&gt;, &lt;code&gt;parentId&lt;/code&gt;) para reconstruir la jerarquía original, incluyendo &lt;strong&gt;subcarpetas anidadas a cualquier nivel&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;4-convierte-cada-petición-individualmente&quot;&gt;4. Convierte cada petición individualmente&lt;/h3&gt;
&lt;p&gt;Para cada petición, traduce:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;URL&lt;/strong&gt;: La segmenta en partes (host, path, query params) para Bruno, pero respeta las variables &lt;code&gt;{{variable}}&lt;/code&gt; sin intentar parsearlas.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Headers&lt;/strong&gt;: Los mantiene y limpia espacios accidentales.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Autenticación&lt;/strong&gt;: Soporta Bearer Token, Basic Auth y API Key (tanto en header como en query param).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cuerpo (body)&lt;/strong&gt;: Maneja JSON (con resaltado de sintaxis), formularios multipart (con detección automática de archivos) y urlencoded.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;5-construye-la-colección-postman&quot;&gt;5. Construye la colección Postman&lt;/h3&gt;
&lt;p&gt;Reconstruye la jerarquía completa usando recursividad: carpetas raíz, subcarpetas y peticiones en su lugar correspondiente. Si la exportación no incluye identificadores, usa un método alternativo como respaldo.&lt;/p&gt;
&lt;h3 id=&quot;6-guarda-el-resultado&quot;&gt;6. Guarda el resultado&lt;/h3&gt;
&lt;p&gt;Escribe el archivo JSON en el formato estándar de Postman Collection v2.1.0, listo para importar.&lt;/p&gt;
&lt;h3 id=&quot;7-muestra-estadísticas&quot;&gt;7. Muestra estadísticas&lt;/h3&gt;
&lt;p&gt;Al finalizar, informa sobre cuántas peticiones y carpetas se han convertido.&lt;/p&gt;
&lt;h2 id=&quot;el-resultado-características-principales-destacadas&quot;&gt;El resultado: características principales destacadas&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Característica&lt;/th&gt;
&lt;th&gt;Qué hace&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Jerarquía completa&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Respeta carpetas y subcarpetas anidadas a cualquier nivel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Búsqueda exhaustiva&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Encuentra peticiones estén donde estén en el JSON&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Autenticación múltiple&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bearer, Basic y API Key (header o query)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Soporte para archivos&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Detecta y convierte campos de tipo file en formularios&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Compatibilidad con Bruno&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Segmenta el host y limpia rutas para importación perfecta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Resaltado JSON&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Configura los cuerpos JSON para que se vean con colores&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Manejo robusto&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Valida archivos, limpia BOM, muestra errores claros&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sin dependencias&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Usa solo módulos nativos de Node.js&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;ejemplo-de-uso&quot;&gt;Ejemplo de uso&lt;/h2&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;node&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; convertir-thunder-a-postman.js&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; prueba-thunder.json&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; coleccion-postman.json&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Salida esperada:&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;✅ Conversión completada con éxito.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;🚀 Fichero generado: coleccion-postman.json&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;📊 Peticiones: 24 | Carpetas: 7&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;limitaciones-del-script&quot;&gt;Limitaciones del script&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Variables de colección&lt;/strong&gt;: No se importan automáticamente (deben recrearse a mano)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scripts pre-request y tests&lt;/strong&gt;: No se convierten (la API es compatible, pero hay que copiarlos manualmente)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Autenticación avanzada&lt;/strong&gt;: OAuth 2.0, AWS Signature y Digest no están soportados&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/conversor-thunder-postman&quot;&gt;Repositorio desde donde descargar el conversor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.usebruno.com/&quot;&gt;Cliente Bruno&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/thunder-postman.JGQ6N9Pq_ZW8Q9F.webp"/><category>api</category><category>json</category><category>herramienta</category><category>código</category><category>javascript</category><category>node.js</category><author>JavGuerra</author></item><item><title>Oracle SQL Literal Converter</title><link>https://javguerra.github.io/blog/osqlc</link><guid isPermaLink="true">https://javguerra.github.io/blog/osqlc</guid><description>Sanitizando SQL para Oracle via web local o por línea de comandos</description><pubDate>Wed, 09 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/osqlc.e18iygQz_1cPFJ7.webp&quot; alt=&quot;Captura de pantalla de Oracle SQL Literal Converter&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#herramienta&lt;/em&gt;, &lt;em&gt;#sql&lt;/em&gt;, &lt;em&gt;#oracle&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#node.js&lt;/em&gt;, &lt;em&gt;#responsive&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#bbdd&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Cuando trabajas con bases de datos Oracle a través de herramientas de administración como SQL*Plus, SQL Developer, Toad o PL/SQL Developer, es casi inevitable chocarse antes o después con el mismo obstáculo frustrante: la gestión de literales de texto con caracteres especiales.&lt;/p&gt;
&lt;p&gt;Quien haya ejecutado alguna vez un INSERT o UPDATE con un texto como “Ibáñez &amp;amp; Asociados” sabrá exactamente de qué hablo. Por un lado, el símbolo del ampersand (&amp;amp;) hace que SQL*Plus se detenga pidiendo interactiva y molestamente el valor para una “variable de sustitución” &amp;amp;Asociados. Por otro lado, los caracteres con acentos, la ñ, los signos de apertura (¿, ¡) o los símbolos de moneda suelen corromperse si el cliente SQL y la base de datos no comparten exactamente la misma configuración NLS o codificación de caracteres.&lt;/p&gt;
&lt;p&gt;Para solucionar este dolor de cabeza, he desarrollado OSQLC (Oracle SQL Literal Converter).&lt;/p&gt;
&lt;p&gt;Puedes descargar el script o acceder a la página web desde el: &lt;a href=&quot;https://github.com/JavGuerra/oracle-sql-literal-converter&quot;&gt;&lt;button&gt;Repositorio del conversor&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;También puedes acceder directamente al conversor web desde: &lt;a href=&quot;https://javguerra.github.io/oracle-sql-literal-converter/&quot;&gt;Oracle SQL Literal Converter&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;cómo-funciona-la-sanitización&quot;&gt;¿Cómo funciona la sanitización?&lt;/h2&gt;
&lt;p&gt;La solución técnica más limpia en Oracle consiste en aislar los caracteres problemáticos y reemplazarlos por su función nativa chr(N) equivalente (basada en el juego de caracteres ISO-8859-1 / Latin-1), concatenándolos con el resto de la cadena.&lt;/p&gt;
&lt;p&gt;OSQLC analiza el script SQL y realiza esta transformación de forma transparente. Por ejemplo, convierte esta sentencia propensa a errores:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;INSERT INTO&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; clientes (nombre, direccion) &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;VALUES&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Ibáñez &amp;amp; Asociados&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;C/ Ramón y Cajal, nº 45&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En este otro código, seguro y portátil para cualquier entorno Oracle:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;INSERT INTO&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; clientes (nombre, direccion) &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;VALUES&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;Ib&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; chr(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;225&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; chr(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;241&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;ez &apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; chr(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;38&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos; Asociados&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&apos;C/ Ram&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; chr(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;243&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos;n y Cajal, n&apos;&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; ||&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; chr(&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;186&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &apos; 45&apos;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Además, el motor de procesado de OSQLC incluye características avanzadas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Respeto estricto de comentarios: Preserva intactos los comentarios de línea (–) y de bloque (/* … */) sin alterar su contenido.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Soporte para Cita Alternativa (q’…’): Procesa correctamente la sintaxis Alternative Quoting Mechanism de Oracle.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Control de saltos de línea: Convierte los retornos de carro (\n y \r) en chr(10) y chr(13), evitando que se rompa la sintaxis en literales multilínea.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;dos-versiones-para-cada-tipo-de-flujo-de-trabajo&quot;&gt;Dos versiones para cada tipo de flujo de trabajo&lt;/h2&gt;
&lt;p&gt;Para hacer la herramienta lo más versátil posible, la he estructurado en dos modalidades complementarias:&lt;/p&gt;
&lt;h3 id=&quot;1-versión-cli-nodejs&quot;&gt;1. Versión CLI (Node.js)&lt;/h3&gt;
&lt;p&gt;Pensada para desarrolladores, automatizaciones o integración en canalizaciones CI/CD y scripts de despliegue. Te permite procesar archivos .sql directamente desde la terminal con un comando sencillo:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;node&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; osqlc.js&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; mi_script.sql&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; script_sanitizado.sql&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;2-versión-web-htmljs-standalone&quot;&gt;2. Versión Web (HTML/JS Standalone)&lt;/h3&gt;
&lt;p&gt;Diseñada para un uso diario, rápido y visual desde cualquier navegador. Se trata de una interfaz web con estilo oscuro que funciona de forma 100% local (client-side).&lt;/p&gt;
&lt;p&gt;No requiere servidores, no instala nada y garantiza la privacidad total, ya que el código SQL jamás sale de tu navegador.&lt;/p&gt;
&lt;p&gt;Entre sus características destacan:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Drag &amp;amp; Drop: Arrastra directamente tus archivos .sql a la zona de carga.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Validación inteligente: Verifica que la extensión sea .sql o .txt y analiza el contenido en busca de palabras clave de SQL (como INSERT, SELECT, UPDATE), lanzando avisos si detecta un archivo incorrecto por error.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Edición y descarga directa: Puedes pegar código a mano o descargar el archivo convertido con un solo clic.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;ventajas&quot;&gt;Ventajas&lt;/h2&gt;
&lt;p&gt;Con OSQLC, lo que antes requería reemplazar caracteres a mano de forma tediosa o lidiar con parámetros de sesión como SET DEFINE OFF, ahora se resuelve en un instante. Ya sea automatizando despliegues en la consola o arrastrando un archivo en la web, la sanitización queda cubierta de punta a punta.&lt;/p&gt;
&lt;p&gt;¿Te has encontrado con este problema en Oracle alguna vez? ¡Espero que la herramienta te sea tan útil en tu día a día como a mí!&lt;/p&gt;
&lt;h2 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h2&gt;
&lt;p&gt;Conoce todas las características de OSQLC:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/oracle-sql-literal-converter&quot;&gt;Repositorio del conversor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://javguerra.github.io/oracle-sql-literal-converter/&quot;&gt;Web de Oracle SQL Literal Converter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/osqlc.e18iygQz_1cPFJ7.webp"/><category>herramienta</category><category>sql</category><category>oracle</category><category>html</category><category>css</category><category>javascript</category><category>node.js</category><category>responsive</category><category>web</category><category>bbdd</category><category>código</category><author>JavGuerra</author></item><item><title>Traducciones de software</title><link>https://javguerra.github.io/blog/traducciones</link><guid isPermaLink="true">https://javguerra.github.io/blog/traducciones</guid><description>Colaboraciones de software libre</description><pubDate>Sat, 13 Aug 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/traducciones.CSUk5c-6_Z25CxaS.webp&quot; alt=&quot;TRaducciones&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#software libre&lt;/em&gt;, &lt;em&gt;#pro-bono&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Cuando puedo, llevo a cabo traducciones del inglés al español del software libre que utilizo. En esta entrada llevaré un listado actualizado de ello.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;note&quot;&gt;&lt;strong&gt;Nota&lt;/strong&gt;: Esta entrada se actualizará cuando se produzcan novedades.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://wekan.github.io/&quot;&gt;Wekan&lt;/a&gt; Vía Transifex. Herramienta para gestión de metodología kan-ban al estilo Trello.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.calormen.com/jslogo/&quot;&gt;JSLogo&lt;/a&gt; Intérprete Logo - &lt;a href=&quot;https://github.com/inexorabletash/jslogo/pull/127&quot;&gt;pr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://moonmoon.org/&quot;&gt;Moonmoon&lt;/a&gt; Planeta RSS - &lt;a href=&quot;https://github.com/moonmoon/moonmoon/blob/master/app/l10n/es.lang&quot;&gt;pr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Manual en español de Owncloud. Se puede descargar, por ejemplo, de &lt;a href=&quot;https://es.scribd.com/document/1016898072/Nube-OwnCloud-Manual-de-Usuario-v0-8&quot;&gt;Nube OwnCloud - Manual de Usuario v0.8&lt;/a&gt; Documentación libre. No es una traducción directa del manual, sino un manual elaborado para la administración y gestión del software.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/codice-beautiful-jekyll-es&quot;&gt;Tema Beautifull Jekill&lt;/a&gt; Ejemplo. Traducción del tema para este git-blog.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://javguerra.github.io/javascript-en-14-minutos/&quot;&gt;JavaScript en 14 minutos&lt;/a&gt; En desarrollo.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://javguerra.github.io/diseno-web-en-4-minutos/&quot;&gt;Diseño web en 4 minutos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Provincias de España, que estaba en account.limesurvey.org/de/downloads/file/34-provinces-of-spain-provincias-de-espa%C3%B1a?tmpl=component. Un complemento en español para el software &lt;a href=&quot;https://www.limesurvey.org/es/&quot;&gt;Limesurvey&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;PHP Guestbook &lt;a href=&quot;https://developers.phpjunkyard.com/viewtopic.php?f=3&amp;amp;t=5587&amp;amp;p=24230&amp;amp;hilit=spanish#p24230&quot;&gt;GBook&lt;/a&gt; y tema &lt;a href=&quot;https://developers.phpjunkyard.com/viewtopic.php?f=3&amp;amp;t=6629&amp;amp;p=27830&amp;amp;hilit=conectiva#p27830&quot;&gt;«Conectiva»&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/SinclairQL/StructuredSuperBasic/blob/main/Source/ssblang.ssb&quot;&gt;Structured SuperBasic&lt;/a&gt; Mensajes de error.&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/traducciones.CSUk5c-6_Z25CxaS.webp"/><category>código</category><category>software libre</category><category>pro-bono</category><author>JavGuerra</author></item><item><title>Apuntes TIC</title><link>https://javguerra.github.io/blog/apuntes</link><guid isPermaLink="true">https://javguerra.github.io/blog/apuntes</guid><description>Materiales de estudio sobre TIC y formaciones impartidas</description><pubDate>Thu, 12 Jan 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/apuntes.DFb5--bH_Z19gvuH.webp&quot; alt=&quot;Apuntes&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#php&lt;/em&gt;, &lt;em&gt;#java&lt;/em&gt;, &lt;em&gt;#bbdd&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Incluyo en este repositorio mis apuntes sobre mis materias de estudio tanto de DAW como autodidactas. También incluyo materiales realizados para formaciones impartidas.&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;note&quot;&gt;&lt;strong&gt;Nota&lt;/strong&gt;: Esta entrada se actualizará cuando se produzcan novedades.&lt;/span&gt;&lt;/p&gt;
&lt;h2 id=&quot;apuntes&quot;&gt;Apuntes&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;BBDD
&lt;ul&gt;
&lt;li&gt;relacional&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Infraestructura
&lt;ul&gt;
&lt;li&gt;servidores (varios)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Programación
&lt;ul&gt;
&lt;li&gt;JAVA&lt;/li&gt;
&lt;li&gt;PHP&lt;/li&gt;
&lt;li&gt;varios&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;repositorio&quot;&gt;Repositorio&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/apuntes-tic&quot;&gt;Apuntes TIC&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/apuntes.DFb5--bH_Z19gvuH.webp"/><category>código</category><category>php</category><category>java</category><category>bbdd</category><author>JavGuerra</author></item><item><title>Conceptos Full Stack Web Developer</title><link>https://javguerra.github.io/blog/conceptos-fswd</link><guid isPermaLink="true">https://javguerra.github.io/blog/conceptos-fswd</guid><description>Ejemplo de maquetación HTML y CSS</description><pubDate>Sat, 23 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/conceptos-fswd.CgRI9xye_Zl0Fl1.webp&quot; alt=&quot;Conceptos full stack&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Maquetación elaborada con HTML 5, CSS 3 y JavaScript Vanilla que incluye formulario y es accesible y responsive.&lt;/p&gt;
&lt;h2 id=&quot;conceptos-fswd&quot;&gt;Conceptos FSWD&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Práctica final del Ramp-up del Bootcamp de FSWD&lt;/strong&gt;&lt;br&gt;
Repositorio en GitHub: &lt;a href=&quot;https://github.com/JavGuerra/conceptos-fswd&quot;&gt;JavGuerra / conceptos-fswd&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;la-página&quot;&gt;La página&lt;/h3&gt;
&lt;p&gt;Esta página corresponde a la práctica final del ramp-up del &lt;a href=&quot;/blog/beca-santander-fswd&quot;&gt;bootcamp sobre Full Stack Web Developer&lt;/a&gt; que estoy realizando en este momento.&lt;/p&gt;
&lt;p&gt;En ella se muestran algunos conceptos aprendidos en esta primera fase, e incluye «algo más» de mi propia cosecha. A continuación algunas de estas mejoras.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/conceptos-fswd/index.html&quot;&gt;&lt;button&gt;Acceder a la página web&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;14-características-destacables-de-esta-página-web&quot;&gt;14 características destacables de esta página web&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;CSS transpilado con &lt;a href=&quot;https://es.wikipedia.org/wiki/Sass&quot;&gt;Sass&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Usa Vanilla JS (JavaScript puro).&lt;/li&gt;
&lt;li&gt;La web implementa los criterios del estándar XHTML (revisado con &lt;a href=&quot;https://html5.validator.nu/&quot;&gt;Nu Html Checker&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;El diseño es adaptable (&lt;a href=&quot;https://es.wikipedia.org/wiki/Dise%C3%B1o_web_adaptable&quot;&gt;&lt;em&gt;responsive&lt;/em&gt;&lt;/a&gt;) según el dispositivo.&lt;/li&gt;
&lt;li&gt;Usa la librería y los iconos de &lt;a href=&quot;https://icons.getbootstrap.com/&quot;&gt;Bootstrap Icons&lt;/a&gt; y las fuentes de letra de &lt;a href=&quot;https://fonts.google.com/&quot;&gt;Google Fonts&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Aplica un &lt;a href=&quot;https://blog.hubspot.es/marketing/efecto-parallax&quot;&gt;efecto Paralax&lt;/a&gt; a la portada (&lt;em&gt;hero&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Implementa el protocolo &lt;a href=&quot;https://ogp.me/&quot;&gt;Open Graph&lt;/a&gt; (&lt;em&gt;head&lt;/em&gt;) para la correcta inserción de la web en redes sociales.&lt;/li&gt;
&lt;li&gt;Es compatible con &lt;em&gt;Progessive Web Aplication&lt;/em&gt; (&lt;a href=&quot;https://developer.mozilla.org/es/docs/Web/Progressive_web_apps&quot;&gt;PWA&lt;/a&gt;) a través de fichero &lt;a href=&quot;https://developer.mozilla.org/es/docs/Web/Manifest&quot;&gt;manifest.json&lt;/a&gt;, por lo que la página puede ser instalada en dispositivos móviles como una web app.&lt;/li&gt;
&lt;li&gt;Implementa técnicas de seguridad en el formulario:
&lt;ul&gt;
&lt;li&gt;Hace uso de un &lt;a href=&quot;https://es.wikipedia.org/wiki/Honeypot&quot;&gt;&lt;em&gt;Honeypod&lt;/em&gt;&lt;/a&gt;, mediante el campo “hp”, para evitar el SPAM.&lt;/li&gt;
&lt;li&gt;Hace uso de un campo oculto “dato” para evitar ataques por &lt;a href=&quot;https://es.wikipedia.org/wiki/Cross-site_scripting&quot;&gt;XSS&lt;/a&gt; y &lt;a href=&quot;https://es.wikipedia.org/wiki/Cross-site_request_forgery&quot;&gt;CRSF&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Es accesible (revisado con el complemento &lt;a href=&quot;https://wave.webaim.org/&quot;&gt;WAVE&lt;/a&gt;):
&lt;ul&gt;
&lt;li&gt;Emplea párrafos y etiquetas contextuales sólo visibles para lectores de pantalla.&lt;/li&gt;
&lt;li&gt;Hace uso de etiquetas &lt;a href=&quot;https://en.wikipedia.org/wiki/WAI-ARIA&quot;&gt;WAI-ARIA&lt;/a&gt; para describir eventos interactivos.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;El fichero README.md tiene sintáxis de marcado ligero &lt;a href=&quot;https://es.wikipedia.org/wiki/Markdown&quot;&gt;Markdown&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Dispone de un código QR para acceso rápido a la web a través de dispositivos móviles.&lt;/li&gt;
&lt;li&gt;Ha sido probado en los navegadores web &lt;strong&gt;Firefox&lt;/strong&gt; y &lt;strong&gt;Chrome&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Web alojada en &lt;a href=&quot;https://github.com/JavGuerra/conceptos-fswd&quot;&gt;Github&lt;/a&gt; pages.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;acceder-a-la-página-web&quot;&gt;Acceder a la página web&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/conceptos-fswd/img/qrcode.svg&quot; alt=&quot;icono&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/conceptos-fswd/index.html&quot;&gt;&lt;button&gt;Ir a la página web&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/conceptos-fswd.CgRI9xye_Zl0Fl1.webp"/><category>portfolio</category><category>web</category><category>código</category><category>html</category><category>css</category><category>javascript</category><author>JavGuerra</author></item><item><title>Buscaminas en JavaScript</title><link>https://javguerra.github.io/blog/buscaminas</link><guid isPermaLink="true">https://javguerra.github.io/blog/buscaminas</guid><description>Pequeño juego online para manejo de eventos</description><pubDate>Thu, 28 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/buscaminas.BEDLb0fd_265uBE.webp&quot; alt=&quot;Buscaminas&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#bootstrap&lt;/em&gt;, &lt;em&gt;#jquery&lt;/em&gt;, &lt;em&gt;#juego&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Programé &lt;a href=&quot;https://javguerra.github.io/BuscaminasJS/index.html&quot;&gt;Buscaminas en JavaScript&lt;/a&gt; como un juego atípico que no consiste en evitar las minas, como estamos acostumbrados en los juegos de escritorio del mismo nombre, sino en hacerlas estallar.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/BuscaminasJS/index.html&quot;&gt;&lt;button&gt;Jugar a Buscaminas&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Una vez se genera el tablero con las dimensiones que deseemos, tendremos una serie de intentos para acertar la posición de las minas. Cada fallo cuenta, así como cada acierto. Termina la partida cuando se han superado el número de fallos posibles o cuando se encuentran todas las minas.&lt;/p&gt;
&lt;p&gt;Realicé este juego durante una semana, como práctica de programación de la asignatura de Desarrollo Web en Entorno Cliente de Formación Profesional de Grado Superior de Desarrollo de Aplicaciones Web (DAW).&lt;/p&gt;
&lt;p&gt;La aplicación, programada en JavaScript, usa Bootstrap y JQuery, es &lt;em&gt;cross-browser&lt;/em&gt; y compatible con navegadores antiguos, tiene diseño &lt;em&gt;responsive&lt;/em&gt;, cumple con los estándares W3C, de accesibilidad web y de accesibilidad de contenidos dinámicos (WAI-ARIA).&lt;/p&gt;
&lt;p&gt;Como ejercicio de programación, es un buen ejemplo de manejo de eventos en JavaScript para interactuar con las casillas del tablero.&lt;/p&gt;
&lt;h2 id=&quot;te-apetece-una-partidita&quot;&gt;¿Te apetece una partidita?&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/BuscaminasJS/index.html&quot;&gt;&lt;button&gt;Jugar a Buscaminas&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/JavGuerra/BuscaminasJS&quot;&gt;Ver el codigo fuente en Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;PS.: La ayuda depara alguna sorpresa… pero intenta jugar sin hacer trampa.&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/buscaminas.BEDLb0fd_265uBE.webp"/><category>portfolio</category><category>web</category><category>código</category><category>css</category><category>html</category><category>javascript</category><category>bootstrap</category><category>jquery</category><category>juego</category><author>JavGuerra</author></item><item><title>Carousel con Bootstrap</title><link>https://javguerra.github.io/blog/galeria-carousel</link><guid isPermaLink="true">https://javguerra.github.io/blog/galeria-carousel</guid><description>Una pequeña galería de fotos de ejemplo</description><pubDate>Fri, 29 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/galeria-vnzla.-8Rqrg6B_Z1gNkrA.webp&quot; alt=&quot;Galería Venezuela&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#viaje&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#bootstrap&lt;/em&gt;, &lt;em&gt;#fotografía&lt;/em&gt;, &lt;em&gt;#edición&lt;/em&gt;, &lt;em&gt;#venezuela&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Las primeras veces que viajé a Venezuela quedé impactado por su belleza y las gentes que allí conocí. Me inspiró para realizar esta &lt;a href=&quot;https://badared.com/javguerra/daw/galeria/&quot;&gt;galería de fotos&lt;/a&gt; de ejemplo para la asignatura de Diseño de Interfaces Web de Formación Profesional de Grado Superior de Desarrollo de Aplicaciones Web (DAW).&lt;/p&gt;
&lt;p&gt;La galería muestra un carousel de imágenes con Boortrap y JavaScript, es &lt;em&gt;responsive&lt;/em&gt; y cumple con los estándares web y de accesibilidad.&lt;/p&gt;
&lt;p&gt;Es un buen ejercicio para mostrar las posibilidades del diseño web con HTML y CSS.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://badared.com/javguerra/daw/galeria/&quot;&gt;&lt;button&gt;visita la galería de fotos&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;La foto de esta entrada es un montaje que realicé con Gimp tomando como base las tres fotos de la galería componiendo con ellas un collage y aplicando filtros de envejecido.&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/galeria-vnzla.-8Rqrg6B_Z1gNkrA.webp"/><category>portfolio</category><category>web</category><category>viaje</category><category>código</category><category>css</category><category>html</category><category>javascript</category><category>bootstrap</category><category>fotografía</category><category>edición</category><category>venezuela</category><author>JavGuerra</author></item><item><title>Summer Quiz</title><link>https://javguerra.github.io/blog/summer-quiz</link><guid isPermaLink="true">https://javguerra.github.io/blog/summer-quiz</guid><description>Un juego que obtiene sus preguntas a través de una API</description><pubDate>Tue, 21 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/summer-quiz.CeOcInKG_1DP5P4.webp&quot; alt=&quot;Summer Quiz&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#juego&lt;/em&gt;, &lt;em&gt;#accesibilidad&lt;/em&gt;, &lt;em&gt;#responsive&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;«Fun 10-question quiz to test your knowledge». &lt;strong&gt;Práctica final del módulo de JavaScript avanzado del Bootcamp de FSWD&lt;/strong&gt;, por Alejandro Rodríguez y Javier Guerra.&lt;/p&gt;
&lt;h1 id=&quot;el-juego&quot;&gt;El juego&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/summer-quiz/&quot;&gt;&lt;button&gt;Acceder al juego&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;El &lt;a href=&quot;/blog/beca-santander-fswd&quot;&gt;bootcamp de FSWD&lt;/a&gt; que estoy realizando, consta de varios módulos. El de JavaScript avanzado termina ahora, y este es el ejercicio final de esta fase de mi formación.&lt;/p&gt;
&lt;p&gt;Se trata de un ejercicio que comprende todos los conceptos generales aprendidos, y que, como siempre, incluye alguna que otra cosa más allá del enunciado.&lt;/p&gt;
&lt;h1 id=&quot;enunciado&quot;&gt;Enunciado&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;El ejercicio consiste en elaborar una SPA que consulte una API de preguntas y respuestas y que cuente con tres partes: 1. bienvenida y gráficas de estadísticas, 2. mostrar diez preguntas, una a una, con sus respectivas opciones de respuesta, y 3. página de resultado.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Conceptualmente hablando, las estadísticas de la parte 1 bien podrían aparecer en la fase 3, la de resultados, pero este es, en resumidas cuentas, el enunciado.&lt;/p&gt;
&lt;p&gt;Algunas características destacables del enunciado son que la aplicación se debe ejecutar en una sola página web (SPA), que realiza consultas a una API, que guarda las puntuaciones en localStorage y que muestra estadísticas. Esta última parte, aunque accesoria, pues no se ha visto en el bootcamp, supuso un reto interesante, ya que ha dado para escribir varias entradas previas en este blog: &lt;a href=&quot;/blog/spinner-loader-asincrono&quot;&gt;Spinner loader asíncrono&lt;/a&gt;, &lt;a href=&quot;/blog/contador-resultados&quot;&gt;Creación de un contador de resultados&lt;/a&gt;, &lt;a href=&quot;/blog/grafica-lineas&quot;&gt;Gráfica de lineas dinámica con SVG&lt;/a&gt; y &lt;a href=&quot;/blog/carga-svg&quot;&gt;Cargar SVG dinámicamente&lt;/a&gt;, todas ellas técnicas incluidas en el ejercicio.&lt;/p&gt;
&lt;p&gt;Es un buen ejercicio para practicar, e igualmente espero que puedas disfrutarlo jugándolo. Este ejercicio lo he llevado a cabo con el apoyo del compañero Alejando.&lt;/p&gt;
&lt;h1 id=&quot;características-destacables&quot;&gt;Características destacables&lt;/h1&gt;
&lt;h2 id=&quot;operativa-de-la-aplicación&quot;&gt;Operativa de la aplicación&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Aplicación de una sola página (SPA).&lt;/li&gt;
&lt;li&gt;Integración de 25 preguntas propias en un JSON. Usa una en cada partida.&lt;/li&gt;
&lt;li&gt;Hace uso de localStorage pata guardar y leer las puntuaciones.&lt;/li&gt;
&lt;li&gt;Gráficas dinámicas en SVG de elaboración propia y uso de DOM para su gestión.
&lt;ul&gt;
&lt;li&gt;Gráfica de líneas para mostrar estadísticas. Manejo del id ‘theline’.&lt;/li&gt;
&lt;li&gt;Contador visual para mostrar el resultado final del quiz. Manejo del id ‘hand’.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Animaciones CSS de gráfica de líneas y personajes.&lt;/li&gt;
&lt;li&gt;Carga de las gráficas &lt;strong&gt;SVG&lt;/strong&gt; al inicio de la app con &lt;code&gt;fetch&lt;/code&gt; para hacer uso de los &lt;code&gt;id&lt;/code&gt; que incorporan y poder así hacer cambios dinámicos. Con &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; esto no funcionaría.&lt;/li&gt;
&lt;li&gt;Los posibles errores se muestran a través de una ventana modal &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Usa JavaScript puro (Vanilla JS) sin &lt;em&gt;frameworks&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Recopila librería de funciones propia en el fichero &lt;code&gt;js/functions.js&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Repositorio compartido en Github y web alojada en Github pages.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;usabilidad&quot;&gt;Usabilidad&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;La web implementa los criterios del estándar XHTML (revisado con &lt;a href=&quot;https://html5.validator.nu/&quot;&gt;Nu Html Checker&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;El diseño es adaptable (&lt;em&gt;responsive&lt;/em&gt;) según el dispositivo.&lt;/li&gt;
&lt;li&gt;Es accesible (revisado con el complemento del navegador &lt;a href=&quot;https://wave.webaim.org/&quot;&gt;WAVE&lt;/a&gt;):
&lt;ul&gt;
&lt;li&gt;Hace uso de etiquetas &lt;strong&gt;WAI-ARIA&lt;/strong&gt; para describir eventos interactivos.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Tiene temática coherente y un cuidado aspecto visual trabajado con CSS.&lt;/li&gt;
&lt;li&gt;Interfaz en inglés acorde al contenido de la API.&lt;/li&gt;
&lt;li&gt;Emplea un ‘spin’ asíncrono para informar al usuario de que se está gestionado la consultas.&lt;/li&gt;
&lt;li&gt;Los botones no se activan hasta que terminan los procesos asíncronos: cargas, consultas…&lt;/li&gt;
&lt;li&gt;La selección de las opciones de cada pregunta se hace a través de botones de radio cuyo aspecto modificado con CSS simula el aspecto de botones de selección.&lt;/li&gt;
&lt;li&gt;Muestra barra de puntuaciones medias y barra de progreso del cuestionario.&lt;/li&gt;
&lt;li&gt;Implementa el protocolo &lt;a href=&quot;https://ogp.me/&quot;&gt;&lt;em&gt;Open Graph&lt;/em&gt;&lt;/a&gt; (en el &lt;code&gt;head&lt;/code&gt;) para la correcta inserción de la web en RRSS.&lt;/li&gt;
&lt;li&gt;Es compatible con &lt;em&gt;Progessive Web Aplication&lt;/em&gt; (PWA) a través de fichero manifest.json, por lo que la página puede ser instalada en dispositivos móviles como una web app.&lt;/li&gt;
&lt;li&gt;Se dispone de un código QR para acceso rápido a la web a través de dispositivos móviles.&lt;/li&gt;
&lt;li&gt;Ha sido probada con los navegadores web Firefox y Chrome.&lt;/li&gt;
&lt;li&gt;Extra: La consola del navegador muestra ayuda con las respuestas.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/summer-quiz/assets/img/qrcode.svg&quot; alt=&quot;QR Code&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/summer-quiz/&quot;&gt;&lt;button&gt;Acceder al juego&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/summer-quiz&quot;&gt;Repositorio / Codigo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/spinner-loader-asincrono&quot;&gt;Spinner loader asíncrono&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/contador-resultados&quot;&gt;Creación de un contador de resultados&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/grafica-lineas&quot;&gt;Gráfica de lineas dinámica con SVG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/carga-svg&quot;&gt;Cargar SVG dinámicamente&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/summer-quiz.CeOcInKG_1DP5P4.webp"/><category>portfolio</category><category>web</category><category>código</category><category>html</category><category>css</category><category>javascript</category><category>juego</category><category>accesibilidad</category><category>responsive</category><author>JavGuerra</author></item><item><title>Códice</title><link>https://javguerra.github.io/blog/codice</link><guid isPermaLink="true">https://javguerra.github.io/blog/codice</guid><description>Mi git-blog sobre programación y formación TIC</description><pubDate>Wed, 21 Aug 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/codice.CdsWx0aT_ZlfDvy.webp&quot; alt=&quot;Códice&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#astro&lt;/em&gt;, &lt;em&gt;#ssg&lt;/em&gt;, &lt;em&gt;#tailwind&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;, &lt;em&gt;#typescript&lt;/em&gt;, &lt;em&gt;#zod&lt;/em&gt;, &lt;em&gt;#node.js&lt;/em&gt;, &lt;em&gt;#markdown&lt;/em&gt;, &lt;em&gt;#responsive&lt;/em&gt;, &lt;em&gt;#accesibilidad&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;Hacia tiempo que quería darle un giro a mi anterior &lt;a href=&quot;/blog/hola-mundo&quot;&gt;git-blog elaborado con Jekill&lt;/a&gt;. Hace un mes me topé con &lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt;, un SSG en JavaScript/TypeScript bajo Node.js, que cuenta con una excelente documentación, y que además incluye un tutorial para hacer un blog. Esto terminó de decidirme para realizar el cambio que ahora presento.&lt;/p&gt;
&lt;h1 id=&quot;retos&quot;&gt;Retos&lt;/h1&gt;
&lt;p&gt;Para llevar a cabo el desarrollo de un nuevo blog personalizado, se me presentaban dos retos:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Realizar la aplicación para que fuera operativa al menos con la mayoría de funcionalidades que ya tenía en el anterior blog.&lt;/li&gt;
&lt;li&gt;Migrar las entradas del blog anterior a la nueva estructura de la aplicación, lo que además implicaba repensar esta estructura.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;la-aplicación&quot;&gt;La aplicación&lt;/h2&gt;
&lt;p&gt;Elaborar la aplicación fue realmente sencillo. Siempre hay atascos, pero con la documentación, el tutorial, el Discord de Astro, los videos de YouTube y la IA, fueron subsanándose. El proyecto ha sido el mejor aprendizaje posible.&lt;/p&gt;
&lt;p&gt;Tres cosas me han llevado algo de tiempo:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Extender la colección de posts usando el esquema RSS.&lt;/li&gt;
&lt;li&gt;Utilizar el componente «Image» de Astro.&lt;/li&gt;
&lt;li&gt;JavaScript/TypeScript no funciona como se espera usando transiciones.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Lo relativo a la colección es lógico, porque estaba usando conceptos nuevos y aprendiendo a usar la &lt;a href=&quot;https://zod.dev/&quot;&gt;biblioteca Zod&lt;/a&gt; para definir y validar el esquema de los datos de las colección de entradas del blog. Zod permite validar el &lt;code&gt;frontmatter&lt;/code&gt; o cabecera de cada post para que no falte nada. La idea era partir del esquema &lt;code&gt;rssSchema&lt;/code&gt; y extenderlo para que incluyese algunos datos no contemplados, como por ejemplo el &lt;code&gt;coverImage&lt;/code&gt; o los &lt;code&gt;tags&lt;/code&gt; (&lt;em&gt;Ver fichero /src/content/config.ts&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;Pero confieso que el uso del componente Image me ha dado algún quebradero de cabeza, posiblemente relacionado con el schema mencionado, pues no me ha sido posible usar indistintamente imágenes con rutas relativas o rutas absolutas en los encabezados de las entradas. El problema tiene que ver con el atributo &lt;code&gt;src&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Si bien Image permite indicar una ruta relativa (/public) o remota (https), cuando se trata de usar la carpeta /src/assets surgen los problemas. La solución pasa por importar las imágenes, pero ¿qué ocurre cuando se ha de importar una colección de imágenes, para, por ejemplo, el listado de los proyectos del portafolio?&lt;/p&gt;
&lt;p&gt;Mi opción consiste en crear un arreglo con todas las imágenes importadas usando &lt;code&gt;import.meta.glob()&lt;/code&gt;, y luego acceder a cada elemento del arreglo referenciado por su ruta, como se muestra aquí:&lt;/p&gt;
&lt;pre class=&quot;astro-code github-dark&quot; style=&quot;background-color:#24292e;color:#e1e4e8; overflow-x: auto;&quot; tabindex=&quot;0&quot; data-language=&quot;javascript&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; portfolio &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt; &quot;@/content/_portfolio.json&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;;  &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// proyectos con sus respectivas rutas de imagenes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; images&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; import&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;glob&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;&quot;@/assets/portfolio/*&quot;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, { eager: &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; projects&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; portfolio.projects.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;project&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  const&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt; image&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; images[&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;`/src/assets/portfolio/${&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;project&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;img&lt;/span&gt;&lt;span style=&quot;color:#9ECBFF&quot;&gt;}`&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;as&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; Record&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;string&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;any&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;&amp;gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;  return&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; { &lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;project, image }; &lt;/span&gt;&lt;span style=&quot;color:#6A737D&quot;&gt;// a cada proyecto se le añade la imagen importada&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#F97583&quot;&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;projects.&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:#FFAB70&quot;&gt;project&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt; =&amp;gt;&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;  &amp;lt;&lt;/span&gt;&lt;span style=&quot;color:#79B8FF&quot;&gt;Image&lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt; src&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{project.image.default} &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;alt&lt;/span&gt;&lt;span style=&quot;color:#F97583&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;{project.alt} &lt;/span&gt;&lt;span style=&quot;color:#B392F0&quot;&gt;inferSize&lt;/span&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:#E1E4E8&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Este ejemplo simplificado mostrará la lista de imágenes asociadas a los proyectos.&lt;/p&gt;
&lt;h2 id=&quot;la-migración&quot;&gt;La migración&lt;/h2&gt;
&lt;p&gt;&lt;img __ASTRO_IMAGE_=&quot;{&amp;quot;alt&amp;quot;:&amp;quot;Códice versión Jekill&amp;quot;,&amp;quot;src&amp;quot;:&amp;quot;@/assets/img/codice-jekill.png&amp;quot;,&amp;quot;index&amp;quot;:0}&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Versión previa del blog en Jekill&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Tras conseguir que todo funcionase, llegó el turno de la migración, que pensaba que sería complicada, pero sólo fue laboriosa.&lt;/p&gt;
&lt;p&gt;Haciendo uso del filtrado de contenido del IDE fui cambiando los enlaces de Jekill de las referencias entre las distintas entradas, y creando el nuevo encabezado (&lt;code&gt;frontmatter&lt;/code&gt;) de cada entrada escrita en Markdown.&lt;/p&gt;
&lt;p&gt;A medida que este cambio se iba realizando fue necesario ir adaptando los estilos de texto haciendo uso de &lt;a href=&quot;https://tailwindcss.com/&quot;&gt;Tailwind&lt;/a&gt; y su plugin &lt;a href=&quot;https://github.com/tailwindlabs/tailwindcss-typography&quot;&gt;Typography&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Por último, como decidí incluir las transiciones de Astro, me topé con un problema curioso. Para activar o desactivar el menú hamburguesa uso JavaScript. La primera vez que se usa, funciona, pero en los siguientes casos, deja de hacerlo. Lo mismo ocurre con el botón «Volver».&lt;/p&gt;
&lt;p&gt;He tenido que hacer una comprobación para recargar siempre el evento click en ambos casos. Ver /src/components/Hamburger.astro y /src/components/ButtonLink.astro respectivamente.&lt;/p&gt;
&lt;p&gt;Lo mejor de todo es que ha sido divertido hacerlo, y conocer Astro, esta nueva y muy potente herramienta que creo que va a dar mucho juego. Quedan por delante innumerables mejoras y actualizaciones, por lo que la diversión continúa.&lt;/p&gt;
&lt;h1 id=&quot;características&quot;&gt;Características&lt;/h1&gt;
&lt;p&gt;La aplicación cuenta con las siguientes secciones: portada, sobre mi, porfolio, blog, temas y enlaces recomendados. Hace uso de las características avanzadas de Astro, y también:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Incluye RSS de contenidos&lt;/li&gt;
&lt;li&gt;Enlaza con la API de Mastodon&lt;/li&gt;
&lt;li&gt;Implementa sitemap para SEO&lt;/li&gt;
&lt;li&gt;Incluye estadísticas del sitio&lt;/li&gt;
&lt;li&gt;Integra Disqus para comentarios&lt;/li&gt;
&lt;li&gt;Implementa un buscador&lt;/li&gt;
&lt;li&gt;Usa tema de color claro/oscuro automático&lt;/li&gt;
&lt;li&gt;Realiza transiciones de página&lt;/li&gt;
&lt;li&gt;Es accesible&lt;/li&gt;
&lt;li&gt;Es responsive&lt;/li&gt;
&lt;li&gt;Usa TypeScript&lt;/li&gt;
&lt;li&gt;Contiene etiquetado Open Graph&lt;/li&gt;
&lt;li&gt;Es compatible con PWA&lt;/li&gt;
&lt;li&gt;Consigue una calificación de carbono «A» (&lt;a href=&quot;https://www.websitecarbon.com/website/javguerra-github-io/&quot;&gt;ver&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;licencias&quot;&gt;Licencias&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Sobre los contenidos (entradas del blog): &lt;a href=&quot;https://creativecommons.org/licenses/by-sa/4.0/deed.es&quot;&gt;CC BY-SA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Sobre el código fuente: &lt;a href=&quot;https://github.com/JavGuerra/tienda-8-bits/blob/main/LICENSE&quot;&gt;GNU GENERAL PUBLIC LICENSE Version 3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Iconos: &lt;a href=&quot;https://www.svgrepo.com/collection/solar-linear-icons/&quot;&gt;Solar Linear Icons&lt;/a&gt; en SVG Repo&lt;/li&gt;
&lt;li&gt;Tipografía: &lt;a href=&quot;https://www.fontsquirrel.com/fonts/blogger-sans&quot;&gt;Blogger_Sans-Medium&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;saber-más&quot;&gt;Saber más&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/blog/api-mastodon&quot;&gt;Accediendo a la API de Mastodon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/JavGuerra/javguerra.github.io&quot;&gt;Repositorio en GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/hola-mundo&quot;&gt;git-blog anterior elaborado con Jekill&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://es.wikipedia.org/wiki/Generador_de_sitios_est%C3%A1ticos&quot;&gt;SSG&lt;/a&gt;, &lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt; y &lt;a href=&quot;https://es.wikipedia.org/wiki/Astro_(framework)&quot;&gt;Astro en Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tailwindcss.com/&quot;&gt;Tailwind&lt;/a&gt; y &lt;a href=&quot;https://github.com/tailwindlabs/tailwindcss-typography&quot;&gt;Typography&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zod.dev/&quot;&gt;Biblioteca Zod&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.astro.build/es/tutorial/0-introduction/&quot;&gt;Construye tu primer blog con Astro&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://youtu.be/sOXW0ZnJxbQ?si=yLRwfY4lyOMaHypc&quot;&gt;Curso de Astro, por Fazt, en Youtube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;ir-a-la-página&quot;&gt;Ir a la página&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://javguerra.github.io/&quot;&gt;&lt;img src=&quot;/assets/img/qr.svg&quot; alt=&quot;Código QR&quot;&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://javguerra.github.io/&quot;&gt;https://javguerra.github.io/&lt;/a&gt;&lt;/p&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/codice.CdsWx0aT_ZlfDvy.webp"/><category>portfolio</category><category>web</category><category>código</category><category>astro</category><category>ssg</category><category>tailwind</category><category>javascript</category><category>typescript</category><category>zod</category><category>node.js</category><category>markdown</category><category>responsive</category><category>accesibilidad</category><author>JavGuerra</author></item><item><title>Batman para QL</title><link>https://javguerra.github.io/blog/batman-ql</link><guid isPermaLink="true">https://javguerra.github.io/blog/batman-ql</guid><description>Web del lanzamiento de un remake para QL del conocido juego de los 80.</description><pubDate>Fri, 06 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://javguerra.github.io/_astro/batmanql.DQI2tAmB_ZOVqUQ.webp&quot; alt=&quot;Banner del lanzamiento de Batman para QL&quot; style=&quot;max-width: 100%; height: auto;&quot; /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Etiquetas:&lt;/strong&gt; &lt;em&gt;#sinclair ql&lt;/em&gt;, &lt;em&gt;#portfolio&lt;/em&gt;, &lt;em&gt;#web&lt;/em&gt;, &lt;em&gt;#código&lt;/em&gt;, &lt;em&gt;#html&lt;/em&gt;, &lt;em&gt;#css&lt;/em&gt;, &lt;em&gt;#javascript&lt;/em&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;El 10 de mayo de 2025 fue lanzado «Batman QL», un remake del «Batman» de 1986 de Jon Ritman y Bernie Drummond para el retro-ordenador &lt;a href=&quot;/blog/sinclair-ql&quot;&gt;Sinclair QL&lt;/a&gt; a cargo de Joan Gayón. Yo hice mi parte elaborando la landing page del lanzamiento que presento en esta entrada.&lt;/p&gt;
&lt;p&gt;Joan es un compañero de nuestro grupo de aficionados en torno a esta máquina, y su juego ha causado sensación, siendo, hoy por hoy, la mejor versión de este clásico para un ordenador de los 80, y el mejor juego para QL de todos los tiempos, tanto por su jugabilidad como por sus gráficos.&lt;/p&gt;
&lt;h1 id=&quot;la-página-de-lanzamiento&quot;&gt;La página de lanzamiento&lt;/h1&gt;
&lt;p&gt;Visita la página para conocer más sobre este juego.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://badared.com/badaman/ql/batman&quot;&gt;&lt;button&gt;Acceder a la página web&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;características&quot;&gt;Características&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Multiidioma&lt;/strong&gt;. La web está disponible tanto en español como inglés. Un fichero index.php determina, en función del navegador, si el visitante habla español o no, y redirige a una u otra página.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;En sintonía con el aspecto del juego&lt;/strong&gt;. El menú de la página simula el menú del juego, y el colorido y la temática son afines.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Responsive&lt;/strong&gt;, Se adapta a distintos dispositivos como móviles (&lt;em&gt;movile first&lt;/em&gt;), tabletas y pantallas de ordenador.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Accesible&lt;/strong&gt;. funciona en lectores de pantalla por voz.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Icono para moviles&lt;/strong&gt;. Es compatible con &lt;em&gt;Progessive Web Aplication&lt;/em&gt; (&lt;a href=&quot;https://developer.mozilla.org/es/docs/Web/Progressive_web_apps&quot;&gt;PWA&lt;/a&gt;) a través de fichero &lt;a href=&quot;https://developer.mozilla.org/es/docs/Web/Manifest&quot;&gt;manifest.json&lt;/a&gt;, por lo que la página puede ser instalada en dispositivos móviles como una web app.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Información para redes sociales&lt;/strong&gt;, Implementa el protocolo &lt;a href=&quot;https://ogp.me/&quot;&gt;Open Graph&lt;/a&gt; para la correcta inserción de la web en redes sociales.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sin frameworks&lt;/strong&gt;. No emplea frameworks de JavaScript o CSS, sino código propio, haciendo más liviana la carga.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Estadísticas&lt;/strong&gt;. La web enlaza un servicio de estadísticas de visitas.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;la-presentación&quot;&gt;La presentación&lt;/h1&gt;
&lt;p&gt;Además de en las redes sociales, tanto el juego como la página fueron presentados el día 17 de mayo de 2025 en el &lt;a href=&quot;/blog/mhc&quot;&gt;Museo de Historia de la Computación&lt;/a&gt;, con un significativo alcance para lo que supone una comunidad como esta.&lt;/p&gt;
&lt;p&gt;Se hicieron eco del lanzamiento las principales web del sector, como Amigawave, Indie Retro News, El Mundo del Spectrum, Computer Emuzone, Spectrum Computing, El Spectrumero, Retroinvaders, Perfect Pixel, Vintage is the new old, spectrumandretronews, Modern Retro Gaming News, De Vuego, Retro8bitshop, Planet Sinclair, entre otras.&lt;/p&gt;
&lt;p&gt;En la primera semana se recibieron más de 1.200 visitas al Blog y la web desde 42 países, más de 3.300 visitas a los posts en foros retro, y se contabilizaron más de 700 descargas.&lt;/p&gt;
&lt;p&gt;Ver la &lt;a href=&quot;/assets/doc/Batman-presenta.pdf&quot;&gt;presentación del juego en PDF&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&quot;el-juego&quot;&gt;El juego&lt;/h1&gt;
&lt;p&gt;Puedes obtener información sobre el juego, sus características y modo de uso en su &lt;a href=&quot;https://badared.com/badaman/ql/batman&quot;&gt;web&lt;/a&gt; o en su &lt;a href=&quot;https://badared.com/badaman/ql/batman/assets/doc/Batman-es.pdf&quot;&gt;manual&lt;/a&gt; disponible para descarga, y también en el artículo &lt;a href=&quot;https://sinclairqles.wordpress.com/2025/05/10/batmanql-joan-gayon-2025/&quot;&gt;Batman, Joan Gayón (2025)&lt;/a&gt; en nuestro blog sobre QL.&lt;/p&gt;
&lt;p&gt;Te adelanto que se trata de una copia fiel pixel a pixel del original, mejorada con mayor colorido, Si autor lo ha llevado a cabo como un reto personal y un homenaje que ha presentado grandes desafíos técnicos.&lt;/p&gt;
&lt;p&gt;Dispones de una versión preparada para emulador en Windows que puedes descargar.&lt;/p&gt;
&lt;h1 id=&quot;enlaces&quot;&gt;Enlaces&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://badared.com/badaman/ql/batman&quot;&gt;Acceder a la página web del juego&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://batmanql.goatcounter.com/&quot;&gt;Estadísticas de acceso público&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/assets/doc/Batman-presenta.pdf&quot;&gt;Presentación del juego en PDF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/blog/sinclair-ql&quot;&gt;Info sobre Sinclair QL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><enclosure url="https://javguerra.github.io/_astro/batmanql.DQI2tAmB_ZOVqUQ.webp"/><category>sinclair ql</category><category>portfolio</category><category>web</category><category>código</category><category>html</category><category>css</category><category>javascript</category><author>JavGuerra</author></item></channel></rss>