<!doctype html>
<th:block
  xmlns:th="https://www.thymeleaf.org"
  th:replace="~{components/base-layout/template :: html(
    title = |${title} - ${site.title}|,
    head = ~{:: head},
    content = ~{:: body}, 
    header = ~{components/header/template :: body}, 
    navbar = ~{}
  )}"
>
  <head th:remove="tag">
    <link
      rel="canonical"
      th:if="${theme.config?.photos_styles?.is_enable_canonical_link}"
      th:href="${siteUrl} + @{/photos}"
    />
    <th:block th:insert="~{components/header/template :: head}"></th:block>
    <script type="module" crossorigin src="/themes/howiehz-higan/assets/1.65.0Bk5FHpu.js" integrity="sha384-cg6x7Pb77Zqih642wbHELBIb8vuQ0VeuH0Zb6tWgHC6J1oxIpFMgVUPeGS0CiGHV"></script>
    <link rel="stylesheet" crossorigin href="/themes/howiehz-higan/assets/1.65.0Nu1u8yY.css" integrity="sha384-h6WHiBEsz55L9LeaTSvyYRiiYVLTekMvNJhG+VjwyKti556zI6k8M+nZTayAbuwQ">
    <link rel="stylesheet" crossorigin href="/themes/howiehz-higan/assets/1.65.0qqpRzaJ.css" integrity="sha384-Mp1UTW6VxvI927jeW5hQKQhZHHoIbZqViDKkUdZge7HsILa3jHqJbI6RsGQpq3Bf">
    <link rel="stylesheet" crossorigin href="/themes/howiehz-higan/assets/1.65.0Bicc1e3.css" integrity="sha384-JZPOQ+7mdAeT6L3rX1fi/Xvhtbr+lZd0Wy165luHFqtcM5hQXidOHfpB5R/zc686">
  </head>
  <body th:remove="tag">
    <article class="photos post" itemscope itemtype="http://schema.org/BlogPosting">
      <script
        id="photos-masonry-script"
        type="module"
        th:if="${theme.config?.photos_styles?.is_enable_masonry_layout}"
        th:data-max-masonry-columns="${theme.config?.photos_styles?.max_masonry_columns}"
        th:data-min-masonry-columns="${theme.config?.photos_styles?.min_masonry_columns}"
        th:data-min-img-width="${theme.config?.photos_styles?.min_img_width}"
        th:data-masonry-gap="${theme.config?.photos_styles?.masonry_gap}"
      >
        const masonryScript = document.querySelector("#photos-masonry-script");
        class Waterfall {
          constructor(options) {
            this.$el = options.$el || null; 
            this.columns = options.columns || 4; 
            this.gap = options.gap || 10; 
            this.width = 0; 
            this.items = []; 
            this.nextImageIndex = 0; 
            this.totalImages = 0; 
            this.H = []; 
            this.flag = null; 
            this.init();
          }
          init() {
            if (this.$el) {
              this.addChildren(Array.from(this.$el.children));
            } else {
              throw new Error("Parent container element not found");
            }
          }
          addChildren(children) {
            if (!Array.isArray(children)) {
              throw new Error("Children should be an array");
            }
            children.forEach((child) => {
              if (!this.items.includes(child)) {
                this.$el.appendChild(child); 
                this.items.push(child);
                this.totalImages++;
              }
            });
            this.reset();
            this.render();
          }
          reset() {
            this.flag = document.createDocumentFragment();
            this.width = this.$el.clientWidth / this.columns;
            this.H = new Array(this.columns).fill(0);
            this.$el.innerHTML = "";
          }
          render() {
            const { width, items, flag, H, gap } = this;
            items.forEach((item) => {
              item.style.width = `${width}px`;
              item.style.position = "absolute";
              const img = item.querySelector("img");
              if (img) {
                const placeAndAnimate = () => {
                  item.style.opacity = 0; 
                  this.placeItem(item, img, H, width, gap, flag);
                  this.updateContainerHeight(); 
                  this.checkAndLoadMoreImages(); 
                  requestAnimationFrame(() => {
                    item.style.transition =
                      "opacity [(${theme.config?.photos_styles?.img_transition_duration_after_load})]s";
                    item.style.opacity = 1;
                  });
                };
                img.complete ? placeAndAnimate() : img.addEventListener("load", placeAndAnimate);
              }
            });
          }
          placeItem(item, img, H, width, gap, flag) {
            const tag = H.indexOf(Math.min(...H));
            item.style.left = `${tag * (width + gap)}px`;
            item.style.top = `${H[tag]}px`;
            H[tag] += (img.height * width) / img.width + gap;
            flag.appendChild(item);
            this.$el.append(flag);
          }
          getMaxHeight() {
            return Math.max(...this.H);
          }
          updateContainerHeight() {
            const maxHeight = this.getMaxHeight();
            this.$el.style.height = `${maxHeight}px`;
          }
          checkAndLoadMoreImages() {
            if (window.scrollY + window.innerHeight + 200 >= this.getMaxHeight()) {
              if (this.nextImageIndex < this.totalImages) {
                const img = this.items[this.nextImageIndex].querySelector("img");
                img.style.display = "block";
                img.loading = "eager";
                this.nextImageIndex++;
              }
            }
          }
        }
        window.onload = () => {
          const MAX_MASONRY_COLUMNS = Number(masonryScript?.dataset.maxMasonryColumns ?? 4);
          const MIN_MASONRY_COLUMNS = Number(masonryScript?.dataset.minMasonryColumns ?? 1);
          const MIN_IMG_WIDTH = Number(masonryScript?.dataset.minImgWidth ?? 300);
          const masonryGap = Number(masonryScript?.dataset.masonryGap ?? 10);
          function calculateColumns() {
            const width = window.innerWidth;
            const columns = Math.floor(width / MIN_IMG_WIDTH);
            return Math.max(MIN_MASONRY_COLUMNS, Math.min(columns, MAX_MASONRY_COLUMNS));
          }
          const photoLists = document.querySelectorAll(".photo-list");
          const waterfallInstances = [];
          photoLists.forEach(($el) => {
            const waterfallInstance = new Waterfall({
              $el: $el,
              columns: calculateColumns(),
              gap: masonryGap,
            });
            waterfallInstances.push(waterfallInstance);
          });
          const checkAllWaterfalls = () => {
            waterfallInstances.forEach((waterfallInstance) => {
              waterfallInstance.checkAndLoadMoreImages();
            });
          };
          let resizeScheduled = false;
          window.addEventListener("resize", () => {
            if (!resizeScheduled) {
              resizeScheduled = true;
              requestAnimationFrame(() => {
                const newColumns = calculateColumns();
                waterfallInstances.forEach((waterfallInstance) => {
                  if (newColumns !== waterfallInstance.columns) {
                    waterfallInstance.columns = newColumns;
                    waterfallInstance.reset();
                    waterfallInstance.render();
                  }
                });
                checkAllWaterfalls();
                resizeScheduled = false;
              });
            }
          });
          window.addEventListener("scroll", checkAllWaterfalls);
          checkAllWaterfalls();
        };
      </script>
      <script
        id="photos-standard-script"
        type="module"
        th:unless="${theme.config?.photos_styles?.is_enable_masonry_layout}"
        th:data-img-transition-duration-after-load="${theme.config?.photos_styles?.img_transition_duration_after_load}"
      >
        const standardScript = document.querySelector("#photos-standard-script");
        const imgTransitionDurationAfterLoad = Number(standardScript?.dataset.imgTransitionDurationAfterLoad ?? 0);
        const photos = document.querySelectorAll(".photo-groups img");
        let nextImageIndex = 0; 
        const totalImages = photos.length; 
        let totalheight = 0; 
        photos.forEach((img) => {
          const placeAndAnimate = () => {
            checkAndLoadMoreImages();
            requestAnimationFrame(() => {
              img.style.transition = `opacity ${imgTransitionDurationAfterLoad}s`;
              img.style.opacity = 1;
            });
          };
          img.complete ? placeAndAnimate() : img.addEventListener("load", placeAndAnimate);
        });
        function checkAndLoadMoreImages() {
          if (window.scrollY + window.innerHeight + 200 >= totalheight) {
            if (nextImageIndex < totalImages) {
              const img = photos[nextImageIndex];
              img.style.display = "block";
              img.loading = "eager";
              totalheight = img.getBoundingClientRect().bottom;
              nextImageIndex++;
            }
          }
        }
        window.addEventListener("scroll", () => checkAndLoadMoreImages());
        window.addEventListener("resize", () => checkAndLoadMoreImages());
        checkAndLoadMoreImages();
      </script>
      <script>
        document.addEventListener("DOMContentLoaded", () => {
          const content = document.querySelector(".content");
          const handleEvent = (event, attr) => {
            const img = event.target.closest(`img[${attr}]`);
            if (img && content.contains(img)) {
              const code = img.getAttribute(attr);
              executeCustomCode(code, img);
            }
          };
          content.addEventListener("mouseover", (event) => handleEvent(event, "data-img-onmouseover"));
          content.addEventListener("mouseout", (event) => handleEvent(event, "data-img-onmouseout"));
          const executeCustomCode = (code, element) => {
            if (code) {
              try {
                eval(code.replace(/this/g, "element"));
              } catch (error) {
                console.error("[Higan Haozi][photos] Error executing custom code:", error);
              }
            }
          };
        });
      </script>
      <div class="content">
        <ul
          class="photo-list"
          th:if="${theme.config?.photos_styles?.is_enable_masonry_layout
                   and !theme.config?.photos_styles?.is_show_photo_group_name}"
        >
          <th:block th:each="group : ${groups}">
            <th:block th:each="photo : ${group.photos}">
              <li class="photo-image">
                <img
                  th:src="@{${photo.spec.url}}"
                  th:srcset="|
                  ${thumbnail.gen(photo.spec.url, 's')} 400w,
                  ${thumbnail.gen(photo.spec.url, 'm')} 800w,
                  ${thumbnail.gen(photo.spec.url, 'l')} 1200w,
                  ${thumbnail.gen(photo.spec.url, 'xl')} 1600w
                  |"
                  sizes="(max-width: 1600px) 100vw, 1600px"
                  th:title="${photo.spec.displayName}"
                  th:alt="${photo.spec.description}"
                  loading="lazy"
                  th:style="'display: none;
                    width: 100%;
                    height: auto;
                    transition: box-shadow 0.1s ease-in, box-shadow 0.3s ease-out;
                    border-radius:' + ${theme.config?.photos_styles?.img_border_radius} + ';'"
                  th:data-img-onmouseover="${theme.config?.photos_styles?.img_onmouseover}"
                  th:data-img-onmouseout="${theme.config?.photos_styles?.img_onmouseout}"
                />
              </li>
            </th:block>
          </th:block>
        </ul>
        <div
          class="photo-groups"
          th:each="group : ${groups}"
          th:if="${theme.config?.photos_styles?.is_enable_masonry_layout
                   and theme.config?.photos_styles?.is_show_photo_group_name}"
        >
          <h2 th:text="${group.spec.displayName}"></h2>
          <ul class="photo-list">
            <th:block th:each="photo : ${group.photos}">
              <li class="photo-image">
                <img
                  th:src="@{${photo.spec.url}}"
                  th:srcset="|
                  ${thumbnail.gen(photo.spec.url, 's')} 400w,
                  ${thumbnail.gen(photo.spec.url, 'm')} 800w,
                  ${thumbnail.gen(photo.spec.url, 'l')} 1200w,
                  ${thumbnail.gen(photo.spec.url, 'xl')} 1600w
                  |"
                  sizes="(max-width: 1600px) 100vw, 1600px"
                  th:title="${photo.spec.displayName}"
                  th:alt="${photo.spec.description}"
                  loading="lazy"
                  th:style="'display: none;
                    width: 100%;
                    height: auto;
                    transition: box-shadow 0.1s ease-in, box-shadow 0.3s ease-out;
                    border-radius:' + ${theme.config?.photos_styles?.img_border_radius} + ';'"
                  th:data-img-onmouseover="${theme.config?.photos_styles?.img_onmouseover}"
                  th:data-img-onmouseout="${theme.config?.photos_styles?.img_onmouseout}"
                />
              </li>
            </th:block>
          </ul>
        </div>
        <div
          class="photo-groups"
          th:each="group : ${groups}"
          th:unless="${theme.config?.photos_styles?.is_enable_masonry_layout}"
        >
          <h2 th:text="${group.spec.displayName}" th:if="${theme.config?.photos_styles?.is_show_photo_group_name}"></h2>
          <ul class="photo-list">
            <th:block th:each="photo : ${group.photos}">
              <li class="photo-image">
                <img
                  th:src="@{${photo.spec.url}}"
                  th:srcset="|
                  ${thumbnail.gen(photo.spec.url, 's')} 400w,
                  ${thumbnail.gen(photo.spec.url, 'm')} 800w,
                  ${thumbnail.gen(photo.spec.url, 'l')} 1200w,
                  ${thumbnail.gen(photo.spec.url, 'xl')} 1600w
                  |"
                  sizes="(max-width: 1600px) 100vw, 1600px"
                  th:title="${photo.spec.displayName}"
                  th:alt="${photo.spec.description}"
                  loading="lazy"
                  th:style="'display: none;
                    opacity: 0;
                    width: 100%;
                    height: auto;
                    transition: box-shadow 0.1s ease-in, box-shadow 0.3s ease-out;
                    border-radius:' + ${theme.config?.photos_styles?.img_border_radius} + ';'"
                  th:data-img-onmouseover="${theme.config?.photos_styles?.img_onmouseover}"
                  th:data-img-onmouseout="${theme.config?.photos_styles?.img_onmouseout}"
                />
              </li>
            </th:block>
          </ul>
        </div>
      </div>
    </article>
  </body>
</th:block>
