Compare commits

..

2 Commits

Author SHA1 Message Date
Sergiotarxz 7c98fc0c27 Removing other ads. 2023-09-06 19:50:31 +02:00
Sergiotarxz f544ee7360 Adding add for la Ermita. 2023-09-06 19:50:09 +02:00
503 changed files with 1683 additions and 430414 deletions

View File

@ -10,10 +10,7 @@ module.exports = {
sourceType: 'module',
project: 'tsconfig.json'
},
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
root: true,
plugins: [ ],
rules: {
indent: ['error', 4, { SwitchCase: 1 }],
},

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "conversejs"]
path = conversejs
url = https://github.com/conversejs/converse.js/

View File

@ -17,7 +17,6 @@ my $build = Module::Build->new(
'DBD::Pg' => 0,
'DateTime::Format::ISO8601.pm' => 0,
'DateTime::Format::Mail.pm' => 0,
'DateTime::Format::Pg' => 0,
'SVG' => 0,
'XML::Twig' => 0,
'JSON' => 0,

View File

@ -1,38 +0,0 @@
<category>
<title>Donde hacer deporte en Burguillos.</title>
<description>
<h2>Actividades deportivas disponibles en Burguillos.</h2>
<p>Aquí puedes encontrar información acerca de las actividades deportivas disponibles en Burguillos, ejercitate para tener un cuerpo y mente más sanos.</p>
<p>¿Conoces alguna actividad deportiva que debiera estar aquí? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a> y haznoslo saber.</p>
</description>
<parent>comercios</parent>
<priority>0</priority>
<menu_text>Deporte</menu_text>
<slug>actividades-deportivas</slug>
<attributes>
<attribute>
<title>Danza en Burguillos.</title>
<identifier>danza</identifier>
<priority>1</priority>
<menu_text>Donde bailar en Burguillos.</menu_text>
<description>
<p>Baila, salta, ejercitaté.</p>
<p>Deslumbra en las redes sociales y los eventos con tus habilidades de danza.</p>
<p>¿A que esperas para echarte un baile?</p>
</description>
</attribute>
<attribute>
<title>Artes marciales en Burguillos.</title>
<identifier>artes-marciales</identifier>
<priority>1</priority>
<menu_text>Donde prácticar artes marciales en Burguillos.</menu_text>
<description>
<p>Práctica artes marciales en Burguillos.</p>
<p>Las artes marciales son un deporte con muchos beneficios, aumenta la flexibilidad, el equilibrio, la disciplina y además son un pasatiempo genial para dedicar tus tardes.</p>
<p>Unete a alguna y aprende una habilidad única.</p>
</description>
</attribute>
</attributes>
</category>

View File

@ -1,13 +0,0 @@
<category>
<title>Tiendas de alimentación en Burguillos</title>
<img src="/img/alimentacion.webp"/>
<description>
<p>Este es un listado de las tiendas de alimentación en Burguillos con la información relevante para disfrutar de tu estancia en Burguillos.</p>
<p>¿Quieres que tu comercio aparezca aquí? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a></p>
</description>
<parent>comercios</parent>
<priority>0</priority>
<menu_text>Tiendas de alimentación</menu_text>
<slug>tiendas-alimentacion</slug>
</category>

View File

@ -1,17 +0,0 @@
<category>
<title>Productos artesanales en Burguillos.</title>
<description>
<p>Descubre la mejor artesanía de Burguillos.</p>
<p>Compra artesanos productos locales de Burguillos.</p>
<p>¿Quieres que tu comercio aparezca aquí? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a></p>
</description>
<parent>comercios</parent>
<priority>0</priority>
<menu_text>Artesanía</menu_text>
<slug>artesania</slug>
<img src="/img/artesania.webp" bottom-preview="630"/>
<attributes>
</attributes>
</category>

View File

@ -1,9 +1,8 @@
<category>
<title>Autobuses.</title>
<title>Horarios de Autobuses.</title>
<description>
<p>Aquí puedes encontrar toda la información sobre los autobuses de Burguillos.</p>
<p>Aquí puedes encontrar toda la información sobre los horarios de autobuses de Burguillos.</p>
</description>
<img src="/img/autobus.webp" bottom-preview="500"/>
<priority>1</priority>
<menu_text>Autobuses</menu_text>
<slug>autobuses</slug>

View File

@ -1,15 +0,0 @@
<category>
<title>Lugares donde celebrar ocasiones.</title>
<description>
<p>Ya sean bodas, bautizos, cumpleaños, fiestas infantiles o comuniones, encuentra en Burguillos el lugar perfecto para recordar para siempre con cariño los momentos especiales de la vida.</p>
<p>¿Quieres que tu comercio aparezca aquí? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a></p>
</description>
<parent>comercios</parent>
<priority>0</priority>
<menu_text>Celebraciones</menu_text>
<slug>celebraciones</slug>
<img src="/img/celebraciones.webp"/>
<attributes>
</attributes>
</category>

View File

@ -1,12 +1,10 @@
<category>
<title>Comercios de Burguillos.</title>
<description>
<p>Aquí puedes encontrar información acerca de los comercios de Burguillos.</p>
<p>¿Quieres que tu comercio aparezca aquí? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a></p>
</description>
<priority>2</priority>
<img src="/img/comercio.webp" bottom-preview="600"/>
<menu_text>Comercios</menu_text>
<slug>comercios</slug>
<random>true</random>
<title>Comercios de Burguillos.</title>
<description>
<p>Aquí puedes encontrar información acerca de los comercios de Burguillos.</p>
<p>¿Quieres que tu comercio aparezca aquí? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a></p>
</description>
<priority>2</priority>
<menu_text>Comercios</menu_text>
<slug>comercios</slug>
</category>

View File

@ -1,14 +0,0 @@
<category>
<title>Dentistas en Burguillos.</title>
<description>
<p>Te traemos una lista de dentistas en Burguillos para que puedas cuidar de la salud y estética de tu boca con los mejores profesionales.</p>
<p>¿Quieres que tu comercio aparezca aquí? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a></p>
<p><a rel="noreferrer nofollow" href="https://www.freepik.es/vector-gratis/mujer-dentista-examinando-dientes-paciente-sobre-fondo-blanco_24553482.htm">Imagen de preview cortesía de Brgfx</a>.</p>
</description>
<priority>2</priority>
<img src="/img/dentista.webp" bottom-preview="530"/>
<menu_text>Dentistas</menu_text>
<slug>dentistas</slug>
<parent>comercios</parent>
</category>

View File

@ -1,23 +1,21 @@
<category>
<title>Donde comer en Burguillos. - Cartas y Menús.</title>
<description>
<title>Donde comer en Burguillos. - Cartas y Menús.</title>
<description>
<h2>Descubre los bares y restaurantes de Burguillos con sus cartas, menús y datos de contacto.</h2>
<p>Aquí puedes encontrar información acerca de los negocios de hostelería de Burguillos.</p>
<p>Aquí puedes encontrar información acerca de los negocios de hostelería de Burguillos.</p>
<p>Disfruta tu comida.</p>
<p>¿Quieres que tu comercio aparezca aquí? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a></p>
</description>
<p>¿Quieres que tu comercio aparezca aquí? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a></p>
</description>
<parent>comercios</parent>
<priority>0</priority>
<menu_text>Donde comer</menu_text>
<slug>donde-comer</slug>
<img src="/img/donde-comer.webp"/>
<priority>0</priority>
<menu_text>Donde comer</menu_text>
<slug>donde-comer</slug>
<attributes>
<attribute>
<title>Comida vegana en Burguillos.</title>
<identifier>comida-vegana</identifier>
<priority>1</priority>
<menu_text>Listado de sitios que tienen oferta de platos veganos.</menu_text>
<img src="/img/vegano.webp" bottom-preview="400"/>
<description>
<h2>Restaurantes y bares con comida vegana en Burguillos.</h2>
@ -33,7 +31,6 @@
<identifier>reparto-a-domicilio-comida</identifier>
<priority>0</priority>
<menu_text>Listado de sitios de comida con reparto a domicilio.</menu_text>
<img src="/img/comida-domicilio.webp" bottom-preview="400"/>
<description>
<h2>Cartas y Menús de Pizzerías, Hamburgueserías, Kebab, Restaurantes, Bares, etc.</h2>
@ -46,7 +43,6 @@
<title>Comer hamburguesas en Burguillos - Cartas y Menús.</title>
<identifier>hamburguesas</identifier>
<priority>0</priority>
<img src="/img/hamburguesa.webp" bottom-preview="600"/>
<menu_text>Listado de sitios de comida que preparan hamburguesas.</menu_text>
<description>
<h2>Hamburgueserias y todo tipo de establecimientos que preparan hamburguesas.</h2>

View File

@ -1,29 +0,0 @@
<category>
<title>Negocios de estética en Burguillos.</title>
<description>
<h2>Descubre todos los negocios que te ayudan a estar más guapo o guapa.</h2>
<p>¿Quieres que tu comercio aparezca aquí? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a></p>
</description>
<parent>comercios</parent>
<priority>0</priority>
<menu_text>Estética</menu_text>
<slug>estetica</slug>
<img src="/img/estetica.webp" bottom-preview="630"/>
<attributes>
<attribute>
<title>Belleza de manos.</title>
<identifier>belleza-manos</identifier>
<priority>1</priority>
<menu_text>Belleza de manos.</menu_text>
<img src="/img/unas.webp"/>
<description>
<h2>¿Andas buscando donde hacerte las uñas en Burguillos?</h2>
<p>No busques más, aquí puedes encontrar una lista de los lugares más destacados.</p>
<p>¿Conoces algún negocio que debería estar listado aquí? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a> y lo añadiremos a este registro.</p>
</description>
</attribute>
</attributes>
</category>

View File

@ -1,17 +1,16 @@
<category>
<title>Información de Burguillos.</title>
<description>
<div class="easter-egg">
<div class="burguillos-logo-container">
<img alt="The logo of Burguillos.info" src="/img/burguillos-new-logo.svg"/>
</div>
</div>
<p>Descubre todo lo que Burguillos, Sevilla tiene para ofrecerte.</p>
<description>
<div class="easter-egg">
<div class="burguillos-logo-container">
<img alt="The logo of Burguillos.info" src="/img/burguillos-new-logo.svg"/>
</div>
</div>
<p>Burguillos.info no está afiliado con el Ayuntamiento de Burguillos.</p>
<p>Un mundo de posibilidades a tu alcance en Burguillos.</p>
</description>
<img src="/img/rotonda.webp"/>
<priority>0</priority>
<menu_text><img alt="Principio" class="index-image-menu" src="/img/burguillos-new-logo.svg?v=1"/></menu_text>
<slug>index</slug>
<p>Esta página está destinada a informar de los sucesos y negocios de nuestro pueblo, cualquiera puede redactar una noticia para que aparezca en este medio mientras pase un proceso de revisión por parte del staff de Burguillos.info.</p>
</description>
<priority>0</priority>
<menu_text><img alt="Principio" class="index-image-menu" src="/img/burguillos-new-logo.svg?v=1"/></menu_text>
<slug>index</slug>
</category>

View File

@ -1,17 +0,0 @@
<category>
<title>Tiendas de ropa y accesorios en Burguillos.</title>
<description>
<p>Descubre las mejores prendas de vestir disponibles en Burguillos.</p>
<p>Compra productos locales de Burguillos.</p>
<p>¿Quieres que tu comercio aparezca aquí? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a></p>
</description>
<parent>comercios</parent>
<priority>0</priority>
<menu_text>Tiendas de ropa y accesorios</menu_text>
<slug>tiendas-ropa</slug>
<img src="/img/tienda-ropa.webp" bottom-preview="630"/>
<attributes>
</attributes>
</category>

View File

@ -6,7 +6,7 @@
<ogdesc>Los horarios de autobuses de Burguillos.</ogdesc>
<category>autobuses</category>
<slug>horarios-autobuses</slug>
<img src="/img/autobus.webp" bottom-preview="500"/>
<img src="/img/autobus.webp"/>
<content>
<h2>Horarios Autobuses Castiblanco - Burguillos - Sevilla - Almaden de la Plata - Alcalá del Río - Rinconada - San Ignacio del Viar.</h2>
<h3>Destino Sevilla.</h3>

View File

@ -0,0 +1,25 @@
<post>
<author>Burguillos.info</author>
<date>2022-11-14T12:00+00:00</date>
<title>Últimas plazas para Taller de Macrame.</title>
<ogdesc>Últimas plazas para Taller de Macrame.</ogdesc>
<category>talleres</category>
<img src="/img/poster-macrame-preview.webp"/>
<slug>ultimas-plazas-taller-de-macrame</slug>
<content>
<img alt="Poster del taller" src="/img/poster-macrame.webp"/>
<p>Ultima hora, nos hemos enterado de un taller de Macramé planeado para el 26 de Noviembre de 10:00 a 18:00 en la Mercería la Gallina Costurera localizada en Avenida Pepe Luna.</p>
<p>El taller está organizado por Maka Guijo y costará 45€ por persona.</p>
<p>Los materiales vienen incluidos con el precio de la plaza.</p>
<p>Si os preguntáis.-¿Qué es el Macramé?.- No os angustieis que yo os lo cuento.</p>
<p>Según Wikipedia, el Macramé es la técnica de crear tejidos mediante el uso de nudos decorativos.</p>
<p>Usando Macramé puedes crear regalos preciosos para tus familiares o amigos; o incluso quedarte tú con tu obra para exponerla, en el cartel se puede apreciar algunas de las cosas que se pueden realizar mediante el uso de Macramé.</p>
<p>Si quieres pasar un buen rato y divertirte con este peculiar estilo de artesanía no dudes en contactar con <a href="tel:+34611489981">611 489 981</a>, no esperes hasta el último momento ya que las plazas son limitadas.</p>
</content>
</post>

View File

@ -0,0 +1,19 @@
<post>
<author>Burguillos.info</author>
<date>2022-11-15T23:41+00:00</date>
<title>Clases de Guitarra con Eduardo Trassierra.</title>
<ogdesc>Clases de Guitarra con Eduardo Trassierra.</ogdesc>
<category>talleres</category>
<img src="/img/eduardo-trasierra-preview.webp"/>
<slug>clases-guitarra-eduardo-trassierra</slug>
<content>
<img alt="Imagen de las clases de guitarra, el profesor Eduardo Trassierra" src="/img/eduardo-trasierra.webp"/>
<p>Os informamos de que se ha abierto el plazo de inscripción para clases de guitarra impartidas por Eduardo Trassierra, un reputado guitarrista a escala nacional.</p>
<p>Las clases estarán localizadas en nuestro municipio, Burguillos.</p>
<p>Desde Burguillos.info aun no conocemos el precio de las clases, el organizador, Ángel, nos ha proporcionado un telefono de contacto donde podéis preguntar todos los detalles. <a href="tel:+34676334071">676334071</a></p>
<p>Las clases comenzarán tan pronto como se reunan 5 personas interesadas. ¡No te demores en inscribirte!</p>
</content>
</post>

View File

@ -3,7 +3,7 @@
<date>2022-11-19T18:03+00:00</date>
<title>Centro Médico Juan Manuel Pérez Sanchez - Datos de Contacto - Pedir Cita</title>
<ogdesc>Centro Médico Juan Manuel Pérez Sanchez - Datos de Contacto - Pedir Cita</ogdesc>
<last_modification_date>2023-05-03T00:59+00:00</last_modification_date>
<last_modification_date>2023-05-03T00:59+00:00</last_modification_date>
<category>comercios</category>
<slug>centro-medico-juan-manuel-perez-sanchez</slug>
<img src="/img/policlinica-burguillos-preview.webp"/>
@ -13,7 +13,7 @@
<p>La clínica Juan Manuel Pérez Sanchez es un centro de atención a la salud dedicado a las siguientes especialidades:</p>
<ul>
<li>Odontologia general, Ortodoncia, Ortodoncia Invisible, Odontopediatría, Estetica Dental y Labios, Protesis y Aparatos Dentales, Implantes...</li>
<li>Odontologia general, Ortodoncia, Ortodoncia Invisible, Odontopediatria, Estetica Dental y Labios, Protesis y Aparatos Dentales, Implantes...</li>
<li>Clínica concertada del plan de atención infantil de la Junta de Andalucía.</li>
<li>Radiografías Panorex-Teleradiografía.</li>
<li>Pedagogia, Especialista en trastornos de lenguaje y audicion, Clases de apoyo, Talleres, Tramitacion de becas escolares.</li>

View File

@ -1,142 +1,424 @@
<post>
<author>Burguillos.info</author>
<date>2022-11-22T09:47+00:00</date>
<title>Mesón - Bar - Cristóbal - Carta y Menú.</title>
<ogdesc>Mesón - Bar - Cristóbal - Carta y Menú.</ogdesc>
<last_modification_date>2023-09-06T11:16+00:00</last_modification_date>
<category>donde-comer</category>
<category>index</category>
<slug>bar-cristobal</slug>
<attributes>
<attribute>hamburguesas</attribute>
</attributes>
<pinned>1</pinned>
<img src="/img/cristobal-preview.webp" />
<content>
<h2 style="background: black; color: red;">Menú actualizado con
nuevos precios y productos 2023-09-06</h2>
<img alt="Entrada al Mesón - Bar Cristobal."
src="/img/cristobal.webp" />
<p>El Mesón - Bar Cristóbal ubicado en la Calle los Palmeros
número 32 es una opción ideal para tomarte un café o comer en
Burguillos.</p>
<p>Además acepta pedidos a domicilio durante los meses
Noviembre, Diciembre, Enero y Febrero de Martes a Domingo
durante las noches.</p>
<p>El número de teléfono de contacto es
<a href="tel:+34621210460">621 210 460</a>.</p>
<p>A continuación procedemos a dejar la carta para que podáis
realizar el pedido que deseeis:</p>
<details>
<summary><h2>Entrantes</h2></summary>
<ul>
<li>Ensaladilla -- Tapa: <b>2.50€</b> 1/2 Ración: <b>5.00€</b> Ración: <b>10.00€</b></li>
<li>Aliño de Pimientos -- Tapa: <b>2.50€</b> 1/2 Ración: <b>5.00€</b> Ración: <b>10.00€</b></li>
<li>Aliño de Pulpo -- Tapa: <b>2.50€</b> 1/2 Ración: <b>5.00€</b> Ración: <b>10.00€</b></li>
<li>Aliño de Huevas -- Tapa: <b>2.50€</b> 1/2 Ración: <b>5.00€</b> Ración: <b>10.00€</b></li>
<li>Huevas con Mayonesa -- Tapa: <b>2.50€</b> 1/2 Ración: <b>5.00€</b> Ración: <b>10.00€</b></li>
<li>Ensalada Mixta -- Ración: <b>4.00€</b></li>
<li>Ensalada Normal -- Ración: <b>3.00€</b></li>
</ul>
</details>
<details>
<summary><h2>Aperitivos</h2></summary>
<ul>
<li>Papas Bravas -- Tapa: <b>3.00€</b> 1/2 Ración: <b>6.00€</b> Ración: <b>12.00€</b></li>
<li>Papas Alioli Calientes -- Tapa: <b>3.00€</b> 1/2 Ración: <b>6.00€</b> Ración: <b>12.00€</b></li>
<li>Papas Alioli Frías -- Tapa: <b>2.50€</b> 1/2 Ración: <b>5.00€</b> Ración: <b>10.00€</b></li>
<li>Croquetas de Jamón -- Tapa: <b>3.00€</b> 1/2 Ración: <b>6.00€</b> Ración: <b>12.00€</b></li>
<li>Croquetas de Cola de Toro -- Tapa: <b>3.50€</b> 1/2 Ración: <b>7.00€</b> Ración: <b>14.00€</b></li>
<li>Nugget de Pollo -- Tapa: <b>3.00€</b> 1/2 Ración: <b>6.00€</b> Ración: <b>12.00€</b></li>
<li>Cachopo -- Ración: <b>8.00€</b></li>
</ul>
</details>
<details>
<summary><h2>En Temporada</h2></summary>
<ul>
<li>Cabrillas -- Tapa: <b>3.00€</b> 1/2 Ración: <b>6.00€</b> Ración: <b>12.00€</b></li>
<li>Caracoles -- Tapa: <b>3.00€</b> 1/2 Ración: <b>6.00€</b> Ración: <b>12.00€</b></li>
</ul>
</details>
<details>
<summary><h2>Ibéricos</h2></summary>
<ul>
<li>Secreto -- Ración: <b>S-P</b></li>
<li>Lagrimitas -- Tapa: <b>3.50€</b> 1/2 Ración: <b>7.00€</b> Ración: <b>14.00€</b></li>
<li>Lagarto -- Tapa: <b>3.50€</b> 1/2 Ración: <b>7.00€</b> Ración: <b>14.00€</b></li>
<li>Tocinito -- Tapa: <b>3.00€</b> 1/2 Ración: <b>6.00€</b> Ración: <b>12.00€</b></li>
</ul>
</details>
<details>
<summary><h2>Carnes</h2></summary>
<ul>
<li>Carne Asá -- Tapa: <b>3.00€</b> 1/2 Ración: <b>6.00€</b> Ración: <b>12.00€</b></li>
<li>Solomillo al Whisky -- Tapa: <b>3.50€</b> 1/2 Ración: <b>8.00€</b> Ración: <b>16.00€</b></li>
<li>Solomillo a la Pimienta -- Tapa: <b>3.50€</b> 1/2 Ración: <b>8.00€</b> Ración: <b>16.00€</b></li>
<li>Solomillo al Roquefort -- Tapa: <b>3.50€</b> 1/2 Ración: <b>8.00€</b> Ración: <b>16.00€</b></li>
<li>Churrasco de Pollo/Cerdo -- Ración: <b>5.50€</b></li>
<li>Mini Serranito de Pollo/Cerdo -- Ración: <b>3.00€</b></li>
<li>Serranito de Pollo/Cerdo -- Ración: <b>5.00€</b></li>
<li>Pechuga de Pollo -- Ración: <b>5.50€</b></li>
<li>Pinchito de Pollo/Cerdo -- Ración: <b>3.00€</b></li>
<li>Brocheta de Solomillo -- Ración: <b>7.00€</b></li>
<li>Hamburguesa Simple -- Ración: <b>2.50€</b></li>
<li>Hamburguesa Completa -- Ración: <b>3.00€</b></li>
<li>Hamburguesa de Buey -- Ración: <b>5.00€</b></li>
</ul>
</details>
<details>
<summary><h2>Montaditos</h2></summary>
<ul>
<li>Montadito de Pollo/Cerdo -- Precio: <b>2.50€</b></li>
<li>Mantecadito de Pollo/Cerdo -- Precio: <b>3.00€</b></li>
<li>Montadito de Gambas -- Precio: <b>3.00€</b></li>
</ul>
</details>
<details>
<summary><h2>Cazuelitas</h2></summary>
<ul>
<li>Carne con tomate -- Tapa: <b>3.00€</b> 1/2 Ración: <b>6.00€</b> Ración: <b>12.00€</b></li>
<li>Carrillada Ibérica -- Tapa: <b>3.00€</b> 1/2 Ración: <b>6.00€</b> Ración: <b>12.00€</b></li>
<li>Atún Encebollado -- Tapa: <b>3.00€</b> 1/2 Ración: <b>6.00€</b> Ración: <b>12.00€</b></li>
<li>Bacalao con Tomate -- Tapa: <b>3.00€</b> 1/2 Ración: <b>6.00€</b> Ración: <b>12.00€</b></li>
<li>Espinacas -- Tapa: <b>3.00€</b> 1/2 Ración: <b>6.00€</b> Ración: <b>12.00€</b></li>
</ul>
</details>
<details>
<summary><h2>Pescados</h2></summary>
<ul>
<li>Chipirón a la Plancha/Frito -- Tapa: <b>3.50€</b> 1/2 Ración: <b>8.00€</b> Ración: <b>16.00€</b></li>
<li>Calamares Fritos -- Tapa: <b>3.00€</b> 1/2 Ración: <b>6.00€</b> Ración: <b>12.00€</b></li>
<li>Choco Frito -- Tapa: <b>3.50€</b> 1/2 Ración: <b>7.00€</b> Ración: <b>14.00€</b></li>
<li>Boquerones -- Tapa: <b>3.00€</b> 1/2 Ración: <b>6.00€</b> Ración: <b>12.00€</b></li>
<li>Acedias -- Tapa: <b>3.00€</b> 1/2 Ración: <b>6.00€</b> Ración: <b>12.00€</b></li>
<li>Puntillitas -- Tapa: <b>3.00€</b> 1/2 Ración: <b>6.00€</b> Ración: <b>12.00€</b></li>
<li>Adobo -- Tapa: <b>3.00€</b> 1/2 Ración: <b>6.00€</b> Ración: <b>12.00€</b></li>
<li>Brocheta de Gambas -- Tapa: <b>3.00€</b> 1/2 Ración: <b>8.00€</b> Ración: <b>14.00€</b></li>
<li>Pescado Variado -- 1/2 Ración: <b>7.00€</b> Ración: <b>14.00€</b></li>
<li>Pez Espada -- Ración: <b>8.00€</b></li>
<li>Merluza -- Ración: <b>6.00€</b></li>
<li>Dorada -- Ración: <b>6.00€</b></li>
</ul>
</details>
<author>Burguillos.info</author>
<date>2022-11-22T09:47+00:00</date>
<title>Mesón - Bar - Cristobal - Carta y Menú.</title>
<ogdesc>Mesón - Bar - Cristobal - Carta y Menú.</ogdesc>
<last_modification_date>2023-09-06T11:16+02:00</last_modification_date>
<category>donde-comer</category>
<slug>bar-cristobal</slug>
<attributes>
<attribute>hamburguesas</attribute>
</attributes>
<img src="/img/cristobal-preview.webp"/>
<content>
<h2 style="background: black; color: red;">Menú actualizado con nuevos precios y productos 2023-09-06</h2>
<img alt="Entrada al Mesón - Bar Cristobal." src="/img/cristobal.webp"/>
<p>El Mesón - Bar Cristobal ubicado en la Calle los Palmeros número 32 es una opción ideal para tomarte un café o comer en Burguillos.</p>
<p>Además acepta pedidos a domicilio durante los meses Noviembre, Diciembre, Enero y Febrero de Martes a Domingo durante las noches.</p>
<details>
<summary><h2>Postres</h2></summary>
<ol>
<li>Arroz con leche <b>2.50€</b></li>
<li>Natillas <b>2.50€</b></li>
<li>Flan de Huevo <b>2.50€</b></li>
<li>Helados Nestle <b>3.00€</b></li>
</ol>
</details>
<p>Por último desde Burguillos.info os indicamos que el precio
por el servicio de pan y picos por comensal es de 0.50€ y que
tenéis la posibilidad de pedir un extra en salsas por
0.50€.</p>
<p>¿Quieres ver tu negocio localizado en Burguillos en este
espacio? Contacta con
<a href="mailto:contact@owlcode.tech">
contact@owlcode.tech</a>.</p>
</content>
<p>El número de teléfono de contacto es <a href="tel:+34621210460">621210460</a>.</p>
<p>A continuación procedemos a dejar la carta para que podáis realizar el pedido que deseeis:</p>
<h2>Entrantes</h2>
<table>
<tr>
<th></th>
<th>Tapa</th>
<th>1/2 Ración</th>
<th>Ración</th>
</tr>
<tr>
<td>Ensaladilla</td>
<td>2.50€</td>
<td>5.00€</td>
<td>10.00€</td>
</tr>
<tr>
<td>Aliño de Pimientos</td>
<td>2.50€</td>
<td>5.00€</td>
<td>10.00€</td>
</tr>
<tr>
<td>Aliño de Pulpo</td>
<td>2.50€</td>
<td>5.00€</td>
<td>10.00€</td>
</tr>
<tr>
<td>Aliño de Huevas</td>
<td>2.50€</td>
<td>5.00€</td>
<td>10.00€</td>
</tr>
<tr>
<td>Huevas con Mayonesa</td>
<td>2.50€</td>
<td>5.00€</td>
<td>10.00€</td>
</tr>
<tr>
<td>Ensalada Mixta</td>
<td>-</td>
<td>-</td>
<td>4.00€</td>
</tr>
<tr>
<td>Ensalada Normal</td>
<td>-</td>
<td>-</td>
<td>3.00€</td>
</tr>
</table>
<h2>Aperitivos</h2>
<table>
<tr>
<th></th>
<th>Tapa</th>
<th>1/2 Ración</th>
<th>Ración</th>
</tr>
<tr>
<td>Papas Bravas</td>
<td>3.00€</td>
<td>6.00€</td>
<td>12.00€</td>
</tr>
<tr>
<td>Papas Alioli Calientes</td>
<td>3.00€</td>
<td>6.00€</td>
<td>12.00€</td>
</tr>
<tr>
<td>Papas Alioli Frías</td>
<td>2.50€</td>
<td>5.00€</td>
<td>10.00€</td>
</tr>
<tr>
<td>Croquetas de Jamón</td>
<td>3.00€</td>
<td>6.00€</td>
<td>12.00€</td>
</tr>
<tr>
<td>Croquetas de Cola de Toro</td>
<td>3.50€</td>
<td>7.00€</td>
<td>14.00€</td>
</tr>
<tr>
<td>Nugget de Pollo</td>
<td>3.00€</td>
<td>6.00€</td>
<td>12.00€</td>
</tr>
<tr>
<td>Cachopo</td>
<td>--</td>
<td>--</td>
<td>8.00€</td>
</tr>
</table>
<h2>En Temporada</h2>
<table>
<tr>
<th></th>
<th>Tapa</th>
<th>1/2 Ración</th>
<th>Ración</th>
</tr>
<tr>
<td>Cabrillas</td>
<td>3.00€</td>
<td>6.00€</td>
<td>12.00€</td>
</tr>
<tr>
<td>Caracoles</td>
<td>3.00€</td>
<td>6.00€</td>
<td>12.00€</td>
</tr>
</table>
<h2>Ibéricos</h2>
<table>
<tr>
<th></th>
<th>Tapa</th>
<th>1/2 Ración</th>
<th>Ración</th>
</tr>
<tr>
<td>Secreto</td>
<td>--</td>
<td>--</td>
<td>S-P</td>
</tr>
<tr>
<td>Lagrimitas</td>
<td>3.50€</td>
<td>7.00€</td>
<td>14.00€</td>
</tr>
<tr>
<td>Lagarto</td>
<td>3.50€</td>
<td>7.00€</td>
<td>14.00€</td>
</tr>
<tr>
<td>Tocinito</td>
<td>3.00€</td>
<td>6.00€</td>
<td>12.00€</td>
</tr>
</table>
<h2>Carnes</h2>
<table>
<tr>
<th></th>
<th>Tapa</th>
<th>1/2 Ración</th>
<th>Ración</th>
</tr>
<tr>
<td>Carne Asá</td>
<td>3.00€</td>
<td>6.00€</td>
<td>12.00€</td>
</tr>
<tr>
<td>Solomillo al Whisky</td>
<td>3.50€</td>
<td>8.00€</td>
<td>16.00€</td>
</tr>
<tr>
<td>Solomillo a la Pimienta</td>
<td>3.50€</td>
<td>8.00€</td>
<td>16.00€</td>
</tr>
<tr>
<td>Solomillo al Roquefort</td>
<td>3.50€</td>
<td>8.00€</td>
<td>16.00€</td>
</tr>
<tr>
<td>Churrasco de Pollo/Cerdo</td>
<td>--</td>
<td>--</td>
<td>5.50€</td>
</tr>
<tr>
<td>Mini Serranito de Pollo/Cerdo</td>
<td>--</td>
<td>--</td>
<td>3.00€</td>
</tr>
<tr>
<td>Serranito de Pollo/Cerdo</td>
<td>--</td>
<td>--</td>
<td>5.00€</td>
</tr>
<tr>
<td>Pechuga de Pollo</td>
<td>--</td>
<td>--</td>
<td>5.50€</td>
</tr>
<tr>
<td>Pinchito de Pollo/Cerdo</td>
<td>--</td>
<td>--</td>
<td>3.00€</td>
</tr>
<tr>
<td>Brocheta de Solomillo</td>
<td>--</td>
<td>--</td>
<td>7.00€</td>
</tr>
<tr>
<td>Hamburguesa Simple</td>
<td>--</td>
<td>--</td>
<td>2.50€</td>
</tr>
<tr>
<td>Hamburguesa Completa</td>
<td>--</td>
<td>--</td>
<td>3.00€</td>
</tr>
<tr>
<td>Hamburguesa de Buey</td>
<td>--</td>
<td>--</td>
<td>5.00€</td>
</tr>
</table>
<h2>Montaditos</h2>
<table>
<tr>
<th></th>
<th>Precio</th>
</tr>
<tr>
<td>Montadito de Pollo/Cerdo</td>
<td>2.50€</td>
</tr>
<tr>
<td>Mantecadito de Pollo/Cerdo</td>
<td>3.00€</td>
</tr>
<tr>
<td>Montadito de Gambas</td>
<td>3.00€</td>
</tr>
</table>
<h2>Cazuelitas</h2>
<table>
<tr>
<th></th>
<th>Tapa</th>
<th>1/2 Ración</th>
<th>Ración</th>
</tr>
<tr>
<td>Carne con tomate</td>
<td>3.00€</td>
<td>6.00€</td>
<td>12.00€</td>
</tr>
<tr>
<td>Carrillada Ibérica</td>
<td>3.00€</td>
<td>6.00€</td>
<td>12.00€</td>
</tr>
<tr>
<td>Atún Encebollado</td>
<td>3.00€</td>
<td>6.00€</td>
<td>12.00€</td>
</tr>
<tr>
<td>Bacalao con Tomate</td>
<td>3.00€</td>
<td>6.00€</td>
<td>12.00€</td>
</tr>
<tr>
<td>Espinacas</td>
<td>3.00€</td>
<td>6.00€</td>
<td>12.00€</td>
</tr>
</table>
<h2>Pescados</h2>
<table>
<tr>
<th></th>
<th>Tapa</th>
<th>1/2 Ración</th>
<th>Ración</th>
</tr>
<tr>
<td>Chipirón a la Plancha/Frito</td>
<td>3.50€</td>
<td>8.00€</td>
<td>16.00€</td>
</tr>
<tr>
<td>Calamares Fritos</td>
<td>3.00€</td>
<td>6.00€</td>
<td>12.00€</td>
</tr>
<tr>
<td>Choco Frito</td>
<td>3.50€</td>
<td>7.00€</td>
<td>14.00€</td>
</tr>
<tr>
<td>Boquerones</td>
<td>3.00€</td>
<td>6.00€</td>
<td>12.00€</td>
</tr>
<tr>
<td>Acedias</td>
<td>3.00€</td>
<td>6.00€</td>
<td>12.00€</td>
</tr>
<tr>
<td>Puntillitas</td>
<td>3.00€</td>
<td>6.00€</td>
<td>12.00€</td>
</tr>
<tr>
<td>Adobo</td>
<td>3.00€</td>
<td>6.00€</td>
<td>12.00€</td>
</tr>
<tr>
<td>Brocheta de Gambas</td>
<td>3.00€</td>
<!-- Precio raro preguntar. -->
<td>8.00€</td>
<td>14.00€</td>
</tr>
<tr>
<td>Pescado Variado</td>
<td>--</td>
<td>7.00€</td>
<td>14.00€</td>
</tr>
<tr>
<td>Pez Espada</td>
<td>--</td>
<td>--</td>
<td>8.00€</td>
</tr>
<tr>
<td>Merluza.</td>
<td>--</td>
<td>--</td>
<td>6.00€</td>
</tr>
<tr>
<td>Dorada.</td>
<td>--</td>
<td>--</td>
<td>6.00€</td>
</tr>
</table>
<h2>Postres</h2>
<ol>
<li>Arroz con leche <b>2.50€</b></li>
<li>Natillas <b>2.50€</b></li>
<li>Flan de Huevo <b>2.50€</b></li>
<li>Helados Nestle <b>3.00€</b></li>
</ol>
<p>Por último desde Burguillos.info os indicamos que el precio por el servicio de pan y picos por comensal es de 0.50€ y que tenéis la posibilidad de pedir un extra en salsas por 0.50€.</p>
<p>¿Quieres ver tu negocio localizado en Burguillos en este espacio? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a>.</p>
</content>
</post>

View File

@ -0,0 +1,34 @@
<post>
<author>Burguillos.info</author>
<date>2023-04-30T23:58:37+02:00</date>
<title>Subida de precio de los autobuses.</title>
<ogdesc>Precios premium por un servicio tercermundista, el estado actual de los autobuses de Burguillos.</ogdesc>
<category>index</category>
<img src="/img/autobus-burguillos-tercer-mundo.webp"/>
<slug>subida-precio-autobus-burguillos</slug>
<content>
<img style="border: 1px black solid;" src="/img/autobus-burguillos-tercer-mundo.webp" alt="Image of an overloaded bus in a third world country."/>
<h3>Precios premium por un servicio tercermundista, el estado actual de los autobuses de Burguillos.</h3>
<p>Damas ha incrementado una vez más el precio del autobús de 2.31€ a <b>2.50€</b>,
mientras el descuento del gobierno nos llega mal y tarde.</p>
<p>Este es solo uno más de la lista de <b>atropellos</b> que la empresa Damas lleva
realizados en la línea de nuestra localidad con los infinitos retrasos de las líneas,
la gente que esta línea.- Supuestamente deficitaria.- Ha dejado en tierra por estar el
autobús demasiado lleno y horarios que no permiten el desarrollo sostenible efectivo
de nuestra localidad.</p>
<p>Desde Damas nos avocan a utilizar coche para desplazarnos a los municipios cercanos, un
medio de transporte extremadamente contaminante comparativamente al autobús haciendo de
este modo lobby de la industria automovilística que está destruyendo nuestro planeta.</p>
<p>Los burguilleros y burguilleras debemos plantarnos ante este insulto a la inteligencia
que es querernos vender como un descuento una subida de precio, debemos hacer saber a
Damas que con Burguillos no se juega.</p>
<p>Por Burguillos y nuestro planeta pasemos a la acción, si no nos quieren escuchar obliguemosles
a hacerlo.</p>
</content>
</post>

View File

@ -3,7 +3,7 @@
<date>2023-05-05T22:21+00:00</date>
<title>Carta y Menú del Bar - Restaurante Durán - Centro de día en Burguillos.</title>
<ogdesc>Carta y Menú del Bar - Restaurante Durán - Centro de día en Burguillos.</ogdesc>
<img src="/img/duran.webp" bottom-preview="600"/>
<img src="/img/duran.webp"/>
<category>donde-comer</category>
<attributes>
<attribute>hamburguesas</attribute>

View File

@ -2,12 +2,9 @@
<author>Burguillos.info</author>
<date>2023-05-06T15:33+00:00</date>
<title>Carta y Menú del Café - Bar Beluche en Burguillos.</title>
<last_modification_date>2023-09-13T16:03+00:00</last_modification_date>
<ogdesc>Carta y Menú del Café - Bar Beluche en Burguillos.</ogdesc>
<img src="/img/beluche.webp" bottom-preview="500"/>
<pinned>2</pinned>
<img src="/img/beluche.webp"/>
<category>donde-comer</category>
<category>index</category>
<attributes>
<attribute>hamburguesas</attribute>
<attribute>reparto-a-domicilio-comida</attribute>
@ -21,120 +18,304 @@
<p>El Café - Bar Beluche es uno de los lugares favoritos de los habitantes de Burguillos para comer o simplemente tomar un refresco o un café.</p>
<p>Su ubicación en calle Albahaca número 13 es inmejorable, ofreciendo terrazas a parte de mesas en el interior.</p>
<p>El teléfono de contacto es <a href="tel:+34691492054">691 492 054</a>, puedes usarlo para reservar, pedir comida a domicilio o pedir que te preparen platos para llevar.</p>
<p>Los teléfonos de contacto son <a href="tel:+34694200713">694 200 713</a> y <a href="tel:+34691492054">691 492 054</a>, puedes usarlos para reservar, pedir comida a domicilio o pedir que te preparen platos para llevar.</p>
<p>Procedemos a transcribir la carta a continuación:</p>
<details>
<summary><h3>Ensaladas</h3></summary>
<ul>
<li>Mixta -- Precio: <b>6.00€</b></li>
<li>César -- Precio: <b>6.50€</b></li>
<li>Trópical -- Precio: <b>N/A</b></li>
</ul>
</details>
<details>
<summary><h3>Revueltos</h3></summary>
<ul>
<li>Gula langostinos -- Precio: <b>7.50€</b></li>
<li>Bacalao dorado -- Precio: <b>7.50€</b></li>
<li>Morcilla de arroz -- Precio: <b>7.50€</b></li>
</ul>
</details>
<details>
<summary><h3>Tapas frías.</h3></summary>
<ul>
<li>Ensaladilla rusa -- Tapa: <b>3.00€</b> Plato: <b>6.00€</b></li>
<li>Aliños del día (Aliño Melva/Salpicón de marisco) -- Tapa: <b>3.00€</b> Plato: <b>6.00€</b></li>
<li>Cóctel de mariscos -- Plato: <b>4.00€</b></li>
<li>Ensaladilla de cangrejo -- Tapa: <b>3.50€</b> Plato: <b>7.00€</b></li>
</ul>
</details>
<details>
<summary><h3>Para compartir</h3></summary>
<ul>
<li>Papas bravas -- Precio tapa: <b>3.50€</b> Precio plato: <b>6.00€</b></li>
<li>Papas de mi prima -- Precio tapa: <b>3.50€</b> Precio plato: <b>6.00€</b></li>
<li>Papas arrieras -- Precio tapa: <b>3.80€</b> Precio plato: <b>7.00€</b></li>
<li>Bartolitos. (Langostinos con bacon) -- Precio tapa: <b>3.80€</b> Precio plato: <b>6.00€</b></li>
<li>Queso rulo con bacon, nueces y miel de caña -- Precio tapa: <b>3.80€</b> Precio plato: <b>6.00€</b></li>
<li>Morcilla crocanti -- Precio tapa: <b>3.50€</b> Precio plato: <b>6.00€</b></li>
<li>Muss de pato -- Precio tapa: <b>4.00€</b> Precio plato: <b>8.00€</b></li>
<li>Duo de rulo y muss de pato -- Precio plato: <b>7.00€</b></li>
<li>Talegitas de queso -- Precio tapa: <b>3.50€</b> Precio plato: <b>6.00€</b></li>
<li>Champiñones con alioli y jamón -- Precio tapa: <b>3.50€</b> Precio plato: <b>6.50€</b></li>
<li>Fideos tostados -- Precio plato: <b>4.00€</b></li>
<li>Variado de croquetas -- Precio plato: <b>11.00€</b></li>
<li>Croquetas de secreto y miel -- Precio tapa: <b>4.00€</b> Precio plato: <b>8.00€</b></li>
</ul>
</details>
<details>
<summary><h3>Rico rico</h3></summary>
<ul>
<li>Pollo kentucky -- Precio tapa: <b>3.50€</b> Precio plato: <b>7.00€</b></li>
<li>Pollo mostaza -- Precio tapa: <b>4.50€</b> Precio plato: <b>8.50€</b></li>
<li>Huevos rotos -- Precio plato: <b>5.00€</b></li>
<li>Pan bao -- Precio tapa: <b>5.00€</b> Precio plato: <b>10.00€</b></li>
<li>Carrillada ibérica -- Precio tapa: <b>3.50€ (Preguntar, en menú real 8.50€)</b> Precio plato: <b>7.00€</b></li>
</ul>
</details>
<details>
<summary><h3>Arroces</h3></summary>
<ul>
<li>Timbal de arroz con chipirones y alioli -- Tapa: <b>4.00€</b> Plato: <b>7.50€</b></li>
<li>Arroz negro -- Tapa: <b>4.50€</b> Plato: <b>8.50€</b></li>
<li>Rissotto cuatro quesos -- Tapa: <b>4.50€</b> Plato: <b>8.50€</b></li>
</ul>
</details>
<details>
<summary><h3>Pescados</h3></summary>
<ul>
<li>Gambas al ajillo -- Precio tapa: <b>4.50€</b> Precio plato: <b>8.00€</b></li>
<li>Gambas a la plancha -- Precio tapa: <b>5.00€</b> Precio plato: <b>10.00€</b></li>
<li>Flamenquín de melva -- Precio tapa: <b>3.50€</b> Precio plato: <b>7.00€</b></li>
<li>Chipirones -- Precio tapa: <b>4.00€</b> Precio plato: <b>7.50€</b></li>
<li>Choco -- Precio plato: <b>S/P</b></li>
<li>Lubina -- Precio plato: <b>S/P</b></li>
<li>Pez espada -- Precio plato: <b>12.00€</b></li>
<li>Merluza confitada -- Precio plato: <b>8.00€</b></li>
<li>Bacalao confitado -- Precio plato: <b>9.00€</b></li>
<li>Montadito de gambas con alioli -- Precio plato: <b>3.20€</b></li>
<li>Almejas con langostinos -- Precio tapa: <b>4.50€</b> Precio plato: <b>8.00€</b></li>
</ul>
</details>
<details>
<summary><h3>Carnes</h3></summary>
<ul>
<li>Solomillo de pavo -- Precio plato: <b>9.00€</b></li>
<li>Medallones de solomillo (Roque, whisky, mojo) -- Precio tapa: <b>3.50€</b> Precio plato: <b>6.50€</b></li>
<li>Solomillo rulo de queso y miel de caña -- Precio tapa: <b>4.00€</b> Precio plato: <b>7.50€</b></li>
<li>Solomillo ibérico -- Precio plato: <b>12.50€</b></li>
<li>Abanico ibérico -- Precio plato: <b>12.50€</b></li>
<li>Presa ibérica -- Precio plato: <b>14.00€</b></li>
<li>Presa con mostaza -- Precio tapa: <b>4.00€</b> Precio plato: <b>8.00€</b></li>
<li>Presa con setas y roquefort -- Precio tapa: <b>4.50€</b> Precio plato: <b>9.00€</b></li>
<li>Chuletón de ternera -- Precio plato: <b>S/P</b></li>
<li>Entrecot de ternera -- Precio plato: <b>S/P</b></li>
<li>Chuletón de vaca vieja madurada -- Precio plato: <b>S/P</b></li>
<li>Entrecot de vaca vieja -- Precio plato: <b>S/P</b></li>
<li>Hamburguesa de buey -- Precio plato: <b>5.50€</b></li>
<li>Mini hamburguesa -- Precio plato: <b>3.00€</b></li>
<li>Montadito de pollo o lomo -- Precio plato: <b>3.00€</b></li>
<li>Montadito de solomillo y queso viejo -- Precio plato: <b>3.80€</b></li>
<li>Serranito -- Precio plato: <b>5.50€</b></li>
<li>Mini serranito de pollo o lomo -- Precio plato: <b>4.00€</b></li>
</ul>
</details>
<details>
<summary><h3>Postres</h3></summary>
<ul>
<li>Gofres con nata y chocolate -- Precio: <b>3.80€</b></li>
<li>Tortitas americanas -- Precio: <b>4.00€</b></li>
<li>Tarta (Porción) -- Precio: <b>3.80€</b></li>
<li>Coulant con helado de vainilla -- Precio: <b>4.00€</b></li>
</ul>
</details>
<h3>Ensaladas</h3>
<table>
<tr>
<th>Nombre</th>
<th>Precio</th>
</tr>
<tr>
<td>Mixta</td>
<td>6.00€</td>
</tr>
<tr>
<td>César</td>
<td>6.50€</td>
</tr>
</table>
<h3>Revueltos</h3>
<table>
<tr>
<th>Nombre</th>
<th>Precio</th>
</tr>
<tr>
<td>Gula langostinos</td>
<td>7.50€</td>
</tr>
<tr>
<td>Bacalao dorado</td>
<td>7.50€</td>
</tr>
</table>
<h3>Para compartir</h3>
<table>
<tr>
<th>Nombre</th>
<th>Precio tapa</th>
<th>Precio plato</th>
</tr>
<tr>
<td>Papas bravas</td>
<td>3.00€</td>
<td>5.50€</td>
</tr>
<tr>
<td>Papas de mi prima</td>
<td>3.50€</td>
<td>6.00€</td>
</tr>
<tr>
<td>Papas arrieras</td>
<td>3.80€</td>
<td>6.50€</td>
</tr>
<tr>
<td>Bartolitos. (Langostinos con bacon)</td>
<td>3.80€</td>
<td>6.00€</td>
</tr>
<tr>
<td>Queso rulo con bacon, nueces y miel de caña</td>
<td>3.80€</td>
<td>6.00€</td>
</tr>
<tr>
<td>Morcilla crocanti</td>
<td>3.50€</td>
<td>6.00€</td>
</tr>
<tr>
<td>Muss de pato</td>
<td>4.00€</td>
<td>8.00€</td>
</tr>
<tr>
<td>Duo de rulo y muss de pato</td>
<td>---</td>
<td>7.00€</td>
</tr>
<tr>
<td>Talegitas de queso</td>
<td>3.50€</td>
<td>6.00€</td>
</tr>
<tr>
<td>Champiñones con alioli y jamón</td>
<td>3.50€</td>
<td>6.50€</td>
</tr>
<tr>
<td>Fideos tostados</td>
<td>---</td>
<td>4.00€</td>
</tr>
<tr>
<td>Variado de croquetas</td>
<td>---</td>
<td>11.00€</td>
</tr>
</table>
<h3>Rico rico</h3>
<table>
<tr>
<th>Nombre</th>
<th>Precio tapa</th>
<th>Precio plato</th>
</tr>
<tr>
<td>Pastel de berenjenas</td>
<td>---</td>
<td>3.50€</td>
</tr>
<tr>
<td>Timbal de arroz con chipirones y alioli</td>
<td>4.00€</td>
<td>7.50€</td>
</tr>
<tr>
<td>Gambas al ajillo</td>
<td>---</td>
<td>7.50€</td>
</tr>
<tr>
<td>Flauta de jamón york y queso</td>
<td>3.00€</td>
<td>6.00€</td>
</tr>
<tr>
<td>Saquitos de gambas y salsa de mango</td>
<td>---</td>
<td>4.80€</td>
</tr>
<tr>
<td>Medallones de solomillo. (Roque, whisky, mojo)</td>
<td>3.50€</td>
<td>6.50€</td>
</tr>
<tr>
<td>Solomillo rulo de queso y miel de caña</td>
<td>4.00€</td>
<td>7.50€</td>
</tr>
<tr>
<td>Carrillada ibérica</td>
<td>3.50€</td>
<td>7.00€</td>
</tr>
<tr>
<td>Pollo bechamel</td>
<td>3.60€</td>
<td>6.50€</td>
</tr>
<tr>
<td>Pollo kentucky</td>
<td>---</td>
<td>3.50€</td>
</tr>
</table>
<h3>Pescados</h3>
<table>
<tr>
<th>Nombre</th>
<th>Precio tapa</th>
<th>Precio plato</th>
</tr>
<tr>
<td>Chipirones</td>
<td>3.90€</td>
<td>7.50€</td>
</tr>
<tr>
<td>Pez espada</td>
<td>---</td>
<td>12.00€</td>
</tr>
<tr>
<td>Merluza confitada</td>
<td>---</td>
<td>7.50€</td>
</tr>
<tr>
<td>Bacalao confitado</td>
<td>---</td>
<td>9.00€</td>
</tr>
</table>
<h3>Carnes</h3>
<table>
<tr>
<th>Nombre</th>
<th>Precio tapa</th>
<th>Precio plato</th>
</tr>
<tr>
<td>Solomillo ibérico</td>
<td>---</td>
<td>12.00€</td>
</tr>
<tr>
<td>Presa ibérica</td>
<td>---</td>
<td>14.00€</td>
</tr>
<tr>
<td>Pluma ibérica</td>
<td>---</td>
<td>13.00€</td>
</tr>
<tr>
<td>Presa con mostaza</td>
<td>4.00€</td>
<td>8.00€</td>
</tr>
<tr>
<td>Solomillo de pavo</td>
<td>---</td>
<td>9.00€</td>
</tr>
<tr>
<td>Medallones de solomillo</td>
<td>3.50€</td>
<td>6.50€</td>
</tr>
<tr>
<td>Hamburguesa de buey</td>
<td>---</td>
<td>5.50€</td>
</tr>
<tr>
<td>Abanico ibérico</td>
<td>---</td>
<td>11.00€</td>
</tr>
<tr>
<td>Mini hamburguesa</td>
<td>---</td>
<td>2.50€</td>
</tr>
<tr>
<td>Montadito de pollo o lomo</td>
<td>---</td>
<td>2.50€</td>
</tr>
<tr>
<td>Mini de pollo o lomo</td>
<td>---</td>
<td>3.50€</td>
</tr>
<tr>
<td>Serranito</td>
<td>---</td>
<td>5.50€</td>
</tr>
<tr>
<td>Montadito de gambas con alioli</td>
<td>---</td>
<td>3.20€</td>
</tr>
</table>
<h3>Postres</h3>
<table>
<tr>
<th>Nombre</th>
<th>Precio</th>
</tr>
<tr>
<td>Gofres con nata y chocolate</td>
<td>3.50€</td>
</tr>
<tr>
<td>Tortitas americanas</td>
<td>3.80€</td>
</tr>
<tr>
<td>Tartas (Porción)</td>
<td>3.50€</td>
</tr>
<tr>
<td>Coulant con helado de vainilla</td>
<td>4.00€</td>
</tr>
</table>
<p>¿Quieres ver tu negocio localizado en Burguillos en este espacio? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a>.</p>
</content>

View File

@ -1,8 +1,8 @@
<post>
<author>Burguillos.info</author>
<date>2023-05-06T22:14+00:00</date>
<title>Carta y Menú del Pepín - Pizzería - Hamburguesería - Baguetería</title>
<ogdesc>Carta y Menú del Pepín - Pizzería - Hamburguesería - Baguetería</ogdesc>
<title>Carta y Menú de la Pizzería - Hamburguesería - Baguetería Pepín</title>
<ogdesc>Carta y Menú de la Pizzería - Hamburguesería - Baguetería Pepín</ogdesc>
<img src="/img/pepin.webp"/>
<category>donde-comer</category>
<attributes>

View File

@ -4,7 +4,7 @@
<last_modification_date>2023-09-02T21:48+00:00</last_modification_date>
<title>Carta y Menú de la Hamburguesería la Ermita</title>
<ogdesc>Carta y Menú de la Hamburguesería la Ermita</ogdesc>
<img src="/img/hamburgueseria-la-ermita.webp" bottom-preview="500"/>
<img src="/img/hamburgueseria-la-ermita.webp"/>
<category>donde-comer</category>
<attributes>
<attribute>hamburguesas</attribute>
@ -13,8 +13,20 @@
</attributes>
<slug>hamburgueseria-la-ermita</slug>
<content>
<h2 style="background: black; color: red;">Carta actualizada 2023-09-02.</h2>
<p>Los productos que han cambiado son:</p>
<h2 style="background: black; color: red;">Menú actualizado con nuevos precios y productos 2024-01-18</h2>
<ul>
<li>Se añaden Alitas al menú.</li>
<li>La cerveza de barril baja 0.50€ su precio.</li>
<li>Se añade tercio a las bebidas.</li>
<li>La radler baja 0.30€ su precio.</li>
<li>Se elimina la sin alcohol 3/4 de la carta.</li>
<li>El litro sube 0.80€ su precio.</li>
<li>Churrasco y patatas desaparece del menú. </li>
<li>Los extras en salsa de las hamburguesas suben 0.20€.</li>
<li>Los ingredientes extra de las pizza suben 0.30€.</li>
</ul>
<img width="50%" alt="Front door of 'Hamburguesería la Ermita'" style="border: solid 1px black;" src="/img/hamburgueseria-la-ermita.webp"/>
<h2>Información de contacto para preparación de pedidos.</h2>
@ -25,194 +37,174 @@
<p>Procedemos a listar la carta.</p>
<details>
<summary><h3>Entrantes.</h3></summary>
<h3>Entrantes.</h3>
<ul>
<li>Alitas <b>3€ tapa</b>.</li>
<li>Chili Cheese Bite <b>3€ tapa</b>.</li>
<li>Fingers de mozarella <b>3€ tapa</b>.</li>
<li>Aros de cebolla <b>3€ tapa</b>.</li>
<li>Nuggets <b>3€ tapa</b>.</li>
<li>Crujientes de pollo <b>3€ tapa</b>.</li>
<li>Lagrimitas <b>3€ tapa</b>.</li>
<li>Croquetas de jamón / queso azul y cebolla caramelizada / pizza <b>3€ tapa</b>.</li>
<li>Patatas alioli <b>3€ tapa 5.50€ plato</b>.</li>
<li>Ensaladilla <b>3€ tapa 5.50€ plato</b>.</li>
</ul>
</details>
<ul>
<li>Alitas <b>3€ tapa</b>.</li>
<li>Chili Cheese Bite <b>3€ tapa</b>.</li>
<li>Fingers de mozarella <b>3€ tapa</b>.</li>
<li>Aros de cebolla <b>3€ tapa</b>.</li>
<li>Nuggets <b>3€ tapa</b>.</li>
<li>Crujientes de pollo <b>3€ tapa</b>.</li>
<li>Lagrimitas <b>3€ tapa</b>.</li>
<li>Croquetas de jamón / queso azul y cebolla caramelizada / pizza <b>3€ tapa</b>.</li>
<li>Patatas alioli <b>2.50€ tapa 4€ plato</b>.</li>
<li>Ensaladilla <b>2.50€ tapa 4€ plato</b>.</li>
</ul>
<details>
<summary><h3>Pizzas.</h3></summary>
<h3>Pizzas.</h3>
<p>Todas las pizzas vienen con 2 ingredientes incluidos en el precio, por 0.60€ puedes añadir un ingrediente extra por 0.70€ o una salsa extra por 0.50€.</p>
<p>Todas las pizzas vienen con 2 ingredientes incluidos en el precio, por 0.60€ puedes añadir un ingrediente extra por 0.60€ o una salsa extra por 0.30€.</p>
<p>Tienes la posibilidad de pedir una pizza mediana nutella por 5.50€ desde Burguillos.info suponemos que no se permiten
otros ingredientes para evitar aberraciones gastronómicas.</p>
<p>Tienes la posibilidad de pedir una pizza mediana nutella por 5.50€ desde Burguillos.info suponemos que no se permiten
otros ingredientes para evitar aberraciones gastronómicas.</p>
<h4>Tamaño de pizza.</h4>
<h4>Tamaño de pizza.</h4>
<ul>
<li>Mediana <b>5.90€</b>.</li>
<li>Grande <b>9.50€</b>.</li>
</ul>
<ul>
<li>Mediana <b>5.50€</b>.</li>
<li>Grande <b>9.00€</b>.</li>
</ul>
<h4>Ingredientes disponibles.</h4>
<h4>Ingredientes disponibles.</h4>
<ul>
<li>Jamón York</li>
<li>Bacon</li>
<li>Salchicha</li>
<li>Pepperoni</li>
<li>Roquefort</li>
<li>Jamón</li>
<li>Barbacoa</li>
<li>Atún</li>
<li>Cebolla</li>
<li>Pimientos</li>
<li>Gambas</li>
<li>Huevo</li>
<li>Aceitunas</li>
<li>Pepinillos</li>
<li>Champiñones</li>
<li>Maíz</li>
<li>Piña</li>
<li>Anchoa</li>
<li>Rulo de cabra</li>
<li>Rúcula</li>
<li>Tomate natural</li>
<li>Carbonara</li>
<li>Carne kebab</li>
<li>Pollo asado y salsa kebab</li>
<li>4 quesos</li>
</ul>
</details>
<ul>
<li>Jamón York</li>
<li>Bacon</li>
<li>Salchicha</li>
<li>Pepperoni</li>
<li>Roquefort</li>
<li>Jamón</li>
<li>Barbacoa</li>
<li>Atún</li>
<li>Cebolla</li>
<li>Pimientos</li>
<li>Gambas</li>
<li>Huevo</li>
<li>Aceitunas</li>
<li>Pepinillos</li>
<li>Champiñones</li>
<li>Maíz</li>
<li>Piña</li>
<li>Anchoa</li>
<li>Rulo de cabra</li>
<li>Rúcula</li>
<li>Tomate natural</li>
<li>Carbonara</li>
<li>Carne kebab</li>
<li>Pollo asado y salsa kebab</li>
<li>4 quesos</li>
</ul>
<details>
<summary><h3>Bebidas.</h3></summary>
<h3>Bebidas.</h3>
<ul>
<li>Refresco <b>1.50€</b></li>
<li>Cerveza de barril <b>1.40€</b></li>
<li>Tercio <b>1.50€</b></li>
<li>Tinto <b>1.50€</b></li>
<li>Radler <b>1.50€</b></li>
<li>Cerveza sin alcohol botellín <b>1.30€</b></li>
<li>Litro <b>3.00€</b></li>
<li>Agua pequeña <b>1.00€</b></li>
<li>Agua grande <b>1.50€</b></li>
<li>Zumo <b>1.20€</b></li>
<li>Café e infusión <b>1.20€</b></li>
<li>Combinado <b>5.00€</b></li>
</ul>
</details>
<ul>
<li>Refresco <b>1.50€</b></li>
<li>Cerveza de barril <b>1.30€</b></li>
<li>Tercio <b>1.50€</b></li>
<li>Tinto <b>1.50€</b></li>
<li>Radler <b>1.50€</b></li>
<li>Cerveza sin alcohol botellín <b>1.20€</b></li>
<li>Litro <b>3.00€</b></li>
<li>Agua pequeña <b>0.80€</b></li>
<li>Agua grande <b>1.20€</b></li>
<li>Zumo <b>1.00€</b></li>
<li>Café e infusión <b>1.20€</b></li>
<li>Combinado <b>4.50€</b></li>
</ul>
<details>
<summary><h3>Helados.</h3></summary>
<h3>Helados.</h3>
<ul>
<li>Sandy <b>2.30€</b></li>
<li>Mix Sandy <b>3.30€</b></li>
<li>Mini Mix Sandy <b>2.60€</b></li>
<li>Batido pequeño <b>2.60€</b></li>
<li>Batido grande <b>3.30€</b></li>
</ul>
</details>
<ul>
<li>Sandy <b>2.20€</b></li>
<li>Mini Sandy <b>1.50€</b></li>
<li>Mix Sandy <b>3.20€</b></li>
<li>Mini Mix Sandy <b>2.50€</b></li>
<li>Batido pequeño <b>2.50€</b></li>
<li>Batido grande <b>3.20€</b></li>
</ul>
<details>
<summary><h3>Bocadillos.</h3></summary>
<h3>Bocadillos.</h3>
<ul>
<li>Tortilla <b>3.50€</b></li>
<li>Cochinito <b>3.20€</b></li>
<li>Lomo adobado <b>3.20€</b></li>
<li>Bacon y queso <b>3.20€</b></li>
<li>Atún y pimiento <b>3.20€</b></li>
<li>Carne mechada y chimichurri <b>3.70€</b></li>
<li>Filete de lomo, mayonesa y lechuga <b>3.90€</b></li>
<li>Serranito de pollo o cerdo <b>4.90€</b></li>
</ul>
</details>
<ul>
<li>Tortilla <b>3.00€</b></li>
<li>Cochinito <b>3.00€</b></li>
<li>Lomo adobado <b>3.00€</b></li>
<li>Bacon y queso <b>3.00€</b></li>
<li>Atún y pimiento <b>3.00€</b></li>
<li>Carne mechada y chimichurri <b>3.50€</b></li>
<li>Filete de lomo, mayonesa y lechuga <b>3.50€</b></li>
<li>Serranito de pollo o cerdo <b>4.50€</b></li>
</ul>
<details>
<summary><h3>Montaditos.</h3></summary>
<h3>Montaditos.</h3>
<ul>
<li>Gambas alioli <b>3.00€</b></li>
<li>Melva con pimiento <b>3.00€</b></li>
<li>Carne mechada con chimichurri <b>3.00€</b></li>
<li>Solomillo (Whisky, roquefort o pimienta) <b>3.00€</b></li>
<li>Pollo o lomo <b>3.00€</b></li>
</ul>
</details>
<ul>
<li>Gambas alioli <b>2.50€</b></li>
<li>Melva con pimiento <b>2.50€</b></li>
<li>Carne mechada con chimichurri <b>2.50€</b></li>
<li>Solomillo (Whisky, roquefort o pimienta) <b>2.50€</b></li>
<li>Pollo o lomo <b>2.50€</b></li>
</ul>
<details>
<summary><h3>Perritos.</h3></summary>
<h3>Perritos.</h3>
<ul>
<li>Simple (Salchicha + salsa) <b>2.20€</b></li>
<li>Completo (Salchicha, cebolla frita, zanahoria, patatas paja y salsa) <b>2.70€</b></li>
</ul>
</details>
<ul>
<li>Simple (Salchicha + salsa) <b>2.00€</b></li>
<li>Completo (Salchicha, cebolla frita, zanahoria, patatas paja y salsa) <b>2.50€</b></li>
</ul>
<details>
<summary><h3>Carnes.</h3></summary>
<ul>
<li>Pechuga y patatas <b>5.90€ plato</b>.</li>
<li>Solomillo (Whisky, roquefort o pimienta) <b>3.00€ tapa 5.90€ plato</b>.</li>
</ul>
</details>
<h3>Carnes.</h3>
<ul>
<li>Pechuga y patatas <b>5.00€ plato</b>.</li>
<li>Solomillo (Whisky, roquefort o pimienta) <b>3.00€ tapa 5.00€ plato</b>.</li>
</ul>
<details>
<summary><h3>Patatas gratinadas.</h3></summary>
<h3>Patatas gratinadas.</h3>
<p>En formato pequeño cuestan 4.00€ y en formato grande 6.00€, a elegir entre las siguientes combinaciones.</p>
<p>En formato pequeño cuestan 4.00€ y en formato grande 6.00€, a elegir entre las siguientes combinaciones.</p>
<ul>
<li>Alioli + queso + bacon.</li>
<li>Salsa cheedar + bacon + cebolla frita.</li>
<li>Salsa kebab + carne kebab.</li>
</ul>
</details>
<ul>
<li>Alioli + queso + bacon.</li>
<li>Salsa cheedar + bacon + cebolla frita.</li>
<li>Salsa kebab + carne kebab.</li>
</ul>
<details>
<summary><h3>Patatas normales.</h3></summary>
<h3>Patatas normales.</h3>
<ul>
<li>Pequeñas <b>1.00€</b></li>
<li>Grandes <b>1.50€</b></li>
<li>Gajo <b>grande 1.50€</b></li>
</ul>
</details>
<ul>
<li>Pequeñas <b>1.00€</b></li>
<li>Grandes <b>1.50€</b></li>
<li>Gajo <b>grande 1.50€</b></li>
<li>Cris Criss - Cross <b>grande 2.00€</b></li>
</ul>
<details>
<summary><h3>Hamburguesas.</h3></summary>
<h3>Hamburguesas.</h3>
<p>Puedes solicitar un extra en salsa por 0.50€.</p>
<p>Puedes solicitar un extra en salsa por 0.50€.</p>
<ul>
<li>Solo carne <b>1.80€</b>.</li>
<li>Solo queso <b>2.30€</b>.</li>
<li>BBQ (Carne, salsa barbacoa, queso y pepinillo) <b>2.90€</b>.</li>
<li>Texas (Carne, salsa barbacoa, queso y aros de cebolla) <b>2.90€</b>.</li>
<li>Cheedar simple (Carne, salsa cheedar, tomate, cebolla frita) <b>2.90€</b>.</li>
<li>Salad (Carne, mayonesa, lechuga y tomate) <b>2.90€</b>.</li>
<li>Porky (Carne cerdo, bacon, salsa bacon, queso, tomate, cebolla frita) + patatas <b>6.90€</b>.</li>
<li>Roquefort (Carne mixta, salsa roquefort, lechuga, tomate, queso granapadano, bacon y cebolla frita) + patatas <b>6.90€</b>.</li>
<li>Campera (Pollo campero, mayonesa, lechuga, tomate, queso y bacon) + patatas <b>6.90€</b>.</li>
<li>Miel y mostaza (Carne mixta, rúcula, tomate, cebolla caramelizada, queso gouda, bacon, salsa miel y mostaza) + patatas <b>6.90€</b>.</li>
<li>Boletus (Carne mixta, queso gouda, bacon, champiñones y salsa boletus) + patatas <b>6.90€</b>.</li>
<li>La Ermita (Carne retinto, salsa barbacoa especial, tomate, cebolla frita, rulo de cabra y bacon) + patatas <b>7.90€</b>.</li>
<li>Cabrales (Carne mixta, salsa cabrales, gouda, bacon, lechuga, tomate y queso) + patatas <b>6.90€</b>.</li>
<li>Cheedar (Carne mixta o pollo empanado, salsa cheedar, cebolla frita, tomate, queso y bacon) + patatas <b>6.90€</b>.</li>
<li>Completa (Carne mixta, mayonesa, lechuga, cebolla frita, tomate, pepinillo y cebolla) + patatas <b>6.90€</b>.</li>
<li>Huevo (Carne mixta, mayonesa, lechuga, cebolla frita, tomate, queso, huevo y bacon) + patatas <b>6.90€</b>.</li>
<li>Steak (Carne mixta, mayonesa, lechuga, tomate, queso, bacon y salsa bbq) + patatas <b>6.90€</b>.</li>
<li>Cheese bacon (Carne mixta, queso, bacon, pepinillo, ketchup, mostaza y cebolla) + patatas <b>6.90€</b>.</li>
<li>Romana (Carne mixta, salsa bbq, lechuga, tomate, queso y aros de cebolla) + patatas <b>6.90€</b>.</li>
</ul>
</details>
<ul>
<li>Solo carne <b>1.50€</b>.</li>
<li>Solo queso <b>2.00€</b>.</li>
<li>BBQ (Carne, salsa barbacoa, queso y pepinillo) <b>2.50€</b>.</li>
<li>Texas (Carne, salsa barbacoa, queso y aros de cebolla) <b>2.50€</b>.</li>
<li>Cheedar simple (Carne, salsa cheedar, tomate, cebolla frita) <b>2.50€</b>.</li>
<li>Salad (Carne, mayonesa, lechuga y tomate) <b>2.50€</b>.</li>
<li>Porky (Carne cerdo, bacon, salsa bacon, queso, tomate, cebolla frita) + patatas <b>6.50€</b>.</li>
<li>Roquefort (Carne mixta, salsa roquefort, lechuga, tomate, queso granapadano, bacon y cebolla frita) + patatas <b>6.50€</b>.</li>
<li>Campera (Pollo campero, mayonesa, lechuga, tomate, queso y bacon) + patatas <b>6.50€</b>.</li>
<li>Miel y mostaza (Carne mixta, rúcula, tomate, cebolla caramelizada, queso gouda, bacon, salsa miel y mostaza) + patatas <b>6.50€</b>.</li>
<li>Boletus (Carne mixta, queso gouda, bacon, champiñones y salsa boletus) + patatas <b>6.50€</b>.</li>
<li>La Ermita (Carne retinto, salsa barbacoa especial, tomate, cebolla frita, rulo de cabra y bacon) + patatas <b>7.50€</b>.</li>
<li>Cabrales (Carne mixta, salsa cabrales, gouda, bacon, lechuga, tomate y queso) + patatas <b>6.50€</b>.</li>
<li>Cheedar (Carne mixta o pollo empanado, salsa cheedar, cebolla frita, tomate, queso y bacon) + patatas <b>6.50€</b>.</li>
<li>Completa (Carne mixta, mayonesa, lechuga, cebolla frita, tomate, pepinillo y cebolla) + patatas <b>6.50€</b>.</li>
<li>Huevo (Carne mixta, mayonesa, lechuga, cebolla frita, tomate, queso, huevo y bacon) + patatas <b>6.50€</b>.</li>
<li>Steak (Carne mixta, mayonesa, lechuga, tomate, queso, bacon y salsa bbq) + patatas <b>6.50€</b>.</li>
<li>Cheese bacon (Carne mixta, queso, bacon, pepinillo, ketchup, mostaza y cebolla) + patatas <b>6.50€</b>.</li>
<li>Romana (Carne mixta, salsa bbq, lechuga, tomate, queso y aros de cebolla) + patatas <b>6.50€</b>.</li>
</ul>
<p>¿Quieres ver tu negocio localizado en Burguillos en este espacio? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a>.</p>
</content>

View File

@ -1,48 +1,42 @@
<post>
<author>Burguillos.info</author>
<date>2023-08-21T13:23+00:00</date>
<last_modification_date>2023-10-01T14:25+00:00</last_modification_date>
<title>Descubre "YoTeLoGuiso" en Burguillos y sus datos de
contacto.</title>
<ogdesc>Descubre "YoTeLoGuiso" en Burguillos y sus datos de
contacto.</ogdesc>
<img src="/img/yo-to-lo-guiso.webp" />
<title>Descubre "YoTeLoGuiso" en Burguillos y sus datos de contacto.</title>
<ogdesc>Descubre "YoTeLoGuiso" en Burguillos y sus datos de contacto.</ogdesc>
<img src="/img/yo-to-lo-guiso.webp"/>
<category>donde-comer</category>
<category>index</category>
<attributes>
<attribute>hamburguesas</attribute>
<attribute>comida-vegana</attribute>
<attribute>reparto-a-domicilio-comida</attribute>
</attributes>
<slug>yo-te-lo-guiso</slug>
<pinned>1</pinned>
<content>
<img witdh="50%" alt="Cartel 'Yo te lo guiso'"
style="border: solid 1px black"
src="/img/yo-to-lo-guiso.webp" />
<p>Con localización en Calle los Palmeros número 32, "Yo te lo
guiso" ofrece una propuesta de catering de comida al peso única
en Burguillos con sus especialidades siempre disponibles y
algunas novedades todos los días.</p>
<p>Podeis hacer encargos para recoger en tienda o envio a domicilio a
Burguillos en este número de teléfono
<img witdh="50%" alt="Cartel 'Yo te lo guiso'" style="border: solid 1px black" src="/img/yo-to-lo-guiso.webp"/>
<p>Con localización en Calle los Palmeros número 32,
"Yo te lo guiso" ofrece una propuesta de catering de
comida al peso única en Burguillos con sus especialidades
siempre disponibles y algunas novedades todos los días.</p>
<p>Podeis hacer encargos para recoger en tienda en este número de teléfono
<a href="tel:+34604424439">604 424 439</a>.</p>
<p>El envio a domicilio tan solo cuesta 1.50€ extra comparado
a comprar en el local.</p>
<p>Recuerda mirar las novedades en Instagram
<a href="https://www.instagram.com/yoteloguiso/">@yoteloguiso</a>.</p>
<p>Los horarios del negocio son de 12:00 a 15:00 y de 20:30 a 23:00 de Miercoles a Sabado.
El Domingo abre de 12:00 a 15:00.</p>
<p>El negocio además de su oferta habitual de carne y pescado ofrece
comida <b>vegana</b> y <b>vegetariana</b> siendo de los pocos negocios
en Burguillos que ofrecen este tipo de servicio. Si quieres
disfrutar de este tipo de comida llamanos con antelación para
que te podamos explicar toda nuestra carta vegana y vegetariana.</p>
<p>Los Jueves son los días del pescado, la oferta de pescado es mucho mayor esos días.
El domingo es el día del arroz.</p>
<p>Recuerda mirar las novedades en Instagram
<a href="https://www.instagram.com/yoteloguiso/">
@yoteloguiso</a>.</p>
<p>El negocio además de su oferta habitual de carne y pescado
ofrece comida <b>vegana</b> y <b>vegetariana</b> siendo de los
pocos negocios en Burguillos
que ofrecen este tipo de servicio. Si quieres disfrutar de este
tipo de comida llamanos con antelación para que te podamos
explicar toda nuestra carta vegana y vegetariana.</p>
<p>Los Jueves son los días del pescado, la oferta de pescado es
mucho mayor esos días. El domingo es el día del arroz.</p>
<p>Especialidades siempre en tienda:</p>
<ul>
<li>Pollo asado.</li>
<li>Pollo relleno.</li>
@ -50,14 +44,14 @@
<li>Empanadas y empanadillas.</li>
<li>Croquetas.</li>
<li>Ensaladas.</li>
<li>Hamburguesas veganas. (Encargar con antelación)</li>
<li>Empanidillas veganas. (Encargar con antelación)</li>
</ul>
<p>Hay una tabla de precios que puedes aplicar para la mayoría
de platos:</p>
<p>Hay una tabla de precios que puedes
aplicar para la mayoría de platos:</p>
<ul>
<li>Verduras:
<b>1.30€/100g</b>.</li>
<li>Verduras: <b>1.30€/100g</b>.</li>
<li>Tortilla: <b>1.80€/100g</b>.</li>
<li>Carnes: <b>1.30€/100g</b>.</li>
<li>Ensaladilla: <b>1.50€</b>.</li>
<li>Empanadilla: <b>2€/unidad</b>.</li>
@ -65,6 +59,7 @@
<li>Paella: <b>1.80€/100g</b>.</li>
<li>Arroz caldoso: <b>1.80€/100g</b>.</li>
</ul>
<p>¿Quieres ver tu negocio localizado en Burguillos en este espacio? Contacta con <a href="mailto:contact@owlcode.tech"> contact@owlcode.tech</a>.</p>
</content>
<p>¿Quieres ver tu negocio localizado en Burguillos en este espacio? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a>.</p>
</content>
</post>

View File

@ -3,7 +3,7 @@
<date>2023-08-24T21:37+00:00</date>
<title>Cervecería el Cañon - Cafetería la Tazza - Carta y Menú</title>
<ogdesc>Cervecería el Cañon - Cafetería la Tazza - Carta y Menú</ogdesc>
<img src="/img/tazza.webp" bottom-preview="470"/>
<img src="/img/tazza.webp"/>
<category>donde-comer</category>
<attributes>
<attribute>hamburguesas</attribute>
@ -12,7 +12,13 @@
<content>
<img witdh="50%" alt="Puerta de la Tazza" style="border: solid 1px black" src="/img/tazza.webp"/>
<p>La Cervecería el Cañon, ubicado en Calle el Castaño número 29, también conocido como Cafetería la Tazza además de su oferta habitual de desayunos como ya sabréis añadió un catalogo de comidas y tapas. ¡Y están riquísimas!</p> <p>Actualmente tiene un horario de verano donde algunas tardes permanece cerrado, informaremos cuando tengamos todos los datos.</p>
<p>La Cervecería el Cañon, ubicado en Calle el Castaño número 29,
también conocido como Cafetería la Tazza
además de su oferta habitual de desayunos como ya sabréis
añadió un catalogo de comidas y tapas. ¡Y están riquísimas!</p>
<p>Actualmente tiene un horario de verano donde algunas tardes
permanece cerrado, informaremos cuando tengamos todos los datos.</p>
<p>Os adjunto la carta para que la tengáis siempre disponible:</p>
@ -173,7 +179,7 @@
<td>4.50€</td>
</tr>
</table>
<h3>Carnes</h3>
<table>

View File

@ -1,22 +0,0 @@
<post>
<author>Burguillos.info</author>
<date>2023-09-07T16:11:00+00:00</date>
<title>Farmacia de Guardia en Burguillos.</title>
<ogdesc>Farmacia de Guardia en Burguillos.</ogdesc>
<img src="/img/farmacia.webp"/>
<category>index</category>
<slug>farmacia-guardia</slug>
<pinned>100</pinned>
<content>
<img alt="Imagen de cruz de Farmacia" src="/img/farmacia.webp"/>
<p>La farmacia de guardia esta semana es:</p>
<ul>
<li>Nombre: <b id="farmacia-name"></b></li>
<li>Dirección: <b id="farmacia-address"></b></li>
</ul>
<p><small>Este artículo se rellena automáticamente con los datos de la Farmacia de Guardia, tu navegador o móvil debe soportar Javascript para que funcione.</small></p>
</content>
</post>

View File

@ -1,73 +0,0 @@
<post>
<author>Burguillos.info</author>
<date>2023-09-07T19:49:00+00:00</date>
<title>Teléfonos de interés de Burguillos.</title>
<ogdesc>Teléfonos de interés de Burguillos.</ogdesc>
<img src="/img/ayuntamiento.webp"/>
<category>index</category>
<slug>telefono-interes-burguillos</slug>
<pinned>100</pinned>
<content>
<img alt="Imagen del ayuntamiento" src="/img/ayuntamiento.webp"/>
<p>Os compartimos un listado de números de teléfono que os pueden hacer falta durante tu estancia en Burguillos:</p>
<p>Teléfono del Ayuntamiento de Burguillos: <b><a href="tel:+34955738125">955 738 125</a></b> dirección: <b>Plaza de la Constitución Española 1</b></p>
<p>Teléfono del Juzgado de paz y registro civil de Burguillos: <b><a href="tel:+34955738820">955 738 820</a></b> dirección: <b>Calle Francisco Hernández sin número</b></p>
<p>Teléfono de los Servicios Sociales de Burguillos: <b><a href="tel:+34955738125">955 738 125</a></b> dirección: <b>Calle Real sin número</b></p>
<p>Teléfono de Consultorio - Centro de salud Nuestra Señora de los Dolores de Burguillos: <b><a href="tel:+34955738612">955 738 612</a></b> dirección: <b>Calle Juan Carlos I sin número</b></p>
<p>Teléfono de Farmacia Cruz de la Ermita de Burguillos: <b><a href="tel:+34955738822">955 738 822</a></b> dirección: <b>Avenida Cruz de la Ermita/José Cuesta Godoy número 98</b></p>
<p>Teléfono de Farmacia Óptica Morera de Burguillos: <b><a href="tel:+34955738413">955 738 413</a></b> dirección: <b>Calle Virgen del Rosario número 13</b></p>
<p>Teléfono de Policía Local de Burguillos: <b><a href="tel:+34955738237">955 738 237</a></b> dirección: <b>Calle Gustavo Adolfo Bécquer sin número</b></p>
<p>Teléfono de Guardia civil puesto Alcalá del Río: <b><a href="tel:+34955651111">955 651 111</a></b> dirección: <b>Calle de San Ignacio número 2</b></p>
<p>Teléfono de Bomberos: <b><a href="tel:+34085">085</a></b>.</p>
<p>Teléfono de Autocares "El Teniente": <b><a href="tel:+34955131904">955 131 904</a></b> dirección: <b>Avenida de los Trabajadores número 31</b></p>
<p>Teléfono Autobuses Damas <b><a href="tel:+34902114492">902 114 492</a></b>.</p>
<p>Teléfono de Taxi Mariano Ballesteros Hidalgo en Burguillos <b><a href="tel:+34605924032">605 924 032</a></b> dirección: <b>Calle Sol número 10 bajo</b>.</p>
<p>Teléfono de Oficina de empleo San José de la Rinconada <b><a href="tel:+34955656671">955 656 671</a></b> dirección: <b>Calle Virgen del Pilar</b>.</p>
<p>Teléfono de Correos en Burguillos <b><a href="tel:+34955738338">955 738 338</a></b> dirección: <b>Calle Real número 19</b>.</p>
<p>Dirección de Centro Cultural Carmen Laffon <b>Calle Real número 2</b>.</p>
<p>Dirección de Centro de día para la tercera edad <b>Calle Real número 1</b>.</p>
<p>Teléfono de Guardería municipal <b><a href="tel:+34685850286">685 850 286</a></b> dirección: <b>Calle Concepción de Osuna 4c</b>.</p>
<p>Teléfono de CEIP Ágora <b><a href="tel:+34854560610">854 560 610</a></b> dirección: <b>Calle Alfonso X el Sabio sin número</b>.</p>
<p>Teléfono de CEIP Manuel Medina <b><a href="tel:+34955739905">955 739 905</a> o <a href="tel:+34955739907">34955739907</a></b> dirección: <b>Calle Concepción de Osuna, sin número.</b></p>
<p>Teléfono del IES Burguillos <b><a href="tel:+34955739585">955 739 585</a></b> dirección: Calle Albahaca sin número.</p>
<p>Teléfono Centro de educación para personas adultas SEPER "La Madroña" en Burguillos <b><a href="tel:+34955739623">955 739 623</a></b> dirección: <b>Calle Real número 2, edificio Carmen Laffon, planta baja</b>.</p>
<p>Teléfono del Centro TAS Burguillos <b><a href="tel:+34722132604">722 132 604</a></b> atendido martes en horario de mañana por Rosa dirección <b>Calle Romero, número 1, módulo D</b> email: <a href="mailto:tasburguillos@fundaciontas.org">tasburguillos@fundaciontas.org</a>.</p>
<p>Teléfono del Aula Periferia <b><a href="tel:+34695240441">695 240 441</a></b> dirección: <b>Calle Gustavo Adolfo Bécquer sin número.</b>.</p>
<p>Teléfono de la Caixa <b><a href="tel:+34954868121">954 868 121</a></b> dirección: <b>Calle Real, número 11</b>.</p>
<p>Teléfono del Santander (Popular) <b><a href="tel:+34955738300">955 738 300</a></b> dirección: <b>Calle Real número 37</b>.</p>
<p>Teléfono de la Caja Rural <b><a href="tel:+34955738437">955 738 437</a></b> dirección: <b>Avenida Andalucía número 29</b>.</p>
<p>Dirección de Cáritas parroquial <b>Calle Concepción de Osuna número 4</b>.</p>
<p>Teléfono de Mancomunidad de Servicios de la Vega <b><a href="tel:+34955111140">955111140</a></b> dirección: <b>Plaza España número 1</b>.</p>
<p>Teléfono de Tanatorio y servicios funerarios <b><a href="tel:+34954103023">954 103 023</a> y <a href="tel:+34635357646">635 357 646</a></b>. dirección: <b>Calle Juan de la Cieva, 14, Polígono Industrial El Estanquillo</b>.</p>
</content>
</post>

View File

@ -1,22 +0,0 @@
<post>
<author>Burguillos.info</author>
<date>2023-09-08T00:26:00+00:00</date>
<title>Código fuente de Burguillos.info.</title>
<ogdesc>Código fuente de Burguillos.info.</ogdesc>
<img src="/img/git.webp"/>
<category>index</category>
<slug>codigo-fuente</slug>
<content>
<img alt="" src="/img/git.webp"/>
<p>Todo el código que soporta Burguillos.info es software libre bajo los terminos de la licencia AGPLv3, en los siguientes enlaces compartimos toda la infraestructura de código que usamos hasta ahora, si tienes alguna duda contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a>.</p>
<ul>
<li>Código de la web <a href="https://git.owlcode.tech/sergiotarxz/burguillos.info">https://git.owlcode.tech/sergiotarxz/burguillos.info</a>. Perl/JavaScript/SASS/Webpack/XML/Mojolicious</li>
<li>Código del buscador <a href="https://git.owlcode.tech/sergiotarxz/burguillos.info.search">https://git.owlcode.tech/sergiotarxz/burguillos.info.search</a>. Java/Spring/Lucene</li>
<li>Código de la aplicación de Android <a href="https://git.owlcode.tech/sergiotarxz/BInfoAndroid">https://git.owlcode.tech/sergiotarxz/BInfoAndroid</a>. Gradle/Java</li>
</ul>
<p>Si quieres tener una web como Burguillos.info pero no sabes por donde empezar a implementarla te recomendamos contactar con Owlcode.tech y contratar sus servicios.</p>
</content>
</post>

View File

@ -1,33 +0,0 @@
<post>
<author>Burguillos.info</author>
<date>2023-09-09T21:53+00:00</date>
<title>Taebe Kim Zumba en Burguillos</title>
<ogdesc>Taebe Kim Zumba en Burguillos</ogdesc>
<img src="/img/zumba.webp" bottom-preview="600"/>
<category>actividades-deportivas</category>
<attributes>
<attribute>danza</attribute>
</attributes>
<slug>zumba-taebe-kim</slug>
<content>
<img width="50%" alt="Cartel zumba Taebe Kim (Contenido transcrito en artículo)" style="border: solid 1px black;" src="/img/zumba.webp"/>
<p>Ya ha vuelto tras el descanso de verano la Zumba para Adultos Taebe Kim, localizada en Calle Antonio Machado número 3.</p>
<p>Esta actividad deportiva de danza se realiza todos los lunes, miercoles y jueves a las 20:00.</p>
<p>El número de teléfono de contacto es <a href="tel:+34615085276">615 085 276</a>.</p>
<p>Puedes visitar su Instagram en <a href="https://www.instagram.com/sandra.martin37zumba">@sandra.martin37zumba</a>.</p>
<p>Además los martes y los jueves se realiza zumba para los más pequeños de 18:30 a 19:30.</p>
<p>La Zumba es un tipo de danza que ejercita tu cuerpo mientras te lo pasas bien, además de ayudarte a convertirte en el rey/reina de la fiesta o de las redes sociales con bailes entretenidos también te puede ayudar a mantenerte saludable y alcanzar tu peso ideal.</p>
<p>Además es una oportunidad perfecta de hacer nuevas amistades o fortalezer vínculos ya existentes.</p>
<p>No dejes pasar la oportunidad, apuntaté ya.</p>
<p>¿Quieres ver tu negocio localizado en Burguillos en este espacio? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a>.</p>
</content>
</post>

View File

@ -1,31 +0,0 @@
<post>
<author>Burguillos.info</author>
<date>2023-09-09T21:53+00:00</date>
<title>Taebe Kim Taekwondo en Burguillos</title>
<ogdesc>Taebe Kim Taekwondo en Burguillos</ogdesc>
<img src="/img/taekwondo.webp"/>
<category>actividades-deportivas</category>
<attributes>
<attribute>artes-marciales</attribute>
</attributes>
<slug>taekwondo-taebe-kim</slug>
<content>
<img width="50%" alt="Cartel taekwondo Taebe Kim (Contenido transcrito en artículo)" style="border: solid 1px black;" src="/img/taekwondo.webp"/>
<p>El Taekwondo Taebe Kim con teléfono <a href="tel:+34645825467">645 825 467</a> y localizado en Calle Antonio Machado número 3 ofrece una increíble oportunidad para aprender Taekwondo formado por el profesor Benito, Técnico Deportivo y Maestro Nacional de Taekwondo, Cinturon Negro 4° DAN.</p>
<p>Entre los beneficios del Taekwondo se encuentran los siguientes:</p>
<ul>
<li>Flexibilidad</li>
<li>Disciplina</li>
<li>Coordinación</li>
<li>Concentración</li>
<li>Defensa personal</li>
</ul>
<p>Recuerda exigir <b>deporte federado</b> que por supuesto Taebe Kim provee.</p>
<p>¿Quieres ver tu negocio localizado en Burguillos en este espacio? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a>.</p>
</content>
</post>

View File

@ -1,33 +0,0 @@
<post>
<author>Burguillos.info</author>
<date>2023-09-11T10:08+00:00</date>
<title>Taebe Kim - Clases de Yoga en Burguillos</title>
<ogdesc>Taebe Kim - Clases de Yoga en Burguillos</ogdesc>
<img src="/img/yoga.webp" bottom-preview="400"/>
<category>actividades-deportivas</category>
<slug>yoga-taebe-kim</slug>
<content>
<img width="50%" alt="Cartel yoga Taebe Kim (Contenido transcrito en artículo)" style="border: solid 1px black;" src="/img/yoga.webp"/>
<p>Damos la bienvenida a este directorio a las clases de Yoga de Taebe Kim, localizadas en
Calle Antonio Machado número 3, y con horario de mañana a las 10:00.</p>
<p>Contacta a este número de teléfono si tienes interés en participar <a href="tel:+34615085276">615 085 276</a>.</p>
<p>Tu momento es ahora...</p>
<p>Por si tienes indecisión te listamos los siguientes beneficios del Yoga:</p>
<ul>
<li>Correción postural.</li>
<li>Fortalece músculos.</li>
<li>Aumenta flexibilidad y elasticidad.</li>
<li>Mejora la concentración y relajación.</li>
<li>Alivia dolor articular y de espalda.</li>
</ul>
<p>¡Cuida tu cuerpo y mente!</p>
<p>¿Quieres ver tu negocio localizado en Burguillos en este espacio? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a>.</p>
</content>
</post>

View File

@ -1,93 +0,0 @@
<post>
<author>Burguillos.info</author>
<date>2023-09-21T09:11+00:00</date>
<title>Carta y menú de Bar el Polígono.</title>
<ogdesc>Carta y menú de Bar el Polígono.</ogdesc>
<img src="/img/bar-poligono.webp" bottom-preview="600"/>
<category>donde-comer</category>
<attributes>
<attribute>hamburguesas</attribute>
<attribute>reparto-a-domicilio-comida</attribute>
</attributes>
<slug>bar-poligono</slug>
<content>
<h2 style="background: black; color: red;">Cerrado permanentemente.</h2>
<img witdh="50%" alt="Puerta de la Bar el Poligono" style="border: solid 1px black" src="/img/bar-poligono.webp"/>
<p>El bar el polígono es un negocio de nueva apertura localizado en Calle Tomás Alba Edison número 8 donde antes se encontraba el Bar el Chori II.</p>
<p>Los horarios de mañana es lunes a viernes de 05:30 a 18:00 y en fines de semana de 07:00 a 16:00, el horario nocturo y de envios a domicilio es
de jueves a domingo de 20:00 a 00:00</p>
<p>El teléfono de contacto <a href="tel:+34651611938">651 611 938</a>.</p>
<p>La carta actualizada con fecha 21 de Septiembre de 2023 luce bastante prometedora y procedemos a compartirla por vosotros.</p>
<h2>Hamburguesas</h2>
<ul>
<li>Simple (Carne y queso) Precio: <b>1.50€</b></li>
<li>Gustosa (Carne, queso, lechuga, tomate y cebolla) Precio: <b>2.80€</b></li>
<li>Diferente (Doble carne, queso, huevo, cebolla y bacon) Precio: <b>3.80€</b></li>
<li>Buey (Carne, queso, bacon, lechuga, tomate y cebolla) Precio: <b>5.00€</b></li>
<li>Crujiente (Pollo, queso, lechuga, tomate y cebolla) Precio: <b>3.80€</b></li>
<li>Pollo (Pollo, lechuga, cebolla, tomate y queso) Precio: <b>2.50€</b></li>
</ul>
<h2>Chucasos</h2>
<ul>
<li>Cochino Precio: <b>3.00€</b></li>
<li>Lomo adobado Precio: <b>3.00€</b></li>
<li>Bacon/queso Precio: <b>3.00€</b></li>
<li>Vegetal y pollo Precio: <b>4.00€</b></li>
<li>Tortilla york y queso Precio: <b>3.50€</b></li>
<li>Pollo Precio: <b>3.50€</b></li>
<li>Hamburguesa Precio: <b>3.50€</b></li>
<li>Serranito de pollo o lomo Precio: <b>5.00€</b></li>
</ul>
<h2>Ensaladas</h2>
<ul>
<li>Normal Precio: <b>3.50€</b></li>
<li>Ensaladilla Precio: <b>3.00€</b></li>
<li>Papas alioli Precio: <b>3.00€</b></li>
<li>Salpicón de Mariscos Precio: <b>3.50€</b></li>
</ul>
<h2>Tapas</h2>
<ul>
<li>Plato de papas Precio: <b>2.50€</b></li>
<li>Papas bravas Precio <b>3.00€</b></li>
<li>Papas gratinadas Precio <b>4.00€</b></li>
<li>Carne con tomate Precio <b>3.50€</b></li>
<li>Carne asada Precio <b>4.00€</b></li>
<li>Tocinito frito Precio <b>4.00€</b></li>
<li>Solomillo al whisky Precio <b>4.50€</b></li>
<li>Churrasco de cerdo Precio <b>4.50€</b></li>
<li>Churrasco de pollo Precio <b>4.50€</b></li>
</ul>
<h2>Pescados</h2>
<ul>
<li>Chipirón plancha Tapa: <b>3.50€</b> Ración: <b>7.50€</b></li>
<li>Calamares fritos Tapa: <b>3.50€</b> Ración: <b>7.50€</b></li>
<li>Boquerones fritos Tapa: <b>3.00€</b> Ración: <b>6.00€</b></li>
<li>Frito variado Tapa: <b>4.50€</b> Ración: <b>10.00€</b></li>
</ul>
<h2>Montaditos</h2>
<ul>
<li>Pollo Precio: <b>3.00€</b></li>
<li>Lomo Precio: <b>3.00€</b></li>
<li>Gambas alioli Precio: <b>3.00€</b></li>
<li>Caballa pimiento morrón Precio: <b>3.00€</b></li>
</ul>
<p>¿Quieres ver tu negocio localizado en Burguillos en este espacio? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a>.</p>
</content>
</post>

View File

@ -1,43 +0,0 @@
<post>
<author>Burguillos.info</author>
<date>2023-09-19T06:00+00:00</date>
<title>Meraki - Arte de uñas y belleza.</title>
<ogdesc>Meraki - Arte de uñas y belleza.</ogdesc>
<img src="/img/meraki.webp" bottom-preview="525"/>
<category>estetica</category>
<attributes>
<attribute>belleza-manos</attribute>
</attributes>
<slug>arte-belleza-unas-meraki</slug>
<content>
<img witdh="50%" alt="Cartel de uñas meraki, transcrito en el artículo." style="border: solid 1px black" src="/img/meraki.webp"/>
<h2>Hazte las uñas en Meraki - Nails Art and Beauty.</h2>
<p>Meraki - Nails Art and Beauty localizado en Avenida de Pepe Luna Local 2 con teléfono <a href="tel:+34674021960">674 021 960</a>
es el lugar perfecto para que puedas explotar al máximo la belleza de tus uñas.</p>
<p>Visita su Tiktok <a href="https://www.tiktok.com/@sonialopeznails">@sonialopeznails</a> o su Instagram <a href="https://www.instagram.com/sonialopeznails/">@sonialopeznails</a>
para ver ejemplos de las creaciones de este negocio en cuanto a estética de uñas.</p>
<p>Meraki - Nails Art and Beauty ofrece los siguientes tipos de tratamientos:</p>
<ul>
<li>Uñas acrílicas o esculpidas.</li>
<li>Técnicas nuevas Gelx y Acrigel.</li>
<li>Decoraciones varias.</li>
<li>Manicura rusa semipermanente.</li>
<li>Parafina manos y pies.</li>
<li>Semipermanente con refuerzo.</li>
<li>Pedicura Spa y esmaltado.</li>
<li>Masajes relajantes y anti estrés.</li>
<li>Tratamientos faciales y corporales.</li>
<li>Depilación laser.</li>
<li>Depilación cera.</li>
<li>Microblading.</li>
<li>Extensiones de pestañas.</li>
</ul>
<p>¿Quieres ver tu negocio localizado en Burguillos en este espacio? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a>.</p>
</content>
</post>

View File

@ -1,34 +0,0 @@
<post>
<author>Burguillos.info</author>
<date>2023-09-20T09:11+00:00</date>
<title>Lo&amp;La - Tienda de Ropa y Accesorios en Burguillos.</title>
<ogdesc>Lo&amp;La - Tienda de Ropa y Accesorios en Burguillos.</ogdesc>
<img src="/img/lola-ropa.webp" bottom-preview="700"/>
<category>tiendas-ropa</category>
<slug>lo-la-ropa-accesorios</slug>
<content>
<img witdh="50%" alt="Puerta principal de Lo&amp;La." style="border: solid 1px black" src="/img/lola-ropa.webp"/>
<h2>Compra ropa y accesorios para sorprender a todos en Lo&amp;La.</h2>
<p>La tienda Lo&amp;La localizado en Calle Virgen del Rosario número 14 - bajo - local 4 con teléfono de contacto <a href="tel:+34955198322">955 198 322</a>
es un lugar ideal para comprar ropa y accesorios con los que deslumbrar a todos tus conocidos.</p>
<p>Ofrece los siguientes tipos de productos:</p>
<ul>
<li>Lencería.</li>
<li>Ropa de hogar.</li>
<li>Ropa de bebe.</li>
<li>Ropa de caballero.</li>
<li>Ropa de señora.</li>
<li>Complementos de señora.</li>
<li>Complementos de caballero.</li>
<li>Productos para la vuelta al cole.</li>
</ul>
<p>No lo dudes, compra en negocios locales, compra en Lo&amp;La.</p>
<p>¿Quieres ver tu negocio localizado en Burguillos en este espacio? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a>.</p>
</content>
</post>

View File

@ -1,95 +0,0 @@
<post>
<author>Burguillos.info</author>
<date>2023-09-21T10:33+00:00</date>
<title>Carta y menú de Bar Coripe.</title>
<ogdesc>Carta y menú de Bar Coripe.</ogdesc>
<img src="/img/bar-coripe.webp" bottom-preview="630"/>
<category>donde-comer</category>
<attributes>
</attributes>
<slug>bar-coripe</slug>
<content>
<img witdh="50%" alt="Puerta de la Bar Coripe" style="border: solid 1px black" src="/img/bar-coripe.webp"/>
<p>Localizado en Calle Sevilla número 4, dentro de la Ermita, el Bar Coripe es un lugar
perfecto para tomar un refrigerio y comer algo.</p>
<p>Procedemos a listaros la carta:</p>
<table>
<tr>
<th>Plato</th>
<th>Tapa</th>
<th>Ración</th>
</tr>
<tr>
<td>Carne Asá</td>
<td>3.00€</td>
<td>6.00€</td>
</tr>
<tr>
<td>Tocinito</td>
<td>3.00€</td>
<td>6.00€</td>
</tr>
<tr>
<td>Lagrimitas</td>
<td>3.00€</td>
<td>6.00€</td>
</tr>
<tr>
<td>Alitas</td>
<td>3.00€</td>
<td>6.00€</td>
</tr>
<tr>
<td>Croquetas</td>
<td>3.00€</td>
<td>6.00€</td>
</tr>
<tr>
<td>Bartolito</td>
<td>3.00€</td>
<td>---</td>
</tr>
<tr>
<td>Boquerón</td>
<td>3.00€</td>
<td>6.00€</td>
</tr>
<tr>
<td>M.P. Empanado</td>
<td>3.00€</td>
<td>---</td>
</tr>
<tr>
<td>Bravas</td>
<td>2.00€</td>
<td>4.00€</td>
</tr>
<tr>
<!-- Esto que eh? -->
<td>H. Pollo</td>
<td>3.00€</td>
<td>---</td>
</tr>
<tr>
<td>Filete de pollo empanado</td>
<td>3.00€</td>
<td>---</td>
</tr>
<tr>
<td>Calamares</td>
<td>3.00€</td>
<td>6.00€</td>
</tr>
<tr>
<td>S.P. Empanado</td>
<td>4.50€</td>
<td>---</td>
</tr>
</table>
<p>¿Quieres ver tu negocio localizado en Burguillos en este espacio? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a>.</p>
</content>
</post>

View File

@ -1,30 +0,0 @@
<post>
<author>Burguillos.info</author>
<date>2023-09-25T19:56+00:00</date>
<title>Restaurante Casa Luis Burguillos</title>
<ogdesc>Restaurante Casa Luis Burguillos</ogdesc>
<img src="/img/casa-luis.webp"/>
<category>donde-comer</category>
<attributes>
</attributes>
<slug>restaurante-casa-luis</slug>
<content>
<img witdh="50%" alt="Puerta del restaurante Casa Luis" style="border: solid 1px black" src="/img/casa-luis.webp"/>
<p>¿Buscas un buen lugar para comer en Burguillos? No busques más, Restaurante Casa Luis en Burguillos ofrece unas comidas completamente excepcionales.</p>
<p>La carta cambia con demasiada frecuencia para mantenerla en esta página; no obstante os
dejamos la lista de sugerencias para que se os haga la boca agua.</p>
<ul>
<li>Gambón plancha.</li>
<li>Albondigas de carrilla.</li>
<li>Perdiz en salsa.</li>
<li>Montadito de berenjena.</li>
<li>Queso rulo.</li>
<li>Redondo de solomillo.</li>
</ul>
<p>¿Quieres ver tu negocio localizado en Burguillos en este espacio? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a>.</p>
</content>
</post>

View File

@ -1,22 +0,0 @@
<post>
<author>Burguillos.info</author>
<date>2023-09-28T08:37+00:00</date>
<title>Nunca fui Gloria - Productos artesanales en Burguillos</title>
<ogdesc>Nunca fui Gloria - Productos artesanales en Burguillos</ogdesc>
<img src="/img/nunca-fui-gloria.webp" bottom-preview="500"/>
<category>artesania</category>
<slug>nunca-fui-gloria</slug>
<content>
<img witdh="50%" alt="Logo nunca-fui-gloria." style="border: solid 1px black" src="/img/nunca-fui-gloria.webp"/>
<h2>Compra productos artesanos en Burguillos.</h2>
<p>Nunca fui Gloria ofrece una amplia oferta de productos artesanales y de artesanía, entre ellos <a href="https://sites.google.com/view/nuncafuigloria/inicio/pendientes">pendientes</a>, <a href="https://sites.google.com/view/nuncafuigloria/inicio/collares">collares</a>, <a href="https://sites.google.com/view/nuncafuigloria/inicio/cuencos">cuencos</a> y <a href="https://sites.google.com/view/nuncafuigloria/inicio/otros">otros</a>.</p>
<p>Visita su <a href="https://sites.google.com/view/nuncafuigloria/">web</a> e <a href="https://www.instagram.com/nuncafuigloria/">Instagram</a> para más información.</p>
<p>Puedes encontrar los productos de Nunca fuí Gloria en el local de la Gallina Costurera localizado Avenida Pepe Luna.</p>
<p>¿Quieres ver tu negocio localizado en Burguillos en este espacio? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a>.</p>
</content>
</post>

View File

@ -1,47 +0,0 @@
<post>
<author>Burguillos.info</author>
<date>2023-09-28T09:59+00:00</date>
<title>Baby Parks - Donde celebrar cumpleaños en Burguillos.</title>
<ogdesc>Baby Parks - Donde celebrar cumpleaños en Burguillos.</ogdesc>
<img src="/img/baby-parks.webp" bottom-preview="500"/>
<category>celebraciones</category>
<slug>baby-parks</slug>
<content>
<img witdh="50%" alt="Fotografía baby park" style="border: solid 1px black" src="/img/baby-parks.webp" bottom-preview="500"/>
<h2>¿Aun no sabes donde celebrar el cumpleaños de tu hijo o nieto?</h2>
<p>El Baby Parks, localizado en Calle los Almendros número 2 local c, es un lugar que puedes alquilar y tiene todo lo necesario para que tanto los peques como los mayores se lo puedan pasar bomba.</p>
<p>Contacta al teléfono <a href="tel:+34698902365">698 902 365</a> para reservar o más información.</p>
<p>Los precios son:</p>
<ul>
<li>Lunes a Jueves: 50€</li>
<li>Viernes a domingo y festivos: 75€</li>
</ul>
<p>La infraestructura para adultos incluye:</p>
<ul>
<li>Barra.</li>
<li>Botellero.</li>
<li>Arcón congelador.</li>
<li>Cafetera.</li>
<li>Microondas.</li>
<li>Sandwichera.</li>
<li>Equipo de sonido.</li>
</ul>
<p>Y para los peques:</p>
<ul>
<li>Pista americana.</li>
<li>Cama elástica.</li>
<li>Baby park.</li>
</ul>
<p>¿Quieres ver tu negocio localizado en Burguillos en este espacio? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a>.</p>
</content>
</post>

View File

@ -1,20 +0,0 @@
<post>
<author>Burguillos.info</author>
<date>2023-10-25T11:12+00:00</date>
<title>Alimentación Las Niñas.</title>
<ogdesc>Alimentación Las Niñas.</ogdesc>
<img src="/img/las-ninas.webp" bottom-preview="750"/>
<category>tiendas-alimentacion</category>
<slug>alimentacion-las-niñas</slug>
<content>
<img width="50%" alt="Front door of 'Alimentación Las Niñas'" style="border: solid 1px black;" src="/img/las-ninas.webp"/>
<p>Localizado en Calle los Palmeros número 34 Alimentación las Niñas es una tienda con variedad de genero en la categoría de alimentación y cuidado del hogar con servicio de pan y charcutería.</p>
<p>Puedes dejar tu pedido encargado para recoger en tienda en el siguiente teléfono <a href="tel:+34664090788">664 090 788</a>.</p>
<p>No te lo pienses, compra local, compra en Burguillos.</p>
<p>¿Quieres ver tu negocio localizado en Burguillos en este espacio? Contacta con <a href="mailto:contact@owlcode.tech">contact@owlcode.tech</a>.</p>
</content>
</post>

View File

@ -1,31 +0,0 @@
<post>
<author>Burguillos.info</author>
<date>2022-12-02T12:56+00:00</date>
<title>Burguillos Dental - Dentista en Burguillos.</title>
<ogdesc>Burguillos Dental - Dentista en Burguillos.</ogdesc>
<category>dentistas</category>
<slug>burguillos-dental</slug>
<img src="/img/burguillos-dental.webp"/>
<content>
<img alt="" src="/img/burguillos-dental.webp"/>
<h2>Hazte tu aparato dental/ortodoncia invisible en Burguillos Dental.</h2>
<p>Burguillos Dental, ubicado en la <a href="/posts/centro-medico-juan-manuel-perez-sanchez">Clínica Juan Manuel Pérez Sánchez</a> poseé un equipo de odontologos y dentistas altamente cualificados.</p>
<p>Ofrecen los siguientes servicios para el cuidado de tu boca:</p>
<ul>
<li>Odontologia general.</li>
<li>Ortodoncia.</li>
<li>Ortodoncia Invisible.</li>
<li>Odontopediatria.</li>
<li>Estetica Dental y Labios.</li>
<li>Protesis y Aparatos Dentales, Implantes.</li>
<li>Plan de atención infantil de la Junta de Andalucía.</li>
<li>Radiografías Panorex-Teleradiografía.</li>
</ul>
<p>Cita previa en <a href="tel:+34635061176">635061176</a> o <a href="mailto:policlinicaburguillos@gmail.com">policlinicaburguillos@gmail.com</a>.</p>
<p>Localizado en Calle la Fuente número 24.</p>
</content>
</post>

@ -1 +0,0 @@
Subproject commit ae2bd63d8fbf93b8bb2a2fa9cc16405a16d0223d

View File

@ -1,171 +0,0 @@
export interface Ad {
img: string,
text: string
href: string
seconds: number
}
export default class CarouselAd {
private currentAdNumber: number | null = null
private ad: Ad | null = null
private timeoutNumber: number | null = null
private firstAd = true
private isLockedSwipe: boolean = false
private getCarousel(): HTMLElement {
const carousel = document.querySelector('.carousel');
if (carousel === null || !(carousel instanceof HTMLElement)) {
this.noMoreAds()
CarouselAd.fail('No carousel.')
}
return carousel
}
static fail(error: string): never {
throw new Error(error)
}
public async run(): Promise<void> {
this.loadOneAd()
try {
let start = 0
let end = 0
this.getCarousel().addEventListener('pointerdown', (event: MouseEvent) => {
start = event.pageX
console.log(start)
})
this.getCarousel().addEventListener('pointerup', (event: MouseEvent) => {
end = event.pageX
console.log(end)
if (start - end > 100) {
if (this.isLockedSwipe) {
return
}
if (this.timeoutNumber !== null) {
window.clearTimeout(this.timeoutNumber)
}
this.loadOneAd()
} else {
const a = this.retrieveLinkCarousel()
if (a !== null) {
window.location.href = a.href
}
}
})
} catch (e) {
console.log(e)
return
}
}
private noMoreAds() {
const carousel = this.getCarousel()
if (carousel !== null) {
carousel.remove();
}
this.expandPageContents();
if (this.timeoutNumber === null) {
return
}
window.clearTimeout(this.timeoutNumber)
}
private expandPageContents() {
const pageContents = document.querySelector('div.page-contents');
if (pageContents === null) {
return;
}
pageContents.classList.add('no-carousel');
}
private retrieveLinkCarousel(): HTMLAnchorElement | null{
const carousel = this.getCarousel()
const a = carousel.querySelector('a')
if (a === null) {
return null
}
return a
}
private async loadOneAd() {
try {
const params = new URLSearchParams();
if (this.currentAdNumber !== null) {
params.append('n', ""+this.currentAdNumber);
}
const response = await fetch('/next-ad.json?' + params)
const responseJson = await response.json()
this.currentAdNumber = responseJson.current_ad_number
this.ad = responseJson.ad
if (this.ad === null) {
this.noMoreAds()
return
}
const must_continue = responseJson.continue
const carousel = this.getCarousel()
if (must_continue === 0
|| carousel.offsetWidth === 0) {
this.noMoreAds();
return;
}
const aPrev = this.retrieveLinkCarousel()
const allAnchors = carousel.querySelectorAll('a')
const a = document.createElement('a')
a.addEventListener('click', (event: MouseEvent) => {
event.preventDefault()
})
a.addEventListener('pointerdown', (event: MouseEvent) => {
event.preventDefault()
})
a.addEventListener('pointerup', (event: MouseEvent) => {
event.preventDefault()
})
const image = document.createElement('img')
const text_container = document.createElement('div')
const text = document.createElement('h4')
const promoted = document.createElement('p')
promoted.classList.add('promoted-tag')
promoted.innerText = "Promocionado"
image.src = this.ad.img
image.alt = ""
text.innerText = this.ad.text
a.href = this.ad.href
a.append(image)
text_container.append(promoted)
text_container.append(text)
a.append(text_container)
if (this.firstAd) {
carousel.innerHTML = ''
this.firstAd = false
}
carousel.append(a)
this.isLockedSwipe = true
window.setTimeout(() => {
a.classList.add('show')
if (aPrev !== null) {
aPrev.classList.remove('show')
aPrev.classList.add('remove')
}
window.setTimeout(() => {
if (aPrev !== null) {
aPrev.remove()
}
for (const a of allAnchors) {
a.remove()
}
this.isLockedSwipe = false
}, 1000)
}, 200)
this.timeoutNumber = window.setTimeout(() => {
this.loadOneAd()
}, this.ad.seconds * 1000)
} catch (e) {
console.error(e)
this.timeoutNumber = window.setTimeout(() => {
this.loadOneAd()
}, 1000)
}
}
}

View File

@ -1,46 +1,21 @@
"use strict";
import Tablesort from 'tablesort';
import CarouselAd from '@burguillosinfo/carousel-ad'
window.Tablesort = require('tablesort');
require('tablesort/src/sorts/tablesort.number');
let fakeSearchInput
let searchMobile
document.addEventListener("DOMContentLoaded", function () {
window.onload = () => {
const menu_expand = document.querySelector('a.menu-expand');
const mobile_foldable = document.querySelector('nav.mobile-foldable');
const transparentFullscreenHide = document.querySelector('div.transparent-fullscreen-hide');
const contentsWithoutMenu = document.querySelector('div.contents-without-menu')
const tables = document.querySelectorAll('table')
fillFarmaciaGuardia();
new CarouselAd().run()
loadAd()
addEasterEggAnimation()
if (menu_expand !== null && mobile_foldable !== null && transparentFullscreenHide !== null && contentsWithoutMenu !== null) {
mobile_foldable.toggleAttribute('aria-hidden')
if (mobile_foldable.getAttribute('aria-hidden') !== null) {
mobile_foldable.setAttribute('aria-hidden', true);
}
transparentFullscreenHide.addEventListener('click', () => {
mobile_foldable.classList.remove('show');
transparentFullscreenHide.classList.remove('show');
menu_expand.classList.remove('active');
contentsWithoutMenu.removeAttribute('aria-hidden')
mobile_foldable.setAttribute('aria-hidden', true)
});
if (menu_expand !== null && mobile_foldable !== null) {
menu_expand.addEventListener('click', () => {
menu_expand.classList.toggle('active');
mobile_foldable.classList.toggle('show');
transparentFullscreenHide.classList.toggle('show');
contentsWithoutMenu.toggleAttribute('aria-hidden')
if (contentsWithoutMenu.getAttribute('aria-hidden') !== null) {
contentsWithoutMenu.setAttribute('aria-hidden', true);
}
mobile_foldable.toggleAttribute('aria-hidden')
if (mobile_foldable.getAttribute('aria-hidden') !== null) {
mobile_foldable.setAttribute('aria-hidden', true);
}
});
}
@ -60,81 +35,20 @@ document.addEventListener("DOMContentLoaded", function () {
executeAndroidExclusiveCode(Android)
}
searchMobile = document.querySelector('nav.mobile-shortcuts div.search')
if (searchMobile !== null) {
fakeSearchInput = searchMobile.querySelector('input')
addListenersSearch()
}
}, false);
function fillFarmaciaGuardia() {
const farmaciaName = document.querySelector('#farmacia-name');
const farmaciaAddress = document.querySelector('#farmacia-address');
if (farmaciaName !== null || farmaciaAddress !== null) {
const port = _port()
const url = new URL(window.location.protocol
+ "//"
+ window.location.hostname
+ port
+ '/farmacia-guardia.json');
fetch(url).then(async (res) => {
const farmacia = await res.json()
if (farmaciaName !== null) {
farmaciaName.innerText = farmacia.name;
farmaciaAddress.innerText = farmacia.address;
}
})
}
}
fakeSearchInput = searchMobile.querySelector('input')
addListenersSearch()
};
function addListenersSearch() {
const searchInPage = document.querySelector('div.search-in-page')
if (searchMobile !== null) {
const searchIcon = searchMobile.querySelector('a.search-icon')
searchIcon.addEventListener('click', (e) => {
const searchIcon = searchMobile.querySelector('div.search-icon')
searchIcon.addEventListener('click', onFakeSearchClick);
fakeSearchInput.addEventListener('change', (e) => {
const searchOverlay = document.querySelector('div.search-overlay');
const searchInput = searchOverlay.querySelector('div.search input');
searchInput.value = fakeSearchInput.value;
onSearchChange(e)
onFakeSearchClick(e)
return true;
})
fakeSearchInput.addEventListener('keyup', (e) => {
if (searchInPage === null) {
return;
}
if (fakeSearchInput.value === "") {
searchInPage.classList.remove('active')
} else {
searchInPage.classList.add('active')
}
if (e.keyCode !== 13) {
return false;
}
const searchOverlay = document.querySelector('div.search-overlay');
const searchInput = searchOverlay.querySelector('div.search input');
searchInput.value = fakeSearchInput.value;
onSearchChange(e)
onFakeSearchClick(e)
return true;
});
}
const nextResult = searchInPage.querySelector('a.down');
const prevResult = searchInPage.querySelector('a.up');
window.addEventListener("keydown", (e) => {
if (e.key.toLowerCase() === "f" && e.ctrlKey) {
openAllDetails()
}
});
window.addEventListener("blur", (e) => {
openAllDetails()
})
if (nextResult !== null && prevResult !== null) {
nextResult.addEventListener('click', () => {
searchInWebsite(fakeSearchInput.value, true);
});
prevResult.addEventListener('click', () => {
searchInWebsite(fakeSearchInput.value, false);
});
}
const exitSearch = document.querySelector('a.exit-search')
@ -146,60 +60,6 @@ function addListenersSearch() {
if (search !== null) {
search.addEventListener('change', onSearchChange);
}
const searchIconDesktop = document.querySelector('nav.desktop a.search-icon');
if (searchIconDesktop !== null) {
searchIconDesktop.addEventListener('click', (e) => {
onFakeSearchClick(e)
})
}
}
function searchInWebsite(value, isToBottom) {
window.find(value, false, !isToBottom, true)
const selection = window.getSelection()
openAllDetails()
if (selection.anchorNode === null) {
const pageContents = document.querySelector('div.page-contents');
pageContents.focus()
searchInWebsite(value, isToBottom)
}
const anchorNode = selection.anchorNode.parentNode
if (anchorNode.tagName !== null
&& anchorNode.tagName === "INPUT") {
const pageContents = document.querySelector('div.page-contents');
pageContents.focus()
searchInWebsite(value, isToBottom)
}
if (anchorNode !== null) {
const pageContents = document.querySelector('div.page-contents');
const offsetTop = _getOffsetTopWithNParent(anchorNode, pageContents);
pageContents.scroll(0, offsetTop - 150)
}
}
function openAllDetails() {
for (const detail of document.querySelectorAll('details')) {
detail.open = true
}
}
function _getOffsetTopWithNParent(element, nParent, _carry = 0) {
if (element === null) {
return null;
}
if (element === nParent) {
return _carry;
}
_carry += element.offsetTop
return _getOffsetTopWithNParent(element.offsetParent, nParent, _carry)
}
function _port() {
let port = window.location.port;
if (port !== '') {
port = ':' + port
}
return port;
}
function onSearchChange() {
@ -210,7 +70,10 @@ function onSearchChange() {
}
const query = search.value;
fakeSearchInput.value = search.value
const port = _port()
let port = window.location.port;
if (port !== '') {
port = ':' + port
}
const url = new URL(window.location.protocol
+ "//"
+ window.location.hostname
@ -238,11 +101,6 @@ function showResults(searchResults, searchObjects) {
for (let searchObject of searchObjects) {
const searchResultContainer = document.createElement('div')
searchResultContainer.classList.add('search-result')
const rowTitleUrlImageDiv = document.createElement('div');
rowTitleUrlImageDiv.classList.add('row-title-url-image');
const columnTitleUrl = document.createElement('div');
columnTitleUrl.classList.add('column-title-url');
const img = document.createElement('img')
const title = document.createElement('b')
const url = document.createElement('a')
const content = document.createElement('p')
@ -258,33 +116,13 @@ function showResults(searchResults, searchObjects) {
+ port
+ searchObject.url
}
let urlImage = searchObject.urlImage;
if (urlImage !== null && urlImage.match(/^\//)) {
urlImage = window.location.protocol
+ "//" + window.location.hostname
+ port
+ urlImage
}
if (urlImage !== null) {
img.alt = ""
img.src = urlImage
}
url.href = searchObject.url
url.innerText = searchObject.url
content.innerText = searchObject.content
if (urlImage !== null) {
rowTitleUrlImageDiv.appendChild(img)
}
columnTitleUrl.appendChild(title);
columnTitleUrl.appendChild(document.createElement('br'))
columnTitleUrl.appendChild(url)
rowTitleUrlImageDiv.appendChild(columnTitleUrl)
searchResultContainer.appendChild(rowTitleUrlImageDiv)
searchResultContainer.appendChild(title)
searchResultContainer.appendChild(document.createElement('br'))
searchResultContainer.appendChild(url)
searchResultContainer.appendChild(content)
searchResults.appendChild(searchResultContainer)
}
@ -378,3 +216,79 @@ function addEasterEggAnimation() {
logoContainer.classList.toggle('active')
})
}
let current_ad_number = null
function expand_page_contents() {
const page_contents = document.querySelector('div.page-contents');
if (page_contents === null) {
return;
}
page_contents.classList.add('no-carousel');
}
function no_more_ads() {
const carousel = document.querySelector('.carousel');
if (carousel !== null) {
carousel.remove();
}
expand_page_contents();
}
function loadAd() {
const params = new URLSearchParams();
if (current_ad_number !== null) {
params.append('n', ""+current_ad_number);
}
fetch('/next-ad.json?' + params).then((res) => {
return res.json()
}).then((res) => {
current_ad_number = res.current_ad_number
const ad = res.ad
const must_continue = res.continue
const carousel = document.querySelector('.carousel');
if (must_continue === 0
|| carousel === null
|| carousel.offsetWidth === 0) {
no_more_ads();
return;
}
const a = _retrieveLinkCarousel(carousel)
a.innerHTML = ""
const image = document.createElement('img')
const text_container = document.createElement('div')
const text = document.createElement('h4')
const promoted = document.createElement('p')
promoted.classList.add('promoted-tag')
promoted.innerText = "Promocionado"
image.src = ad.img
image.alt = ""
text.innerText = ad.text
a.href = ad.href
a.append(image)
text_container.append(promoted)
text_container.append(text)
a.append(text_container)
window.setTimeout(() => {
loadAd()
}, ad.seconds * 1000)
}).catch(() => {
window.setTimeout(() => {
loadAd()
}, 1000)
});
}
function _retrieveLinkCarousel(carousel) {
const maybeA = carousel.querySelector('a')
if (maybeA !== null) {
return maybeA
}
const a = document.createElement('a')
carousel.innerHTML = ""
carousel.append(a)
return a
}

View File

@ -47,11 +47,11 @@ sub startup ($self) {
$r->get('/privacy.txt')->to('Privacy#index');
$r->get('/sitemap.xml')->to('Sitemap#sitemap');
$r->get('/robots.txt')->to('Robots#robots');
$r->get('/aprende-a-dibujar-con-krita')->to('Page#rickroll');
# $r->get('/:post')->to('Page#post');
$r->get('/stats')->to('Metrics#stats');
$r->get('/search.json')->to('Search#search');
$r->get('/farmacia-guardia.json')->to('FarmaciaGuardia#current');
$r->get('/<:category>.rss')->to('Page#category_rss');
$r->get('/:category_slug/atributo/<:attribute_slug>-preview.png')->to('Attribute#get_attribute_preview');
$r->get('/:category_slug/atributo/:attribute_slug')->to('Attribute#get');

View File

@ -47,23 +47,20 @@ sub get_next ( $self, $current_ad_number = undef ) {
if ( !defined $current_ad_number ) {
$current_ad_number = 0;
}
my $ad;
while (!defined $ad || $ad->id eq $current_ad_number) {
$ad = $self->get_rand_ad($array)->clone;
}
my $ad = $self->get_rand_ad($array)->clone;
return {
ad => $ad->serialize,
continue => 1,
current_ad_number => $ad->id,
current_ad_number => $self->_get_next_number($current_ad_number),
};
}
sub get_rand_ad($self, $array) {
my $valid_ads = [ grep { $_->is_active } @$array ];
my $max_weight = $self->sum_weights($valid_ads);
my $max_weight = $self->sum_weights($array);
my $rand = int(rand() * $max_weight);
my $sum_weight = 0;
for my $ad (@$valid_ads) {
for my $ad (@$array) {
$sum_weight += $ad->weight;
if ($rand < $sum_weight) {
return $ad;

View File

@ -1,39 +0,0 @@
package BurguillosInfo::Ads::Afasode;
use v5.36.0;
use strict;
use warnings;
use utf8;
use feature 'signatures';
use Moo;
use parent 'BurguillosInfo::Ad';
sub id ($self) {
return 'afasode-loteria';
}
sub weight {
return 15;
}
sub is_active ($self) {
return 0;
}
sub img {
return '/img/afasode.svg';
}
sub href {
return '/posts/boletos-loteria-afasode-sevilla-2023';
}
sub text {
return
'54359 es el número de la lotería de Navidad de AFASODE, colabora con una buena causa y no pierdas la ilusión.';
}
1;

View File

@ -50,7 +50,7 @@ sub href {
sub text($self) {
if ($self->default_alternative == 1) {
return '¡Anunciate en Burguillos.info! Precios a partir de 18.00€, pulsa aquí y escribenos.';
return '¡Anunciate en Burguillos.info! Precios a partir de 18.15€, pulsa aquí y escribenos.';
}
return
'Pulsando este anuncio puedes enviarnos un correo para anunciarte en este sitio. ¡Si me ves funciona!';

View File

@ -1,52 +0,0 @@
package BurguillosInfo::Ads::Beluche;
use v5.36.0;
use strict;
use warnings;
use utf8;
use feature 'signatures';
use Moo;
use parent 'BurguillosInfo::Ad';
sub id ($self) {
return 'beluche';
}
sub weight {
return 50;
}
sub max_alternative {
return 2;
}
sub default_alternative($self) {
return int($self->alternative * ($self->max_alternative + 1));
}
sub is_active ($self) {
return 1;
}
sub img ($self) {
if ( $self->default_alternative == 1 ) {
return '/img/anuncio-beluche-2.webp'
}
return '/img/anuncio-beluche-1.webp'
}
sub text($self) {
if ( $self->default_alternative == 1 ) {
return 'Un ambiente inmejorable en el local y un servicio de reparto a domicilio excelente. Tu comida en Café Bar Beluche.';
}
return 'Increíbles platos en Café Bar Beluche, ve y descubreló.';
}
sub href {
return '/posts/cafe-bar-beluche?come-from-ad=1';
}
1;

View File

@ -1,65 +0,0 @@
package BurguillosInfo::Ads::BurguillosDental;
use v5.36.0;
use strict;
use warnings;
use utf8;
use feature 'signatures';
use Moo;
use parent 'BurguillosInfo::Ad';
sub id ($self) {
return 'burguillos-dental';
}
sub weight {
return 50;
}
sub max_alternative {
return 3;
}
sub seconds($self) {
return 15;
}
sub default_alternative($self) {
return int($self->alternative * ($self->max_alternative + 1));
}
sub is_active ($self) {
return 0;
}
sub img ($self) {
if ( $self->default_alternative == 2 ) {
return '/img/burguillos-dental-ad-0-small.webp'
}
if ( $self->default_alternative == 1 ) {
return '/img/burguillos-dental-ad-1-small.webp'
}
return '/img/burguillos-dental-ad-1-small.webp'
}
sub text($self) {
if ( $self->default_alternative == 2 ) {
return 'Pide presupuesto para conseguir una sonrisa perfecta en Burguillos Dental, '.
'ubicado en Centro Médico Juan Manuel Pérez Sanchez.';
}
if ( $self->default_alternative == 1 ) {
return '¿Te has hecho ya tu limpieza completa de boca anual? Confia en profesionales, confia en Burguillos Dental, '.
'ubicado en Centro Médico Juan Manuel Pérez Sanchez.';
}
return '¿Te duele un diente? No lo dejes, ven a Burguillos Dental '.
'ubicado en Centro Médico Juan Manuel Pérez Sanchez.';
}
sub href {
return '/posts/burguillos-dental?come-from-ad=1';
}
1;

View File

@ -1,55 +0,0 @@
package BurguillosInfo::Ads::ChaletEnVentaCalleHinojo;
use v5.36.0;
use strict;
use warnings;
use utf8;
use DateTime;
use feature 'signatures';
use Moo;
use parent 'BurguillosInfo::Ad';
sub id ($self) {
return 'chalet-en-venta-calle-hinojo';
}
sub weight {
return 50;
}
sub max_alternative {
return 1;
}
sub seconds($self) {
return 15;
}
sub default_alternative($self) {
return int($self->alternative * ($self->max_alternative + 1));
}
sub is_active ($self) {
if (DateTime->new(year => 2024, month => 6, day => 11) < DateTime->now()) {
return 0;
}
return 1;
}
sub img ($self) {
return '/img/chalet-calle-hinojo.webp';
}
sub text($self) {
return 'Chalet pareado en venta en calle Hinojo por 160 000€';
}
sub href {
return 'https://www.idealista.com/inmueble/104802645/';
}
1;

View File

@ -1,58 +0,0 @@
package BurguillosInfo::Ads::Cristobal;
use v5.36.0;
use strict;
use warnings;
use utf8;
use feature 'signatures';
use Moo;
use parent 'BurguillosInfo::Ad';
sub id ($self) {
return 'cristobal';
}
sub weight {
return 50;
}
sub max_alternative {
return 3;
}
sub default_alternative($self) {
return int($self->alternative * ($self->max_alternative + 1));
}
sub is_active ($self) {
return 0;
}
sub img ($self) {
if ( $self->default_alternative == 2 ) {
return '/img/anuncio-cristobal-1.webp'
}
if ( $self->default_alternative == 1 ) {
return '/img/anuncio-cristobal-2.webp'
}
return '/img/anuncio-cristobal-3.webp'
}
sub text($self) {
if ( $self->default_alternative == 2 ) {
return 'Disfruta de comidas abundantes en Bar Cristóbal. Contacta a 621 210 460.';
}
if ( $self->default_alternative == 1 ) {
return 'Bar Cristóbal, para chuparse los dedos. Contacta a 621 210 460.';
}
return '¿Te apetece una cervecita y buena comida? Ven a Bar Cristóbal. Contacta a 621 210 460.';
}
sub href {
return '/posts/bar-cristobal?come-from-ad=1';
}
1;

View File

@ -0,0 +1,59 @@
package BurguillosInfo::Ads::Ermita;
use v5.36.0;
use strict;
use warnings;
use utf8;
use Moo;
use parent 'BurguillosInfo::Ad';
sub max_alternative {
return 1;
}
sub default_alternative ($self) {
return int( $self->alternative * ( $self->max_alternative + 1 ) );
}
sub weight {
return 50;
}
sub id ($self) {
return 'ermita';
}
sub is_active ($self) {
return 1;
}
sub seconds ($self) {
if ( $self->default_alternative == 1 ) {
return 5;
}
return 8;
}
sub img ($self) {
if ( $self->default_alternative == 0 ) {
return '/img/anuncio-ermita-1.webp';
}
return '/img/anuncio-ermita-2.webp';
}
sub href {
return '/posts/hamburgueseria-la-ermita';
}
sub text ($self) {
if ( $self->default_alternative == 1 ) {
return
'Prueba los helados Sandy en la Pizzería/Hamburguesería la Ermita';
}
return
'Increíbles hamburguesas y pizzas en Pizzería/Hamburguesería la Ermita';
}
1;

View File

@ -1,50 +0,0 @@
package BurguillosInfo::Ads::OwlcodeTech;
use v5.36.0;
use strict;
use warnings;
use utf8;
use feature 'signatures';
use Moo;
use parent 'BurguillosInfo::Ad';
sub id ($self) {
return 'owlcode-tech';
}
sub weight {
return 50;
}
sub seconds($self) {
return 15;
}
sub max_alternative {
return 1;
}
sub default_alternative($self) {
return int($self->alternative * ($self->max_alternative + 1));
}
sub is_active ($self) {
return 0;
}
sub img ($self) {
return '/img/owlcode-tech.webp';
}
sub text($self) {
return '¿Tienes una PYME o eres autónomo y aun no tienes presencia web? Consigue una web totalmente subvencionada. Pulsa aquí para más información.';
}
sub href {
return 'mailto:contact@owlcode.tech?subject=Quiero%20una%20web%20completamente%20subvencionada';
}
1;

View File

@ -1,59 +0,0 @@
package BurguillosInfo::Ads::YoTeLoGuiso;
use v5.36.0;
use strict;
use warnings;
use utf8;
use feature 'signatures';
use Moo;
use parent 'BurguillosInfo::Ad';
sub id ($self) {
return 'yo-te-lo-guiso';
}
sub weight {
return 50;
}
sub max_alternative {
return 3;
}
sub default_alternative($self) {
return int($self->alternative * ($self->max_alternative + 1));
}
sub is_active ($self) {
return 0;
}
sub img ($self) {
if ( $self->default_alternative == 2 ) {
return '/img/anuncio-yo-te-lo-guiso-3.webp';
}
if ( $self->default_alternative == 1 ) {
return '/img/anuncio-yo-te-lo-guiso-2.webp';
}
return '/img/anuncio-yo-te-lo-guiso-1.webp';
}
sub text($self) {
if ( $self->default_alternative == 2 ) {
return '¡Comida distinta cada día! Ven a YoTeLoGuiso.';
}
if ( $self->default_alternative == 1 ) {
return
'Una comida como esta no la ves todos los días, disponible en Burguillos, entra y descubrelo. Y O T E L O G U I S O';
}
return 'Comida hecha como en tu casa, YoTeLoGuiso...';
}
sub href {
return '/posts/yo-te-lo-guiso?come-from-ad=1';
}
1;

View File

@ -23,7 +23,7 @@ sub new {
return bless {}, shift;
}
sub Retrieve ($self) {
sub Retrieve($self) {
if ( defined $cached_categories ) {
return $cached_categories;
}
@ -31,45 +31,21 @@ sub Retrieve ($self) {
for my $category_file ( $CATEGORIES_DIR->children ) {
warn "Bad file $category_file, omiting...", next
if !-f $category_file || $category_file !~ /\.xml$/;
my $dom = Mojo::DOM->new( $category_file->slurp_utf8 );
defined( my $title = $dom->at(':root > title')->text )
my $dom = Mojo::DOM->new( $category_file->slurp_utf8 );
defined(my $title = $dom->at(':root > title')->text)
or die "Missing title at $category_file.";
defined( my $description = $dom->at(':root > description')->content )
defined(my $description = $dom->at(':root > description')->content)
or die "Missing description at $category_file";
defined( my $slug = $dom->at(':root > slug')->text )
defined(my $slug = $dom->at(':root > slug')->text)
or die "Missing slug at $category_file";
defined( my $menu_text = $dom->at(':root > menu_text')->content )
defined (my $menu_text = $dom->at(':root > menu_text')->content)
or die "Missing menu_text at $category_file";
defined( my $priority = $dom->at(':root > priority')->text )
defined (my $priority = $dom->at(':root > priority')->text)
or die "Missing priority at $category_file";
my $attributes = $self->_GetAttributes( $dom, $category_file );
my $parent_tag = $dom->at(':root > parent');
my $random_tag = $dom->at(':root > random');
my $image_element = $dom->at(':root > img');
my $image;
my $image_bottom_preview;
my $random;
if ( defined $random_tag ) {
{
$random = $random_tag->text;
if ( $random =~ /^true$/i || $random =~ /^yes$/ ) {
$random = 1;
next;
}
if ( int($random) != 0 ) {
$random = 1;
next;
}
$random = 0;
}
}
if ( defined $image_element ) {
$image = $image_element->attr->{src};
$image_bottom_preview = $image_element->attr->{'bottom-preview'};
}
my $attributes = $self->_GetAttributes($dom, $category_file);
my $parent_tag = $dom->at(':root > parent');
my $parent;
if ( defined $parent_tag ) {
if (defined $parent_tag) {
$parent = $parent_tag->content;
}
my $category = {
@ -79,16 +55,11 @@ sub Retrieve ($self) {
description => $description,
priority => $priority,
(
( defined $parent ) ? ( parent => $parent )
: ()
(defined $parent) ?
(parent => $parent) :
()
),
attributes => $attributes,
(
( defined $random ) ? ( random => $random )
: ()
),
image_bottom_preview => $image_bottom_preview,
image => $image,
};
$cached_categories->{$slug} = $category;
}
@ -97,92 +68,64 @@ sub Retrieve ($self) {
return $cached_categories;
}
sub _GetAttributes ( $self, $dom, $category_file ) {
sub _GetAttributes($self, $dom, $category_file) {
my $attributes_tag = $dom->at(':root > attributes');
my %attributes;
if ( defined $attributes_tag ) {
my @attribute_tag_list =
$attributes_tag->find('attributes > attribute')->each;
if (defined $attributes_tag) {
my @attribute_tag_list = $attributes_tag->find('attributes > attribute')->each;
for my $attribute_tag (@attribute_tag_list) {
defined( my $menu_text =
$attribute_tag->at('attribute > menu_text')->content )
defined (my $menu_text = $attribute_tag->at('attribute > menu_text')->content)
or die "Missing attribute menu_text at $category_file";
defined( my $description =
$attribute_tag->at('attribute > description')->content )
defined (my $description = $attribute_tag->at('attribute > description')->content)
or die "Missing attribute description at $category_file";
defined( my $title = $attribute_tag->at('attribute > title')->text )
defined (my $title = $attribute_tag->at('attribute > title')->text)
or die "Missing attribute title at $category_file";
defined( my $identifier =
$attribute_tag->at('attribute > identifier')->text )
defined (my $identifier = $attribute_tag->at('attribute > identifier')->text)
or die "Missing attribute identifier at $category_file";
defined( my $priority =
$attribute_tag->at('attribute > priority')->text )
defined (my $priority = $attribute_tag->at('attribute > priority')->text)
or die "Missing attribute priority at $category_file";
my $image_element = $attribute_tag->at('attribute > img');
my $image;
my $image_bottom_preview;
if ( defined $image_element ) {
$image = $image_element->attr->{src};
$image_bottom_preview =
$image_element->attr->{'bottom-preview'};
}
$attributes{$identifier} = {
title => $title,
identifier => $identifier,
priority => $priority,
menu_text => $menu_text,
description => $description,
image => $image,
image_bottom_preview => $image_bottom_preview,
title => $title,
identifier => $identifier,
priority => $priority,
menu_text => $menu_text,
description => $description,
};
}
}
return \%attributes;
}
sub _PopulateChildrenField ( $self, $categories ) {
for my $category_name ( keys %$categories ) {
sub _PopulateChildrenField($self, $categories) {
for my $category_name (keys %$categories) {
my $category = $categories->{$category_name};
$category->{children} //= [];
my $parent_name = $category->{parent};
if ( !defined $parent_name ) {
if (!defined $parent_name) {
next;
}
my $parent = $categories->{$parent_name};
if ( !defined $parent ) {
die
"Category $parent_name not exists and it is the parent of $category_name.";
}
if ( !exists $category->{random} && exists $parent->{random} ) {
$category->{random} = $parent->{random};
if (!defined $parent) {
die "Category $parent not exists and is the parent of $category_name.";
}
$parent->{children} //= [];
push $parent->{children}->@*, $category;
}
}
sub _AvoidGrandChildCategories ( $self, $categories ) {
for my $category_slug ( keys %$categories ) {
sub _AvoidGrandChildCategories($self, $categories) {
for my $category_slug (keys %$categories) {
my $category = $categories->{$category_slug};
my $parent = $category->{parent};
if ( defined $parent && defined $categories->{$parent}{parent} ) {
die
"$category_slug category is grandchild of $categories->{$parent}{parent}) category and this is not allowed.";
my $parent = $category->{parent};
if (defined $parent && defined $categories->{$parent}{parent}) {
die "$category_slug category is grandchild of $categories->{$parent}{parent}) category and this is not allowed.";
}
}
}
sub PreviewOg ( $self, $category, $isWhatsApp = 0 ) {
my $title = $category->{title};
my $description = $category->{description};
my $image = $category->{image};
my $image_bottom_preview = $category->{image_bottom_preview};
if ($isWhatsApp) {
return BurguillosInfo::Preview->WhatsappAlternativeGenerate( $title, $description, $image,
$image_bottom_preview );
}
return BurguillosInfo::Preview->Generate( $title, $description, $image,
$image_bottom_preview );
sub PreviewOg($self, $category) {
my $title = $category->{title};
my $description = $category->{description};
return BurguillosInfo::Preview->Generate($title, $description, undef);
}
1;

View File

@ -28,7 +28,7 @@ sub run ( $self, @args ) {
my $search_backend = $config->{search_backend};
my $search_index = $config->{search_index};
my $ua = Mojo::UserAgent->new;
my $posts = BurguillosInfo::Posts->new->Retrieve(0);
my $posts = BurguillosInfo::Posts->new->Retrieve;
my $categories = BurguillosInfo::Categories->new->Retrieve;
my $index = [];
$self->_index_posts( $index, $posts );
@ -50,22 +50,16 @@ sub _index_categories ( $self, $index, $categories ) {
->all_text;
my $title = $category->{title};
my $attributes = $category->{attributes};
my $image = $category->{image};
$self->_index_attributes( $index, $slug, $attributes );
push @$index, {
title => $title,
titleNormalized => $index_utils->n($title),
content => $content,
contentNormalized => $index_utils->n( $content =~ s/\s+/ /gr ),
url => $url,
urlNormalized => $index_utils->n($url),
(
( defined $image )
? ( urlImage => $image )
: ()
)
};
push @$index,
{
title => $title,
titleNormalized => $index_utils->n($title),
content => $content,
contentNormalized => $index_utils->n( $content =~ s/\s+/ /gr ),
url => $url,
urlNormalized => $index_utils->n($url),
};
}
}
@ -76,7 +70,6 @@ sub _index_attributes ( $self, $index, $category_slug, $attributes ) {
my $slug = $attribute->{identifier};
my $url = "/$category_slug/atributo/$slug";
my $title = $attribute->{title};
my $image = $attribute->{image};
my $content =
Mojo::DOM->new( '<html>' . $attribute->{description} . '</html>' )
->all_text;
@ -88,11 +81,6 @@ sub _index_attributes ( $self, $index, $category_slug, $attributes ) {
content => $content =~ s/\s+/ /gr,
urlNormalized => $index_utils->n($url),
url => $url,
(
( defined $image )
? ( urlImage => $image )
: ()
)
};
}
}

View File

@ -13,7 +13,6 @@ sub next_ad {
my $self = shift;
my $ads_factory = BurguillosInfo::Ads->new;
my $current_ad_number = $self->param('n');
$self->res->headers->access_control_allow_origin('*');
$self->render( json => $ads_factory->get_next($current_ad_number) );
}
1;

View File

@ -25,24 +25,11 @@ sub get_attribute_preview ($self) {
return $self->reply->not_found;
}
my $is_whatsapp = $self->req->headers->user_agent =~ /whatsapp/i;
$is_whatsapp ||= $self->req->headers->user_agent =~ /facebook/i;
my $data;
if ($is_whatsapp) {
$data = BurguillosInfo::Preview->WhatsappAlternativeGenerate(
$attribute->{title}, $attribute->{description},
$attribute->{image}, $attribute->{image_bottom_preview}
)
} else {
$data = BurguillosInfo::Preview->Generate(
$attribute->{title}, $attribute->{description},
$attribute->{image}, $attribute->{image_bottom_preview}
)
}
$self->render(
format => 'png',
data => $data,
data => BurguillosInfo::Preview->Generate(
$attribute->{title}, $attribute->{description}, undef
),
);
}

View File

@ -1,16 +0,0 @@
package BurguillosInfo::Controller::FarmaciaGuardia;
use v5.34.1;
use strict;
use warnings;
use BurguillosInfo::FarmaciaGuardia;
use Mojo::Base 'Mojolicious::Controller', '-signatures';
sub current($self) {
my $farmacia = BurguillosInfo::FarmaciaGuardia->new->get_current;
$self->render( json => $farmacia->serialize );
}
1;

View File

@ -17,17 +17,16 @@ use Crypt::Bcrypt qw/bcrypt bcrypt_check/;
my $tracking;
my $iso8601 = DateTime::Format::ISO8601->new;
my $iso8601 = DateTime::Format::ISO8601->new;
sub request {
shift;
shift;
eval {
my $c = shift;
my $c = shift;
my $app = $c->app;
if ( !defined $tracking ) {
if (!defined $tracking) {
$tracking = BurguillosInfo::Tracking->new($app);
}
$tracking->register_request($c);
$tracking->register_request($c);
};
if ($@) {
say STDERR $@;
@ -35,34 +34,29 @@ sub request {
}
sub stats {
my $self = shift;
if ( !$self->valid_login ) {
$self->res->headers->location('/stats/login');
$self->render( text => 'You must login', status => 302 );
return;
}
$self->session( expiration => 0 );
my $data = $tracking->get_global_data($self);
my $data_per_url = $tracking->get_data_for_urls($self);
my $google_data = $tracking->get_google_data($self);
$self->_filter_data_per_url($data_per_url);
$self->_filter_data_per_url($google_data);
$self->render(
tracking_data => $data,
tracking_by_url => $data_per_url,
google_data => $google_data
);
my $self = shift;
if (!$self->valid_login) {
$self->res->headers->location('/stats/login');
$self->render(text => 'You must login', status => 302);
return;
}
my $data = $tracking->get_global_data($self);
my $data_per_url = $tracking->get_data_for_urls($self);
my $google_data = $tracking->get_google_data($self);
$self->_filter_data_per_url($data_per_url);
$self->_filter_data_per_url($google_data);
$self->render(tracking_data => $data, tracking_by_url => $data_per_url, google_data => $google_data);
}
sub _filter_data_per_url ( $self, $data_per_url ) {
sub _filter_data_per_url($self, $data_per_url) {
my $filter = $self->param('filter');
if ( !defined $filter ) {
if (!defined $filter) {
return;
}
my @new_data_per_url;
if ( $filter eq 'remove-extensions' ) {
my @new_data_per_url;
if ($filter eq 'remove-extensions') {
for my $url (@$data_per_url) {
if ( $url->{path} =~ /\.\w+$/ ) {
if ($url->{path} =~ /\.\w+$/) {
next;
}
push @new_data_per_url, $url;
@ -72,65 +66,67 @@ sub _filter_data_per_url ( $self, $data_per_url ) {
}
sub submit_login {
my $self = shift;
if ( $self->valid_login ) {
$self->res->headers->location('/stats');
$self->render( text => 'Already logged in.', status => 302 );
return;
}
my $password = $self->param('password');
if ( !defined $password ) {
$self->render( text => 'No password passed.', status => 400 );
return;
}
my $bcrypted_pass = $self->config->{bcrypt_pass_stats};
if ( !defined $bcrypted_pass ) {
warn "No bcrypt pass.";
$self->render( text => 'Server error.', status => 500 );
return;
}
say $password;
say $bcrypted_pass;
if ( !bcrypt_check( $password, $bcrypted_pass ) ) {
$self->render( text => 'Wrong password', status => 401 );
return;
}
say STDERR 'Login success.';
my $expiration_date = DateTime->now->add( days => 1 );
$self->session->{login} = "date_end_login:$expiration_date";
$self->res->headers->location('/stats');
$self->render( text => 'Login success.', status => 302 );
return;
my $self = shift;
if ($self->valid_login) {
$self->res->headers->location('/stats');
$self->render(text => 'Already logged in.', status => 302);
return;
}
my $password = $self->param('password');
if (!defined $password) {
$self->render(text => 'No password passed.', status => 400);
return;
}
my $bcrypted_pass = $self->config->{bcrypt_pass_stats};
if (!defined $bcrypted_pass) {
warn "No bcrypt pass.";
$self->render(text => 'Server error.', status => 500);
return;
}
say $password;
say $bcrypted_pass;
if (!bcrypt_check( $password, $bcrypted_pass )) {
$self->render(text => 'Wrong password', status => 401);
return;
}
say STDERR 'Login success.';
my $expiration_date = DateTime->now->add( days => 1);
$self->session->{login} = "date_end_login:$expiration_date";
$self->res->headers->location('/stats');
$self->render(text => 'Login success.', status => 302);
return;
}
sub valid_login {
my $self = shift;
my $login_cookie = $self->session->{login};
if ( !defined $login_cookie ) {
return;
}
my $self = shift;
my $login_cookie = $self->session->{login};
if (!defined $login_cookie) {
return;
}
my ($date_text) = $login_cookie =~ /^date_end_login:(.*)$/;
my $date;
eval { $date = $iso8601->parse_datetime($date_text); };
if ($@) {
warn "Bad date in cookie $login_cookie.";
return;
}
my $current_date = DateTime->now();
if ( $current_date > $date ) {
return;
}
return 1;
my ($date_text) = $login_cookie =~ /^date_end_login:(.*)$/;
my $date;
eval {
$date = $iso8601->parse_datetime($date_text);
};
if ($@) {
warn "Bad date in cookie $login_cookie.";
return;
}
my $current_date = DateTime->now();
if ($current_date > $date) {
return;
}
return 1;
}
sub login {
my $self = shift;
if ( $self->valid_login ) {
$self->res->headers->location('/stats');
$self->render( text => 'You are already logged in.', status => 302 );
return;
}
$self->render;
my $self = shift;
if ($self->valid_login) {
$self->res->headers->location('/stats');
$self->render(text => 'You are already logged in.', status => 302);
return;
}
$self->render;
}
1;

View File

@ -21,15 +21,20 @@ sub index {
my $current_category = $categories->{'index'};
# Render template "example/welcome.html.ep" with message
my $base_url = $self->config('base_url');
$self->stash( ogimage =>
( $base_url . '/' . $current_category->{slug} . '-preview.png' ) );
$self->render(
categories => $categories,
current_category => $current_category,
current_category => $current_category
);
}
sub rickroll($self) {
if ($self->req->headers->user_agent =~ /bot/i) {
return $self->render(text => '');
}
$self->res->headers->location('http://ibaillanos.tv');
$self->render(text => '', status => 302);
}
sub category_rss {
require BurguillosInfo;
my $self = shift;
@ -44,7 +49,7 @@ sub category_rss {
}
my $dom = Mojo::DOM->new_tag( 'rss', version => '2.0', undef );
my $channel_tag = Mojo::DOM->new_tag('channel');
my $base_url = BurguillosInfo->new->config->{base_url};
my $base_url = BurguillosInfo->new->config->{base_url};
if ( $category_name eq 'all' ) {
my $title_tag = Mojo::DOM->new_tag( 'title', 'Burguillos.info' );
my $description_tag = Mojo::DOM->new_tag( 'description',
@ -68,8 +73,8 @@ sub category_rss {
my $description_tag = Mojo::DOM->new_tag( 'description',
'Todas las noticias de la categoria de Burguillos.info '
. $category->{title} );
my $link_tag =
Mojo::DOM->new_tag( 'link', $base_url . '/' . $category->{slug} );
my $link_tag = Mojo::DOM->new_tag( 'link',
$base_url . '/' . $category->{slug} );
$channel_tag->child_nodes->first->append_content($title_tag);
$channel_tag->child_nodes->first->append_content($description_tag);
$channel_tag->child_nodes->first->append_content($link_tag);
@ -93,9 +98,9 @@ sub _post_to_rss {
my $post = shift;
my $item_tag = Mojo::DOM->new_tag('item');
my $title_tag = Mojo::DOM->new_tag( 'title', $post->{title} );
my $base_url = BurguillosInfo->new->config->{base_url};
my $link =
Mojo::DOM->new_tag( 'link', $base_url = '/posts/' . $post->{slug} );
my $base_url = BurguillosInfo->new->config->{base_url};
my $link = Mojo::DOM->new_tag( 'link',
$base_url = '/posts/' . $post->{slug} );
my $description = Mojo::DOM->new_tag( 'description',
Mojo::DOM->new( $post->{content} )->all_text );
my $guid = Mojo::DOM->new_tag( 'guid', $post->{slug} );
@ -144,11 +149,10 @@ sub category {
$self->render( template => '404', status => 404 );
return;
}
$self->stash( ogimage =>
( $base_url . '/' . $current_category->{slug} . '-preview.png' ) );
$self->render(
template => 'page/index',
categories => $categories,
template => 'page/index',
categories => $categories,
ogimage => $base_url . '/' . $current_category->{slug} . '-preview.png',
current_category => $current_category
);
}
@ -162,12 +166,10 @@ sub get_category_preview {
$self->render( template => '404', status => 404 );
return;
}
my $category = $categories->{$category_slug};
my $is_whatsapp = $self->req->headers->user_agent =~ /whatsapp/i;
$is_whatsapp ||= $self->req->headers->user_agent =~ /facebook/i;
my $category = $categories->{$category_slug};
$self->render(
format => 'png',
data => $category_model->PreviewOg( $category, $is_whatsapp )
data => $category_model->PreviewOg($category)
);
}
@ -180,13 +182,10 @@ sub get_post_preview {
$self->render( template => '404', status => 404 );
return;
}
my $is_whatsapp = $self->req->headers->user_agent =~ /whatsapp/i;
$is_whatsapp ||= $self->req->headers->user_agent =~ /facebook/i;
say $self->req->headers->user_agent;
my $post = $posts_slug->{$slug};
$self->render(
format => 'png',
data => $post_model->PreviewOg( $post, $is_whatsapp )
data => $post_model->PreviewOg($post)
);
}
1;

View File

@ -10,12 +10,10 @@ use Mojo::Base 'Mojolicious::Controller', '-signatures';
sub index($self) {
return $self->render(text => <<"EOF");
Esta aplicación no almacena datos que puedan identificar
de forma única a los usuarios.\r\n
Con fines analíticos y técnicos se almacenan la cantidad
de visitas a cada página.\r\n
La dirección IP, Agente de Usuario y parametros GET con los
que se visita la página es almacenado de forma temporal
(90 días) para detectar posibles ciberataques, tras ese tiempo
es sustituido por un hash.
Esta política puede cambiar en un futuro si se
requieren funcionalidades como registros.\r\n
EOF

View File

@ -11,7 +11,6 @@ use Mojo::Base 'Mojolicious::Controller', '-signatures';
use Mojo::UserAgent;
use BurguillosInfo::IndexUtils;
use BurguillosInfo::Posts;
my $index_utils = BurguillosInfo::IndexUtils->new;
@ -37,23 +36,9 @@ sub search ($self) {
return $self->render( status => 400, json => { ok => 0 } );
}
my $searchObjects = $output->{searchObjects};
$searchObjects = [grep { $self->filterSearch($_) } @$searchObjects];
return $self->render(
status => 200,
json => { ok => 1, searchObjects => $searchObjects }
);
}
sub filterSearch($self, $searchObject) {
my $url = $searchObject->{url};
my ($posts_by_categories, $posts) = BurguillosInfo::Posts->Retrieve;
my $slug;
if ($url =~ m{^/posts/([^/]+?)(?:\?.*)?$}) {
$slug = $1;
if (!defined $posts->{$slug}) {
return 0;
}
}
return 1
}
1;

View File

@ -43,12 +43,6 @@ sub MIGRATIONS {
\&_populate_locations,
\&_populate_locations,
\&_populate_locations,
'CREATE TABLE farmacia_guardia (
uuid UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
date timestamp NOT NULL,
id_farmacia TEXT NOT NULL
);',
'CREATE INDEX farmacia_guardia_index on farmacia_guardia (date, id_farmacia, uuid);',
);
}

View File

@ -1,20 +0,0 @@
package BurguillosInfo::Farmacia;
use v5.36.0;
use strict;
use warnings;
use utf8;
use Moo::Role;
requires qw(id name address);
sub serialize ($self) {
return {
id => $self->id,
name => $self->name,
address => $self->address,
};
}
1;

View File

@ -1,141 +0,0 @@
package BurguillosInfo::FarmaciaGuardia;
use v5.36.0;
use strict;
use warnings;
use utf8;
use feature 'signatures';
use Data::Dumper;
use Moo;
use DateTime;
use DateTime::Format::Pg;
use Mojo::UserAgent;
use BurguillosInfo::Farmacias;
use BurguillosInfo::Farmacias::CruzDeLaErmita;
use BurguillosInfo::Farmacias::Morera;
has _app => ( is => 'lazy', );
has _db => ( is => 'lazy' );
sub _build__app {
require BurguillosInfo;
return BurguillosInfo->new;
}
sub get_current ($self) {
my $date_search = $self->_get_search_date;
my $farmacia_db = $self->_search_horario_db($date_search);
if (defined $farmacia_db) {
return $farmacia_db;
}
my $farmacia;
eval {
$farmacia = $self->_request_horario_internet($date_search);
};
if (!defined $farmacia) {
die "API possibly broken for Farmacia de Guardia. $@";
}
$self->_register_farmacia($date_search, $farmacia);
return $farmacia;
}
sub _register_farmacia($self, $date_search, $farmacia) {
my $f = DateTime::Format::Pg->new;
my $dbh = $self->_db;
$dbh->do(<<'EOF', undef, $f->format_datetime($date_search), $farmacia->id);
INSERT INTO farmacia_guardia (date, id_farmacia) VALUES (?, ?);
EOF
}
sub _search_horario_db ( $self, $date_search ) {
my $f = DateTime::Format::Pg->new;
my $db = $self->_db;
$date_search = $date_search->clone;
$date_search->set_time_zone('UTC');
my $start_farmacia_week = $self->_get_start_date_week($date_search);
my $end_farmacia_week = $self->_get_end_date_week($date_search);
my $horarios = $db->selectall_arrayref(
<<'EOF', { Slice => {} }, $f->format_datetime($start_farmacia_week), $f->format_datetime($end_farmacia_week) );
SELECT id_farmacia from farmacia_guardia where date > ? and date < ?;
EOF
if (!scalar @$horarios) {
return;
}
my $id = $horarios->[0]{id_farmacia};
return BurguillosInfo::Farmacias->new->by_id($id);
}
sub _request_horario_internet ( $self, $date_search ) {
my $ua = $self->_ua;
my $result = $ua->get(
'http://www.farmaciacruzdelaermita.com/index.php/component/dpcalendar/events',
form => {
limit => 0,
compact => 0,
my => 0,
format => 'raw',
ids => 10,
'date-start' => $date_search->epoch,
'date-end' => $date_search->epoch,
_ => $date_search->epoch * 1000,
}
)->result;
my $json;
eval { $json = $result->json; };
if ($@) {
die "Unable to recover data of Farmacia de Guardia $@.";
}
my $data;
eval { $data = $json->[0]{data}; };
if ( $@ || !defined $data ) {
die "Unable to get data of calendar.";
}
if ( scalar @$data ) {
return BurguillosInfo::Farmacias::CruzDeLaErmita->new;
}
return BurguillosInfo::Farmacias::Morera->new;
}
sub _ua {
return Mojo::UserAgent->new;
}
sub _get_search_date ($self) {
my $current_date = DateTime->now;
my $date_search = $current_date->clone;
if ( $date_search < $self->_get_start_date_week($current_date) ) {
$date_search = $date_search->add( days => -1 );
}
return $date_search;
}
sub _get_end_date_week ( $self, $date_search ) {
my $start_farmacia_week = $self->_get_start_date_week($date_search);
my $end_farmacia_week = $start_farmacia_week->clone->add( weeks => 1 );
$end_farmacia_week->set_time_zone('Europe/Madrid');
$end_farmacia_week->set_hour(9);
$end_farmacia_week->set_minute(30);
$end_farmacia_week->set_time_zone('UTC');
return $end_farmacia_week;
}
sub _get_start_date_week ( $self, $date_search ) {
my $start_farmacia_week = $date_search->clone->truncate( to => 'week' );
$start_farmacia_week->set_time_zone('Europe/Madrid');
$start_farmacia_week->set_hour(9);
$start_farmacia_week->set_minute(30);
$start_farmacia_week->set_time_zone('UTC');
return $start_farmacia_week;
}
sub _build__db ($self) {
require BurguillosInfo::DB;
return BurguillosInfo::DB->connect( $self->_app );
}
1;

View File

@ -1,66 +0,0 @@
package BurguillosInfo::Farmacias;
use v5.36.0;
use strict;
use warnings;
use utf8;
use Moo;
use Module::Pluggable
search_path => ['BurguillosInfo::Farmacias'],
instantiate => 'new',
on_require_error => sub ( $plugin, $error ) {
die $error;
};
{
my $array;
sub array($self) {
if (!defined $array) {
$self->_populate_farmacias;
}
return $array;
}
sub _populate_farmacias($self) {
$array = [];
@$array = $self->plugins();
for my $farmacia (@$array) {
$self->_check_farmacia_valid($farmacia);
}
}
}
{
my $farmacias_by_id;
sub by_id($self, $target_id) {
if (!defined $farmacias_by_id) {
$self->_populate_farmacias_by_id;
}
if (!defined $target_id) {
die 'You must pass $target_id.';
}
my $farmacia = $farmacias_by_id->{$target_id};
if (!defined $farmacia) {
die "Farmacia $target_id not found.";
}
return $farmacia;
}
sub _populate_farmacias_by_id($self) {
$farmacias_by_id = {};
my $farmacias = $self->array;
for my $farmacia (@$farmacias) {
$farmacias_by_id->{$farmacia->id} = $farmacia;
}
}
}
sub _check_farmacia_valid($self, $farmacia) {
if ( !$farmacia->does('BurguillosInfo::Farmacia') ) {
die "$farmacia does not implement BurguillosInfo::Farmacia.";
}
}
1;

View File

@ -1,27 +0,0 @@
package BurguillosInfo::Farmacias::CruzDeLaErmita;
use v5.36.0;
use strict;
use warnings;
use utf8;
use feature 'signatures';
use Moo;
use parent 'BurguillosInfo::Farmacia';
sub id {
return 'cruz_de_la_ermita';
}
sub name {
return 'Farmacia Cruz de La Ermita';
}
sub address {
return 'Avenida. Alcalde José Cuesta Godoy, Nº 21. (La calle aun es Avenida Cruz de la Ermita si lo buscas en Google Maps.)';
}
1;

View File

@ -1,24 +0,0 @@
package BurguillosInfo::Farmacias::Morera;
use v5.36.0;
use strict;
use warnings;
use utf8;
use Moo;
sub id {
return 'morera';
}
sub name {
return 'Farmacia Óptica Morera';
}
sub address {
return 'Calle Virgen del Rosario número 13';
};
use parent 'BurguillosInfo::Farmacia';
1;

View File

@ -25,7 +25,6 @@ sub normalize($self, $text) {
my $stemmer = Lingua::Stem::Snowball->new( lang => 'es' );
$stemmer->stem_in_place(\@words);
$decomposed = join " ", @words;
$decomposed =~ s/\bpizzeri\b/pizz/gi;
return $decomposed;
}

View File

@ -20,10 +20,10 @@ use DateTime;
use BurguillosInfo::Preview;
const my $CURRENT_FILE => __FILE__;
const my $ROOT_PROJECT => path($CURRENT_FILE)->parent->parent->parent;
const my $PUBLIC_DIR => $ROOT_PROJECT->child('public');
const my $POSTS_DIR => $ROOT_PROJECT->child('content/posts');
const my $CURRENT_FILE => __FILE__;
const my $ROOT_PROJECT => path($CURRENT_FILE)->parent->parent->parent;
const my $PUBLIC_DIR => $ROOT_PROJECT->child('public');
const my $POSTS_DIR => $ROOT_PROJECT->child('content/posts');
my $cached_posts_by_category;
my $cached_posts_by_slug;
@ -32,33 +32,34 @@ sub new {
return bless {}, shift;
}
sub _ReturnCacheFilter ( $self, $filters = 1 ) {
sub _ReturnCacheFilter {
my $self = shift;
my %posts_by_category_filtered;
my %posts_by_slug_filtered;
my $iso8601 = DateTime::Format::ISO8601->new;
my $current_date = DateTime->now;
for my $category ( keys %$cached_posts_by_category ) {
for my $post ( @{ $cached_posts_by_category->{$category} } ) {
if ($filters) {
my $date_post;
eval { $date_post = $iso8601->parse_datetime( $post->{date} ); };
if ($@) {
print $@ . ': ' . Data::Dumper::Dumper $post;
}
if ( $date_post > $current_date ) {
next;
}
my $date_post;
eval {
$date_post = $iso8601->parse_datetime( $post->{date} );
};
if ($@) {
print Data::Dumper::Dumper $post;
}
if ( $date_post > $current_date ) {
next;
}
$posts_by_slug_filtered{ $post->{slug} } = $post;
$posts_by_category_filtered{ $category } //= [];
push @{ $posts_by_category_filtered{ $category } }, $post;
$posts_by_category_filtered{ $post->{category} } //= [];
push @{ $posts_by_category_filtered{ $post->{category} } }, $post;
}
}
return ( \%posts_by_category_filtered, \%posts_by_slug_filtered );
}
sub _GeneratePostFromFile ( $self, $post_file ) {
warn "Bad file $post_file, omiting...", return
warn "Bad file $post_file, omiting...", return
if !-f $post_file || $post_file !~ /\.xml$/;
my $dom = Mojo::DOM->new( $post_file->slurp_utf8 );
my $title = $dom->at(':root > title')->text
@ -69,32 +70,18 @@ sub _GeneratePostFromFile ( $self, $post_file ) {
or die "Missing date at $post_file.";
my $ogdesc = $dom->at(':root > ogdesc')->text
or die "Missing ogdesc at $post_file";
my @categories = $dom->find(':root > category')->map('text')->each;
my $slug = $dom->at(':root > slug')->text
my $category = $dom->at(':root > category')->text
or die "Missing category at $post_file.";
my $slug = $dom->at(':root > slug')->text
or die "Missing slug at $post_file.";
my $content_tag = $dom->at(':root > content')
my $content = $dom->at(':root > content')->content
or die "Missing content at $post_file.";
for my $tag ( $content_tag->children->each ) {
$tag->content( $tag->content =~ s/\n//gr );
}
if ( !scalar @categories ) {
die 'Missing category';
}
my $content = $content_tag->content;
my $pinned_node = $dom->at(':root > pinned');
my $image_element = $dom->at(':root > img');
my $image;
my $image_bottom_preview;
my $attributes = $self->_GetAttributes( $post_file, $dom );
my $attributes = $self->_GetAttributes($post_file, $dom);
my $pinned;
if ( defined $pinned_node ) {
$pinned = int( $pinned_node->text );
}
if ( defined $image_element ) {
$image = $image_element->attr->{src};
$image_bottom_preview = $image_element->attr->{'bottom-preview'};
$image = $image_element->attr->{src};
}
my $last_modification_date_element =
@ -105,38 +92,31 @@ sub _GeneratePostFromFile ( $self, $post_file ) {
}
return {
title => $title,
author => $author,
date => $date,
ogdesc => $ogdesc,
categories => [@categories],
category => $categories[0],
slug => $slug,
content => $content,
attributes => $attributes,
image_bottom_preview => $image_bottom_preview,
title => $title,
author => $author,
date => $date,
ogdesc => $ogdesc,
category => $category,
slug => $slug,
content => $content,
(
( defined $last_modification_date )
? ( last_modification_date => $last_modification_date )
: ()
),
( ( defined $image ) ? ( image => $image ) : () ),
(
( defined $pinned ) ? ( pinned => $pinned )
: ()
)
attributes => $attributes,
};
}
sub _GetAttributes ( $self, $post_file, $dom ) {
sub _GetAttributes($self, $post_file, $dom) {
my $attributes_tag = $dom->at(':root > attributes');
my %attributes;
if ( defined $attributes_tag ) {
my @attribute_list =
$attributes_tag->find('attributes > attribute')->map('text')->each;
%attributes = map {
if (defined $attributes_tag) {
my @attribute_list = $attributes_tag->find('attributes > attribute')->map('text')->each;
%attributes = map {
my $identifier = $_;
( $identifier => 1 );
($identifier => 1);
} @attribute_list;
}
return \%attributes;
@ -148,70 +128,46 @@ sub _GeneratePostCache ($self) {
$cached_posts_by_slug = {};
for my $post_file ( sort { $b cmp $a } $POSTS_DIR->children ) {
my $post = $self->_GeneratePostFromFile($post_file);
if ( !defined $post ) {
if (!defined $post) {
next;
}
my $categories = $post->{categories};
for my $category ($post->{categories}->@*) {
$cached_posts_by_category->{$category} //= [];
my $slug = $post->{slug};
my $category_posts = $cached_posts_by_category->{$category};
$cached_posts_by_slug->{$slug} = $post;
push @$category_posts, $post;
}
my $category = $post->{category};
$cached_posts_by_category->{$category} //= [];
my $slug = $post->{slug};
my $category_posts = $cached_posts_by_category->{$category};
$cached_posts_by_slug->{$slug} = $post;
push @$category_posts, $post;
}
}
sub Retrieve ( $self, $filters = 1 ) {
sub Retrieve {
my $self = shift;
if ( defined $cached_posts_by_category && defined $cached_posts_by_slug ) {
return $self->_ReturnCacheFilter($filters);
return $self->_ReturnCacheFilter;
}
$self->_GeneratePostCache();
return $self->_ReturnCacheFilter($filters);
return $self->_ReturnCacheFilter;
}
my $cache_all_post_categories = {};
sub RetrieveAllPostsForCategory ( $self, $category_name ) {
if (defined $cache_all_post_categories->{$category_name}) {
return $cache_all_post_categories->{$category_name};
}
my $categories = BurguillosInfo::Categories->new->Retrieve;
my $category = $categories->{$category_name};
if ( defined $cache_all_post_categories->{$category_name} ) {
my $posts = $cache_all_post_categories->{$category_name};
return $self->shufflePostsIfRequired( $category, $posts );
}
my $posts = $self->RetrieveDirectPostsForCategory($category_name);
my $posts = $self->RetrieveDirectPostsForCategory($category_name);
for my $child_category ( $category->{children}->@* ) {
my $child_category_name = $child_category->{slug};
push @$posts,
@{ $self->RetrieveDirectPostsForCategory($child_category_name) };
@{$self->RetrieveDirectPostsForCategory($child_category_name)};
}
@$posts = sort {
DateTime::Format::ISO8601->parse_datetime( $b->{date} )
<=> DateTime::Format::ISO8601->parse_datetime( $a->{date} )
@$posts = sort {
DateTime::Format::ISO8601->parse_datetime($b->{date}) <=>
DateTime::Format::ISO8601->parse_datetime($a->{date})
} @$posts;
$cache_all_post_categories->{$category_name} = $posts;
return $self->shufflePostsIfRequired( $category, $posts );
}
sub comparePinned ( $self, $a, $b ) {
my $cmp = $b->{pinned} <=> $a->{pinned};
if ( $cmp != 0 ) {
return $cmp;
}
return int( rand(3) ) - 1;
}
sub shufflePostsIfRequired ( $self, $category, $posts ) {
my $pinned_posts = [
sort { $self->comparePinned( $a, $b ) }
grep { defined $_->{pinned} } @$posts
];
$posts = [ grep { !exists $_->{pinned} } @$posts ];
if ( exists $category->{random} && $category->{random} ) {
require List::AllUtils;
$posts = [ List::AllUtils::shuffle @$posts ];
}
return [ @$pinned_posts, @$posts ];
return $posts;
}
sub RetrieveDirectPostsForCategory ( $self, $category_name ) {
@ -223,19 +179,18 @@ sub RetrieveDirectPostsForCategory ( $self, $category_name ) {
}
my $posts = $post_by_category->{$category_name};
$posts //= [];
return $self->shufflePostsIfRequired( $category, [@$posts] );
return [@$posts];
}
sub PreviewOg ( $self, $post, $isWhatsApp ) {
my $title = $post->{title};
my $content = $post->{content};
my $image_file = $post->{image};
my $image_bottom_preview = $post->{image_bottom_preview};
if ($isWhatsApp) {
return BurguillosInfo::Preview->WhatsappAlternativeGenerate( $title,
$content, $image_file, $image_bottom_preview );
}
return BurguillosInfo::Preview->Generate( $title, $content, $image_file,
$image_bottom_preview );
sub PreviewOg {
my $self = shift;
my $post = shift;
my $title = $post->{title};
my $content = $post->{content};
my $image_file = $post->{image};
return BurguillosInfo::Preview->Generate($title, $content, $image_file);
}
1;

View File

@ -13,57 +13,31 @@ use Path::Tiny;
use Const::Fast;
use Capture::Tiny qw/capture/;
use MIME::Base64;
use Digest::SHA qw/sha512_hex/;
use Encode;
const my $CURRENT_FILE => __FILE__;
const my $ROOT_PROJECT => path($CURRENT_FILE)->parent->parent->parent;
const my $PUBLIC_DIR => $ROOT_PROJECT->child('public');
const my $BURGUILLOS_LOGO => $PUBLIC_DIR->child('img/burguillos-new-logo.svg');
const my $SVG_WIDTH => 1200;
const my $SVG_HEIGHT => 630;
const my $SVG_EMBEDDED_IMAGE_MAX_WIDTH => 1200;
const my $SVG_EMBEDDED_IMAGE_MAX_HEIGHT => 400;
const my $SVG_HEIGHT => 627;
const my $SVG_EMBEDDED_IMAGE_MAX_WIDTH => 1000;
const my $SVG_EMBEDDED_IMAGE_MAX_HEIGHT => 200;
sub Generate (
$self, $title, $content,
$image_file = undef,
$image_bottom_preview = undef
)
{
my $sha512 = sha512_hex(Encode::encode('utf8', $title.$content.($image_file//'').($image_bottom_preview//'')));
my $cached_image = path("public/img/preview.$sha512.generated.png");
if (!-f $cached_image) {
my $dom = Mojo::DOM->new($content);
$content = $dom->all_text;
sub Generate($self, $title, $content, $image_file) {
my $dom = Mojo::DOM->new($content);
$content = $dom->all_text;
my $svg = $self->_GenerateSVGPreview(
$self->_DivideTextContentInLines($title, 62)->[0],
$self->_DivideTextContentInLines($content),
$image_file, $image_bottom_preview
);
$cached_image->spew_raw($self->_SVGToPNG($svg));
}
return $cached_image->slurp_raw;
my $svg =
$self->_GenerateSVGPreview( $title, $self->_DivideTextContentInLines($content), $image_file );
return $self->_SVGToPNG($svg);
}
sub WhatsappAlternativeGenerate($self, $title, $content, $image_file = undef, $image_bottom_preview = undef) {
my $complete_png = $self->Generate($title, $content, $image_file, $image_bottom_preview);
my ( $stdout, $stderr ) = capture {
open my $fh, '|-', 'convert', '/dev/stdin', '-resize', "@{[$SVG_WIDTH/2]}x@{[$SVG_HEIGHT/2]}", 'png:fd:1';
binmode $fh, ':raw';
print $fh $complete_png;
close $fh;
};
say STDERR $stderr;
return $stdout;
}
sub _ToPng ( $self, $image ) {
if ( $image =~ /\.\w+$/ ) {
sub _ToPng($self, $image) {
if ($image =~ /\.\w+$/) {
my $new_image = $image =~ s/\.\w+$/.generated.png/r;
say $new_image;
if ( !-e $new_image ) {
if (!-e $new_image) {
system 'convert', '-background', 'none', "$image", "$new_image";
}
$image = $new_image;
@ -71,7 +45,7 @@ sub _ToPng ( $self, $image ) {
return path($image);
}
sub _GenerateSVGPreviewHeaderBar ( $self, $svg, $group ) {
sub _GenerateSVGPreviewHeaderBar($self, $svg, $group) {
$group->rect(
x => 0,
y => 0,
@ -87,9 +61,10 @@ sub _GenerateSVGPreviewHeaderBar ( $self, $svg, $group ) {
style => { fill => '#F8F8FF' }
);
my $burguillos_logo_png = path( $self->_ToPng($BURGUILLOS_LOGO) );
my $burguillos_logo_png = path($self->_ToPng($BURGUILLOS_LOGO));
say $burguillos_logo_png;
say '' . $burguillos_logo_png;
say ''.$burguillos_logo_png;
$group->image(
x => 10,
y => 5,
@ -105,9 +80,7 @@ sub _GenerateSVGPreviewHeaderBar ( $self, $svg, $group ) {
)->cdata('Burguillos.info');
}
sub _GenerateSVGPreview ( $self, $title, $content, $image_file,
$image_bottom_preview )
{
sub _GenerateSVGPreview($self, $title, $content, $image_file) {
my @content = @$content;
my $svg = SVG->new( width => $SVG_WIDTH, height => $SVG_HEIGHT );
@ -119,40 +92,37 @@ sub _GenerateSVGPreview ( $self, $title, $content, $image_file,
}
);
$self->_GenerateSVGPreviewHeaderBar( $svg, $group );
$self->_GenerateSVGPreviewHeaderBar($svg, $group);
my $new_y;
if ( defined $image_file ) {
$new_y = $self->_AttachImageSVG( $svg, $group, $image_file,
$image_bottom_preview );
$new_y = $self->_AttachImageSVG( $group, $image_file );
}
$new_y //= 100;
$group->text(
x => 10,
y => $new_y,
style => { 'font-size' => 42 }
style => { 'font-size' => 50 }
)->cdata($title);
my $n = 0;
for my $line (@content) {
next if $line =~ /^\s*$/;
$group->text(
x => 10,
y => $new_y + 40 + ( 30 * $n ),
style => { 'font-size' => 32 }
style => { 'font-size' => 38 }
)->cdata($line);
$n++;
last if $n > 2;
}
return $svg->xmlify;
}
sub _SVGToPNG ( $self, $svg ) {
sub _SVGToPNG($self, $svg) {
my ( $stdout, $stderr ) = capture {
open my $fh, '|-', qw{convert /dev/stdin png:fd:1};
binmode $fh, ':utf8';
binmode $fh, 'utf8';
print $fh $svg;
close $fh;
};
@ -160,10 +130,10 @@ sub _SVGToPNG ( $self, $svg ) {
return $stdout;
}
sub _DivideTextContentInLines ( $self, $content, $n_chars_per_line = 79 ) {
$content =~ s/(\s)\s+/$1/g;
sub _DivideTextContentInLines($self, $content) {
my @content_divided_in_lines = split /\n/, $content;
my @new_content;
my $n_chars_per_line = 70;
for my $line (@content_divided_in_lines) {
if ( length($line) <= $n_chars_per_line ) {
@ -183,11 +153,9 @@ sub _DivideTextContentInLines ( $self, $content, $n_chars_per_line = 79 ) {
}
return \@new_content;
}
sub _AttachImageSVG ( $self, $svg, $group, $image_file, $image_bottom_preview )
{
sub _AttachImageSVG($self, $svg, $image_file) {
$image_file = $PUBLIC_DIR->child( './' . $image_file );
$image_file = path( $self->_ToPng($image_file) );
$image_file = path($self->_ToPng($image_file));
my ( $stdout, $stderr, $error ) = capture {
system qw/identify -format "%wx%h"/, $image_file;
};
@ -196,10 +164,6 @@ sub _AttachImageSVG ( $self, $svg, $group, $image_file, $image_bottom_preview )
return;
}
my ( $width, $height ) = $stdout =~ /^"(\d+)x(\d+)"$/;
$height = int( $height * 1200 / $width );
$width = 1200;
my $height_complete_image = ( 1200 / $width ) * $height;
if ( $height > $SVG_EMBEDDED_IMAGE_MAX_HEIGHT ) {
$width /= $height / $SVG_EMBEDDED_IMAGE_MAX_HEIGHT;
$width = int($width);
@ -212,36 +176,18 @@ sub _AttachImageSVG ( $self, $svg, $group, $image_file, $image_bottom_preview )
$width = $SVG_EMBEDDED_IMAGE_MAX_WIDTH;
}
my $defs = $svg->defs();
my $clip_path = $defs->clipPath( id => 'cut-top' );
$clip_path->rect( x => 0, y => 50, width => 1200, height => $height );
my $x = 0;
my $y_image = 50 - $height_complete_image + $height;
if ( defined $image_bottom_preview
&& $height_complete_image > $SVG_EMBEDDED_IMAGE_MAX_HEIGHT )
{
$y_image += $height_complete_image - $image_bottom_preview;
}
my $y = 50;
my $x = int( ( $SVG_WIDTH / 2 ) - ( $width / 2 ) );
my $y = 90;
my ($output) = capture {
system qw/file --mime-type/, $image_file;
};
my ($format) = $output =~ /(\S+)$/;
$group->image(
x => 0,
y => $y_image,
width => $SVG_WIDTH,
height => $height_complete_image,
-href => "data:$format;base64," . encode_base64( $image_file->slurp ),
'clip-path' => 'url(#cut-top)',
);
$group->rect(
x => 0,
y => $y + $height,
width => $SVG_WIDTH,
height => $SVG_HEIGHT,
style => { fill => 'azure' },
$svg->image(
x => $x,
y => $y,
width => $width,
height => $height,
-href => "data:$format;base64," . encode_base64( $image_file->slurp )
);
return $y + $height + 50;
}

View File

@ -10,22 +10,17 @@
"author": "",
"license": "AGPL-v3",
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"eslint": "^8.53.0",
"eslint-config-prettier": "^9.0.0",
"@typescript-eslint/eslint-plugin": "^5.59.2",
"@typescript-eslint/parser": "^5.59.2",
"eslint": "^8.40.0",
"eslint-plugin-no-relative-import-paths": "^1.5.2",
"husky": "^8.0.3",
"lint-staged": "^14.0.1",
"prettier": "^3.0.3",
"prettier-eslint": "^16.1.2",
"typescript": "^5.2.2",
"typescript": "^5.0.4",
"webpack-cli": "^5.1.4"
},
"dependencies": {
"babel-loader": "^9.1.3",
"ol": "^8.1.0",
"tablesort": "^5.3.0",
"ts-loader": "^9.5.0"
"tablesort": "^5.3.0"
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,5 @@
html {
height: 100%;
touch-action: none; }
height: 100%; }
body {
margin: 0;
@ -9,33 +8,6 @@ body {
min-height: 100%;
width: 100%;
height: 100%; }
body summary h2, body summary h3, body summary h4, body summary h5 {
display: inline; }
body converse-muc-sidebar {
display: none !important; }
body div.converse-container {
width: 100%;
height: 400px;
margin-left: 0px; }
body div.page-contents div.footer p.attribution {
font-size: 0.8em; }
body div.page-contents div.footer p.attribution a {
font-size: 0.8em; }
body span.round-center {
background: blueviolet;
color: #FEFEFA;
line-height: 100%;
aspect-ratio: 1 / 1;
display: inline-flex;
border-radius: 0.3em;
height: 0.7em;
font-size: 0.7em;
padding: 0.3em;
text-align: center;
justify-content: center;
align-items: center;
vertical-align: middle;
margin-bottom: 0.15em; }
body div.search-overlay {
overflow-y: scroll;
display: none;
@ -50,13 +22,6 @@ body {
display: flex; }
body div.search-overlay div.search-results {
margin: 7px; }
body div.search-overlay div.search-results img {
width: 75px; }
body div.search-overlay div.search-results div.search-result div.row-title-url-image {
display: flex;
flex-direction: row; }
body div.search-overlay div.search-results div.search-result div.row-title-url-image img {
margin: 10px; }
body div.search-overlay div.bounding-search-bar {
margin: 7px;
width: calc(100% - 20px);
@ -68,8 +33,6 @@ body {
height: 60px;
margin-left: 0px;
margin-right: 0px; }
body div.search-overlay div.bounding-search-bar a.up, body div.search-overlay div.bounding-search-bar a.down {
display: none; }
body div.search-overlay div.bounding-search-bar a.exit-search {
width: 60px;
background: whitesmoke;
@ -84,23 +47,18 @@ body {
margin-left: 10px;
margin-right: 10px;
display: flex; }
body div.search a.search-icon {
height: calc(100% - 40px);
align-self: center;
margin: 20px;
margin-left: 7px;
margin-right: 7px;
body div.search div.search-icon {
height: calc(100% - 28px);
display: flex;
background: aliceblue;
align-items: center;
margin: 7px;
padding: 7px;
border-radius: 10px;
border: solid gray 1px;
aspect-ratio: 1 / 1;
width: auto; }
body div.search a.search-icon img {
height: 80%;
aspect-ratio: 1 / 1; }
aspect-ratio: 1/1; }
body div.search div.search-icon img {
height: 80%; }
body div.search div.fake-text-box {
width: calc(100% - 60px);
display: flex;
@ -130,16 +88,10 @@ body {
body div.carousel {
position: fixed;
top: 80%;
height: 20%;
width: 100%; }
height: calc(20% - 6px);
width: calc(100% - 6px);
border: solid 3px black; }
body div.carousel a {
position: absolute;
top: 0;
border: solid 3px black;
width: calc(100% - 6px);
height: calc(100% - 6px);
left: 100%;
transition: left 1s ease-in;
font-size: 13px;
background: #f2eb8c;
color: blueviolet;
@ -147,18 +99,14 @@ body {
text-align: center;
justify-content: space-between;
align-items: center;
height: 100%;
text-decoration: none; }
body div.carousel a.show {
left: 0%; }
body div.carousel a.remove {
left: -100%; }
body div.carousel a:hover, body div.carousel a:focus {
background: blueviolet;
color: #f2eb8c; }
body div.carousel a p {
margin-bottom: 1px; }
body div.carousel a h4 {
margin: 0; }
body div.carousel div.promoted-tag, body div.carousel h3 {
margin: 0;
margin-right: 5px; }
body div.carousel img {
margin: 10px;
height: calc(100% - 20px);
@ -200,88 +148,33 @@ body {
display: none; }
body nav.desktop a {
vertical-align: middle; }
body nav.desktop a.search-icon {
width: 60px;
height: 60px;
display: flex;
align-items: center;
justify-content: center; }
body nav.desktop a.search-icon img {
background: aliceblue;
border-radius: 10px;
padding: 10%;
width: 60%;
height: 60%; }
body div.transparent-fullscreen-hide {
position: fixed;
background: black;
left: 0;
width: 100%;
opacity: 40%;
top: 80px;
height: calc(100% - 60px);
z-index: 250;
display: none; }
body div.transparent-fullscreen-hide.show {
display: block; }
body nav.mobile-foldable {
visibility: hidden;
position: fixed;
left: 100%;
width: Min(70%, 600px);
top: 80px;
height: calc(100% - 80px);
z-index: 500;
transition: left 0.5s ease-in, visibility 0.5s ease-in;
background: #FEFEFA; }
body nav.mobile-foldable > a:first-child {
margin-top: 30px; }
display: none;
background: blueviolet;
color: #f2eb8c; }
body nav.mobile-foldable a {
display: block;
font-size: 1.1em;
height: auto;
padding-left: auto;
padding-right: auto;
color: blueviolet;
background: #FEFEFA;
margin-top: 10px;
padding: 10px;
margin-left: 10px;
border-radius: 20px;
width: calc(100% - 20px - 20px - 2px); }
body nav.mobile-foldable div.child-categories-mobile {
margin-left: 80px;
width: calc(100% - 90px - 20px); }
body nav.mobile-foldable div.child-categories-mobile a {
display: list-item;
font-size: 1em; }
display: block; }
body nav.mobile-foldable.show {
left: 30%;
visibility: visible; }
display: block; }
body nav.mobile-shortcuts > a {
display: flex;
align-items: center;
justify-content: center; }
body nav.mobile-shortcuts > a.active {
background: #FEFEFA;
color: #dcdcf5; }
body nav.mobile-shortcuts > a.active:focus {
background: #f2eb8c; }
body a.menu-expand {
padding-bottom: 9px; }
body a.menu-expand .open-menu-icon-hover {
display: none; }
body a.menu-expand:hover .open-menu-icon-hover, body a.menu-expand:focus .open-menu-icon-hover, body a.menu-expand.active .open-menu-icon-hover {
body a.menu-expand:hover .open-menu-icon-hover, body a.menu-expand:focus .open-menu-icon-hover {
display: block; }
body a.menu-expand:hover .open-menu-icon, body a.menu-expand:focus .open-menu-icon, body a.menu-expand.active .open-menu-icon {
body a.menu-expand:hover .open-menu-icon, body a.menu-expand:focus .open-menu-icon {
display: none; }
body nav > a.menu-expand > img {
width: 40px;
height: 40px; }
width: 30px;
height: 30px; }
body nav > a > img.index-image-menu {
vertical-align: middle;
width: 60px;
height: 60px; }
width: 40px;
height: 40px; }
body nav > a > img.index-image-menu, body div.burguillos-logo-container > img {
transition-property: transform;
transition-duration: 2s;
@ -289,74 +182,30 @@ body {
body nav > a:hover > img.index-image-menu,
body div.burguillos-logo-container.active > img {
transform: rotate(-1.5707963268rad); }
body div.search-in-page {
display: none;
position: fixed;
top: 80px;
height: 60px;
width: 100%;
align-items: center;
background: blueviolet;
z-index: 3; }
body div.search-in-page a.up, body div.search-in-page a.down {
display: flex;
align-items: center;
justify-content: center;
height: calc(100% - 28px);
align-self: center;
margin: 7px;
display: flex;
background: aliceblue;
align-items: center;
padding: 7px;
border-radius: 10px;
border: solid gray 1px;
aspect-ratio: 1/1; }
body div.search-in-page a.up img, body div.search-in-page a.down img {
height: 80%; }
body div.search-in-page span {
color: whitesmoke;
font-size: 25px; }
body div.search-in-page.active {
display: flex; }
body nav.mobile-shortcuts {
position: fixed;
display: flex;
align-items: center;
width: 100%;
background: blueviolet;
height: 80px;
justify-content: start;
flex-direction: row;
height: 60px;
top: 0%; }
body nav.mobile-shortcuts a {
height: 100%;
width: 80px;
width: 16.6666666667%;
padding-left: 0;
padding-top: 0;
padding-right: 0;
padding-bottom: 0; }
body nav.mobile-shortcuts a.go-to-index {
position: absolute;
left: 0;
top: 0; }
body nav.mobile-shortcuts div.search {
position: absolute;
left: 80px;
top: 10%;
width: Min(calc(100% - 90px * 2), 500px);
width: calc(100% * 4 / 6 - 20px);
height: 80%;
border-radius: 10px; }
body nav.mobile-shortcuts a.menu-expand {
position: absolute;
left: Min(calc(100% - 80px), 600px);
top: 0;
align-self: end; }
body div.page-contents {
background: #FEFEFA;
position: fixed;
top: 80px;
height: calc(80% - 80px);
top: 60px;
height: calc(80% - 60px);
width: 100%;
overflow-y: scroll; }
body div.page-contents div.child-categories-mobile a {
@ -373,11 +222,6 @@ body {
border-collapse: collapse;
width: 100%;
table-layout: fixed; }
body div.page-contents table tr:hover {
background: blueviolet;
color: #f2eb8c; }
body div.page-contents table tr:hover th, body div.page-contents table tr:hover td {
border: 3px solid #f2eb8c; }
body div.page-contents table td, body div.page-contents table th {
font-size: 12px; }
body div.page-contents th, body div.page-contents td {
@ -398,13 +242,7 @@ body {
body div.page-contents div.description div.articles {
display: flex;
flex-direction: row;
flex-wrap: wrap;
font-size: 0.7rem; }
body div.page-contents div.description div.articles a {
width: 45%;
margin-left: 5%; }
body div.page-contents div.description div.articles a:nth-child(2n+1) {
margin-left: 0%; }
flex-wrap: wrap; }
body div.page-contents div.description div.articles div.image-container {
margin-left: 2.5%;
margin-top: 10px;
@ -418,9 +256,11 @@ body {
background: white;
max-height: 100%;
max-width: 100%;
min-width: 277px;
border: solid 1px black; }
body div.page-contents div.description div.articles a {
min-height: 90%;
width: 100%;
display: block;
text-decoration: none;
text-overflow: ellipsis;
@ -434,11 +274,14 @@ body {
height: 90%;
padding: 5%;
padding-top: 1%;
background: #f2eb8c;
color: blueviolet;
box-shadow: 8px 8px 1px 0px #8ddfd6;
border: 3px solid black; }
body div.page-contents div.description div.articles a article p, body div.page-contents div.description div.articles a article h4, body div.page-contents div.description div.articles a article h3, body div.page-contents div.description div.articles a article h2 {
margin: 0px; }
body div.page-contents div.description div.articles a article p {
font-size: 0.9rem; }
body div.page-contents div.description div.articles a article div.article-up-part {
height: 12em; }
body div.page-contents div.description div.articles a article div.article-down-part {
@ -516,67 +359,45 @@ body {
body div.page-contents table th, body div.page-contents table td {
font-size: 20px; } }
@media (min-width: 768px) {
body converse-muc-sidebar {
display: flex !important; }
body converse-muc-sidebar.hidden {
display: none !important; }
body div.converse-container {
margin-left: 15px; } }
@media (min-width: 694px) {
body div.carousel a {
font-size: 20px; }
body div.carousel h3 {
font-size: 25px; }
body div.page-contents div.description div.articles a {
width: 45%;
margin-left: 5%; }
body div.page-contents div.description div.articles a:nth-child(2n+1) {
margin-left: 0%; }
body div.page-contents img {
max-width: 694px; } }
@media (min-width: 700px) {
body nav.mobile-foldable {
left: -100%; }
body nav.mobile-foldable.show {
left: 0; } }
@media (min-width: 1333px) {
body div.page-contents div.description div.articles a {
width: 30%;
margin-left: 3%; }
body div.page-contents div.description div.articles a:nth-child(2n+1) {
margin-left: 3%; }
body div.page-contents div.description div.articles a:nth-child(3n+1) {
margin-left: 0%; } }
@media (min-width: 848px) {
body div.page-contents div.description div.articles a {
width: 30%;
margin-left: 3%; }
body div.page-contents div.description div.articles a:nth-child(2n+1) {
margin-left: 3%; }
body div.page-contents div.description div.articles a:nth-child(3n+1) {
margin-left: 0%; } }
@media (min-width: 1333px) {
body div.page-contents div.description div.articles a {
width: 22%;
margin-left: 3%; }
body div.page-contents div.description div.articles a:nth-child(3n+1) {
margin-left: 3%; }
body div.page-contents div.description div.articles a:nth-child(4n+1) {
margin-left: 0%; } }
@media (max-width: 200px) {
body {
font-size: 20px; } }
@media (max-height: 400px) {
body div.carousel {
height: 120px;
top: calc(100% - 120px); }
@media (min-width: 1100px) {
body nav.mobile-shortcuts {
display: none; }
body div.page-contents {
height: calc(100% - 60px - 120px); } }
top: 0%;
left: 5%;
height: 80%;
width: 90%;
border: solid 1px black; }
body div.page-contents nav.mobile-foldable, body div.page-contents nav.mobile-foldable.show {
display: none; }
body div.page-contents div.description {
margin-left: 10%;
margin-right: 10%; }
body div.page-contents nav.desktop {
display: block;
height: auto;
height: 60px; }
body div.page-contents nav.desktop a {
display: table-cell;
height: 60px; }
body div.page-contents nav.desktop a img.index-image-menu {
height: 40px;
width: 40px; }
body div.page-contents.no-carousel {
height: 100%; } }
@media (min-width: 1333px) {
body div.page-contents div.description div.articles a {
width: 30%;
margin-left: 3%; }
body div.page-contents div.description div.articles a:nth-child(2n+1) {
margin-left: 3%; }
body div.page-contents div.description div.articles a:nth-child(3n+1) {
margin-left: 0%; } }

View File

@ -8,52 +8,12 @@ $background-secondary: #635283;
$color-secondary: #8eea6d;
$accent-secondary: #fde68f;
$primary-secondary: #590e11;
$background_sidebar: $background-page; //#F5F5DC;
$color_sidebar: #dcdcf5;
$attribution_font_size: 0.8em;
html {
height: 100%;
touch-action: none;
}
body {
summary {
h2, h3, h4, h5 {
display: inline;
}
}
converse-muc-sidebar {
display: none !important;
}
div.converse-container {
width: 100%;
height: 400px;
margin-left: 0px;
}
div.page-contents div.footer p.attribution {
font-size: $attribution_font_size;
a {
font-size: $attribution_font_size;
}
}
span.round-center {
background: $background_div;
color: $background_sidebar;
line-height: 100%;
aspect-ratio: 1 / 1;
display: inline-flex;
border-radius: 0.3em;
height: 0.7em;
font-size: 0.7em;
padding: 0.3em;
text-align: center;
justify-content: center;
align-items: center;
vertical-align: middle;
margin-bottom: 0.15em;
}
div.search-overlay {
overflow-y: scroll;
display: none;
@ -64,106 +24,70 @@ body {
z-index: 3;
top: 0;
flex-direction: column;
&.active {
display: flex;
display: flex;
}
div.search-results {
margin: 7px;
img {
width: 75px;
}
div.search-result {
div.row-title-url-image {
display: flex;
flex-direction: row;
img {
margin: 10px;
}
}
}
margin: 7px;
}
div.bounding-search-bar {
margin: 7px;
width: calc(100% - 20px);
border-radius: 10px;
height: 60px;
display: flex;
div.search {
width: calc(100% - 60px);
height: 60px;
margin-left: 0px;
margin-right: 0px;
}
a.up, a.down {
display: none;
}
a.exit-search {
width: 60px;
background: whitesmoke;
margin: 7px;
width: calc(100% - 20px);
border-radius: 10px;
height: 60px;
display: flex;
justify-content: center;
align-items: center;
img {
width: 60%;
div.search {
width: calc(100% - 60px);
height: 60px;
margin-left: 0px;
margin-right: 0px;
}
a.exit-search {
width: 60px;
background: whitesmoke;
height: 60px;
display: flex;
justify-content: center;
align-items: center;
img {
width: 60%;
}
}
}
}
}
div.search {
background: whitesmoke;
margin-left: 10px;
margin-right: 10px;
display: flex;
a.search-icon {
height: calc(100% - 40px);
align-self: center;
margin: 20px;
margin-left: 7px;
margin-right: 7px;
display: flex;
background: aliceblue;
align-items: center;
padding: 7px;
border-radius: 10px;
border: solid gray 1px;
aspect-ratio: 1 / 1;
width: auto;
img {
height: 80%;
aspect-ratio: 1 / 1;
}
div.search-icon {
height: calc(100% - 28px);
display: flex;
background: aliceblue;
align-items: center;
margin: 7px;
padding: 7px;
border-radius: 10px;
border: solid gray 1px;
aspect-ratio: 1/1;
img {
height: 80%;
}
}
div.fake-text-box {
width: calc(100% - 60px);
display: flex;
align-items: center;
input[type="text"] {
font-size: 30px;
width: 100%;
height: 70%;
background: none;
border: none;
outline: none;
}
width: calc(100% - 60px);
display: flex;
align-items: center;
input[type="text"] {
font-size: 30px;
width: 100%;
height: 70%;
background: none;
border: none;
outline: none;
}
}
}
p, h1, h2, h3, h4, a {
font-family: 'arial';
}
@ -196,24 +120,11 @@ body {
div.carousel {
position: fixed;
top: 80%;
height: 20%;
width: 100%;
height: calc(20% - 6px);
width: calc(100% - 6px);
border: solid 3px black;
a {
position: absolute;
top: 0;
border: solid 3px black;
width: calc(100% - 6px);
height: calc(100% - 6px);
left: 100%;
transition: left 1s ease-in;
&.show {
left: 0%;
}
&.remove {
left: -100%;
}
font-size: 13px;
background: $color_div;
color: $background_div;
@ -221,18 +132,18 @@ body {
text-align: center;
justify-content: space-between;
align-items: center;
height: 100%;
text-decoration: none;
&:hover, &:focus {
background: $background_div;
color: $color_div;
}
p {
margin-bottom: 1px;
}
h4 {
margin: 0;
}
}
div.promoted-tag, h3 {
margin: 0;
margin-right: 5px;
}
img {
@ -276,8 +187,8 @@ body {
text-decoration: none;
color: $color_div;
margin: 0;
background: $background_div;
background: $background_div;
&:hover, &:focus {
background: $color_div;
color: $background_div;
@ -297,99 +208,28 @@ body {
a {
vertical-align: middle;
}
a.search-icon {
width: 60px;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
img {
background: aliceblue;
border-radius: 10px;
padding: 10%;
width: 60%;
height: 60%;
}
}
}
div.transparent-fullscreen-hide {
position: fixed;
background: black;
left: 0;
width: 100%;
opacity: 40%;
top: 80px;
height: calc(100% - 60px);
z-index: 250;
display: none;
&.show {
display: block;
}
}
nav.mobile-foldable {
visibility: hidden;
position: fixed;
left: 100%;
width: Min(70%, 600px);
top: 80px;
height: calc(100% - 80px);
z-index: 500;
transition: left 0.5s ease-in, visibility 0.5s ease-in;
background: $background_sidebar;
& > a:first-child {
margin-top: 30px;
}
display: none;
background: $background_div;
color: $color_div;
a {
//background: $color_div;
//color: $background_div;
display: block;
font-size: 1.1em;
height: auto;
padding-left: auto;
padding-right: auto;
color: $background_div;
// border: 1px solid black;
background: $background_sidebar;
margin-top: 10px;
padding: 10px;
margin-left: 10px;
border-radius: 20px;
width: calc(100% - 20px - 20px - 2px);
}
div.child-categories-mobile {
margin-left: 80px;
width: calc(100% - 90px - 20px);
a {
display: list-item;
font-size: 1em;
}
}
}
nav.mobile-foldable.show {
left: 30%;
visibility: visible;
display: block;
}
nav.mobile-shortcuts > a {
display: flex;
align-items: center;
justify-content: center;
&.active {
background: $background_sidebar;
color: $color_sidebar;
&:focus {
background: $color_div;
}
}
}
a.menu-expand {
@ -399,7 +239,7 @@ body {
display: none;
}
&:hover, &:focus, &.active {
&:hover, &:focus {
.open-menu-icon-hover {
display: block;
}
@ -411,14 +251,14 @@ body {
}
nav > a.menu-expand > img {
width: 40px;
height: 40px;
width: 30px;
height: 30px;
}
nav > a > img.index-image-menu {
vertical-align: middle;
width: 60px;
height: 60px;
width: 40px;
height: 40px;
}
nav > a > img.index-image-menu, div.burguillos-logo-container > img {
@ -432,94 +272,36 @@ body {
transform: rotate(-1.5707963268rad);
}
div.search-in-page {
display: none;
position: fixed;
top: 80px;
height: 60px;
width: 100%;
align-items: center;
background: $background_div;
z-index: 3;
a.up, a.down {
display: flex;
align-items: center;
justify-content: center;
height: calc(100% - 28px);
align-self: center;
margin: 7px;
display: flex;
background: aliceblue;
align-items: center;
padding: 7px;
border-radius: 10px;
border: solid gray 1px;
aspect-ratio: 1/1;
img {
height: 80%;
}
}
span {
color: whitesmoke;
font-size: 25px;
}
&.active {
display: flex;
}
}
nav.mobile-shortcuts {
position: fixed;
display: flex;
align-items: center;
width: 100%;
background: $background_div;
height: 80px;
justify-content: start;
flex-direction: row;
height: 60px;
top: 0%;
a {
height: 100%;
width: 80px;
width: (100% / 6);
padding-left: 0;
padding-top: 0;
padding-right: 0;
padding-bottom: 0;
}
a.go-to-index {
position: absolute;
left: 0;
top: 0;
}
div.search {
position: absolute;
left: 80px;
top: 10%;
width: Min(calc(100% - 90px * 2), 500px);
width: calc(100% * 4 / 6 - 20px);
height: 80%;
border-radius: 10px;
}
a.menu-expand {
position: absolute;
left: Min(calc(100% - 80px), 600px);
top: 0;
align-self: end;
}
}
div.page-contents {
background: $background-page;
position: fixed;
top: 80px;
height: calc(80% - 80px);
top: 60px;
height: calc(80% - 60px);
width: 100%;
overflow-y: scroll;
@ -541,15 +323,6 @@ body {
border-collapse: collapse;
width: 100%;
tr:hover {
background: $background_div;
color: $color_div;
th, td {
border: 3px solid $color_div;
}
}
td, th {
font-size: 12px;
}
@ -586,15 +359,6 @@ body {
display: flex;
flex-direction: row;
flex-wrap: wrap;
font-size: 0.7rem;
a {
&:nth-child(2n+1) {
margin-left: 0%;
}
width: 45%;
margin-left: 5%;
}
div.image-container {
margin-left: 2.5%;
@ -610,12 +374,14 @@ body {
background: white;
max-height: 100%;
max-width: 100%;
min-width: 277px;
border: solid 1px black;
}
}
a {
min-height: 90%;
width: 100%;
display: block;
text-decoration: none;
text-overflow: ellipsis;
@ -638,6 +404,10 @@ body {
margin: 0px;
}
p {
font-size: 0.9rem;
}
div.article-up-part {
height: 12em;
}
@ -652,6 +422,7 @@ body {
padding: 5%;
padding-top: 1%;
background: $color_div;
color: $background_div;
box-shadow: 8px 8px 1px 0px #8ddfd6;
border: 3px solid black;
@ -775,32 +546,9 @@ body {
}
}
}
@media (min-width: 768px) {
body {
converse-muc-sidebar {
display: flex !important;
&.hidden {
display: none !important;
}
}
div.converse-container {
margin-left: 15px;
}
}
}
@media (min-width: 694px) {
body {
div.carousel {
a {
font-size: 20px;
}
h3 {
font-size: 25px;
}
}
div.page-contents {
div.description {
div.articles {
@ -814,22 +562,52 @@ body {
}
}
}
img {
max-width: 694px;
}
}
}
}
@media (min-width: 700px) {
@media (min-width: 1100px) {
body {
nav.mobile-foldable {
left: -100%;
nav.mobile-shortcuts {
display: none;
}
div.page-contents {
nav.mobile-foldable, nav.mobile-foldable.show {
display: none;
}
nav.mobile-foldable.show {
left: 0;
div.description {
margin-left: 10%;
margin-right: 10%;
}
nav.desktop {
display: block;
height: auto;
height: 60px;
a {
display: table-cell;
height: 60px;
img.index-image-menu {
height: 40px;
width: 40px;
}
}
}
top: 0%;
left: 5%;
height: 80%;
width: 90%;
border: solid 1px black;
}
div.page-contents.no-carousel {
height: 100%;
}
}
}
@ -855,67 +633,3 @@ body {
}
}
}
@media (min-width: 848px) {
body {
div.page-contents {
div.description {
div.articles {
a {
&:nth-child(2n+1) {
margin-left: 3%;
}
&:nth-child(3n+1) {
margin-left: 0%;
}
width: 30%;
margin-left: 3%;
}
}
}
}
}
}
@media (min-width: 1333px) {
body {
div.page-contents {
div.description {
div.articles {
a {
&:nth-child(3n+1) {
margin-left: 3%;
}
&:nth-child(4n+1) {
margin-left: 0%;
}
width: 22%;
margin-left: 3%;
}
}
}
}
}
}
@media (max-width: 200px) {
body {
font-size: 20px;
}
}
@media (max-height: 400px) {
body {
div.carousel {
height: 120px;
top: calc(100% - 120px);
}
div.page-contents {
height: calc(100% - 60px - 120px);
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

79316
public/dist/converse.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,371 +0,0 @@
/*!
MIT License
Copyright (c) 2018 Arturas Molcanovas <a.molcanovas@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/*!
localForage -- Offline Storage, Improved
Version 1.10.0
https://localforage.github.io/localForage
(c) 2013-2017 Mozilla, Apache License 2.0
*/
/*!
* Sizzle CSS Selector Engine v2.3.6
* https://sizzlejs.com/
*
* Copyright JS Foundation and other contributors
* Released under the MIT license
* https://js.foundation/
*
* Date: 2021-02-16
*/
/*!
* URI.js - Mutating URLs
*
* Version: 1.19.11
*
* Author: Rodney Rehm
* Web: http://medialize.github.io/URI.js/
*
* Licensed under
* MIT License http://www.opensource.org/licenses/mit-license
*
*/
/*!
* URI.js - Mutating URLs
* IPv6 Support
*
* Version: 1.19.11
*
* Author: Rodney Rehm
* Web: http://medialize.github.io/URI.js/
*
* Licensed under
* MIT License http://www.opensource.org/licenses/mit-license
*
*/
/*!
* URI.js - Mutating URLs
* Second Level Domain (SLD) Support
*
* Version: 1.19.11
*
* Author: Rodney Rehm
* Web: http://medialize.github.io/URI.js/
*
* Licensed under
* MIT License http://www.opensource.org/licenses/mit-license
*
*/
/*!
2020 Jason Mulligan <jason.mulligan@avoidwork.com>
@version 7.0.0
*/
/*!
MIT License
Copyright (c) 2018 Arturas Molcanovas <a.molcanovas@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/*! @license DOMPurify 2.3.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.6/LICENSE */
/*! https://mths.be/punycode v1.4.0 by @mathias */
/**
* @copyright 2022, the Converse.js contributors
* @license Mozilla Public License (MPLv2)
* @description This is the form utilities module.
*/
/**
* @copyright 2022, the Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
/**
* @copyright Alfredo Medrano Sánchez and the Converse.js contributors
* @description
* Component inspired by the one from fa-icons
* https://github.com/obsidiansoft-io/fa-icons/blob/master/LICENSE
* @license Mozilla Public License (MPLv2)
*/
/**
* @copyright JC Brand
* @license Mozilla Public License (MPLv2)
* @description A plugin which restricts Converse to only one chat.
*/
/**
* @copyright Shachaf Ben-Kiki and the Converse.js contributors
* @description
* Started as a fork of Shachaf Ben-Kiki's jsgif library
* https://github.com/shachaf/jsgif
* @license MIT License
*/
/**
* @copyright The Converse.js contributors
* @license Mozilla Public License (MPLv2)
* @description Converse.js plugin which add support for XEP-0206: XMPP Over BOSH
*/
/**
* @copyright The Converse.js contributors
* @license Mozilla Public License (MPLv2)
* @description Converse.js plugin which adds support for XEP-0198: Stream Management
*/
/**
* @copyright The Converse.js contributors
* @license Mozilla Public License (MPLv2)
* @description This is the core utilities module.
*/
/**
* @copyright The Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
/**
* @description
* Converse.js plugin which shows a list of currently open
* rooms in the "Rooms Panel" of the ControlBox.
* @copyright 2022, the Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
/**
* @description
* Converse.js plugin which add support for registering
* an "App Server" as defined in XEP-0357
* @copyright 2021, the Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
/**
* @description
* Converse.js plugin which adds views for bookmarks specified in XEP-0048.
* @copyright 2022, the Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
/**
* @description Converse.js (A browser based XMPP chat client)
* @copyright 2021, The Converse developers
* @license Mozilla Public License (MPLv2)
*/
/**
* @description Converse.js plugin which adds views for XEP-0048 bookmarks
* @copyright 2022, the Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
/**
* @description UI code XEP-0313 Message Archive Management
* @copyright 2021, the Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
/**
* @description XEP-0313 Message Archive Management
* @copyright 2022, the Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
/**
* @license
* Copyright 2017 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @license
* Copyright 2020 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @license MIT or GPL-2.0
* @fileOverview Favico animations
* @author Miroslav Magda, http://blog.ejci.net
* @source: https://github.com/ejci/favico.js
* @version 0.3.10
*/
/**
* @module converse-carbons
* @copyright The Converse.js contributors
* @license Mozilla Public License (MPLv2)
* @description Implements support for XEP-0280 Message Carbons
*/
/**
* @module converse-chatboxviews
* @copyright 2022, the Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
/**
* @module converse-dragresize
* @copyright 2022, the Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
/**
* @module converse-emoji
* @copyright 2022, the Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
/**
* @module converse-fullscreen
* @license Mozilla Public License (MPLv2)
* @copyright 2022, the Converse.js contributors
*/
/**
* @module converse-headlines-view
* @copyright 2022, the Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
/**
* @module converse-minimize
* @copyright 2022, the Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
/**
* @module converse-notification
* @copyright 2022, the Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
/**
* @module converse-pubsub
* @copyright The Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
/**
* @module converse-register
* @description
* This is a Converse.js plugin which add support for in-band registration
* as specified in XEP-0077.
* @copyright 2022, the Converse.js contributors
* @license Mozilla Public License (MPLv2)
*/
/**
* @module converse-rsm
* @copyright The Converse.js contributors
* @license Mozilla Public License (MPLv2)
* @description XEP-0059 Result Set Management
* Some code taken from the Strophe RSM plugin, licensed under the MIT License
* Copyright 2006-2017 Strophe (https://github.com/strophe/strophejs)
*/
/**
* @module i18n
* @copyright 2022, the Converse.js contributors
* @license Mozilla Public License (MPLv2)
* @description This is the internationalization module
*/
/**
* @preserve jed.js https://github.com/SlexAxton/Jed
*/
/**
* Clears the specified timeout and interval.
* @method u#clearTimers
* @param {number} timeout - Id if the timeout to clear.
* @param {number} interval - Id of the interval to clear.
* @private
* @copyright Simen Bekkhus 2016
* @license MIT
*/
/**
* Creates a {@link Promise} that resolves if the passed in function returns a truthy value.
* Rejects if it throws or does not return truthy within the given max_wait.
* @method u#waitUntil
* @param {Function} func - The function called every check_delay,
* and the result of which is the resolved value of the promise.
* @param {number} [max_wait=300] - The time to wait before rejecting the promise.
* @param {number} [check_delay=3] - The time to wait before each invocation of {func}.
* @returns {Promise} A promise resolved with the value of func,
* or rejected with the exception thrown by it or it times out.
* @copyright Simen Bekkhus 2016
* @license MIT
*/
/*@cc_on!@*/

File diff suppressed because one or more lines are too long

11
public/dist/emojis.js vendored

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="192px" height="192px" viewBox="0 0 192 192" enable-background="new 0 0 192 192" xml:space="preserve"> <image id="image0" width="192" height="192" x="0" y="0"
href="data:image/png;base64,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" />
</svg>

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

View File

@ -1,310 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve"> <image id="image0" width="512" height="512" x="0" y="0"
href="data:image/png;base64,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" />
</svg>

Before

Width:  |  Height:  |  Size: 24 KiB

Some files were not shown because too many files have changed in this diff Show More