{"id":2639,"date":"2025-06-16T14:10:43","date_gmt":"2025-06-16T13:10:43","guid":{"rendered":"https:\/\/lifeforall-europe.org\/?page_id=2639"},"modified":"2026-08-30T13:12:34","modified_gmt":"2026-08-30T12:12:34","slug":"photo-gallery","status":"publish","type":"page","link":"https:\/\/lifeforall-europe.org\/es\/photo-gallery\/","title":{"rendered":"Galer\u00eda de fotos"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"2639\" class=\"elementor elementor-2639\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b704a17 e-flex e-con-boxed e-con e-parent\" data-id=\"b704a17\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-45cbe18 elementor-widget elementor-widget-heading\" data-id=\"45cbe18\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">pHOTO gALLERY<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-5608390 e-flex e-con-boxed e-con e-parent\" data-id=\"5608390\" data-element_type=\"container\" data-e-type=\"container\" id=\"events-section\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-d19da4a e-con-full event-buttons e-grid e-con e-child\" data-id=\"d19da4a\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t<a class=\"elementor-element elementor-element-b5d42c5 e-con-full event-btn e-transform e-flex elementor-invisible e-con e-child\" data-id=\"b5d42c5\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;,&quot;animation&quot;:&quot;fadeIn&quot;,&quot;_transform_scale_effect_hover&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:1.03,&quot;sizes&quot;:[]},&quot;_transform_scale_effect_hover_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_scale_effect_hover_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]}}\" data-folderid=\"1DbzGZiBn_KmsH87JIwarZ9uS1sW9sMW8\" href=\"#gallery-container\">\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-5b2e263 e-con-full event-btn e-transform e-flex elementor-invisible e-con e-child\" data-id=\"5b2e263\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;,&quot;animation&quot;:&quot;fadeIn&quot;,&quot;_transform_scale_effect_hover&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:1.03,&quot;sizes&quot;:[]},&quot;_transform_scale_effect_hover_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_scale_effect_hover_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]}}\" data-folderid=\"1lfFwf285p7pXh-raBYDkIJiSIPIWF7LQ\" href=\"#gallery-container\">\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-9924d95 e-con-full event-btn e-transform e-flex elementor-invisible e-con e-child\" data-id=\"9924d95\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;,&quot;animation&quot;:&quot;fadeIn&quot;,&quot;_transform_scale_effect_hover&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:1.03,&quot;sizes&quot;:[]},&quot;_transform_scale_effect_hover_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_scale_effect_hover_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]}}\" data-folderid=\"1Z1ZH9_rHF0IJnySePFsArnRNjLB0GfPg\" href=\"#gallery-container\">\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-4cc362e e-con-full event-btn e-transform e-flex elementor-invisible e-con e-child\" data-id=\"4cc362e\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;,&quot;animation&quot;:&quot;fadeIn&quot;,&quot;_transform_scale_effect_hover&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:1.03,&quot;sizes&quot;:[]},&quot;_transform_scale_effect_hover_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_scale_effect_hover_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]}}\" data-folderid=\"18E1pG-xsPMV6YSC7fA7Tt5qsKBuG7FO9\" href=\"#gallery-container\">\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-97e5f3f e-con-full event-btn e-transform e-flex elementor-invisible e-con e-child\" data-id=\"97e5f3f\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;,&quot;animation&quot;:&quot;fadeIn&quot;,&quot;_transform_scale_effect_hover&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:1.03,&quot;sizes&quot;:[]},&quot;_transform_scale_effect_hover_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_scale_effect_hover_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]}}\" data-folderid=\"1_sgI0VSZVnLO4qE9zAQ-WlkTWzEeCopy\" href=\"#gallery-container\">\n\t\t\t\t<\/a>\n\t\t<a class=\"elementor-element elementor-element-ea4367f e-con-full event-btn e-transform e-flex elementor-invisible e-con e-child\" data-id=\"ea4367f\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;,&quot;animation&quot;:&quot;fadeIn&quot;,&quot;_transform_scale_effect_hover&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:1.03,&quot;sizes&quot;:[]},&quot;_transform_scale_effect_hover_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_scale_effect_hover_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]}}\" data-folderid=\"1oEIdOaDjg7oe6ghc0izMHjS9sa3M1sto\" href=\"#gallery-container\">\n\t\t\t\t<\/a>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-8728860 e-flex e-con-boxed e-con e-parent\" data-id=\"8728860\" data-element_type=\"container\" data-e-type=\"container\" id=\"gallery-container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-38613a9 e-con-full e-flex e-con e-child\" data-id=\"38613a9\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4c4804d elementor-mobile-align-justify elementor-widget-mobile__width-inherit elementor-widget elementor-widget-button\" data-id=\"4c4804d\" data-element_type=\"widget\" data-e-type=\"widget\" id=\"look-in-drive-btn\" data-widget_type=\"button.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<div class=\"elementor-button-wrapper\">\n\t\t\t\t\t<a class=\"elementor-button elementor-size-sm\" role=\"button\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t<span class=\"elementor-button-icon\">\n\t\t\t\t<svg aria-hidden=\"true\" class=\"e-font-icon-svg e-fab-google-drive\" viewBox=\"0 0 512 512\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"><path d=\"M339 314.9L175.4 32h161.2l163.6 282.9H339zm-137.5 23.6L120.9 480h310.5L512 338.5H201.5zM154.1 67.4L0 338.5 80.6 480 237 208.8 154.1 67.4z\"><\/path><\/svg>\t\t\t<\/span>\n\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\">Look All in Drive<\/span>\n\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/a>\n\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3cbb8b3 elementor-widget elementor-widget-html\" data-id=\"3cbb8b3\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<head>\r\n  <link rel=\"stylesheet\" href=\"https:\/\/cdn.jsdelivr.net\/npm\/basiclightbox@5\/dist\/basicLightbox.min.css\">\r\n  <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/basiclightbox@5\/dist\/basicLightbox.min.js\"><\/script>\r\n<\/head>\r\n\r\n<div class=\"botones-interactivos\" id=\"botonesFiltro\">\r\n  <button class=\"boton-filter boton-3 active\" data-filter=\"all\">All<\/button>\r\n  <button class=\"boton-filter boton-1\" data-filter=\"images\">Images<\/button>\r\n  <button class=\"boton-filter boton-2\" data-filter=\"videos\">Videos<\/button>\r\n<\/div>\r\n\r\n<div id=\"gallery\" class=\"grid-gallery\" style=\"opacity: 0;\"><\/div>\r\n\r\n<div id=\"scrollSentinel\"><\/div>\r\n\r\n<div id=\"loadingMessage\"\r\n  style=\"text-align:center; font-weight: bold; padding: 1rem; display: none; color: #153240; font-size: 1.5rem;\">\r\n  Loading...\r\n<\/div>\r\n\r\n<button id=\"scrollTopBtn\" style=\"display:none;\">\r\n  <svg width=\"55\" height=\"25\" viewBox=\"0 0 24 10\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\">\r\n    <defs>\r\n      <filter id=\"shadow\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\r\n        <!-- Sombra m\u00e1s ligera -->\r\n        <feDropShadow dx=\"1\" dy=\"1\" stdDeviation=\"0.8\" flood-color=\"rgba(0,0,0,0.3)\" \/>\r\n      <\/filter>\r\n    <\/defs>\r\n\r\n    <path d=\"M1 8L12 1L23 8\" stroke=\"#ededed\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n      stroke-linejoin=\"round\" filter=\"url(#shadow)\" \/>\r\n  <\/svg>\r\n<\/button>\r\n\r\n\r\n\r\n<style>\r\n  * {\r\n    box-sizing: border-box;\r\n  }\r\n\r\n  #scrollSentinel {\r\n    height: 1px;\r\n  }\r\n\r\n  #scrollTopBtn {\r\n    position: fixed;\r\n    bottom: 5px;\r\n    \/* pegado al fondo inicialmente *\/\r\n    left: 50%;\r\n    transform: translateX(-50%);\r\n    z-index: 2;\r\n    border: none;\r\n    background: none;\r\n    box-shadow: none;\r\n    border-radius: 50%;\r\n    cursor: pointer;\r\n    font-size: 24px;\r\n    opacity: 0.55;\r\n    transition: bottom 0.3s ease, opacity 0.3s ease;\r\n  }\r\n\r\n  #scrollTopBtn:hover {\r\n    opacity: 1;\r\n  }\r\n\r\n  .botones-interactivos {\r\n    max-width: 700px;\r\n    margin: 0 auto 1rem;\r\n    display: flex;\r\n    justify-content: center;\r\n    gap: 12px;\r\n    transition: opacity 0.5s ease;\r\n    flex-wrap: none;\r\n  }\r\n\r\n  .botones-interactivos .boton-filter {\r\n    background-color: #153240;\r\n    font-family: 'Portico', sans-serif;\r\n    color: white;\r\n    border: none;\r\n    border-radius: 10px;\r\n    padding: 2.5% 20px;\r\n    text-align: center;\r\n    cursor: pointer;\r\n    transition: background-color 0.3s ease, color 0.3s ease, box-shadow 0.3s ease;\r\n    letter-spacing: 1.5px;\r\n    display: flex;\r\n    justify-content: center;\r\n    align-items: center;\r\n    min-width: 100px;\r\n    flex: 1;\r\n    max-width: 150px;\r\n    width: 100%;\r\n  }\r\n\r\n  .botones-interactivos .boton-filter.active {\r\n    background-color: #1e5068;\r\n    box-shadow: 0 0 8px rgba(21, 50, 64, 0.7);\r\n    color: white;\r\n  }\r\n\r\n  .botones-interactivos .boton-filter:hover {\r\n    background-color: #1e5068;\r\n    color: white;\r\n  }\r\n\r\n  .botones-interactivos .boton-filter.active:hover {\r\n    color: white !important;\r\n    background-color: #1e5068;\r\n    box-shadow: 0 0 10px rgba(21, 80, 104, 0.9);\r\n  }\r\n\r\n  .botones-interactivos .boton-filter:hover,\r\n  .botones-interactivos .boton-filter:focus {\r\n    outline: none !important;\r\n    box-shadow: none !important;\r\n    border: none !important;\r\n  }\r\n\r\n  .grid-gallery {\r\n    max-width: 1400px;\r\n    margin: 0 auto;\r\n    padding: 1rem;\r\n    display: grid;\r\n    grid-template-columns: repeat(4, 1fr);\r\n    grid-auto-rows: 240px;\r\n    gap: 10px;\r\n  }\r\n\r\n  .media-container {\r\n    height: auto;\r\n    border-radius: 5px;\r\n    overflow: hidden;\r\n    position: relative;\r\n    cursor: pointer;\r\n    transition: transform 0.3s ease, box-shadow 0.3s ease;\r\n  }\r\n\r\n  .media-container:hover {\r\n    transform: scale(1.03);\r\n    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\r\n  }\r\n\r\n  .media-container img {\r\n    width: 100%;\r\n    height: 100%;\r\n    object-fit: cover;\r\n    border-radius: 5px;\r\n  }\r\n\r\n  .media-container.vertical {\r\n    grid-row: span 2;\r\n  }\r\n\r\n  .media-container.horizontal {\r\n    grid-row: span 1;\r\n  }\r\n\r\n  .video-thumbnail {\r\n    width: 100%;\r\n    height: 100%;\r\n    object-fit: cover;\r\n    border-radius: 12px;\r\n  }\r\n\r\n  .play-icon {\r\n    position: absolute;\r\n    top: 50%;\r\n    left: 50%;\r\n    transform: translate(-50%, -50%);\r\n    width: 60px;\r\n    height: 60px;\r\n    opacity: 0.85;\r\n    pointer-events: none;\r\n  }\r\n\r\n  .lightbox-nav-arrow {\r\n    position: fixed;\r\n    top: 50%;\r\n    transform: translateY(-50%);\r\n    background-color: #153240;\r\n    border-radius: 50%;\r\n    width: 50px;\r\n    height: 50px;\r\n    cursor: pointer;\r\n    display: flex;\r\n    align-items: center;\r\n    justify-content: center;\r\n    color: white;\r\n    user-select: none;\r\n    z-index: 10001;\r\n    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);\r\n    transition: background-color 0.3s ease;\r\n    opacity: 0.85;\r\n  }\r\n\r\n  .lightbox-nav-arrow.disabled {\r\n    opacity: 0.4;\r\n    cursor: default;\r\n  }\r\n\r\n  .lightbox-nav-arrow:hover:not(.disabled) {\r\n    background-color: #1e5068;\r\n    opacity: 1;\r\n  }\r\n\r\n  .lightbox-nav-arrow.left {\r\n    left: -14%;\r\n  }\r\n\r\n  .lightbox-nav-arrow.right {\r\n    right: -14%;\r\n  }\r\n\r\n  .btn-drive,\r\n  .btn-close {\r\n    padding: 10px 20px;\r\n    border-radius: 8px;\r\n    font-size: 1em;\r\n    user-select: none;\r\n    border: 1px solid transparent;\r\n    color: white;\r\n    cursor: pointer;\r\n    transition: background-color 0.3s ease, border-color 0.3s ease;\r\n    display: inline-block;\r\n    text-decoration: none;\r\n    text-align: center;\r\n  }\r\n\r\n  .btn-drive {\r\n    background-color: #153240;\r\n    border-color: #1e4051;\r\n  }\r\n\r\n  .btn-drive:hover {\r\n    background-color: #1e5068;\r\n    border-color: #1e5068;\r\n    color: #fff;\r\n  }\r\n\r\n  .btn-close {\r\n    background-color: #a83232 !important;\r\n    border-color: #cc3333 !important;\r\n  }\r\n\r\n  .btn-close:hover {\r\n    background-color: #cc4444 !important;\r\n    border-color: #cc4444 !important;\r\n    color: #fff !important;\r\n  }\r\n\r\n\r\n  @media (max-width: 769px) {\r\n    .grid-gallery {\r\n      max-width: 100%;\r\n      grid-template-columns: repeat(2, 1fr);\r\n      grid-auto-rows: 130px;\r\n      padding: 0;\r\n      gap: 8px;\r\n    }\r\n\r\n    .lightbox-nav-arrow {\r\n      width: 35px;\r\n      height: 50px;\r\n      top: 50%;\r\n      transform: translateY(-50%);\r\n      background: none;\r\n      border-radius: none;\r\n      border: none;\r\n      box-shadow: none;\r\n    }\r\n\r\n    .lightbox-nav-arrow:hover:not(.disabled) {\r\n      background: none;\r\n    }\r\n\r\n    .lightbox-nav-arrow svg {\r\n      width: 35px;\r\n      height: 50px;\r\n      filter: drop-shadow(2px 2px 2px rgba(0, 0, 0, 0.5));\r\n    }\r\n\r\n    .lightbox-nav-arrow.left {\r\n      left: 2%;\r\n    }\r\n\r\n    .lightbox-nav-arrow:hover:not(.disabled) {\r\n      opacity: 0.5;\r\n    }\r\n\r\n    .lightbox-nav-arrow.right {\r\n      right: 2%;\r\n    }\r\n\r\n    .media-container img {\r\n      border-radius: 8px;\r\n    }\r\n\r\n    .media-container {\r\n      border-radius: 8px;\r\n    }\r\n\r\n  }\r\n<\/style>\r\n\r\n<script>\r\n  let folderId = null;\r\n  const apiKey = 'AIzaSyBsHHIoBwgH_zMk4l7R1a7_1S3iLvNh5X8';\r\n  const gallery = document.getElementById('gallery');\r\n  const filterButtons = document.querySelectorAll('.boton-filter');\r\n  const eventButtons = document.querySelectorAll('.event-btn');\r\n  const lookInDriveBtn = document.getElementById('look-in-drive-btn');\r\n\r\n\r\n\r\n  const allowedVideoMimeTypes = [\r\n    'video\/mp4',\r\n    'video\/quicktime',\r\n    'video\/webm',\r\n    'video\/avi',\r\n    'video\/mov',\r\n    'video\/x-matroska',\r\n  ];\r\n\r\n  gallery.style.opacity = 0;\r\n  gallery.style.display = 'none';\r\n\r\n  if (lookInDriveBtn) {\r\n    lookInDriveBtn.style.display = 'none';\r\n  }\r\n\r\n  filterButtons.forEach(btn => btn.style.display = 'none');\r\n\r\n  \/\/ Funci\u00f3n para mostrar filtros\r\n  function showFilters() {\r\n    filterButtons.forEach(btn => {\r\n      btn.style.display = 'inline-block';\r\n      btn.style.visibility = 'visible';\r\n      btn.style.opacity = '1';\r\n    });\r\n  }\r\n\r\n  let nextPageToken = null;\r\n  let isLoading = false;\r\n  let currentFilter = 'all';\r\n  let allImages = [];\r\n  let currentIndex = -1;\r\n  let lightboxInstance = null;\r\n\r\n  const getDriveImageLinkPermanent = (fileId, size = 800) => `https:\/\/lh3.googleusercontent.com\/d\/${fileId}=s${size}`;\r\n  const getDriveImagePage = (fileId) => `https:\/\/drive.google.com\/file\/d\/${fileId}\/view`;\r\n\r\n\r\n  function resetGallery() {\r\n    gallery.innerHTML = '';\r\n    allImages = [];\r\n    nextPageToken = null;\r\n    currentFilter = 'all';\r\n    gallery.style.opacity = 0;\r\n    gallery.style.display = 'none';\r\n\r\n    \/\/ Reset filtros visualmente\r\n    filterButtons.forEach(btn => btn.classList.remove('active'));\r\n    const allBtn = document.querySelector('button[data-filter=\"all\"]');\r\n    if (allBtn) allBtn.classList.add('active');\r\n  }\r\n\r\n  eventButtons.forEach(btn => {\r\n    btn.addEventListener('click', async () => {\r\n      const newFolderId = btn.dataset.folderid;\r\n      if (!newFolderId) return;\r\n\r\n      if (folderId === newFolderId) {\r\n        \/\/ Ya cargado ese folder, hacer nada o refrescar\r\n        return;\r\n      }\r\n\r\n      \/\/ Cambiar folderId y resetear\r\n      folderId = newFolderId;\r\n      resetGallery();\r\n\r\n      \/\/ Mostrar galer\u00eda y cargar im\u00e1genes\r\n      gallery.style.display = 'grid'; \/\/ o como prefieras para mostrar\r\n\r\n      \/\/ Actualiza bot\u00f3n de Drive\r\n      setDriveBtnUrl(folderId);\r\n\r\n      \/\/ Mostrar filtros \ud83d\udc47\r\n      showFilters();\r\n\r\n      \/\/ Cargar primer batch y renderizar\r\n      const files = await fetchMediaBatch();\r\n      await renderMedia(files);\r\n\r\n      \/\/ Aplicar filtro \"all\"\r\n      filterGallery('all');\r\n    });\r\n  });\r\n\r\n  \/\/ Funci\u00f3n para enlazar correctamente el bot\u00f3n de Drive\r\n  function setDriveBtnUrl(folderId) {\r\n    const btn = document.getElementById('look-in-drive-btn');\r\n    if (!btn || !folderId) return;\r\n\r\n    const url = `https:\/\/drive.google.com\/drive\/folders\/${folderId}`;\r\n\r\n    btn.style.display = 'inline-block';\r\n    btn.removeAttribute('disabled');\r\n    btn.style.cursor = 'pointer';\r\n\r\n    if (btn.tagName.toLowerCase() === 'a') {\r\n      btn.setAttribute('href', url);\r\n      btn.setAttribute('target', '_blank');\r\n      btn.setAttribute('rel', 'noopener noreferrer');\r\n      btn.onclick = null;\r\n      btn.onkeydown = null;\r\n    } else {\r\n      btn.setAttribute('role', 'link');\r\n      btn.setAttribute('tabindex', '0');\r\n      btn.dataset.url = url;\r\n      btn.onclick = () => window.open(url, '_blank', 'noopener,noreferrer');\r\n      btn.onkeydown = (e) => {\r\n        if (e.key === 'Enter' || e.key === ' ') {\r\n          e.preventDefault();\r\n          btn.click();\r\n        }\r\n      };\r\n    }\r\n  }\r\n\r\n  \/\/ Reset de la galer\u00eda\r\n  function resetGallery() {\r\n    gallery.innerHTML = '';\r\n    nextPageToken = null;\r\n    currentFilter = \"all\";\r\n    gallery.style.opacity = 0;\r\n    gallery.style.display = 'none';\r\n  }\r\n\r\n  async function fetchMediaBatch() {\r\n    if (isLoading || !folderId) return [];\r\n    isLoading = true;\r\n    try {\r\n      const url = new URL(\"https:\/\/www.googleapis.com\/drive\/v3\/files\");\r\n      url.searchParams.set(\"q\", `'${folderId}' in parents and (mimeType contains 'image\/' or mimeType contains 'video\/')`);\r\n      url.searchParams.set(\"fields\", \"nextPageToken, files(id,name,mimeType,thumbnailLink)\");\r\n      url.searchParams.set(\"pageSize\", \"32\");\r\n      url.searchParams.set(\"key\", apiKey);\r\n      if (nextPageToken) url.searchParams.set(\"pageToken\", nextPageToken);\r\n\r\n      const response = await fetch(url);\r\n      const data = await response.json();\r\n      nextPageToken = data.nextPageToken || null;\r\n      return data.files || [];\r\n    } catch (err) {\r\n      console.error('Drive error:', err);\r\n      return [];\r\n    } finally {\r\n      isLoading = false;\r\n    }\r\n  }\r\n\r\n\r\n  async function renderMedia(files) {\r\n    if (!files.length) return;\r\n    files.forEach(file => {\r\n      const isImage = file.mimeType.startsWith('image\/');\r\n      const isVideo = allowedVideoMimeTypes.includes(file.mimeType.toLowerCase());\r\n\r\n      if (!isImage && !isVideo) {\r\n        \/\/ Ignorar archivos que no sean ni imagen ni video v\u00e1lido\r\n        return;\r\n      }\r\n\r\n      const container = document.createElement('div');\r\n      container.className = 'media-container';\r\n      container.dataset.type = isImage ? 'images' : 'videos';\r\n      container.dataset.fileId = file.id;\r\n\r\n      if (isImage) {\r\n        const img = document.createElement('img');\r\n        img.src = getDriveImageLinkPermanent(file.id);\r\n        img.alt = file.name;\r\n        img.onload = () => {\r\n          const isVertical = img.naturalHeight > img.naturalWidth;\r\n          container.classList.add(isVertical ? 'vertical' : 'horizontal');\r\n        };\r\n        img.addEventListener('click', () => openLightboxById(file.id));\r\n        container.appendChild(img);\r\n        allImages.push({ id: file.id, name: file.name, container });\r\n      } else if (isVideo) {\r\n        const wrapper = document.createElement('a');\r\n        wrapper.href = getDriveImagePage(file.id);\r\n        wrapper.target = '_blank';\r\n        wrapper.className = 'video-wrapper';\r\n\r\n        const thumbnail = document.createElement('img');\r\n        thumbnail.src = file.thumbnailLink || getDriveImageLinkPermanent(file.id, 400);\r\n        thumbnail.alt = file.name;\r\n        thumbnail.className = 'video-thumbnail';\r\n\r\n        const playIcon = document.createElement('div');\r\n        playIcon.className = 'play-icon';\r\n        playIcon.innerHTML = `<svg viewBox=\"0 0 200 200\"><circle cx=\"100\" cy=\"100\" r=\"90\" fill=\"rgba(21, 50, 64, 0.7)\"\/><polygon points=\"80,60 140,100 80,140\" fill=\"white\"\/><\/svg>`;\r\n\r\n        wrapper.appendChild(thumbnail);\r\n        wrapper.appendChild(playIcon);\r\n        container.appendChild(wrapper);\r\n      }\r\n\r\n      gallery.appendChild(container);\r\n    });\r\n\r\n    gallery.style.opacity = 1;\r\n\r\n    \/\/ Ocultar bot\u00f3n videos si no hay videos visibles\r\n    const hasVideos = !!gallery.querySelector('.media-container[data-type=\"videos\"]');\r\n    const videoButton = document.querySelector('button[data-filter=\"videos\"]');\r\n    if (videoButton) videoButton.style.display = hasVideos ? 'flex' : 'none';\r\n  }\r\n\r\n\r\n  function filterGallery(type) {\r\n    currentFilter = type;\r\n    const items = gallery.querySelectorAll('.media-container');\r\n    items.forEach(item => {\r\n      item.style.display = (type === 'all' || item.dataset.type === type) ? 'block' : 'none';\r\n    });\r\n\r\n    \/\/ Detectar tipos presentes visibles en la galer\u00eda\r\n    const hasImages = !!gallery.querySelector('.media-container[data-type=\"images\"]');\r\n    const hasVideos = !!gallery.querySelector('.media-container[data-type=\"videos\"]');\r\n\r\n    \/\/ Controlar visibilidad bot\u00f3n \"videos\"\r\n    const videoButton = document.querySelector('button[data-filter=\"videos\"]');\r\n    if (videoButton) videoButton.style.display = hasVideos ? 'flex' : 'none';\r\n\r\n    \/\/ Controlar visibilidad bot\u00f3n \"all\"\r\n    const allButton = document.querySelector('button[data-filter=\"all\"]');\r\n    if (allButton) {\r\n      if ((hasImages && !hasVideos) || (!hasImages && hasVideos)) {\r\n        \/\/ Solo hay un tipo, ocultar \"all\"\r\n        allButton.style.display = 'none';\r\n        \/\/ Opcional: si el filtro actual es \"all\", cambiar al tipo que s\u00ed hay\r\n        if (currentFilter === 'all') {\r\n          const newFilter = hasImages ? 'images' : 'videos';\r\n          filterGallery(newFilter);\r\n          \/\/ Adem\u00e1s actualizar clases activas en botones\r\n          document.querySelectorAll('.boton-filter').forEach(btn => {\r\n            btn.classList.toggle('active', btn.dataset.filter === newFilter);\r\n          });\r\n        }\r\n      } else {\r\n        \/\/ Hay ambos tipos, mostrar \"all\"\r\n        allButton.style.display = 'flex';\r\n      }\r\n    }\r\n  }\r\n\r\n\r\n\r\n  filterButtons.forEach(button => {\r\n    button.addEventListener('click', () => {\r\n      if (button.classList.contains('active')) return;\r\n      filterButtons.forEach(btn => btn.classList.remove('active'));\r\n      button.classList.add('active');\r\n      filterGallery(button.dataset.filter);\r\n    });\r\n  });\r\n\r\n  function getVisibleImages() {\r\n    return allImages.filter(img => window.getComputedStyle(img.container).display !== 'none');\r\n  }\r\n\r\n  function openLightboxById(fileId) {\r\n    const visibleImages = getVisibleImages();\r\n    currentIndex = visibleImages.findIndex(img => img.id === fileId);\r\n    if (currentIndex === -1) return;\r\n    showLightboxImage(currentIndex, visibleImages);\r\n  }\r\n\r\n  async function showLightboxImage(index, visibleImages) {\r\n    if (index < 0) return;\r\n\r\n    if (index >= visibleImages.length) {\r\n      if (nextPageToken) {\r\n        const newFiles = await fetchMediaBatch();\r\n        await renderMedia(newFiles);\r\n        const newVisible = getVisibleImages();\r\n        if (newVisible.length > visibleImages.length) {\r\n          currentIndex = visibleImages.length;\r\n          showLightboxImage(currentIndex, newVisible);\r\n        }\r\n        return;\r\n      } else {\r\n        index = visibleImages.length - 1;\r\n        currentIndex = index;\r\n      }\r\n    }\r\n\r\n    const imgData = visibleImages[index];\r\n    if (!imgData) return;\r\n\r\n    const content = document.createElement('div');\r\n    content.style.position = 'relative';\r\n    content.style.textAlign = 'center';\r\n\r\n    \/\/ Loading\r\n    const loadingDiv = document.createElement('div');\r\n    loadingDiv.textContent = 'Loading...';\r\n    loadingDiv.style.cssText = `\r\n    font-weight: bold;\r\n    font-size: 1.5rem;\r\n    padding: 2rem;\r\n    color: white;\r\n  `;\r\n    content.appendChild(loadingDiv);\r\n\r\n    const img = document.createElement('img');\r\n    img.src = getDriveImageLinkPermanent(imgData.id, 1600);\r\n    img.alt = imgData.name;\r\n    img.style.maxWidth = '100%';\r\n    img.style.maxHeight = '85vh';\r\n    img.style.display = 'none';\r\n    img.style.margin = 'auto';\r\n\r\n    \/\/ Botones\r\n    const buttonsContainer = document.createElement('div');\r\n    buttonsContainer.style.cssText = `\r\n    display: flex; \r\n    justify-content: center; \r\n    gap: 10px; \r\n    margin-top: 10px;\r\n    visibility: hidden;\r\n  `;\r\n\r\n    const driveLink = document.createElement('a');\r\n    driveLink.href = getDriveImagePage(imgData.id);\r\n    driveLink.target = '_blank';\r\n    driveLink.textContent = 'See in Drive';\r\n    driveLink.classList.add('btn-drive');\r\n    buttonsContainer.appendChild(driveLink);\r\n\r\n    const closeButton = document.createElement('button');\r\n    closeButton.textContent = 'Close';\r\n    closeButton.classList.add('btn-close');\r\n    closeButton.onclick = () => { if (lightboxInstance) lightboxInstance.close(); };\r\n    buttonsContainer.appendChild(closeButton);\r\n\r\n\r\n    driveLink.classList.add('btn-drive');\r\n    closeButton.classList.add('btn-close');\r\n\r\n    content.appendChild(img);\r\n    content.appendChild(buttonsContainer);\r\n\r\n    \/\/ Flechas\r\n    const leftArrow = document.createElement('div');\r\n    leftArrow.className = 'lightbox-nav-arrow left';\r\n    leftArrow.style.visibility = 'hidden';\r\n    leftArrow.innerHTML = `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 18 9 12 15 6\" \/><\/svg>`;\r\n    if (index === 0) leftArrow.classList.add('disabled');\r\n    leftArrow.addEventListener('click', () => {\r\n      if (index > 0) {\r\n        currentIndex = index - 1;\r\n        showLightboxImage(currentIndex, getVisibleImages());\r\n      }\r\n    });\r\n    content.appendChild(leftArrow);\r\n\r\n    const rightArrow = document.createElement('div');\r\n    rightArrow.className = 'lightbox-nav-arrow right';\r\n    rightArrow.style.visibility = 'hidden';\r\n    rightArrow.innerHTML = `<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"9 18 15 12 9 6\" \/><\/svg>`;\r\n    if (index === visibleImages.length - 1 && !nextPageToken) rightArrow.classList.add('disabled');\r\n    rightArrow.addEventListener('click', () => {\r\n      if (index < visibleImages.length - 1 || nextPageToken) {\r\n        currentIndex = index + 1;\r\n        showLightboxImage(currentIndex, getVisibleImages());\r\n      }\r\n    });\r\n    content.appendChild(rightArrow);\r\n\r\n    if (lightboxInstance) lightboxInstance.close();\r\n\r\n    lightboxInstance = basicLightbox.create(content, {\r\n      onShow: () => {\r\n        document.body.style.overflow = 'hidden'; \/\/ Bloquear scroll\r\n        document.body.style.position = 'fixed';\r\n        document.body.style.width = '100%';\r\n      },\r\n      onClose: () => {\r\n        document.body.style.overflow = ''; \/\/ Restaurar scroll\r\n        document.body.style.position = '';\r\n        document.body.style.width = '';\r\n\r\n        const visibleImgs = getVisibleImages();\r\n        if (currentIndex >= 0 && visibleImgs[currentIndex]) {\r\n          visibleImgs[currentIndex].container.scrollIntoView({ behavior: 'smooth', block: 'center' });\r\n        }\r\n      }\r\n    });\r\n\r\n    lightboxInstance.show();\r\n\r\n    img.onload = () => {\r\n      loadingDiv.style.display = 'none';\r\n      img.style.display = 'block';\r\n      buttonsContainer.style.visibility = 'visible';\r\n      leftArrow.style.visibility = 'visible';\r\n      rightArrow.style.visibility = 'visible';\r\n    };\r\n  }\r\n\r\n  const loadingMessage = document.getElementById('loadingMessage');\r\n\r\n  const sentinel = document.getElementById('scrollSentinel');\r\n\r\n  const observer = new IntersectionObserver(async (entries) => {\r\n    if (!folderId) return;\r\n    if (entries[0].isIntersecting && nextPageToken && !isLoading) {\r\n      loadingMessage.style.display = 'block';\r\n      const newFiles = await fetchMediaBatch();\r\n      await renderMedia(newFiles);\r\n      loadingMessage.style.display = 'none';\r\n    }\r\n  }, { rootMargin: '300px' });\r\n\r\n\r\n  observer.observe(sentinel);\r\n\r\n\r\n  \/\/ Detectar teclas de flecha\r\n  document.addEventListener('keydown', (e) => {\r\n    if (!lightboxInstance) return; \/\/ Solo si est\u00e1 abierto\r\n    if (e.key === 'ArrowLeft') {\r\n      currentIndex = Math.max(0, currentIndex - 1);\r\n      showLightboxImage(currentIndex, getVisibleImages());\r\n    }\r\n    if (e.key === 'ArrowRight') {\r\n      const visibleImages = getVisibleImages();\r\n      if (currentIndex < visibleImages.length - 1 || nextPageToken) {\r\n        currentIndex++;\r\n        showLightboxImage(currentIndex, visibleImages);\r\n      }\r\n    }\r\n  });\r\n\r\n  let touchStartX = 0;\r\n  let touchEndX = 0;\r\n\r\n  function handleGesture() {\r\n    if (!lightboxInstance || !lightboxInstance.visible()) return; \/\/ Solo si el lightbox est\u00e1 abierto\r\n\r\n    const visibleImages = getVisibleImages();\r\n    if (touchEndX < touchStartX - 50) {\r\n      \/\/ Swipe a la izquierda \u2192 siguiente imagen\r\n      if (currentIndex < visibleImages.length - 1 || nextPageToken) {\r\n        currentIndex++;\r\n        showLightboxImage(currentIndex, visibleImages);\r\n      }\r\n    }\r\n\r\n    if (touchEndX > touchStartX + 50) {\r\n      \/\/ Swipe a la derecha \u2192 imagen anterior\r\n      if (currentIndex > 0) {\r\n        currentIndex--;\r\n        showLightboxImage(currentIndex, visibleImages);\r\n      }\r\n    }\r\n  }\r\n\r\n  document.addEventListener('touchstart', e => {\r\n    if (e.touches.length === 1) {\r\n      touchStartX = e.touches[0].clientX;\r\n    }\r\n  }, { passive: true });\r\n\r\n  document.addEventListener('touchend', e => {\r\n    if (e.changedTouches.length === 1) {\r\n      touchEndX = e.changedTouches[0].clientX;\r\n      handleGesture();\r\n    }\r\n  }, { passive: true });\r\n\r\n\r\n  const scrollBtn = document.getElementById('scrollTopBtn');\r\n  const galleryEl = document.getElementById('gallery');\r\n\r\n  window.addEventListener('scroll', () => {\r\n    const galleryRect = galleryEl.getBoundingClientRect();\r\n    const windowHeight = window.innerHeight;\r\n\r\n    \/\/ Si la galer\u00eda sigue visible, mostramos el bot\u00f3n pegado abajo\r\n    if (galleryRect.bottom > windowHeight) {\r\n      scrollBtn.style.position = 'fixed';\r\n      scrollBtn.style.bottom = '5px';\r\n      scrollBtn.style.display = 'block';\r\n    }\r\n    \/\/ Si ya se termin\u00f3 la galer\u00eda, lo fijamos al final de la galer\u00eda\r\n    else {\r\n      scrollBtn.style.position = 'absolute';\r\n      scrollBtn.style.bottom = '40px';\r\n    }\r\n  });\r\n\r\n  \/\/ Scroll hacia arriba\r\n  scrollBtn.addEventListener('click', () => {\r\n    window.scrollTo({ top: 0, behavior: 'smooth' });\r\n  });\r\n\r\n\r\n\r\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>pHOTO gALLERY Look All in Drive All Images Videos Loading&#8230;<\/p>","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-2639","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/lifeforall-europe.org\/es\/wp-json\/wp\/v2\/pages\/2639","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lifeforall-europe.org\/es\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/lifeforall-europe.org\/es\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/lifeforall-europe.org\/es\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/lifeforall-europe.org\/es\/wp-json\/wp\/v2\/comments?post=2639"}],"version-history":[{"count":1297,"href":"https:\/\/lifeforall-europe.org\/es\/wp-json\/wp\/v2\/pages\/2639\/revisions"}],"predecessor-version":[{"id":10703,"href":"https:\/\/lifeforall-europe.org\/es\/wp-json\/wp\/v2\/pages\/2639\/revisions\/10703"}],"wp:attachment":[{"href":"https:\/\/lifeforall-europe.org\/es\/wp-json\/wp\/v2\/media?parent=2639"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}