/home/bdqbpbxa/demo-subdomains/billine.goodface.com.ua/js/custom-solutions.js
// Prevent default function

function preventDefault(e) {
  e.preventDefault();
}

// Scroll lock

function lockScroll() {
  const html = document.documentElement;
  const body = document.body;

  const scrollTop = window.scrollY;

  html.classList.add("-scroll-lock");
  body.classList.add("-scroll-lock");

  document.body.scrollTo(0, scrollTop);
  html.setAttribute("data-scroll", scrollTop);

  $(".--modal-scrollable-element").on("touchmove pointermove", preventDefault);
}

function unlockScroll() {
  const html = document.documentElement;
  const body = document.body;

  const scrollPositionBeforeLock = html.getAttribute("data-scroll");

  html.classList.remove("-scroll-lock");
  body.classList.remove("-scroll-lock");

  window.scrollTo(0, scrollPositionBeforeLock);
  document.body.scrollTo(0, 0);

  $(".--modal-scrollable-element").off("touchmove pointermove", preventDefault);
}

// Check device type

const isApple = navigator.userAgent.toLowerCase().indexOf("mac") !== -1;
const isAndroid = navigator.userAgent.toLowerCase().indexOf("android") !== -1;

if (isApple) {
  document.body.classList.add("-apple");
}

if (isAndroid) {
  document.body.classList.add("-android");
}

// Check device size

window.isPc = window.innerWidth > 1024;
window.isTablet = window.innerWidth > 759 && window.innerWidth <= 1024;
window.isMobile = window.innerWidth < 760;

function checkDeviceSize() {
  window.isPc = window.innerWidth > 1024;
  window.isTablet = window.innerWidth > 759 && window.innerWidth <= 1024;
  window.isMobile = window.innerWidth < 760;
}

window.addEventListener("DOMContentLoaded", checkDeviceSize);
window.addEventListener("resize", checkDeviceSize);

// Set CSS variable with window.innerHeight

function setCssWindowInnerHeight() {
  document.documentElement.style.setProperty(
    "--window-inner-height",
    `${window.innerHeight}px`
  );
}

window.addEventListener("DOMContentLoaded", setCssWindowInnerHeight);
window.addEventListener("resize", setCssWindowInnerHeight);

// Set window height

function checkWindowHeight() {
  return Math.max(
    document.body.scrollHeight,
    document.documentElement.scrollHeight,
    document.body.offsetHeight,
    document.documentElement.offsetHeight,
    document.body.clientHeight,
    document.documentElement.clientHeight
  );
}

let scrollHeight = checkWindowHeight();

window.addEventListener("resize", () => {
  scrollHeight = checkWindowHeight;
});

// Set CSS variable with scrollbar width

function setScrollbarWidthInCSS() {
  $("body").append(`
		<div id="scrollbar-width-test" style="position: absolute;top: -999px;left: -999px;width: 50px;height: 50px;overflow: scroll;">
			<div style="height: 100px;"></div>
		</div>
	`);

  const scrollbarWidthTestEl = $("#scrollbar-width-test")[0];
  const scrollbarWidth =
    scrollbarWidthTestEl.offsetWidth - scrollbarWidthTestEl.clientWidth;

  document.documentElement.style.setProperty(
    "--scrollbar-width",
    `${scrollbarWidth}px`
  );

  window.scrollbarWidth = scrollbarWidth;

  scrollbarWidthTestEl.remove();
}

window.addEventListener("DOMContentLoaded", setScrollbarWidthInCSS);
window.addEventListener("resize", setScrollbarWidthInCSS);

// Click outside callback

function customClickOutsideCallback(selector, callback) {
  $(document).on("mouseup", function (e) {
    const isSelector = $(e.target).is(selector);
    const hasParent = $(e.target).closest(selector).length;

    if (!isSelector && !hasParent && typeof callback === "function") {
      callback(e, selector);
    }
  });
}

// Lazyload - params

// if you set DEFAULT_LAZYLOAD_OFFSET to 0 or false
// then all elements on the page will be loaded the first time the scroll event fires

const DEFAULT_LAZYLOAD_OFFSET = 700;

// Lazyload - loaders

function imgLazyload(customSelector, customLazyloadOffset) {
  const isSelectorValid = typeof customSelector === "string";

  const selector = isSelectorValid
    ? `${customSelector} img.-lazyload`
    : "img.-lazyload";
  const notSelector = isSelectorValid
    ? ".-loaded"
    : ".-loaded, [data-custom-lazyload-trigger] .-lazyload";

  $(selector)
    .not(notSelector)
    .each(function () {
      if (!customSelector && !isElementAllowToLoad(this, customLazyloadOffset))
        return;

      $(this).on("load", lazyloadFullLoadedCallback);
      $(this).removeAttr("srcset").addClass("-loaded");
    });
}

function bgLazyload(customSelector, customLazyloadOffset) {
  const isSelectorValid = typeof customSelector === "string";

  const selector = isSelectorValid
    ? `${customSelector} .-bg-lazyload`
    : ".-bg-lazyload";
  const notSelector = isSelectorValid
    ? ".-loaded"
    : ".-loaded, [data-custom-lazyload-trigger] .-bg-lazyload";

  $(selector)
    .not(notSelector)
    .each(function () {
      if (!customSelector && !isElementAllowToLoad(this, customLazyloadOffset))
        return;

      const src = $(this).attr("data-src");

      $(this)
        .css("background-image", `url(${src})`)
        .removeAttr("data-src")
        .addClass("-loaded");
    });
}

function videoLazyload(customSelector, customLazyloadOffset) {
  const isSelectorValid = typeof customSelector === "string";

  const selector = isSelectorValid
    ? `${customSelector} video.-lazyload`
    : "video.-lazyload";
  const notSelector = isSelectorValid
    ? ".-loaded"
    : ".-loaded, [data-custom-lazyload-trigger] .-lazyload";

  $(selector)
    .not(notSelector)
    .each(function () {
      if (!customSelector && !isElementAllowToLoad(this, customLazyloadOffset))
        return;

      $(this).on("loadeddata", lazyloadFullLoadedCallback);

      const src = $(this).attr("data-src");
      const dataStart = $(this).attr("data-start-position");

      const t = dataStart ? `#t=${dataStart}` : "";
      const source = `<source type="video/mp4" src="${src}${t}" />`;

      $(this).html(source).removeAttr("data-src").addClass("-loaded");
    });
}

function iframeLazyload(customSelector, customLazyloadOffset) {
  const isSelectorValid = typeof customSelector === "string";

  const selector = isSelectorValid
    ? `${customSelector} iframe.-lazyload`
    : "iframe.-lazyload";
  const notSelector = isSelectorValid
    ? ".-loaded"
    : ".-loaded, [data-custom-lazyload-trigger] iframe.-lazyload";

  $(selector)
    .not(notSelector)
    .each(function () {
      if (!customSelector && !isElementAllowToLoad(this, customLazyloadOffset))
        return;

      const src = $(this).attr("data-src");

      $(this).on("load", lazyloadFullLoadedCallback);
      $(this).attr("src", src).removeAttr("data-src").addClass("-loaded");
    });
}

// Lazyload

function isElementAllowToLoad(el, customLazyloadOffset) {
  const lazyloadOffset = customLazyloadOffset
    ? customLazyloadOffset
    : DEFAULT_LAZYLOAD_OFFSET;

  if (!lazyloadOffset) return true;

  const offsetTop = $(el).offset().top;
  const offsetToLoad = window.scrollY + window.innerHeight + lazyloadOffset;

  return offsetTop < offsetToLoad;
}

function lazyloadFullLoadedCallback(e) {
  $(e.target).addClass("-full-loaded");
  $(e.target).off("load", lazyloadFullLoadedCallback);
}

function lazyload(customSelector, customLazyloadOffset) {
  imgLazyload(customSelector, customLazyloadOffset);
  bgLazyload(customSelector, customLazyloadOffset);
  videoLazyload(customSelector, customLazyloadOffset);
  iframeLazyload(customSelector, customLazyloadOffset);

  const notLoadedElementsCount = $(".-lazyload, .-bg-lazyload").not(
    ".-loaded"
  ).length;

  if (notLoadedElementsCount === 0) {
    $(window).off("scroll", lazyloadOnScroll);
    window.dispatchEvent(new Event("lazyload-final"));
  }
}

function viewportLazyload() {
  lazyload(false, 1);
}

function lazyloadOnScroll() {
  if (window.scrollY > 0) {
    lazyload();
  }
}

$(window).on("load", viewportLazyload);
$(window).on("load scroll", lazyloadOnScroll);

// Selector full transitionend callback

function fullTransitionendCallback(element, callback, customProperty = false) {
  if ($(element).length === 0) return;

  const transitionProperties = $(element)
    .css("transition-property")
    .split(",")
    .map((property) => {
      return property.trim();
    });

  const transitionDurations = $(element)
    .css("transition-duration")
    .split(",")
    .map((duration) => {
      return parseFloat(duration);
    });

  let longestProperty = false;

  if (transitionProperties.length > 1 && customProperty === false) {
    longestProperty =
      transitionProperties[
        transitionDurations.indexOf(Math.max(...transitionDurations))
      ];
  }

  $(element).on("transitionstart", function () {
    $(this).removeAttr("data-transitionend-triggered");
  });

  $(element).on("transitionend", function (e) {
    const isTriggered = $(this).is("[data-transitionend-triggered]");

    if (isTriggered) return;

    const isCustomProperty =
      customProperty && e.originalEvent.propertyName === customProperty;
    const isSingleCallback =
      customProperty === false &&
      longestProperty === false &&
      typeof callback === "function";
    const isLongestPropertyCallback =
      longestProperty &&
      e.originalEvent.propertyName === longestProperty &&
      typeof callback === "function";

    if (isCustomProperty || isSingleCallback || isLongestPropertyCallback) {
      $(this).attr("data-transitionend-triggered", true);
      callback(e);
    }
  });
}

// Anchor link

const scrollLinkMinSpeed = 600;
const scrollLinkSpeedValue = 2;

const scrollLinkDefaultOffset = {
  default: {
    1024: 138,
  },
};
const scrollLinkCustomOffset = {
  default: {
    1024: 138,
  },
};

const scrollLinkDefaultOffsetToTop = false;
const scrollLinkCustomOffsetToTop = false;

const scrollLinkDefaultOffsetToBottom = false;
const scrollLinkCustomOffsetToBottom = false;

// Anchor link - logic

$(document).on("click", "a", function (e) {
  const href = $(this).attr("href");
  const to = getElementByHref(href);

  if (to) {
    e.preventDefault();

    const position = getScrollLinkFinalPosition(to);

    if (position === window.scrollY) return;

    const speed = getScrollSpeedByPosition(position);

    $("html, body").animate({ scrollTop: position }, speed);
  }

  if ($(this).closest(".api-navigation").length) {
    history.pushState(
      {
        id: href,
        source: "web",
      },
      "Welcome",
      href
    );
  }
});

// Anchor link - helpers

function getElementByHref(href) {
  let hash = false;

  if (href.indexOf("#") === 0) {
    hash = href;
  } else {
    const url = new URL(href);

    if (
      url.host === window.location.host &&
      url.pathname === window.location.pathname
    ) {
      hash = url.hash ? url.hash : false;
    }
  }

  if (hash == "#") {
    hash = false;
  } else {
    hash = $(hash);
  }

  return hash.length ? hash : false;
}

function getScrollLinkDefaultValue(value, hasBg) {
  if (value === false) return false;

  let returnValue = false;

  if (typeof value === "object") {
    let objectKey;

    if (hasBg && typeof value["hasBg"] !== "undefined") {
      objectKey = value["hasBg"];
    } else {
      objectKey = value["default"];
    }

    if (typeof objectKey === "string" || typeof objectKey === "number") {
      returnValue = objectKey;
    } else if (typeof objectKey === "object") {
      Object.keys(objectKey).forEach((key) => {
        if (window.innerWidth > key) {
          returnValue = objectKey[key];
          return false;
        }
      });
    }
  } else {
    returnValue = value;
  }

  return returnValue;
}

function getScrollLinkPositionByParams(to, offsetValue, customOffsetValue) {
  const pageScrollHeight = Math.max(
    document.body.scrollHeight,
    document.documentElement.scrollHeight,
    document.body.offsetHeight,
    document.documentElement.offsetHeight,
    document.body.clientHeight,
    document.documentElement.clientHeight
  );

  const maxScrollHeight = pageScrollHeight - window.innerHeight;

  const header = $(".header");
  const marginTop = parseInt(to.css("margin-top"));

  let offset = 0;
  let position = to.offset().top;

  if (offsetValue === "margin") {
    offset += marginTop;
  } else if (offsetValue === "half-margin") {
    offset += marginTop / 2;
  } else if (offsetValue === "header-height") {
    offset += header.length ? header.outerHeight() : 0;
  }

  if (customOffsetValue) {
    offset += customOffsetValue;
  }

  position -= offset;

  if (position < 0) {
    position = 0;
  } else if (position > maxScrollHeight) {
    position = maxScrollHeight;
  }

  return position;
}

function getScrollLinkFinalPosition(to) {
  const hasBg = $(to).hasClass("--has-bg");

  const offsetValue = getScrollLinkDefaultValue(scrollLinkDefaultOffset, hasBg);
  const customOffsetValue = getScrollLinkDefaultValue(
    scrollLinkCustomOffset,
    hasBg
  );

  const offsetValueToTop = getScrollLinkDefaultValue(
    scrollLinkDefaultOffsetToTop,
    hasBg
  );
  const customOffsetValueToTop = getScrollLinkDefaultValue(
    scrollLinkCustomOffsetToTop,
    hasBg
  );

  const offsetValueToBottom = getScrollLinkDefaultValue(
    scrollLinkDefaultOffsetToBottom,
    hasBg
  );
  const customOffsetValueToBottom = getScrollLinkDefaultValue(
    scrollLinkCustomOffsetToBottom,
    hasBg
  );

  let position = getScrollLinkPositionByParams(
    to,
    offsetValue,
    customOffsetValue
  );

  if (
    position > window.scrollY &&
    (offsetValueToBottom || customOffsetValueToBottom)
  ) {
    if (offsetValueToBottom === false) {
      position = getScrollLinkPositionByParams(
        to,
        offsetValue,
        customOffsetValueToBottom
      );
    } else if (customOffsetValueToBottom === false) {
      position = getScrollLinkPositionByParams(
        to,
        offsetValueToBottom,
        customOffsetValue
      );
    } else {
      position = getScrollLinkPositionByParams(
        to,
        offsetValueToBottom,
        customOffsetValueToBottom
      );
    }
  }

  if (
    position < window.scrollY &&
    (offsetValueToTop || customOffsetValueToTop)
  ) {
    if (offsetValueToTop === false) {
      position = getScrollLinkPositionByParams(
        to,
        offsetValue,
        customOffsetValueToTop
      );
    } else if (customOffsetValueToTop === false) {
      position = getScrollLinkPositionByParams(
        to,
        offsetValueToTop,
        customOffsetValue
      );
    } else {
      position = getScrollLinkPositionByParams(
        to,
        offsetValueToTop,
        customOffsetValueToTop
      );
    }
  }

  return position;
}

function getScrollSpeedByPosition(position) {
  let speed = position * (0.001 * scrollLinkSpeedValue) * 100;

  if (speed < scrollLinkMinSpeed) {
    speed = scrollLinkMinSpeed;
  }

  return speed;
}

// Check in viewport

function checkElementsInViewport() {
  $("[data-check-in-viewport]").each(function () {
    const viewportTop = window.scrollY;
    const viewportBottom = viewportTop + window.innerHeight;

    const offsetTop = $(this).offset().top;
    const offsetBottom = offsetTop + $(this).outerHeight();

    const isInViewport =
      (offsetTop > viewportTop && offsetTop < viewportBottom) ||
      (offsetBottom > viewportTop && offsetBottom < viewportBottom);

    const hasInViewportClass = $(this).hasClass("-in-viewport");
    const hasNotInViewportClass = $(this).hasClass("-not-in-viewport");

    if (isInViewport && !hasInViewportClass) {
      $(this).removeClass("-not-in-viewport").addClass("-in-viewport");
    }

    if (!isInViewport && !hasNotInViewportClass) {
      $(this).removeClass("-in-viewport").addClass("-not-in-viewport");
    }
  });
}

$(window).on("load resize scroll", checkElementsInViewport);