if (typeof google != "undefined") {
  google.charts.load("current", { packages: ["gauge"] });
  google.charts.setOnLoadCallback(drawChartsIfAny());
}
String.prototype.rtrim = function(s) { 
  return this.replace(new RegExp(s + "*$"),''); 
};
const Toast = Swal.mixin({
  toast: true,
  position: "top-end",
  showConfirmButton: false,
  timer: 3000,
  timerProgressBar: true,
  didOpen: (toast) => {
    toast.addEventListener("mouseenter", Swal.stopTimer);
    toast.addEventListener("mouseleave", Swal.resumeTimer);
  },
});

$.fn.selectRange = function (start, end) {
  if (end === undefined) {
    end = start;
  }
  return this.each(function () {
    if ("selectionStart" in this) {
      this.selectionStart = start;
      this.selectionEnd = end;
    } else if (this.setSelectionRange) {
      this.setSelectionRange(start, end);
    } else if (this.createTextRange) {
      var range = this.createTextRange();
      range.collapse(true);
      range.moveEnd("character", end);
      range.moveStart("character", start);
      range.select();
    }
  });
};

function checkAddPages() {
  if ($(".list-group.add-pages input").length == 0) {
    $(".add-pages-btn").addClass("d-none");
  }
}

function clearInputValidity(th) {
  $("#site_add_links").removeClass("was-validated");
  var input = th[0];
  input.setCustomValidity("");
  input.reportValidity();
}

var speedChart;
var speedData;
var speedOptions;
var hovertimer, unhovertimer;
var newSiteEl;
var newSiteModal;
var newSiteEl2;
var newSiteModal2;
var batchSitesEl;
var batchSiteModal;
var site_id = 0;
var user_id = 0;
var currentPage = "";
var thisIsHovered;
var snapshot_id_popped = 0;
var moveDebounce;
var reqInv = 0;
var reqSeconds = 0;
var prevMousePosition = { x: 0, y: 0 };
var screenshots = {};
var lastrow = null;
var preload = [];
var preloadsizes = [];
var preloadIDs = [];
var preloadCounts = {};
var firstCBClicked = null;
var lastCBClicked = null;
var compareInv = 0;
var heartbeatInv = 0;
var interval_ids = {};
var interval_site_ids = {};
var interval_id = 0;
var site_link_check_debounce = 0
var meter_strength = {
  0: "Horrible",
  1: "Bad",
  2: "Weak",
  3: "Good",
  4: "Strong",
};
if ($("html").attr("lang") == "es") {
  meter_strength = {
    0: "Horrible",
    1: "Malo",
    2: "Débil",
    3: "Bueno",
    4: "Fuerte",
  };
}
var meter_color = {
  0: "bd-orange-500",
  1: "bd-red-500",
  2: "bd-yellow-500",
  3: "bd-blue-500",
  4: "bd-green-500",
};

var meter_size = {
  0: "20%",
  1: "40%",
  2: "60%",
  3: "80%",
  4: "100%",
};
var batchInv, crawlInv, multibatchInv;
var Swal;
var is_translating = false;

function drawChartsIfAny() {
  if ($("#speed_test").length) {
    drawSpeedGauge(parseFloat($("#speed_test").val()));
  }

  if ($("#diff_test").length && 0) {
    drawDiffChart(parseFloat($("#diff_test").val()));
  }
}

$(document).ready(function () {
  heartbeatInv = setInterval(function(){
    jQuery.ajax({
      url: "/heartbeat",
      method: "get",
      dataType: "json",
      data: {},
      success: function (result) {
      },
    });
  },180000)
  $( document ).off().on( "ajaxComplete", function( event, xhr, settings ) {
    if(xhr.responseJSON && xhr.responseJSON.message && xhr.responseJSON.message.match(/unauthenticated/i)){
      window.location = '/login'
    }
  });
  if($("tr.site-page .site-link-check:checked").length == $("tr.site-page .site-link-check").length){
    jQuery("#snapshot_links_cb").prop("checked",true)
  }
  if ($(".health-check-accordion").length) {
    $(".health-check-accordion-trigger").on("click", function (e) {
      e.preventDefault();
      var target = $(this).attr("aria-controls");
      console.log(target);
      var panel = $("#" + target);
      if (panel.is("[hidden]")) {
        $(this).attr("aria-expanded", "true");
        panel.removeAttr("hidden");
      } else {
        $(this).attr("aria-expanded", "false");
        panel.attr("hidden", "hidden");
      }
    });
  }
  
  $(".show-boom-plugin-info").on("click", function () {
    $(this).find("i.fa-solid").toggleClass("fa-chevron-down fa-chevron-up");
    $(".boom-plugin-info").toggleClass("d-none");
  });

  $(".b2-item").css({ height: $(".b2-item:first").width() });
  $("#search").on("search", function () {
    $("#searchform").submit();
  });
  adjustImageFrame();
  $(".loading-block-overlay").find(".message").text("");
  var overlayTarget = document.querySelector(".loading-block-overlay .message");
  if (overlayTarget) {
    // Create an observer instance.
    var overlayObserver = new MutationObserver(function (mutations) {
      if (lang == "en") return;
      if (!is_translating) {
        is_translating = true;
        var data = { text: [overlayTarget.innerText] };
        $(overlayTarget).hide();
        jQuery.ajax({
          url: "/translate/",
          method: "get",
          dataType: "json",
          data: data,
          success: function (result) {
            if (result.translation) {
              $(overlayTarget).text(result.translation[0]);
            }
            setTimeout(function () {
              $(overlayTarget).show();
              is_translating = false;
            }, 0);
          },
        });
      }
    });
    overlayObserver.observe(overlayTarget, {
      attributes: true,
      childList: true,
      characterData: true,
    });
  }

  Swal = swal.mixin({
    didRender: () => {
      if (
        lang == "en" ||
        $(".swal2-html-container")
          .html()
          .match(
            /progress-bar/ &&
              !$(".swal2-html-container")
                .html()
                .match(/translate progress-bar/)
          )
      )
        return;
      $(".swal2-container").hide();

      var data = {
        text: [
          $(".swal2-title").text(),
          $(".swal2-html-container").text(),
          $(".swal2-footer").text(),
          $(".swal2-confirm").text(),
          $(".swal2-deny").text(),
          $(".swal2-cancel").text(),
        ],
      };
      jQuery.ajax({
        url: "/translate/",
        method: "get",
        dataType: "json",
        data: data,
        success: function (result) {
          if (result.translation) {
            $(".swal2-title").html(result.translation[0]);
            if ($(".swal2-html-container").find(".progress-bar").length == 0) {
              $(".swal2-html-container").html(result.translation[1]);
            }
            $(".swal2-footer").html(result.translation[2]);
            $(".swal2-confirm").html(result.translation[3]);
            $(".swal2-deny").html(result.translation[4]);
            $(".swal2-cancel").html(result.translation[5]);
          }
          setTimeout(function () {
            $(".swal2-container").show();
          }, 0);
        },
      });
    },
  });
  if ($(".request_seconds").length) {
    reqSeconds = parseInt($(".request_seconds").text());
  }

  if (window.location.pathname.length > 1) {
    $(".nav-link[href*='" + window.location.pathname + "']")
      .parent()
      .addClass("active");
  }

  $(window).on("beforeunload", function () {
    $(".pw-strength-meter").remove();
    if (
      $(".download-invoice:hover").length == 0 &&
      $(".email-to:hover").length == 0 &&
      $(".nav-help:hover").length == 0 &&
      $(".no-overlay:hover").length == 0 &&
      $(".btn-download-snapshot:hover").length == 0
    ) {
      //$(".loading-block-overlay").find(".message").text('');
      $(".loading-block-overlay").css({ opacity: 1 }).show();
    }
    const intervalId = window.setInterval(() => {}, Number.MAX_SAFE_INTEGER);

    for (let i = 1; i < intervalId; i++) {
      window.clearInterval(i);
    }
  });
  $.ajaxSetup({
    headers: {
      "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
    },
  });
  if ($(".hideme-count").length) {
    var hidden = $(".hideme").length;
    $(".hideme-count").text(hidden);
  }
  if ($(".filter-site-link").length) {
    $(".filter-site-link")
      .on("keyup", function (e) {
        var keyword = $(this).val();
        $(".site-page").not(".hidden-page").show();
        if (keyword.length > 0) {
          $(".site-page").hide();
          $("tr.site-page:contains('" + keyword + "')").show();
        }
        //console.log(keyword)
      })
      .on("search", function (e) {
        var keyword = $(this).val();
        if (keyword.length > 0) {
          $(".site-page").hide();
          $("tr.site-page:contains('" + keyword + "')").show();
        } else {
          $(".site-page").not(".hidden-page").show();
        }
      });
  }
  $(".loading-block-overlay").fadeTo(205, 0, function () {
    $(this).hide();
  });
  $(".expand-subfolders").on("click", function (e) {
    e.preventDefault();
    var f = $(this).data("folder");
    $(".subfolders-" + f).toggleClass("d-none");
    if (!$(".subfolders-" + f).hasClass("d-none")) {
      $(this).text("↴");
    } else {
      $(this).text("↳");
    }
  });
  $(".btn-recrawl").on("click", function (e) {
    e.preventDefault();
    var url = $(this).attr("href");
    Swal.fire({
      icon: "warning",
      title: "Are you sure?",
      html: "This will remove all snapshots and re-crawl your site for pages.",
      showCancelButton: true,

      cancelButtonColor: "#d33",
      confirmButtonText: "Confirm Re-Crawl",
    }).then((result) => {
      if (result.isConfirmed) {
        window.location = url;
      }
    });
  });
  $(".btn-crawl").on("click", function (e) {
    e.preventDefault();
    if (Object.keys(interval_site_ids).length >= 5) {
      Swal.fire({
        title: "Re-Crawl Error",
        icon: "error",
        html: "No more than 5 manual crawls can be ran concurrently.",
      });
      return;
    }
    var domain = $("#domain").val();
    var isA = false;
    var th = $(this);
    th.fadeTo(100, 0.5);
    if ($(this).data("site_id")) {
      site_id = $(this).data("site_id");
      isA = $(this);
    } else {
      $(this).remove();
    }
    var page_counter = $("[data-crawl=" + site_id + "]");

    if (page_counter.length) {
      interval_ids[site_id] = {
        last: -1,
        attempts: 0,
        element: $("[data-crawl=" + site_id + "]"),
      };
      interval_site_ids[site_id] = site_id;
      page_counter.html(
        '<div class="spinner-border spinner-border spinner-border-sm"></div> <span></span>'
      );
      jQuery.ajax({
        url: "/recrawl/" + site_id,
        method: "get",
        dataType: "json",
        data: {},
        success: function (result) {
          setTimeout(function () {
            clearInterval(interval_id);
            interval_id = setInterval(function () {
              if (Object.keys(interval_site_ids).length) {
                jQuery.ajax({
                  url: "/crawled/" + site_id,
                  method: "get",
                  dataType: "json",
                  data: { site_ids: interval_site_ids },
                  success: function (result) {
                    if (result.sites.length == 0) {
                      clearInterval(interval_id);
                    }
                    for (var i in result.sites) {
                      var site_id = result.sites[i].site_id;
                      var count = parseInt(result.sites[i].count);
                      console.log(site_id, count);
                      var page_counter = $("[data-crawl=" + site_id + "]");
                      var last = interval_ids[site_id].last;
                      var attempts = interval_ids[site_id].attempts;
                      page_counter.find("span").html(count);
                      if (count != parseInt(last) && count) {
                        if (count < parseInt(last)) {
                          page_counter.addClass("text-danger");
                        } else {
                          page_counter
                            .removeClass("text-danger")
                            .addClass("text-success");
                        }
                        last = count;
                        attempts = 0;
                      } else {
                        if (count > 0) {
                          attempts++;
                        }
                      }
                      interval_ids[site_id].last = last;
                      interval_ids[site_id].attempts = attempts;

                      if (attempts >= 5) {
                        page_counter.text(last);
                        //clearInterval(interval_ids[site_id].interval_id)
                        delete interval_site_ids[site_id];
                        th.fadeTo(100, 1).addClass("text-success");
                        page_counter.removeClass(
                          "animate__animated animate__flash"
                        );
                        setTimeout(function () {
                          page_counter
                            .delay(1)
                            .addClass("animate__animated animate__flash");
                        }, 500);
                      }
                    }
                  },
                });
              } else {
                clearInterval(interval_id);
              }
            }, 5000);
          }, 1);
        },
      });
    }
  });
  $(".btn-batch-cancel").on("click", function () {
    var batch_id = $(this).attr("data-batch-id");
    jQuery.ajax({
      url: "/batch/cancel/" + batch_id,
      method: "get",
      dataType: "json",
      data: {},
      success: function (result) {
        window.location.reload();
      },
    });
  });
  $(".btn-queue-cancel").on("click", function () {
    var queue_id = $(this).attr("data-queue-id");
    jQuery.ajax({
      url: "/queue/cancel/" + queue_id,
      method: "get",
      dataType: "json",
      data: {},
      success: function (result) {
        window.location.reload();
      },
    });
  });
  if ($(".progress-bar").length) {
    initDataQueue();
  }
  // indicates snapshot is done but comparison is not
  if (!$(".progress-content").length && $(".awaiting-comparison").length) {
    initCheckSnapshotComplete();
  } else {
    $(".awaiting-comparison").hide()
  }
  if (!$(".progress-content").length && $(".awaiting-crawl").length) {
    initCrawlComplete();
  }
  
  $("[data-lazy-queue]").each(function () {
    var site_id = $(this).attr("data-lazy-queue");

    doLazyQueue(site_id);
  });
  var myIntervals = {};
  $("[data-crawl-id][data-crawl-id!='']").each(function () {
    var site_id = $(this).attr("data-crawl-id");
    var crawlIcon = $(this);
    var interval = 10000;

    myIntervals[crawlIcon.index("[data-crawl-id]")] = setInterval(function () {
      crawlIcon.attr("data-inv", crawlInv);
      jQuery.ajax({
        url: "/crawled/" + site_id,
        method: "get",
        dataType: "json",
        data: {},
        success: function (result) {
          var inv = myIntervals[crawlIcon.index("[data-crawl-id]")];
          clearInterval(inv);

          if (result.length > 0) {
            var site_id = result[0].site_id;
            console.log("interval #" + inv + " cleared");
            var spinner = $("[data-crawl-id=" + site_id + "]");
            spinner.siblings().remove();
            spinner.after("<span>Done</span>");
            spinner.hide();
          }
        },
      });
    }, 5000);
  });
  $("#admin_notes").on("blur", function () {
    var comment_parent = $(this).parent();
    comment_parent.addClass("saving");
    jQuery.ajax({
      url: "/sites/save/" + parseInt($("#admin_notes").data("site_id")),
      method: "post",
      dataType: "json",
      data: { comments: $("#admin_notes").val() },
      success: function (result) {
        setTimeout(function () {
          comment_parent.removeClass("saving");
        }, 500);
      },
      error: function (xhr) {
        popupError(xhr, form);
      },
    });
  });
  if ($("#middle-circle").text() == "?") {
    var site_id = $("#middle-circle").data("site_id");
    compareInv = setInterval(function () {
      jQuery.ajax({
        url: "/incompare/" + parseInt(site_id),
        method: "get",
        dataType: "json",
        success: function (result) {
          
          if (!result.response) {
            let timerInterval;
            clearInterval(compareInv);
            jQuery("#middle-circle").html("Ready")
            jQuery("#progress-spinner").css({background: "#73a81e"})
            jQuery(".compare-in-progress").remove();
            jQuery(".compare-dialog").html('<i class="fa fa-info-circle"></i> Difference images have been generated and are ready for viewing. Please <a href="">refresh</a> the page to see the results. If you continue to see this message it either indicates that compares are taking longer than usual or an issue exists.')
            jQuery(".image-diff").html('<a href="">Refresh</a>')
            setInterval(function(){
              jQuery(".compare-dialog").toggleClass("animate__rubberBand")
            },2000)
            
            jQuery(".compare-in-progress").remove()
            if(!Swal.isVisible() && 0){
             
              Swal.fire({
                title: "Comparison Complete",
                html: "Reloading in <b></b> ms.",
                timer: 6000,
                allowOutsideClick: false,
                timerProgressBar: true,
                didOpen: () => {
                  Swal.showLoading();
                  const timer = Swal.getPopup().querySelector("b");
                  timerInterval = setInterval(() => {
                    var s = Swal.getTimerLeft()
                    timer.textContent = s;
                  }, 100);
                },
                willClose: () => {
                  clearInterval(timerInterval);
                }
              }).then((result) => {
                if (result.dismiss === Swal.DismissReason.timer) {
                  window.location.reload();
                }
              });
            }
            
            
            
          }
        },
        error: function (xhr) {
          popupError(xhr, form);
        },
      });
    }, 1000);
  }
  console.log("COMPARE", $("#middle-circle").text() == "?");

  $("[data-batch-id][data-batch-id!='']").each(function () {
    var batch_id = $(this).attr("data-batch-id");

    var progressbarElem = $(".progress-bar");
    var progressElem = $(".progress");
    var progressText = $(".progress-bar-progress");
    if ($(".progress-content").length) {
      /* Swal.fire({
				html:$(".progress-content").html(),
				title: 'Snapshot in Progress',
				footer: '<div class="batch-progress-footer"></div>',
				allowOutsideClick: () => !Swal.isLoading(),
				didOpen: () => {
					$(".progress-content").remove();
					Swal.showLoading();
				},
			}); */
    } else {
      progressbarElem = $(this).find(".progress-bar");
      progressElem = $(this).find(".progress");
      progressText = $(this).find(".progress-bar-progress");
    }

    var countJobs = 1;
    var seconds = 0;
    var minutes = 0;
    var hours = 0;
    var totalTime = 0;
    var interval = 1000;
    var breath = true;
    batchInv = setInterval(function () {
      var s = new Date().getTime();
      breath = !breath;
      if (breath) {
        $(".progress").stop().fadeTo(interval, 1);
      } else {
        $(".progress").stop().fadeTo(interval, 0.5);
      }
      jQuery.ajax({
        url: "/batch/" + batch_id,
        method: "get",
        dataType: "json",
        data: {},
        success: function (result) {
          var progressbarElem = $(".progress-bar");
          var progressElem = $(".progress");
          var progressText = $(".progress-bar-progress");
          var e = new Date().getTime();
          var pendingJobs = result.pendingJobs;
          var failedJobs = parseInt(result.failedJobs);
          if (failedJobs > 0) {
            $(".btn-batch-cancel").removeClass("d-none");
            $(".btn-batch-cancel")
              .find("span")
              .html("(" + failedJobs + " Jobs)");
          }
          var elapsed = (e - s) / 100;
          if (result.progress == 0) {
            return;
          }
          totalTime = totalTime + elapsed;
          seconds = Math.floor(totalTime / countJobs) * pendingJobs;

          //+result.failedJobs
          //+result.pendingJobs
          countJobs++;
          if (seconds > 60) {
            minutes = seconds / 60;
            seconds = seconds - minutes * 60;
            if (minutes > 60) {
              hours = minutes / 60;
              minutes = minutes - hours * 60;
            } else {
              hours = 0;
            }
          } else {
            hours = minutes = 0;
          }
          var hourText = "";
          var minText = "";
          if (hours > 0) {
            hourText = hours + "h ";
          }
          if (minutes > 0) {
            minText = minutes + "h ";
          }

          var estText = " - " + hourText + minText + seconds + "s remaining";
          var status = "Completed";
          var icon = "success";
          var progress = result.progress;
          var finishedAt = result.finishedAt;
          var cancelledAt = result.cancelledAt;
          if (cancelledAt) {
            status = "Failed at " + progress + "%";
            icon = "error";
            progress = 100;
          }
          progressbarElem.css({ width: progress + "%" });
          progressText.html(progress + "%");
          //progressText.append(estText);
          progressElem.attr("aria-valuenow", progress);
          if (progress == 100) {
            clearInterval(batchInv);
            Swal.fire({
              icon: icon,
              title: "Snapshot Capture " + status,
              html: "Refreshing Page...",
              timer: 5000,
              allowOutsideClick: false,
              timerProgressBar: true,
              didOpen: () => {
                Swal.showLoading();
              },
            }).then((result) => {
              if (result.dismiss === Swal.DismissReason.timer) {
                window.location.reload();
              }
            });
          }
        },
      });
    }, interval);
  });
  if (typeof registration_incomplete != "undefined") {
    if (registration_incomplete && window.location.pathname.match(/register/)) {
      $(".step1").toggleClass("btn-primary btn-success");
      $(".step2").toggleClass("btn-light btn-primary");
      $("form#register-form").hide();
      $("form#payment-form").show();
      initPaymentIntent();
    } else if (window.location.pathname.match(/register/)) {
      window.location = "/dashboard";
    }
  }

  const tooltipTriggerList = document.querySelectorAll("[data-bs-title]");
  const tooltipList = [...tooltipTriggerList].map(
    (tooltipTriggerEl) =>
      new bootstrap.Tooltip(tooltipTriggerEl, {
        trigger: "hover",
      })
  );

  /* var snapshotCarousel = document.querySelector('#snapshotCarousel')
    
    if(snapshotCarousel){
    	var carousel = new bootstrap.Carousel(snapshotCarousel, {
		  interval: false,
		  wrap: true
		})
		
		snapshotCarousel.addEventListener('slide.bs.carousel', function () {
		  // do something...
		  
		})	
    }*/

  newSiteEl = document.getElementById("new-site");
  if (newSiteEl) {
    newSiteModal = new bootstrap.Modal(newSiteEl, {
      keyboard: false,
    });
    newSiteEl.addEventListener("hidden.bs.modal", () => {
      /*  $(newSiteModal._element).find("h1").text("New Site"); */
      $(newSiteModal._element).find("button[type=submit]");
      $("#new-site").find("form").trigger("reset");
      $(".tagsinput").tagsinput("removeAll");
      $("form#new_site").find("input").val("");
      site_id = 0;
      user_id = 0;
      $("[name='site[snapshot_weekly]']").prop("checked", false);
      $("#snapshot_schedule").hide("fast");
    });
    newSiteEl.addEventListener("show.bs.modal", (event) => {
      const button = event.relatedTarget;

      var form;
      if (typeof button == "object") {
        form = button.getAttribute("data-bs-form");
      } else {
        form = "#new_site";
      }

      $("#new-site").find("form").hide();

      $(form).show();
      $("[name='site[snapshot_weekly]']").prop("checked", false);
      $("#snapshot_schedule").hide("fast");
      $(form).find("input[type!=hidden]").val("");
      if (form == "#batch_site") {
        /* $(newSiteModal._element)
                    .find("h1")
                    .html("<strong>Create Multiple</strong> Sites");
                $(newSiteModal._element)
                    .find("button[type=submit]") */
      } else if (form == "#new_site") {
        /* $(newSiteModal._element)
                    .find("h1")
                    .html("<strong>Create New</strong> Site");
                $(newSiteModal._element)
                    .find("button[type=submit]") */
      }
    });
  }

  /* ajax user */
  if (typeof zxcvbn != "undefined") {
    $("#password")
      .on("keyup", function () {
        var password_strength = zxcvbn($(this).val());
        if ($(this).val()) {
          $(".pw-text").text(meter_strength[password_strength.score]);
          $(".pw-stength")
            .removeClass(
              "bd-orange-500 bd-red-500 bd-yellow-500 bd-green-500 bd-blue-500"
            )
            .addClass(meter_color[password_strength.score])
            .css({ width: meter_size[password_strength.score] });
        } else {
          $(".pw-text").text("");
          $(".is-invalid").removeClass("is-invalid");
          $(".invalid-feedback").hide().find("span").text("");
          $(".pw-stength")
            .removeClass(
              "bd-orange-500 bd-red-500 bd-yellow-500 bd-green-500 bd-blue-500"
            )
            .css({ width: "0%" });
        }
      })
      .on("focus", function () {
        $(".pw-strength-meter").show("fast");
      })
      .on("blur", function () {
        var password_strength = zxcvbn($(this).val());
        if ($(this).val()) {
          $(".pw-text").text(meter_strength[password_strength.score]);
        } else {
          $(".is-invalid").removeClass("is-invalid");
          $(".invalid-feedback").hide().find("span").text("");
          $(".pw-strength-meter").hide("fast");
        }
      });
  }

  /* ajax register user */
  $("form#register-form").on("submit", function (e) {
    var form = $(this);
    e.preventDefault();
    $(".is-invalid").removeClass("is-invalid");
    var serialized = form.serializeArray();
    var data = {};
    form.find(".spinner-border").removeClass("d-none");
    Object.entries(serialized).forEach(([key, value]) => {
      var field = value.name.replace(/site\[/, "").replace(/\]/, "");
      data[field] = value.value;
    });
    if (is_free) {
      data.is_free = "true";
    } else {
      data.is_free = "false";
    }
    data.stripe_id = $("input[name=selected_plan_id]:checked").attr(
      "data-stripe-id"
    );
    if (data.password) {
      var password_strength = zxcvbn($("#password").val());

      if (password_strength.score < 3) {
        var msg = "The password you entered isnt a very good one.";
        if (password_strength.feedback.warning) {
          msg +=
            "<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" +
            password_strength.feedback.warning;
        }
        if (password_strength.feedback.suggestions) {
          msg +=
            "<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" +
            password_strength.feedback.suggestions[0];
        }

        $("#password")
          .addClass("is-invalid")
          .siblings(".invalid-feedback")
          .find("span")
          .html(msg);
        popupMsg("Password Error", msg, "error", function () {});
        form.find(".spinner-border").addClass("d-none");
        return false;
      } else if ($("#password_confirmation").val() == "") {
        $("#password_confirmation")
          .addClass("is-invalid")
          .siblings(".invalid-feedback")
          .find("span")
          .text("Confirm password cannot be empty!");
        popupMsg(
          "Password Error",
          "Confirm password cannot be empty!",
          "error",
          function () {}
        );
        form.find(".spinner-border").addClass("d-none");
        return false;
      } else if ($("#password").val() != $("#password_confirmation").val()) {
        $("#password_confirmation")
          .addClass("is-invalid")
          .siblings(".invalid-feedback")
          .find("span")
          .text("Passwords must match!");
        popupMsg(
          "Password Error",
          "Passwords must match!",
          "error",
          function () {}
        );
        form.find(".spinner-border").addClass("d-none");
        return false;
      }
    }

    jQuery.ajax({
      url: "/users/register",
      method: "post",
      dataType: "json",
      data: data,
      success: function (result) {
        if (!is_free) {
          $(".step1").toggleClass("btn-primary btn-success");
          $(".step2").toggleClass("btn-light btn-primary");
          $("form#register-form").hide();
          $("form#payment-form").show();
          form.find(".spinner-border").addClass("d-none");
          initPaymentIntent();
        } else {
          $(".step1").toggleClass("btn-primary btn-success");
          $(".step2").toggleClass("btn-light btn-success");
          $(".step3").toggleClass("btn-light btn-success");
          $("form#register-form").hide();
          $("form#payment-form").hide();
          $("#checkout-success").show();
          form.find(".spinner-border").addClass("d-none");
        }
      },
      error: function (xhr) {
        popupError(xhr, form);
      },
    });
  });

  /* ajax edit user */
  $("form#edit_user").on("submit", function (e) {
    var form = $(this);
    e.preventDefault();
    $(".is-invalid").removeClass("is-invalid");
    var serialized = form.serializeArray();
    var data = {};
    form.find(".spinner-border").removeClass("d-none");
    Object.entries(serialized).forEach(([key, value]) => {
      var field = value.name.replace(/site\[/, "").replace(/\]/, "");
      data[field] = value.value;
    });
    data.is_admin = $("#is_admin").prop("checked") ? 1 : 0;
    data.is_dev = $("#is_dev").prop("checked") ? 1 : 0;
    if (data.password) {
      var password_strength = zxcvbn($("#password").val());

      if (password_strength.score < 3) {
        var msg = "The password you entered isnt a very good one.";
        if (password_strength.feedback.warning) {
          msg +=
            "<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" +
            password_strength.feedback.warning;
        }
        if (password_strength.feedback.suggestions) {
          msg +=
            "<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" +
            password_strength.feedback.suggestions[0];
        }

        $("#password")
          .addClass("is-invalid")
          .siblings(".invalid-feedback")
          .find("span")
          .html(msg);
        popupMsg("Password Error", msg, "error", function () {});
        form.find(".spinner-border").addClass("d-none");
        return false;
      } else if ($("#password_confirmation").val() == "") {
        $("#password_confirmation")
          .addClass("is-invalid")
          .siblings(".invalid-feedback")
          .find("span")
          .text("Confirm password cannot be empty!");
        popupMsg(
          "Password Error",
          "Confirm password cannot be empty!",
          "error",
          function () {}
        );
        form.find(".spinner-border").addClass("d-none");
        return false;
      } else if ($("#password").val() != $("#password_confirmation").val()) {
        $("#password_confirmation")
          .addClass("is-invalid")
          .siblings(".invalid-feedback")
          .find("span")
          .text("Passwords must match!");
        popupMsg(
          "Password Error",
          "Passwords must match!",
          "error",
          function () {}
        );
        form.find(".spinner-border").addClass("d-none");
        return false;
      }
    }

    jQuery.ajax({
      url: "/users/ajaxSave/" + parseInt($("#user_id").val()),
      method: "post",
      dataType: "json",
      data: data,
      success: function (result) {
        $(".chg-pwd").hide();
        var msg = result.message;
        $("#password_confirmation,#password").val("");
        Toast.fire({
          icon: "success",
          title: "Profile Saved!",
        });
        // popupMsg(msg, "", "success", function () {window.location.reload()},"Click OK to reload.");
        form.find(".spinner-border").addClass("d-none");
      },
      error: function (xhr) {
        popupError(xhr, form);
      },
    });
  });
  /* ajax edit site */
  $("form#new_site")
    .find("button[type=submit")
    .on("click", function () {
      $(".invalid-feedback").hide();
      if ($("input:invalid").length) {
        $("input:invalid").each(function () {
          $(this).siblings(".invalid-feedback").show();
        });
      }
    });
  $("form#new_site").on("submit", function (e) {
    var form = $(this);
    e.preventDefault();
    $(".is-invalid").removeClass("is-invalid");
    var serialized = form.serializeArray();
    var data = {};
    //form.find('.spinner-border').removeClass("d-none")
    Object.entries(serialized).forEach(([key, value]) => {
      var field = value.name.replace(/site\[/, "").replace(/\]/, "");
      data[field] = jQuery.trim(value.value);
    });
    data.snapshot_weekly = $(this)
      .find("[name='site[snapshot_weekly]']")
      .prop("checked")
      ? 1
      : 0;
    data.threshold = $(this).find("[name='site[threshold]']").prop("checked")
      ? 1
      : 0;
    if (typeof site_id == "undefined") {
      site_id = 0;
    }

    $(".loading-block-overlay").find(".message").html("Saving Site....");
    $(".loading-block-overlay").css({ opacity: 1 }).show();

    jQuery.ajax({
      url: "/sites/save/" + parseInt(site_id),
      method: "post",
      dataType: "json",
      data: data,
      success: function (result) {
        if (result.errors) {
          Swal.fire({
            title: "The following sites were not added:",
            icon: "error",
            html: result.errors,
            didOpen: () => {
              $("#new-site").modal("hide");
            },
            didClose: () => {
              window.location.reload();
            },
          });
        } else {
          if (site_id) {
            newSiteModal.hide();
            msg = "Site saved!";
            if(result.tags){
              var tags = result.tags.split(",")
              console.log(tags)
              var data_tags = result.tags + " " + $("tr.site-"+site_id).data("wo-tags")
              $("tr.site-"+site_id).attr("data-tags",data_tags)
              var tags_html = "";
              for(var i in tags){
                tags_html += '<span class="btn btn-outline-primary btn-sm me-1 mb-1">'+tags[i]+'</span>'
              }
              $("tr.site-"+site_id).find(".edit-tags").html(tags_html);
            }
            $(".loading-block-overlay").css({ opacity: 0 }).hide();
            var site_row = $("tr.site-" + site_id);
            if (site_row.length) {
              site_row.find(".latest-snapshot-link").text(data.name);
            }
            Toast.fire({
              icon: "info",
              title: msg,
              timer: "3000",
            });
          } else {
            msg = "Site created!";
            $(".loading-block-overlay")
              .find(".message")
              .html(msg)
              .addClass("animate__animated animate__bounce");
            setTimeout(function () {
              $(".loading-block-overlay").find(".message").html("Reloading...");
              window.location.reload();
            }, 3000);
          }
        }

        //popupMsg(msg,'','success',function(){window.location.reload()})
        //form.find('.spinner-border').addClass("d-none")
      },
      error: function (xhr) {
        popupError(xhr, form);

        
       
      },
    });
  });
  $(".batch_reset").on("click", function (e) {
    e.preventDefault();

    $(".loading-block-overlay").find(".message").html("Please Wait...");
    $(".loading-block-overlay").css({ opacity: 1 }).show();
    var num_to_approve = $(".select_site:checked").length;
    var num_approved = 0;
    $(".select_site:checked").each(function () {
      var site_id = $(this).val();

      jQuery.ajax({
        url: "/recrawl/" + parseInt(site_id),
        method: "get",
        async: true,
        dataType: "json",
        data: {},
        success: function (result) {
          num_approved++;

         
          if (num_approved == num_to_approve) {
            $(".loading-block-overlay")
              .find(".message")
              .html("Reset Completed! Reloading...");
            window.location.reload();
          }
        },
        error: function (xhr) {
          popupError(xhr);
        },
      });
    });
  });
  $(".batch_approve").on("click", function (e) {
    e.preventDefault();

    $(".loading-block-overlay").find(".message").html("Please Wait...");
    $(".loading-block-overlay").css({ opacity: 1 }).show();
    var num_to_approve = $(".select_site:checked").length;
    var num_approved = 0;
    $(".select_site:checked").each(function () {
      var site_id = $(this).val();

      jQuery.ajax({
        url: "/snapshots/approve/" + parseInt(site_id),
        method: "post",
        async: true,
        dataType: "json",
        data: {
          is_dev: window.location.pathname.match(/\/live\//) ? 0 : 1,
        },
        success: function (result) {
          num_approved++;

          $(".loading-block-overlay")
            .find(".message")
            .html("Approving " + result.site + "...");
          if (num_approved == num_to_approve) {
            $(".loading-block-overlay")
              .find(".message")
              .html("Approval Completed! Reloading...");
            window.location.reload();
          }
        },
        error: function (xhr) {
          popupError(xhr);
        },
      });
    });
  });
  $(".new-snapshotsss").on("click", function (e) {
    e.preventDefault();
    var spinner = $(
      '<div class="spinner-border spinner-border-sm" role="status"></div>'
    );
    var href = $(this).attr("href");
    var th = $(this);
    var id = th.data("id");
    spinner.insertAfter(th);
    th.attr("disabled", true).addClass("opacity-50 disabled d-none");
    jQuery.ajax({
      url: href,
      method: "get",
      dataType: "html",
      success: function (result) {
        Toast.fire({
          icon: "info",
          title: "Snapshots Queued",
          html: "Reloading...",
          timer: "3000",
        });
        setTimeout(function () {
          $(".loading-block-overlay").find(".message").html("Reloading...");
          window.location.reload();
        }, 3000);
      },
      error: function (xhr) {
        popupError(xhr, form);
      },
    });
  });
  $(".btn-new-snapshot").on("click", function (e) {
    e.preventDefault();
    if ($(this).hasClass("make")) {
      Swal.fire({
        title:
          "Do you want to set the latest screenshot to be the new reference?",
        showDenyButton: true,
        confirmButtonText: "Yes",

        denyButtonText: `No`,
      }).then((result) => {
        /* Read more about isConfirmed, isDenied below */
        if (result.isConfirmed) {
          takeSnapshot($(this).attr("data-id"), $(this).hasClass("make"));
          Swal.fire("Reference screenshot has been updated!", "", "success");
        } else if (result.isDenied) {
          Swal.fire(
            "The reference screenshot will not be changed.",
            "",
            "info"
          );
        }
      });
    } else {
      takeSnapshot($(this).attr("data-id"), $(this).hasClass("make"));
    }
  });
  $("form#batch_site").on("submit", function (e) {
    var form = $(this);
    e.preventDefault();
    $(".is-invalid").removeClass("is-invalid");
    var serialized = form.serializeArray();
    var data = {};
    //form.find('.spinner-border').removeClass("d-none")
    Object.entries(serialized).forEach(([key, value]) => {
      var field = value.name.replace(/site\[/, "").replace(/\]/, "");
      data[field] = value.value;
    });
    data.urls = []
    
    $(".multisiteListGroup").find(".list-group-item").each(function(){
      data.urls.push($(this).text())
    })
    if( data.urls.length == 0){
      alert("You have not provided any valid URLS.")
      return;
    }
   

    data.snapshot_weekly = $(this)
      .find("[name='site[snapshot_weekly]']")
      .prop("checked")
      ? 1
      : 0;
    data.threshold = $(this).find("[name='site[threshold]']").prop("checked")
      ? 1
      : 0;
    data.is_batch = true;
    if (typeof site_id == "undefined") {
      site_id = 0;
    }
    if (site_id == 0) {
      $(".loading-block-overlay").find(".message").html("Saving Site...");
    } else {
      $(".loading-block-overlay").find(".message").html("");
    }
    $(".loading-block-overlay").css({ opacity: 1 }).show();
    jQuery.ajax({
      url: "/sites/save/" + parseInt(site_id),
      method: "post",
      dataType: "json",
      data: data,
      success: function (result) {
        if (result.success) {
          $(".loading-block-overlay")
            .find(".message")
            .html("Sites Created!")
            .addClass("animate__animated animate__bounce");
          setTimeout(function () {
            $(".loading-block-overlay").find(".message").html("Reloading...");
            window.location.reload();
          }, 3000);
        }
      },
      error: function (xhr) {
        //popupError(xhr, form);
        $(".loading-block-overlay").css({ opacity: 0 }).hide();
        title = xhr.responseJSON.message;
        Object.entries(xhr.responseJSON.errors).forEach(([key, value]) => {
          if (form != null) {
            if (form.find("[name='site[" + key + "]']").length) {
              form.find("[name='site[" + key + "]']").addClass("is-invalid");
              form
                .find("[name='site[" + key + "]']")
                .unbind("keypress")
                .on("keypress", function () {
                  $(this).removeClass("is-invalid");
                });
            } else {
              form.find("[name='" + key + "']").addClass("is-invalid");
              form
                .find("[name='" + key + "']")
                .unbind("keypress")
                .on("keypress", function () {
                  $(this).removeClass("is-invalid");
                });
            }
          }
          msg = value.join("<br>");
        });
        Swal.fire({
          title: title,
          icon: "error",
          html: msg,
          didOpen: () => {
            $(".loading-block-overlay")
              .find(".message")
              .html("Refreshing Page...");
            $("#new-site").modal("hide");
          },
          didClose: () => {
            window.location.reload();
          },
        });
      },
    });
  });
  $(".show-token").on("click", function (e) {
    e.preventDefault();
    var token = $(this).data("api_token");
    navigator.clipboard.writeText(token);
    if (token) {
      Toast.fire({
        title: "Token copied to clipboard!",
        timer: "3000",
      });
    }
  });
  $(".btd-add-payment").on("click", function (e) {
    e.preventDefault();
    var paymentEl = document.getElementById("payment-method");
    var paymentModal = new bootstrap.Modal(paymentEl, {
      keyboard: false,
    });
    paymentEl.addEventListener("shown.bs.modal", () => {
      initPaymentIntent();
    });
    paymentModal.show();
  });
  const snapShotCanvasElem = document.getElementById("snapShotCanvas");
  const snapShotCompareCanvasElem = document.getElementById(
    "snapShotCompareCanvas"
  );
  if (snapShotCanvasElem) {
    /* var throttleMouseMoveFn = _.throttle(function (e) {
           
            var xDiff = Math.abs(prevMousePosition.x - e.screenX);
            var yDiff = Math.abs(prevMousePosition.y - e.screenY);

            if (xDiff < 50 && yDiff < 50) {
                clearTimeout(moveDebounce);
                moveDebounce = null;
            }
            prevMousePosition.x = e.screenX;
            prevMousePosition.y = e.screenY;
        }, 500);
        var throttleMouseWheelFn = _.throttle(function (e) {
            clearTimeout(moveDebounce);
            moveDebounce = null;
        }, 500);
        document.addEventListener("mousemove", throttleMouseMoveFn);
        document.addEventListener("mousewheel", throttleMouseWheelFn);
        $("body").on("mousewheel", function (e) {
            if (moveDebounce !== null) {
                clearTimeout(moveDebounce);
            }

            moveDebounce = setTimeout(function () {
                // nothing to do here we just need to set moveDebounce
                moveDebounce = null;
            }, 150);
        }); */
    $("body").on("scroll", function (e) {
      if ($("#snapshotCarousel:hover").length) {
        e.preventDefault();
      }
    });
    $("body").on("scroll", function (e) {
      adjustImageFrame();
    });

    snapShotCanvasElem.addEventListener("hide.bs.offcanvas", (event) => {
      //$(".site-list").addClass("col-lg-12").removeClass("col-lg-6")
      //$(".stretch").removeClass("col-lg-12").addClass("col-lg-6")
      snapShotCompareCanvas.hide();
      $(".pip").addClass("offscreen");
      $("tr.site-page").removeClass("site-page-hovered");
    });
    snapShotCanvasElem.addEventListener("show.bs.offcanvas", (event) => {
      //$(".site-list").removeClass("col-lg-12").addClass("col-lg-6")
      //$(".stretch").removeClass("col-lg-6").addClass("col-lg-12")
      $(".pip").removeClass("offscreen");
    });
    snapShotCompareCanvasElem.addEventListener("hide.bs.offcanvas", (event) => {
      $(".pip").removeClass("offscreen");

      var scrollPosition = $("#snapShotCanvas .offcanvas-body").scrollTop();
      var ratio = $(".pip-image").height() / $(".left-image").height();
      var pipOffset = -scrollPosition * ratio;
      $(".pip-image").css({ top: pipOffset + "px" });
    });
    snapShotCompareCanvasElem.addEventListener("show.bs.offcanvas", (event) => {
      //$(".pip").addClass("offscreen");
    });
  }
  $(".pip .bi-arrows-fullscreen").on("click", function () {
    if (thisIsHovered) {
      thisIsHovered.find(".view-screenshot").click();
    }
  });
  $(".click-to-view").on("click", function (e) {
    e.preventDefault();
    var refImg = thisIsHovered.data("ref-image");
    window.open(refImg);
  });
  $(".btn-download-snapshot").on("click", function () {
    var site_id = $(this).attr("data-id");
    var is_dev = window.location.pathname.match(/\/live\//) ? 0 : 1;
    window.location = "/sites/download/" + is_dev + "/" + parseInt(site_id);
  });
  $(".view-comparison").on("click", function () {
    snapShotCompareCanvas.show();
    /* var pip = $(".pip-image").clone()
		pip.removeClass("w-auto m-auto")
		pip.css({zIndex:9999,width:$(".pip-image").width()+"px",top:$(".pip-image").offset().top+"px",left:$(".pip-image").offset().left+"px",transition:"height 0.5s ease, width 0.5s ease, left 0.5s ease, top 0.5s ease"})
		pip.insertBefore($(".pip"))
		setTimeout(function(){
			pip.css({width:"50%",top:"62px",left:"0"})
			setTimeout(function(){
				snapShotCompareCanvas.show()
				setTimeout(function(){
					pip.fadeTo(500,0,function(){
						pip.remove();
					})
				},500)
			},500)
		},0) */
  });
  //$(".snapshot-container").css({maxHeight: ($("form#site_links").height()/2)+"px"});
  $("#snapshotCarousel").css({
    height: $(window).height() / 2 + "px",
    width: $(window).height() / 2 + "px",
  });

  //synchronize scroll of open canvas

  $("#snapShotCanvas .offcanvas-body")
    .off()
    .on("scroll", function (e) {
      if ($("#snapShotCanvas:hover").length > 0) {
        var scrollPosition = $(this).scrollTop();
        $("#snapShotCompareCanvas .offcanvas-body").scrollTop(scrollPosition);
        var ratio = $(".pip-image").height() / $(".left-image").height();
        var pipOffset = -scrollPosition * ratio;
        $(".pip-image")
          .stop()
          .css({ top: pipOffset + "px" });
      }
    });
  $("#snapShotCompareCanvas .offcanvas-body")
    .off()
    .on("scroll", function (e) {
      if ($("#snapShotCompareCanvas:hover").length > 0) {
        if ($("#snapShotCanvas").hasClass("show")) {
          var scrollPosition = $(this).scrollTop();
          $("#snapShotCanvas .offcanvas-body").scrollTop(scrollPosition);
        }
        var ratio = $(".pip-image").height() / $(".left-image").height();
        var pipOffset = -scrollPosition * ratio;
        $(".pip-image")
          .stop()
          .css({ top: pipOffset + "px" });
      }
    });

  $(".btn-fs").on("click", function () {
    $("#snapshotCarousel").addClass("fullscreen");
    $("body,html").addClass("has-fullscreen");
    $(".btn-min-fs").removeClass("fs-disabled");
    $(this).addClass("fs-disabled");
    //fs.removeAttr("style")
    $("[data-bs-title]").tooltip("hide");
    if($(".btn-old").hasClass("btn-primary")){
      loadCrops();
    }
  });
  $(".btn-min-fs").on("click", function () {
    $("#snapshotCarousel").removeClass("fullscreen");
    $("body,html").removeClass("has-fullscreen");
    $(".btn-fs").removeClass("fs-disabled");
    $(this).addClass("fs-disabled");
    //fs.removeAttr("style")
    $("[data-bs-title]").tooltip("hide");
    hideCrops();
  });
  $(".btn-close-fs").on("click", function () {
    $("#snapshotCarousel").removeClass("fullscreen");
    $("body,html").removeClass("has-fullscreen");
    $(".btn-fs").removeClass("fs-disabled");
    $(".btn-min-fs").addClass("fs-disabled");
    $("#snapshotCarousel").addClass("d-none");
    $("[data-bs-title]").tooltip("hide");
    hideCrops();
  });
  $(".btn-account-change-password").on("click", function () {
    if ($(".chg-pwd").is(":visible")) {
      $(".chg-pwd").hide("fast");
      $("#password, #password_confirmation").val("");
    } else {
      $(".chg-pwd").show("fast");
    }
  });

  /**
   * PreLoad Images
   */
  preload = [];
  preloadsizes = [];
  preloadIDs = [];
  preloadCounts = {};
  var totalpreloadsize = 0;
  $("[data-ref-image]").each(function () {
    if (!$(this).find(".site-link-check").prop("checked")) {
      $(this).removeClass("image-loading");
      return;
    }
    var rImg = $(this).data("ref-image");
    var cImg =
      typeof $(this).data("image") != "undefined"
        ? $(this).data("image")
        : null;
    var dImg =
      typeof $(this).data("diff-image") != "undefined"
        ? $(this).data("diff-image")
        : null;
    var size =
      typeof $(this).data("ref-size") != "undefined"
        ? parseInt($(this).data("ref-size"))
        : 0;
    var snapshot_id = $(this).data("snapshot_id");
    if (typeof preloadIDs[snapshot_id] == "undefined") {
      preloadCounts[snapshot_id] = 0;
    }

    if (rImg) {
      preloadCounts[snapshot_id] += 1;
      preloadIDs.push(snapshot_id);
      preload.push(rImg);
      preloadsizes.push(size);
      totalpreloadsize += size;
    }
    if (cImg) {
      preloadCounts[snapshot_id] += 1;
      preloadIDs.push(snapshot_id);
      preload.push(cImg);
      preloadsizes.push(size);
      totalpreloadsize += size;
    }
    if (dImg) {
      preloadCounts[snapshot_id] += 1;
      preloadIDs.push(snapshot_id);
      preload.push(dImg);
      preloadsizes.push(size);
      totalpreloadsize += size;
    }
  });

  var lazyloadImages;
  var sizeUnit = " KB";
  totalpreloadsize = totalpreloadsize / 1024;
  if (totalpreloadsize > 1024) {
    totalpreloadsize = totalpreloadsize / 1024;
    sizeUnit = " MB";
  }
  if (totalpreloadsize > 1024) {
    totalpreloadsize = totalpreloadsize / 1024;
    sizeUnit = " GB";
  }
  const nFormat = new Intl.NumberFormat();
  totalpreloadsize = totalpreloadsize.toFixed(1);
  totalpreloadsize = nFormat.format(totalpreloadsize);
  if ("IntersectionObserver" in window) {
    var rowObserver = new IntersectionObserver(function (entries, {}) {
      entries.forEach(function (entry) {
        var row = entry.target;
        if (entry.isIntersecting) {
          $(row).addClass("lastrow");
        } else {
          $(row).removeClass("lastrow");
        }
      });
      lastrow = $(".site-page.lastrow:last");
    });

    document.querySelectorAll(".site-page").forEach(function (row) {
      rowObserver.observe(row);
    });
    var nocache_string = new Date().getTime();
    var lazyObserver = new IntersectionObserver(function (entries, {}) {
      entries.forEach(function (entry) {
        var img = entry.target;
        if (entry.isIntersecting) {
          $(img).attr("decoding","async")
          lazyObserver.unobserve(img);
          var src = $(img).data("src");
          var I = new Image();
          $(I).on("load", function () {
            $(img).attr("src", $(img).data("src"));
            $(img).removeClass("lazy");
          });
          I.src = src;
        }
      });
    });

    document.querySelectorAll(".b2-item > img.lazy").forEach(function (img) {
      lazyObserver.observe(img);
    });
  }

  $(".image-loading").removeClass("image-loading");
  if (preload.length && false) {
    var current = 0;
    var currentsize = 0;
    if ($(".progress-bar").length == 0) {
      Toast.fire({
        title: "Pre-Loading Screenshots...",
        allowOutsideClick: false,
        position: "bottom-end",
        timer: 99999,
        html: '<div style="height:50px;" class="progress rounded-0" role="progressbar" aria-label="Info example" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"><div class="translate progress-bar preload-bar text-white bg-primary rounded-0 text-dark" style="width: 0%">0%</div></div>',
        didOpen: () => {
          for (var i in preload) {
            var src = preload[i];
            var Img = new Image();
            $(Img).attr("data-index", i);
            $(Img)
              .on("load", function () {
                var filesize = preloadsizes[parseInt($(this).attr("idx"))];
                current++;
                currentsize += filesize;
                var formattedcurrentsize = currentsize / 1024;
                var formattedSizeUnit = " KB";
                if (formattedcurrentsize > 1024) {
                  formattedcurrentsize = formattedcurrentsize / 1024;
                  var formattedSizeUnit = " MB";
                }
                if (formattedcurrentsize > 1024) {
                  formattedcurrentsize = formattedcurrentsize / 1024;
                  var formattedSizeUnit = " GB";
                }
                const nFormat = new Intl.NumberFormat();
                formattedcurrentsize = formattedcurrentsize.toFixed(1);
                formattedcurrentsize = nFormat.format(formattedcurrentsize);
                var p = Math.ceil((current / preload.length) * 100);
                var preload_id = preloadIDs[$(this).data("index")];
                preloadCounts[preload_id] -= 1;
                if (preloadCounts[preload_id] <= 0) {
                  $(
                    ".site-page[data-snapshot_id=" + preload_id + "]"
                  ).removeClass("image-loading");
                }

                //console.log(preload_id,preloadCounts[preload_id])
                $(".preload-bar")
                  .css({ width: p + "%" })
                  .text(
                    formattedcurrentsize +
                      formattedSizeUnit +
                      " / " +
                      totalpreloadsize +
                      sizeUnit
                  );
                var src = $(this).attr("src");
                var u = new URL(src);
                var file = u.pathname.split("/").reverse()[0];
                $(this)
                  .addClass(
                    "screenshot position-absolute top-0 left-0 w-100 snapshot-page"
                  )
                  .addClass(file.replace(/\./, "-"))
                  .css({ opacity: 0 });
                if (file.match(/ref/)) {
                  $(this).addClass("old");
                } else if (file.match(/diff/)) {
                  $(this).addClass("diff").css({ opacity: 0 });
                } else {
                  $(this).addClass("new").css({ opacity: 0 });
                }
                screenshots[file] = $(this);
                if (p >= 100) {
                  setTimeout(function () {
                    Swal.close();
                  }, 1000);
                }
              })
              .on("error", function () {
                current++;
                //console.log('error',src);
              });
            $(Img).attr("idx", i);
            Img.src = src;
          }
        },
      });
    } else {
      // THIS PRELOAD IS ACTIVE
      for (var i in preload) {
        var src = preload[i];
        var Img = new Image();
        $(Img).on("load", function () {
          current++;
          var p = Math.ceil((current / preload.length) * 100);
          $(".preload-bar")
            .css({ width: p + "%" })
            .text(p + "%");
          var src = $(this).attr("src");
          var u = new URL(src);
          var file = u.pathname.split("/").reverse()[0];
          $(this)
            .addClass(
              "screenshot position-absolute top-0 left-0 w-100 snapshot-page"
            )
            .addClass(file.replace(/\./, "-"))
            .css({ opacity: 0 });
          if (file.match(/ref/)) {
            $(this).addClass("old");
          } else if (file.match(/diff/)) {
            $(this).addClass("diff").css({ opacity: 0 });
          } else {
            $(this).addClass("new").css({ opacity: 0 });
          }
          screenshots[file] = $(this);
          if (p >= 100) {
            //Swal.close();
          }
        });
        Img.src = src;
      }
    }
  }
  $(".b2-item")
    .on("click", function (e) {
      e.preventDefault();

      $(this).toggleClass("enlarged");
      if ($(this).hasClass("enlarged")) {
        $(".b2-item").not($(this)).hide();
      } else {
        $(".b2-item").show();
      }
    })
    .on("mouseover", function () {
      var title = $(this).attr("title");
      $(".b2-data-title").text(title);
    })
    .on("mouseout", function () {
      $(".b2-data-title").text("");
    });
  for (var i in preload) {
    var src = preload[i];
    var Img = new Image();

    Img.src = src;
    var u = new URL(src);
    var file = u.pathname.split("/").reverse()[0];
    $(Img)
      .addClass("screenshot position-absolute top-0 left-0 w-100 snapshot-page")
      .addClass(file.replace(/\./, "-"))
      .css({ opacity: 0 });
    if (file.match(/ref/)) {
      $(Img).addClass("old");
    } else if (file.match(/diff/)) {
      $(Img).addClass("diff").css({ opacity: 0 });
    } else {
      $(Img).addClass("new").css({ opacity: 0 });
    }
    $(Img).css({ opacity: 0 });
    screenshots[file] = $(Img);
  }

  /**
   *  reset hover
   */
  jQuery(document).on("mouseover", function (e) {
    clearTimeout(unhovertimer);
    unhovertimer = setTimeout(function () {
      if (
        jQuery(".site-page-hovered:hover").length == 0 &&
        $("#snapshotCarousel:hover").length == 0
      ) {
        /*  $("#snapshotCarousel").addClass("d-none");
                $("tr.site-page").removeClass("site-page-hovered");
                
                hovertimer = null */
      }
    }, 1750);
  });
  hideCrops();
  $(".btn-crop").addClass("d-none");
  // init buttons
  $(".btn-crop").off("click")
  .on("click", function () {
    initCrop();  
  }).addClass("d-none");
  $(".btn-old")
    .off("click")
    .on("click", function () {
      $(".btn-crop").removeClass("d-none");
      loadCrops();
      $(".btn-new").addClass("btn-secondary").removeClass("btn-primary");
      $(".btn-diff").addClass("btn-secondary").removeClass("btn-primary");
      $(".btn-old").removeClass("btn-secondary").addClass("btn-primary");
      $("img.new,img.diff").css({ opacity: 0, zIndex: 0 });
      setTimeout(function () {
        console.log( $("img.old").attr("class"))
        $("img.old").css({ opacity: 1, zIndex: 1 });
      }, 300);
  });
  $(".btn-new")
    .off("click")
    .on("click", function () {
      hideCrops();
      $(".btn-crop").addClass("d-none");
      $(".btn-old").addClass("btn-secondary").removeClass("btn-primary");
      $(".btn-diff").addClass("btn-secondary").removeClass("btn-primary");
      $(".btn-new").removeClass("btn-secondary").addClass("btn-primary");
      $("img.old,img.diff").css({ opacity: 0, zIndex: 0 });
      setTimeout(function () {
        $("img.new").css({ opacity: 1, zIndex: 1 });
      }, 300);
    });
  $(".btn-diff")
    .off("click")
    .on("click", function () {
      hideCrops();
      $(".btn-crop").addClass("d-none");
      $(".btn-old").addClass("btn-secondary").removeClass("btn-primary");
      $(".btn-new").addClass("btn-secondary").removeClass("btn-primary");
      $(".btn-diff").removeClass("btn-secondary").addClass("btn-primary");
      $("img.new,img.old").css({ opacity: 0, zIndex: 0 });
      setTimeout(function () {
        $("img.diff").css({ opacity: 1, zIndex: 1 });
      }, 300);
    });
  /**
   * image hover
   */
  jQuery(".site-page")
    .on("mouseover", function (e) {
     
      
      if ($(this).hasClass("image-loading")) {
        jQuery(".site-pages:not(.nosort)").sortable("disable");
        return;
      }
      jQuery(".site-pages:not(.nosort)").sortable("enable");
      if (thisIsHovered == $(this)) {
        return;
      } else {
        thisIsHovered = $(this);
        $(".hovered").removeClass("hovered");
        $(this).addClass("hovered");
        if (hovertimer) {
          clearTimeout(hovertimer);
          hovertimer = null;
        }
      }

      hovertimer = setTimeout(function () {
        if (typeof thisIsHovered == "undefined") {
          return;
        }
       
        var snapshot_id = thisIsHovered.data("snapshot_id");
        snapshot_id_popped = snapshot_id
        if (
          $("#snapshotCarousel .card-body").find(
            "img[class*=" + snapshot_id + "]"
          ).length > 0
        ) {
          return;
        }
        $(".image-spinner").removeClass("d-none").addClass("d-flex");
        var rImg = thisIsHovered.data("ref-image");
        var cImg =
          typeof thisIsHovered.data("image") != "undefined"
            ? thisIsHovered.data("image")
            : null;
        var dImg =
          typeof thisIsHovered.data("diff-image") != "undefined"
            ? thisIsHovered.data("diff-image")
            : null;
        var refImg_date = null;
        var screenshotImg_date = null;
        var diffImg_date = null;
        var percent_diff = null;
        $(".image-buttons").addClass("d-none");

        $("#snapshotCarousel .card-body").find("img").remove();
       
        if (!rImg) {
          $(".image-info").html(
            '<i class="text-danger fa fa-exclamation-circle"></i> Screenshot is not available.'
          );
          $(".image-spinner").addClass("d-none").removeClass("d-flex");
          //$("#snapshotCarousel").addClass("d-none")
          return;
        }

        adjustImageFrame();
        $("#snapshotCarousel").removeClass("d-none");
        

       
        if ($(window).width() < 992) {
          console.log("is mobile");
          $("[data-bs-title]").tooltip("hide");
          $("#snapshotCarousel").addClass("fullscreen");
          //$(".btn-fs").attr("title","Minimize")
          $("body,html").addClass("has-fullscreen");
          $(".btn-min-fs").hide();
          $(".btn-fs").hide();
          $(".btn-close-fs").css({ right: "15px" });
        } else {
          var space = $(".linksbox").offset().left + $(".linksbox").width();
        
          if(typeof e.originalEvent == 'undefined'){
            console.log("next triggerer")
          } else {
            $("#snapshotCarousel").removeClass("fullscreen");
          }
          //$(".btn-fs").attr("title","Maximize")
          $("body,html").removeClass("has-fullscreen");
          $("#snapshotCarousel").css({
            width: $(document).width() - space - 45,
          });
          console.log($(document).width() - space - 45)
          $(".btn-fs").show();
          $(".btn-min-fs").show();
          $(".btn-close-fs").css({ right: "65px" });
        }
        var other_images = 0;
        $(".btn-crop").addClass("d-none");
        var nocache_string = new Date().getTime();
        if (typeof rImg != "undefined") {
          refImg_date = thisIsHovered.data("ref-image-date");
          var u = new URL(rImg);
          var file = u.pathname.split("/").reverse()[0];
          var rimg = screenshots[file];
          
          if (typeof rimg == "undefined") {
            $(".loading_ss").addClass("d-none");
            $(".inactive_ss").removeClass("d-none");
            $(".image-info").text(
              "To enable preview for this page check the box associated with it then reload the page."
            );
            return;
          } else {
            rimg.attr("decoding","async")
            rimg.attr("src",rimg.attr("src")+"?nocache="+nocache_string)
            
            $(".loading_ss").removeClass("d-none");
            $(".inactive_ss").addClass("d-none");
            rimg.prependTo($("#snapshotCarousel .card-body"));
            other_images = rimg.siblings("img").length;
            $(".image-info").html(thisIsHovered.data("taken_text"));
          }
        } else {
          
        }
        if (cImg) {
          other_images++;
          screenshotImg_date = thisIsHovered.data("image-date");
          var u = new URL(cImg);
          var file = u.pathname.split("/").reverse()[0];
          var img = screenshots[file];
          img.attr("decoding","async")
          img.attr("src",img.attr("src")+"?nocache="+nocache_string)
          img.prependTo($("#snapshotCarousel .card-body"));
          img.css({ opacity: 1 });
        }

        if (dImg) {
          other_images++;
          percent_diff = thisIsHovered.data("percent-diff");
          diffImg_date = thisIsHovered.data("diff-image-date");

          var u = new URL(dImg);
          var file = u.pathname.split("/").reverse()[0];
          var img = screenshots[file].clone();
          img.attr("decoding","async")
          img.attr("src",img.attr("src")+"?nocache="+nocache_string)
          img.addClass("diff").removeClass("new");
          img.prependTo($("#snapshotCarousel .card-body"));
          img.css({ opacity: 1 });
          $(".btn-diff").addClass("btn-primary").removeClass("btn-secondary");
          $(".btn-diff")
            .removeClass("d-none")
            .addClass("btn-secondary")
            .removeClass("btn-primary");
          $(".btn-new")
            .removeClass("d-none")
            .addClass("btn-secondary")
            .removeClass("btn-primary");
          $(".btn-old")
            .removeClass("d-none")
            .addClass("btn-secondary")
            .removeClass("btn-primary");
          $(".image-info").html(thisIsHovered.data("popup_text"));
          $(".btn-crop").removeClass("d-none");
        } else {
         
          $(".btn-diff").addClass("d-none");
          $(".btn-new").addClass("d-none");
          $(".btn-old").addClass("d-none");
          rimg.css({ zIndex: 1 })
          rimg.on("load",function(){
            rimg.fadeTo(500,1);
          })
        }
        if (rImg) {
          if (other_images > 0) {
            $(".btn-diff").trigger("click");
          } else {
            $(".btn-old").trigger("click");
          }
        }

        $(".image-buttons").removeClass("d-none");
        setTimeout(function () {
          $(".image-spinner").addClass("d-none").removeClass("d-flex");
        }, 300);
      }, 500);
    })
    .on("mouseout", function () {
      if (hovertimer) {
        clearTimeout(hovertimer);
        hovertimer = null;
      }
    });

  jQuery(".view-screenshot").on("click", function (e) {
    e.preventDefault();
    var th = (thisIsHovered = $(this).parent().parent().parent());
    th.each(function () {
      if (
        $(this).find(".fa-grip-vertical:hover").length > 0 ||
        $(this).find(".btn-link-hide:hover").length > 0 ||
        $(this).find(".form-check-input:hover").length > 0 ||
        $(this).find(".form-check-label:hover").length > 0
      ) {
        return;
      }

      var screenshotImg = $(this).data("image");
      var refImg = $(this).data("ref-image");
      var diffImg = $(this).data("diff-image");

      var page = $(this).attr("data-page");

      $(".carousel-item.active").toggleClass("active d-none");
      $(".carousel-item[data-page='" + page + "']").toggleClass(
        "active d-none"
      );
      $("#snapShotCompareCanvas .offcanvas-title").html(
        $(".domain-text").text() + page
      );
      if ($("#snapShotCanvas").hasClass("show")) {
      }

      if (e.type != "mouseover" || 1) {
        $("tr.site-page").removeClass("site-page-hovered");
        $(this).addClass("site-page-hovered");
        $(".btn-new").addClass("btn-secondary").removeClass("btn-primary");
        $(".btn-old").addClass("btn-primary").removeClass("btn-secondary");
        if (diffImg) {
          lazyLoadScreenshot($(".right-image"), diffImg);
          lazyLoadScreenshot($(".left-image"), screenshotImg);
          lazyLoadScreenshot($(".pip-image"), screenshotImg);
          $(".btn-old")
            .off("click")
            .on("click", function () {
              $(".btn-new")
                .addClass("btn-secondary")
                .removeClass("btn-primary");
              $(this).removeClass("btn-secondary").addClass("btn-primary");
              lazyLoadScreenshot($(".left-image"), refImg);
            })
            .show();
          $(".btn-new")
            .off("click")
            .on("click", function () {
              $(".btn-old")
                .addClass("btn-secondary")
                .removeClass("btn-primary");
              $(this).removeClass("btn-secondary").addClass("btn-primary");
              lazyLoadScreenshot($(".left-image"), screenshotImg);
            })
            .show();
        } else {
          $(".btn-old").hide();
          $(".btn-new").hide();
          lazyLoadScreenshot($(".right-image"), screenshotImg);
          lazyLoadScreenshot($(".left-image"), screenshotImg);
          lazyLoadScreenshot($(".pip-image"), screenshotImg);
        }
        $(".pip-image").css({ top: "0px" });
        snapShotCanvas.show();
      }

      currentPage = page;
    });
  });

  $(".snapshot-nav.next-button").on("click",function(){
    var next = thisIsHovered.next("tr")
    if(next.length == 0){
      next = $(".site-page:first")
    }
    
    $("#snapshotCarousel").find(".card-body").animate({left:-$("#snapshotCarousel").width()},200,
      function(){
        
        $(this).find("img.screenshot").css({opacity:0})
        $(this).css({left:0})
        next.trigger("mouseover")
       
    })
   
  })
  $(".snapshot-nav.prev-button").on("click",function(){
    var next = thisIsHovered.prev("tr")
    if(next.length == 0){
      next = $(".site-page:last")
    }
    next.trigger("mouseover")
    $("#snapshotCarousel").find(".card-body").animate({left:$("#snapshotCarousel").width()},200,
      function(){
        
        $(this).find("img.screenshot").css({opacity:0})
        $(this).css({left:0})
        next.trigger("mouseover")
       
    })
  })
  jQuery(".btn-approve").on("click", function (e) {
    e.preventDefault();

    var site_id = $(this).attr("data-id");

    Swal.fire({
      title: "Are you sure?",
      icon: "warning",
      html: "You are about to make the most recent snapshot your new baseline. Future snapshots will reference this one.",
      showCancelButton: true,

      cancelButtonColor: "#d33",
      confirmButtonText: "Yes, do it!",
    }).then((result) => {
      if (result.isConfirmed) {
        $(".loading-block-overlay").find(".message").html("Please Wait...");
        $(".loading-block-overlay").css({ opacity: 1 }).show();
        jQuery.ajax({
          url: "/snapshots/approve/" + parseInt(site_id),
          method: "post",
          dataType: "json",
          data: {
            is_dev: window.location.pathname.match(/\/live\//) ? 0 : 1,
          },
          success: function (result) {
            $(".loading-block-overlay")
              .find(".message")
              .html("Done! Reloading...");
            window.location.reload();
          },
          error: function (xhr) {
            popupError(xhr);
          },
        });
      }
    });
  });
  jQuery(".new-snapshot").on("click", function (e) {
    e.preventDefault();
    var site_id = $(this).attr("data-id");
    jQuery.ajax({
      url: "/snapshots/take/" + parseInt(site_id),
      method: "post",
      dataType: "json",
      data: {},
      success: function (result) {},
      error: function (xhr) {
        popupError(xhr);
      },
    });
  });
  jQuery(".btn-recrawl").on("click", function (e) {
    e.preventDefault();
    var html = $(this).data("bs-title");
    var href = $(this).attr("href");
    Swal.fire({
      title: "Recrawl Site?",
      icon: "warning",
      html: html,
      width: "500px",
      showCancelButton: true,
      cancelButtonColor: "#73a81e",
      confirmButtonText: "Do it!",
    }).then((result) => {
      if (result.isConfirmed) {
        window.location = href;
      }
    });
  });

  if (jQuery("#site_links").length > 0) {
    $("tr.site-page").each(function () {
      var link = $(this);
      initLinkTrash(link);
    });
    $(".site-link-check").on("click", function (e) {
      
      if (!e.shiftKey) {
        firstCBClicked = $(this);
      }

      var boxes_checked = $(".site-link-check:checked").length;

      if (firstCBClicked && e.shiftKey) {
        var first = firstCBClicked.index(".site-link-check");
        var last = $(this).index(".site-link-check");
        var selected = [];
        if (first > last) {
          last = first;
          first = $(this).index(".site-link-check");
        }
        for (var i = last; i >= first; i--) {
          var cb = $(".site-link-check:eq(" + i + ")");
          selected.push(cb);
          cb.prop("checked", firstCBClicked.prop("checked")).change();
        }

        if (selected.length == $(".site-link-check").length) {
          $("#snapshot_links_cb").prop("checked", true);
        }
        firstCBClicked = $(this);
      }
      submitLinkForm();
      
    });

    jQuery(".site-pages:not(.nosort)").sortable({
      placeholder: "page-sort-placeholder",
      items: "> .site-page",
      distance: 5,
      stop(event, ui) {
        submitLinkForm();
      },
    });

    // /$(".last_snapshot_time").html(Math.floor(Math.random() * 100) + 1 + " minutes")
    //$(".num_of_pages").html($("tr.site-page").length);
    $(".page-ref-snapshot").on("click", function () {
      var th = $(this);
      var refImg = $(".snapshot-ref-image").find("img");
      var diffImg = $(".snapshot-ref-image").find("img");
      refImg.fadeTo(500, 0, function () {
        var i = new Image();

        $(i).on("load", function () {
          refImg.attr("src", $(this).attr("src"));
          setTimeout(function () {
            refImg.fadeTo(500, 1);
          }, 100);
        });

        i.src = th.attr("data-ref-src");
      });

      diffImg.fadeTo(500, 0, function () {
        if (th.attr("data-src")) {
          var i = new Image();

          $(i).on("load", function () {
            diffImg.attr("src", $(this).attr("src"));
            setTimeout(function () {
              diffImg.fadeTo(500, 1);
            }, 100);
          });

          i.src = th.attr("data-src");
        }
      });
    });
  }
  if (jQuery("#site_links").length && 0) {
    resetLinksForm(site_id, false);
    var form = $("#site_links");
    var site_id = form.find("#site_id").val();
    //$(".loading-block-overlay").css({opacity:1}).show();
    form.find(".alert").addClass("d-none");

    var tr = $("<tr class='links-row'><td class='p-0' colspan='8'></td></tr>");

    jQuery.ajax({
      url: "/sites/links/" + parseInt(site_id),
      method: "post",
      dataType: "json",
      data: { is_dev: 0 },
      success: function (result) {
        form.find(".list-group-item.loader").addClass("d-none");
        form.find(".list-group-item.header").show();

        $(".add-site-link").val("");
        if (result.found_urls.length == 0) {
          form.find(".alert").removeClass("d-none");
        }

        Object.entries(result.found_urls).forEach(([key, value]) => {
          var checked = "";
          var hidden = "";
          var display = "";
          var hideText = "";
          var icon = "-slash";
          var hiddenClass = "";
          // first time its an string then its an object
          if (typeof value == "object") {
            if (typeof value.hidden != "undefined") {
              if (value.hide_Status == "1") {
                hidden = "hideme";
                hideText = "";
                icon = "";
                hiddenClass = "opacity-25";
              }
            }
            if (value.is_active == "1") {
              checked = "checked";
            }
            //value = value.value;
          }

          var link = $(
            '<tr class="site-page ' +
              hiddenClass +
              '">\
		            				 <td class="col-1 drag-handle">\
				                        <i class="fa-solid fa-grip-vertical"></i>\
				                    </td>\
		            				<td><div class="form-check col-3">\
		            					<div class="spinner-border spinner-border-sm d-none" role="status">\
						                	<span class="visually-hidden">Loading...</span>\
						            	</div>\
						              <input class="' +
              hidden +
              ' form-check-input site-link-check" type="checkbox" ' +
              checked +
              ' value="' +
              value.page +
              '" id="snapshot_links_' +
              key +
              '" name="links[' +
              key +
              ']">\
						              <label class="form-check-label" for="snapshot_links_' +
              key +
              '">\
						               <a href="https://' +
              result.base_url +
              value.page +
              '" target="_blank">' +
              value.page +
              '</a>\
						              </label>\
					            	</div></td>\
					            	<td><i class="fa-solid fa-chart-pie"></i></td>\
					            	<td><i class="fa-solid fa-image"></i></td>\
					            	<td >\
									<button class="btn d-inline-block btn-link btn-link-trash float-end text-danger text-decoration-none" ><i class="fa fa-trash"></i> Delete</button>\
					            	<button class="btn d-inline-block  btn-link btn-link-hide float-end text-decoration-none" ><i class="fa-sharp fa-solid fa-eye' +
              icon +
              '"></i> <span>' +
              hideText +
              "</span></button>\
					            	</td>\
					            	</tr>"
          );
          initLinkTrash(link);
          link.appendTo(form.find(".links-container"));
          if (value.value == "/") {
            link
              .find(".btn-link-hide, .btn-link-trash")
              .attr("disabled", true)
              .hide();
            link.find(".form-check-input").attr("disabled", true);
            link.addClass("domain");
          }
        });
        $(".site-link-check").on("click", function () {
          $(this).closest(".spinner-border").removeClass("d-none");
          submitLinkForm();
        });
        jQuery(".list-group")
          .unbind()
          .sortable({
            items: "> tr.site-page:gt(0)",
            forceHelperSize: true,
            distance: 5,
            stop(event, ui) {
              submitLinkForm();
            },
          });
        $(".num_of_pages").html($("tr.site-page").length);
      },
      error: function (xhr) {
        resetLinksForm(site_id, false);

        popupError(xhr, form);
      },
    });
  }

  $("#site_links,#site_add_links").on("submit", function (e) {
    e.preventDefault();
  });
  $(".pastebox").on("click", function (e) {
    var domain = $("#domain").val();
    var domain_url = $("#domain_url").val();
    var inputContainer = $(
      '<div class="input-group mb-1 has-validation"><button class="rounded-0 add-pages-remove btn btn-danger"><i class="fa fa-minus" onclick="$(this).parent().parent().remove();checkAddPages();"></i></button></div>'
    );
    var input = $(
      '<input onchange="clearInputValidity($(this))" onkeydown="clearInputValidity($(this))" placeholder="https://' +
        domain +
        '/page" type="url"   class="list-group-item form-control rounded-0"  value="' +
        domain_url +
        '/">'
    );
    inputContainer.prependTo($(".list-group.add-pages"));
    input.prependTo(inputContainer).focus();
    input.selectRange(input.val().length);
    $("#site_add_links").removeClass("was-validated");
    $(".add-pages-btn").removeClass("d-none");
  });
  $(".add-pages-btn").on("click", function () {
    var domain = $("#domain").val();
    $("#site_add_links").removeClass("was-validated");
    var data = { links: [] };
    $(".list-group.add-pages input").each(function () {
      $(this).blur();
      var input = $(this)[0];
      const validityState = input.validity;
      var v = $(this).val();
      input.setCustomValidity("");
      input.reportValidity();
      if (!v) {
        input.setCustomValidity("Field cannot be blank");
        input.reportValidity();
      } else {
        var url = null;
        try {
          url = new URL(v);
        } catch (e) {
          input.setCustomValidity(
            "Please enter a valid url! For example: https://www.example.com"
          );
          input.reportValidity();
        }
        if (url.host != domain) {
          input.setCustomValidity("Url domain must match site domain!");
          input.reportValidity();
        } else {
          data.links.push(v);
        }
      }
    });
    $("#site_add_links").addClass("was-validated");
    if ($(".list-group.add-pages input:invalid").length == 0) {
      var form = $("#site_add_links");
      var site_id = form.find("#site_id").val();
      $(".loading-block-overlay").css({ opacity: 1 }).show();
      $(".loading-block-overlay")
        .find(".message")
        .html(
          'Checking urls...<br><i class="text-danger fa fa-exclamation-circle"></i> Do not refresh or close this window!'
        );
      jQuery.ajax({
        url: "/sites/links/add/" + parseInt(site_id),
        method: "post",
        dataType: "json",
        data: data,
        success: function (result) {
          $(".loading-block-overlay").css({ opacity: 0 }).hide();
          $(".loading-block-overlay").find(".message").html("");
          var html = "";
          if (result.errors.length) {
            html =
              "<p class='text-start'>The following pages were not added:<ul class='text-start ms-2'>";
            for (var link in result.errors) {
              html +=
                '<li class="text-danger"><i class="fa-solid fa-circle-xmark"></i> ' +
                link +
                ": " +
                result.errors[link] +
                "<li>";
            }
            html += "</ul></p>";
          }
          var footer = "";
          if (result.success) {
            html +=
              "<p class='text-start'>The following pages were added:<ul class='text-start ms-2'>";
            for (var link in result.success) {
              html +=
                '<li class="text-success"><i class="fa-solid fa-circle-check"></i> ' +
                link +
                "<li>";
            }
            html += "</ul></p>";
            html +=
              "<hr><p class=\"text-start\">Click 'Reload' to refresh this page. New pages will appear at the bottom of the list.</p>";
            footer =
              "<i class='fa-solid text-info fa-circle-info'></i> In the event of redirects, pages will store the path of the page we are redirected to.";
          }
          Swal.fire({
            icon: "info",
            html: html,
            showCancelButton: false,
            cancelButtonColor: "#d33",
            confirmButtonText: "Reload",
          }).then((result) => {
            if (result.isConfirmed) {
              window.location.reload();
            }
          });
        },
        error: function (xhr) {
          $(".loading-block-overlay").css({ opacity: 0 }).hide();
          $(".loading-block-overlay").find(".message").html("");
          popupError(xhr, form);
        },
      });
    }
  });
  window.addEventListener("paste", (e) => {
    ////console.log(e);
    var domain = $("#domain").val();
    if ($(".pastebox").length && $(".pastebox:hover").length) {
      e.stopPropagation();
      e.preventDefault();
      var listgroup = $(".list-group.add-pages");
      clipboardData = e.clipboardData || window.clipboardData;
      pastedData = clipboardData.getData("Text").replace(/[^\S\r\n]/g, "");
      var pages = pastedData.split("\n");

      var wereValid = false;
      for (var page in pages) {
        //console.log(page);
        var path = $.trim(pages[page]);
        try {
          url = new URL(path);
          var page = $(
            '<div class="input-group mb-1 has-validation"><input type="text"onchange="clearInputValidity($(this))" onkeydown="clearInputValidity($(this))"   placeholder="https://' +
              domain +
              '/page"   value="' +
              path +
              '" class="list-group-item form-control rounded-0"><button class="rounded-0 add-pages-remove btn btn-danger"><i class="fa fa-minus" onclick="$(this).parent().parent().remove();checkAddPages();"></i></div>'
          );
          page.appendTo(listgroup);
          wereValid = true;
        } catch (e) {}
      }
      if (wereValid) {
        $("#site_add_links").removeClass("was-validated");
        $(".add-pages-btn").removeClass("d-none");
      } else {
        Swal.fire({
          icon: "error",
          title: "No valid urls were detected in your clipboard.",
        });
      }
      /*  
            https://www.firespike.com
            https://www.firespike.com/services/digital-marketing/
            https://www.firespike.com/solutions/content-management/
            https://www.firespike.com/company/mission/ 
            */
    }
   
    if ($("#urls").length && $("#urls:hover").length) {
      //e.stopPropagation();
      e.preventDefault();
      var transposedText = [];
      var listgroup = $(".list-group.add-pages");
      clipboardData = e.clipboardData || window.clipboardData;
      pastedData = clipboardData.getData("Text").replace(/[^\s\S\r\n,]/g, "");
      var sites = pastedData.replace(/(\s|\n|,)/g,"\n");
      sites = sites.split("\n")
      console.log(sites)
      var wereValid = false;
      for (var page in sites) {
       
        var url = sites[page].rtrim('\r').rtrim('/')
        url = $.trim(url);
        if(url.substring(0,4) != "http"){
          url = "https://" + url
        }
        
        console.log(url);
        try {
          var parsed = new URL(url);
          if(parsed.protocol && parsed.host){
            var listItem = $('<li class="list-group-item d-flex justify-content-between align-items-center mb-0">'+url.toLowerCase()+'<span onclick="jQuery(this).parent().remove();if($(\'.multisiteListGroup\').find(\'.list-group-item\').length == 0){$(\'#no-sites\').show()}" class="fa fa-trash" style="cursor:pointer;" aria-hidden="true"></span></li>')
            listItem.appendTo($(".multisiteListGroup"))
            
            
          }
          
          
        } catch (e) {
          
        }
      }
      $("#urls").val('');
      if($(".multisiteListGroup").find(".list-group-item").length > 0){
        $("#no-sites").hide()
      }
      
      /*  
            https://www.babineauconstruction.com/
            https://actioncoachingteams.com/
            actioncoachingteams.com/
            babineauconstruction.com/
              

            */
    }
  });

  jQuery(".btn-cancel-links").click(function (e) {
    var site_id = $("tr[table-id].table-success").attr("table_id");
    resetLinksForm(site_id);
  });
  jQuery("[data-edit-site]").click(function (e) {
    e.preventDefault();
    $("#batch_site").hide();
    // $(newSiteModal._element).find("h1").html("<strong>Edit</strong> Site");
    //$(newSiteModal._element).find("button[type=submit]").text("SAVE SITE");
    var url = $(this).attr("href");
    site_id = parseInt($(this).attr("data-edit-site"));
    user_id = parseInt($(this).attr("data-user-id"));
    jQuery.ajax({
      url: url,
      method: "post",
      dataType: "json",
      data: {
        site_id: site_id,
      },
      success: function (result) {
        newSiteModal.show();
        Object.entries(result.site).forEach(([key, value]) => {
          $("[name='site[" + key + "]']").val(value);
          if (key == "tags" && value) {
            value.split(",").forEach((tag) => {
              $(".tagsinput").tagsinput("add", tag);
            });
          }
        });
        $("[name='user_id']").val(result.site.user_id);
        $("#new_user_id").val(result.site.user_id)
        if (result.site.auth_username || result.site.auth_password) {
          $("#credential-fields").show();
        }
        if (result.site.dev_auth_username || result.site.dev_auth_password) {
          $("#dev-credential-fields").show();
        }
        if (parseInt(result.site.snapshot_weekly)) {
          $("[name='site[snapshot_weekly]']").prop("checked", true);
          $("#snapshot_schedule").show("fast");
          $("#snapshot_threshold").show("fast");
        } else {
          $("[name='site[snapshot_weekly]']").prop("checked", false);
          $("#snapshot_schedule").hide("fast");
          $("#snapshot_threshold").hide("fast");
        }
        if (parseInt(result.site.threshold)) {
          $("[name='site[threshold]']").prop("checked", true);
        } else {
          $("[name='site[threshold]']").prop("checked", false);
        }
      },
      error: function (xhr) {},
    });
  });

  $("#site_snapshot_weekly").on("click", function () {
    if ($(this).prop("checked")) {
      $("#snapshot_schedule").show("fast");
      $("#snapshot_threshold").show("fast");
    } else {
      $("#snapshot_schedule").hide("fast");
      $("#snapshot_threshold").hide("fast");
    }
  });
  /* tags */
  // https://bootstrap-tagsinput.github.io/bootstrap-tagsinput/examples/
  initTagsInput();
  $(".add-tag").on("click", function (e) {
    e.preventDefault();
    $(".tagsinput").tagsinput("add", $(this).text());
  });

  /* misc inputs */
  $("#edit_user").on("change", function () {
    $("#edit_user").find("button[type=submit]").removeAttr("disabled");
  });

  /* delete handler */
  $(".btn-delete").on("click", function (e) {
    e.preventDefault();
    var url = $(this).attr("href");
    var msg = $(this).attr("data-confirm")
      ? $(this).attr("data-confirm")
      : "Are you sure?";
    Swal.fire({
      html: msg,
      icon: "warning",
      showCancelButton: true,
      cancelButtonColor: "#d33",
      confirmButtonText: "Yes, delete it!",
    }).then((result) => {
      if (result.isConfirmed) {
        window.location = url;
      }
    });
  });
  $(".btn-delete-payment-method").on("click", function (e) {
    e.preventDefault();
    var url = $(this).attr("href");
    var msg = $(this).attr("data-confirm")
      ? $(this).attr("data-confirm")
      : "Are you sure?";
    Swal.fire({
      title: msg,
      icon: "warning",
      showCancelButton: true,
      cancelButtonColor: "#d33",
      confirmButtonText: "Yes, delete it!",
    }).then((result) => {
      if (result.isConfirmed) {
        window.location = url;
      }
    });
  });
  /* change plan handler */
  $(".btn-change-plan").on("click", function (e) {
    e.preventDefault();
    var type = $(this).attr("data-type");
    var url = $(this).attr("href");
    var num_sites = parseInt($(this).data("num_sites"));
    var customer_num_sites = parseInt($(this).data("customer_num_sites"));
    if (type == "Ignore") {
      window.location = "/account";
      return;
    } else if (type == "Downgrade") {
      var sites_overage = customer_num_sites - num_sites;
      var html =
        "Are you sure you want to change your plan? Your payment method will be billed immediately and your new plan will start today.";
      var btnText = "Yes, " + type.toLowerCase() + " it!";
      if (sites_overage > 0) {
        html =
          "This plan allows " +
          num_sites +
          " sites. Downgrading your plan will require us to delete " +
          sites_overage +
          " of your existing sites. You can cancel this downgrade and delete the sites yourself, then come back, or we can do it automatically (deleting the last " +
          sites_overage +
          " sites added).";
        btnText = "Downgrade and delete " + sites_overage + " sites";
      }
      Swal.fire({
        title: "Downgrade Plan",
        html: html,
        icon: "warning",
        showCancelButton: true,
        width: "500px",
        cancelButtonText: "Cancel",
        footer:
          '<input type="text" class="form-control" placeholder="Have a coupon? Enter it here." id="coupon">',
        cancelButtonColor: "#d33",
        confirmButtonText: btnText,
      }).then((result) => {
        if (result.isConfirmed) {
          if ($("#coupon").val()) {
            url = url + "/" + $.trim($("#coupon").val());
          }
          jQuery.ajax({
            url: url,
            method: "post",
            async: true,
            dataType: "json",
            data: {},
            success: function (result) {
              window.location = "/dashboard";
            },
            error: function (xhr) {
              popupError(xhr, null);
            },
          });
          //window.location = url;
        }
      });
    } else {
      var html = $(this).attr("data-confirm")
        ? $(this).attr("data-confirm")
        : "Are you sure you want to change your plan? Your payment method will be billed immediately and your new plan will start today.";
      Swal.fire({
        title: type + " Plan",
        html: html,
        icon: "warning",
        width: "500px",
        footer:
          '<input type="text" class="form-control" placeholder="Have a coupon? Enter it here." id="coupon">',
        showCancelButton: true,
        cancelButtonColor: "#d33",
        confirmButtonText: "Yes, " + type.toLowerCase() + " it!",
      }).then((result) => {
        if (result.isConfirmed) {
          if ($("#coupon").val()) {
            url = url + "/" + $.trim($("#coupon").val());
          }
          jQuery.ajax({
            url: url,
            method: "post",
            async: true,
            dataType: "json",
            data: {},
            success: function (result) {
              window.location = "/dashboard";
            },
            error: function (xhr) {
              popupError(xhr, null);
            },
          });
          //window.location = url;
        }
      });
    }
  });
  /* cancel handler */
  $(".btn-cancel").on("click", function (e) {
    e.preventDefault();
    if ($(this).is("[disabled]")) {
      Swal.fire({
        title: "This subscription is already cancelled.",
        icon: "info",
      });
      return false;
    }
    var url = $(this).attr("href");
    var msg = $(this).attr("data-confirm")
      ? $(this).attr("data-confirm")
      : "Are you sure you want to cancel your subscription? It will remain active until the next billing cycle.";
    Swal.fire({
      title: msg,
      icon: "warning",
      showCancelButton: true,
      cancelButtonColor: "#d33",
      confirmButtonText: "Yes, cancel it!",
    }).then((result) => {
      if (result.isConfirmed) {
        window.location = url;
      }
    });
  });
  $(".datepicker.card_expire").datepicker({
    dateFormat: "mm/y",
    changeYear: true,
  });
  $(".select_site")
    .on("click", function (e) {
      var boxes_checked = $(".select_site:checked").length;
      if (!e.shiftKey) {
        firstCBClicked = $(this);
      }

      var boxes_checked = $(".select_site:checked").length;

      if (firstCBClicked && e.shiftKey) {
        var first = firstCBClicked.index(".select_site");
        var last = $(this).index(".select_site");
        var selected = [];
        if (first > last) {
          last = first;
          first = $(this).index(".select_site");
        }
        for (var i = last; i >= first; i--) {
          var cb = $(".select_site:eq(" + i + ")");
          selected.push(cb);
          cb.prop("checked", firstCBClicked.prop("checked")).change();
        }

        if (selected.length == $(".select_site").length) {
          $("#select_site").prop("checked", true);
        }
        firstCBClicked = $(this);
      }
    })
    .on("change", function (e) {
      var checked = $(this).prop("checked");
      if (checked) {
        $(this).parent().parent().addClass("table-primary");
      } else {
        $(this).parent().parent().removeClass("table-primary");
      }
      if ($(".select_site:checked").length > 0) {
        //$(".filter-tag-group").addClass("d-none");
        //$(".btn.edit_tags").removeClass("d-none");
        $(".delete_sites").removeClass("d-none");
        $(".batch_take_snapshot,.batch_approve,.batch_reset").removeClass("d-none");
        $(".edit_tags").removeClass("d-none");
      } else {
        //$(".filter-tag-group").removeClass("d-none");
        //$(".btn.edit_tags").addClass("d-none");
        $(".delete_sites").addClass("d-none");
        $(".batch_take_snapshot,.batch_approve,.batch_reset").addClass("d-none");
        $(".edit_tags").addClass("d-none");
      }
    });

  $(".batch_take_snapshot").on("click", function (e) {
    $(".batch_take_snapshot").addClass("disabled");
    if ($(".select_site:checked").length == 0) {
      Swal.fire({
        icon: "error",
        title: "You must select at least one site.",
      });
      return;
    }

    $(".batch_take_snapshot").find(".spinner-border").removeClass("d-none");
    $(".batch_take_snapshot").find(".fa-camera").hide();
    let total_snapshots_processed = 0;
    var pages = [];
    $(".batch_take_snapshot").find(".spinner-border").addClass("d-none");
    $(".batch_take_snapshot").find(".fa-camera").show();
    $(".loading-block-overlay").css({ opacity: 1 }).show();
    $(".loading-block-overlay").find(".message").html("Queuing Snapshots...");
    $(".select_site:checked").each(function () {
      var site_id = $(this).val();
      var page = $(this).parent().siblings(".title").find("a:first").text();
      pages.push(page);
      jQuery.ajax({
        url: "/queue_snapshot/" + site_id,
        method: "get",
        async: true,
        success: function (result) {
          total_snapshots_processed++;
          if (total_snapshots_processed == $(".select_site:checked").length) {
            Toast.fire({
              icon: "success",
              title: "Snapshots Queued!",
              text: pages.join(", "),
              timer: "3000",
            });

            setTimeout(function () {
              window.location.reload();
            }, 3000);
          }
        },
      });
    });
  });
  $(".btn.edit_tags")
    .off("click")
    .on("click", function (e) {
      if ($(".select_site:checked").length == 0) {
        Swal.fire({
          icon: "error",
          title: "You must select at least one site.",
        });
        return;
      }
      e.preventDefault();
      $(this).addClass("d-none");
      $(".btn.cancel_edit_tags").removeClass("d-none");
      $(".btn.save_edit_tags").removeClass("d-none");
      $(
        ".batch_take_snapshot,.add-new-site-button,.add-multiple-sites-button, .btn.delete_sites"
      ).addClass("d-none");
      $(".btn.save_edit_tags").addClass("disabled").attr("disabled", true);
      makeSiteTagsEditable(true);
    });
  $(".btn.save_edit_tags")
    .off("click")
    .on("click", function (e) {
      saveSiteTags();
    });
  $(".btn.delete_sites")
    .off("click")
    .on("click", function (e) {
      Swal.fire({
        title: "Delete Site?",
        icon: "warning",
        html: "Really delete these site and all of their snapshot data? This action cannot be undone.",
        showCancelButton: true,
        confirmButtonText: "Delete",
        cancelButtonColor: "#198754",
      }).then((result) => {
        /* Read more about isConfirmed, isDenied below */
        if (result.isConfirmed) {
          $("input.select_site").each(function () {
            if ($(this).prop("checked")) {
              var site_id = $(this).val();
              jQuery.ajax({
                url: "/sites/delete/" + site_id,
                method: "get",
                async: true,
                success: function (result) {},
                error: function (xhr) {
                  popupError(xhr, null);
                },
              });
            }
          });
          $(".loading-block-overlay").find(".message").html("Reloading...");
          window.location.reload();
        } else {
          Swal.close();
        }
      });
    });
  $(".btn.cancel_edit_tags")
    .off("click")
    .on("click", function (e) {
      e.preventDefault();
      if (tagsChanged) {
        Swal.fire({
          title: "Do you want to save the changes?",
          showDenyButton: true,
          showCancelButton: true,
          confirmButtonText: "Save",

          denyButtonText: `Don't save`,
          cancelButtonColor: "#ffc107",
        }).then((result) => {
          /* Read more about isConfirmed, isDenied below */
          if (result.isConfirmed) {
            saveSiteTags();
          } else if (result.isDenied) {
            $(".btn.cancel_edit_tags").addClass("d-none");
            $(".btn.edit_tags").removeClass("d-none");
            $(".btn.save_edit_tags").addClass("d-none");
            $(
              ".batch_take_snapshot,.add-new-site-button,.add-multiple-sites-button,.btn.delete_sites,.add-new-site-button,.add-multiple-sites-button"
            ).removeClass("d-none");
            makeSiteTagsEditable(false);
          }
        });
      } else {
        $(".btn.cancel_edit_tags").addClass("d-none");
        $(".btn.edit_tags").removeClass("d-none");
        $(".btn.save_edit_tags").addClass("d-none");
        $(
          ".batch_take_snapshot,.btn.delete_sites,.add-new-site-button,.add-multiple-sites-button"
        ).removeClass("d-none");
        makeSiteTagsEditable(false);
      }
    });
  $("#filter_by_tag").on("keyup change", function () {
    var str = $(this).val().toLowerCase();
    if (str.length < 3) {
      $("tr[data-tags]").show();
      return;
    }
    if (str) {
      $("tr[data-tags]").hide();
      $("tr[data-tags*='" + str + "']").show();
    } else {
      $("tr[data-tags]").show();
    }
  });

  $(".btn-view-take").on("click", function (e) {
    e.preventDefault();
    $(".loading-block-overlay").css({ opacity: 1 }).show();
    var index = $(this).attr("data-id");
    $(".site-page").hide();
    $(".site-page-popup.links-" + index).show();
    $("tbody.site-pages").css({ opacity: 0 });
    var refImage = $(".site-page-popup.links-" + index).find(
      ".reference-image img"
    );

    refImage.on("load", function () {
      $("tbody.site-pages").addClass("editing").fadeTo(500, 1);
    });
    refImage.attr("src", refImage.attr("data-src"));
    var diffImage = $(".site-page-popup.links-" + index).find(
      ".difference-image img"
    );
    diffImage.attr("src", diffImage.attr("data-src"));
  });
});

function saveSiteTags() {
  $(".bootstrap-tagsinput").each(function () {
    var tags = [];
    var site_id = $(this).siblings(".tagsinput").data("id");
    $(this)
      .find(".tag")
      .each(function () {
        var tag = jQuery.trim($(this).text());
        if (
          $("#filter_by_tag").find("option[value='" + tag + "']").length == 0
        ) {
          $('<option value="' + tag + '">').appendTo($("#filter_by_tag"));
        }
        tags.push(tag);
      });
    tags = tags.join(",");
    $(this).parent().attr("data-tags", tags);
    $(".site-" + site_id).attr("data-tags", tags);
    var data = { tags: "", site_id: site_id };
    data.tags = tags;
    if (site_id) {
      jQuery.ajax({
        url: "/sites/tags/save/" + site_id,
        method: "post",
        async: true,
        dataType: "json",
        data: data,
        success: function (result) {
          Toast.fire({
            icon: "success",
            title: "Tags saved!",
            timer: "3000",
          });
          $(".btn.cancel_edit_tags").addClass("d-none");
          $(".btn.edit_tags").removeClass("d-none");
          $(".btn.save_edit_tags").addClass("d-none");
          $(".batch_take_snapshot").removeClass("d-none");
          makeSiteTagsEditable(false);
          $("#select_site,.site_select").prop("checked", false).change();
        },
        error: function (xhr) {
          popupError(xhr, null);
        },
      });
    }
  });
  $(".loading-block-overlay")
    .find(".message")
    .html("Tags Saved!")
    .addClass("animate__animated animate__bounce");
  setTimeout(function () {
    $(".loading-block-overlay").find(".message").html("Reloading...");
    window.location.reload();
  }, 1000);
}
function initTagsInput() {
  $(".tagsinput").tagsinput({
    tagClass: "btn btn-sm btn-light border-secondary mb-1",
  });
  setTimeout(function () {
    $(".bootstrap-tagsinput > input").addClass("border-0");
    $(".bootstrap-tagsinput")
      .addClass("form-control")
      .on("keydown", function (e) {
        var keyCode = e.keyCode || e.which;
        if (keyCode == 9) {
        }
      });
  }, 0);
  $(".tagsinput").on("itemAdded", function (event) {
    $("[data-role=remove]").each(function () {
      var tag = $(this).parent().text();
      var remove = $(
        '<i data-tag="' + tag + '" class="fa fa-xmark ms-2 text-danger"></i>'
      );
      $(this).replaceWith(remove);
      remove.on("click", function () {
        $(".tagsinput").tagsinput("remove", $(this).attr("data-tag"));
      });
    });
  });
}
var tagsChanged = false;
function makeSiteTagsEditable(toggle) {
  if (toggle) {
    $(".select_site:checked").each(function () {
      var site_id = $(this).parent().parent().attr("site_id");
      var tag_cell = $(this).parent().parent().find(".edit-tags");
      var orig_tags = $(this).parent().parent().find(".edit-tags").data("tags");

      tag_cell.attr("data-tags", orig_tags);
      var tag_input = $(
        '<input class="form-control tagsinput" data-id="' +
          site_id +
          '" id="tags"  data-value="' +
          orig_tags +
          '" type="text"  />'
      );
      tag_cell.html("");
      tag_input.appendTo(tag_cell);
    });

    initTagsInput();
    $(".tagsinput[data-id]").each(function () {
      var value = $(this).data("value");
      value.split(",").forEach((tag) => {
        $(this).tagsinput("add", tag);
      });
    });
    $(".tagsinput")
      .on("itemAdded", function (event) {
        tagsChanged = true;
        $(".btn.save_edit_tags").removeClass("disabled").removeAttr("disabled");
      })
      .on("itemRemoved", function (event) {
        tagsChanged = true;
        $(".btn.save_edit_tags").removeClass("disabled").removeAttr("disabled");
      });
  } else {
    $(".select_site:checked").each(function () {
      var tag_cell = $(this).parent().parent().find(".edit-tags");
      var orig_tags = jQuery.trim(tag_cell.attr("data-tags"));
      tag_cell.html(orig_tags);
    });
  }
}

function lazyLoadScreenshot(img, src) {
  ////console.log(src);
  // /snapshotCarouselFS
  var identifier = src.split("/").pop().replace(/\./, "-");
  $(".screenshot").css({opacity:0});
  if ($("." + identifier).length == 0) {
    if (identifier.match(/diff/)) {
      $(".btn-new").click();
      $(".btn-old").click();
    }
    $(
      '<img  decoding="async" class="screenshot position-relative w-100 snapshot-page ' +
        identifier +
        '">'
    ).insertBefore(img);
    img = $("." + identifier);
    $(".image-spinner").removeClass("d-none").addClass("d-flex");
    img.css({opacity:0})
    
   
    img.on("load", function () {
       
        $(".image-spinner").addClass("d-none").removeClass("d-none");
        setTimeout(function () {
          //img.fadeTo(1000, 1);
        }, 500);
        img.attr("data-src", src);
        
        
    });
    img.src = src;
    
  } else {
    $("." + identifier).show();
  }
}

function adjustImageFrame() {
  if ($("#site_add_links").length) {
    var top = $("#site_add_links").position().top;
    let width = $("#snapshotCarousel").parent().width();
    if (
      $("#site_add_links")[0].getBoundingClientRect().y < 100 ||
      $("body").scrollTop() >= 300
    ) {
      top = $(window).height() / 2 - $("#snapshotCarousel").height() / 2;
    }
    $("#snapshotCarousel").css({ top: top });
    $("#offcanvasB2").css({
      width: width,
      height: $("#snapshotCarousel").height(),
      top: top,
    });
    $(".b2-item").css({ height: $(".b2-item:first").width() });
  }
}

async function lazyLoadSnapshot(img, src, latest = false, index) {
  img.fadeTo(500, 0.5, function () {
    var i = new Image();
    $(i).on("load", function () {
      img.attr("src", src);
      img.attr("data-src", src);
      if (latest) {
        $(".latest-snapshot img").attr("src", src);
      }
      setTimeout(function () {
        img.fadeTo(500, 1);
        if (img.parent().hasClass("reference-image")) {
          //takeSnapshot(index)
        }
      }, 100);
    });
    i.src = src;
  });
}

function takeSnapshot(page_index, update_ref = false) {
  var target = "";
  var th;
  if (update_ref) {
    th = $(".btn-new-snapshot.make[data-id=" + page_index + "]");
  } else {
    th = $(".btn-new-snapshot.take[data-id=" + page_index + "]");
  }

  if (typeof th.attr("data-target") != "undefined") {
    target = th.attr("data-target");
  }
  var first = false;
  var which = th.attr("data-which");
  var is_dev = th.attr("data-dev");
  var spinner = th.find(".spinner-border");
  $("tbody.editing").addClass("loading");
  var site_id = $(".site-page-popup.links-" + page_index).attr("data-id");
  var refImage = $(".site-page-popup.links-" + page_index).find(
    ".reference-image img"
  );
  var diffImage = $(".site-page-popup.links-" + page_index).find(
    ".difference-image img"
  );
  var loading = $(".site-page-popup.links-" + page_index).find(
    ".loading-image-overlay"
  );
  var spinner_text = loading.find(".spinner-text");
  loading.find(".spinner-border").show();
  loading.show().fadeTo(500, 1);
  spinner.removeClass("d-none");
  //console.log(refImage.attr("data-src").match(/no\-snapshot/));
  //console.log(diffImage.attr("data-src").match(/no\-snapshot/));
  if (refImage.attr("data-src").match(/no\-snapshot/)) {
    first = true;
    spinner_text.text("Taking First Snapshot...");
  } else if (diffImage.attr("data-src").match(/no\-snapshot/)) {
    spinner_text.text("Taking screenshot...");
  } else if (update_ref) {
    spinner_text.text("Updating reference screenshot...");
  } else {
    spinner_text.text("Taking screenshot...");
  }
  jQuery.ajax({
    url: "/snapshots/take/" + parseInt(site_id),
    method: "post",
    dataType: "json",
    data: { which: which, is_dev: is_dev },
    success: function (result) {
      $(".spinner-border").hide();
      loading.fadeTo(500, 0).hide();
      spinner.addClass("d-none");
      spinner_text.text("");
      $("tbody.editing").removeClass("loading");
      if (target == "popup") {
        if (update_ref) {
          $(".percent-" + page_index).text("0.0%");
          refImage.attr("src", diffImage.attr("src"));
        } else {
          if (result.snapshot.match(/ref/)) {
            lazyLoadSnapshot(refImage, result.snapshot, false, page_index);
            diffImage.attr("src", result.snapshot.replace(/ref-/, ""));
            $(".site-page.links-" + page_index)
              .find(".btn-view-take")
              .removeClass(
                "text-danger text-warning text-dark text-success text-primary"
              )
              .addClass("text-success");
          } else {
            lazyLoadSnapshot(diffImage, result.snapshot, true, page_index);
            diffImage
              .siblings("button")
              .removeClass("invisible")
              .removeAttr("disabled");
          }
        }
        $(".last_snapshot_time").text("Seconds");
        $(".last_snapshot_url").text(
          $(".site-page.links-" + page_index)
            .find("a:first")
            .text()
        );
        if (result.misMatchPercentage) {
          var mismatch = parseFloat(result.misMatchPercentage);
          mismatch = mismatch.toFixed(1);
          $(".percent-" + page_index).text(mismatch + "%");
          $(".percent-overlay").text(mismatch + "% Change");
          if (mismatch > 1) {
            var explanation =
              "The percantage difference is so slow it's possibly related to either legitimate content changes or the screenshot was taken before images or videos were done loading.";
            if (mismatch >= 15) {
              explanation =
                "There is a good chance that something is broken on your site. You should definitely visit your site and review this page.";
            } else if (mismatch > 5) {
              explanation =
                "There might be something broken on your site. You should probably visit your site and review this page.";
            }
            explanation +=
              " If you are satisfied with the screenshot despite differences you can close this window and click on 'APPROVE' to assign it as the new screenshot.";
            Swal.fire({
              title:
                '<span class="text-danger"><i class="fa-solid fa-triangle-exclamation"></i> MisMatch ' +
                mismatch +
                "%</span>",
              html:
                '<div class="row"><p class="lead text-left">' +
                explanation +
                '</p>\
							  <div class="col-4"><h3 class="text-center">Reference</h3><img class="border border-danger" src="' +
                refImage.attr("src") +
                '"></div>\
							  <div class="col-4"><h3 class="text-center">Difference</h3><img class="border border-danger" src="' +
                result.diff +
                '"></div>\
							  <div class="col-4"><h3 class="text-center">Screenshot</h3><img class="border border-danger" src="' +
                diffImage.attr("src") +
                '"></div>\
							  </div>',
              width: "100%",
              height: "100%",
              showCloseButton: true,
            });
          } else {
            Swal.fire({
              icon: "success",
              title: "There were no changes detected!",
            });
          }
        }
      }
      if (which != "all") {
        $(".last_snapshot_url").text(which);
      }
    },
    error: function (xhr) {
      $("tbody.editing").removeClass("loading");
      spinner.addClass("d-none");
      loading.fadeTo(500, 0).hide();
      popupError(xhr);
    },
  });
}
function closeSnapshots() {
  $(".loading-block-overlay").css({ opacity: 0 }).hide();

  $(".site-page").show();
  $(".site-page-popup").hide();
  $("tbody.site-pages").removeClass("editing loading");
}
function addSiteLink() {
  var input = $(".add-site-link");
  var domain = $(".domain-text").text();
  var value = input.val();

  if (!value) {
    input.addClass("is-invalid");
  } else {
    if (
      $(".site-link-check[value='/" + value + "']").length > 0 ||
      $(".site-link-check[value='/" + value + "/']").length > 0
    ) {
      input.addClass("is-invalid");
      Swal.fire({
        icon: "error",
        title: "Duplicate Page",
        html: "Page urls must be unique.",
      });
    } else {
      var key = $(".site-page").length;

      var link = $(
        '<tr class="site-page d-none">\
							<td class="drag-handle">\
		                        <i class="fa-solid fa-grip-vertical pt-3"></i>\
		                    </td>\
		                    <td><div class="form-check col-3">\
	        					<div class="spinner-border spinner-border-sm d-none" role="status">\
				                	<span class="visually-hidden">Loading...</span>\
				            	</div>\
				              <input  class="form-check-input site-link-check" data-snapshot_id="" type="checkbox" checked="" value="/' +
          value +
          '" id="snapshot_links_' +
          key +
          '" name="links[' +
          key +
          ']">\
				              <label class="form-check-label" for="snapshot_links_' +
          key +
          '">\
				               <a href="' +
          domain +
          "/" +
          value +
          '" target="_blank">/' +
          value +
          '</a>\
				              </label>\
			            	</td>\
			            	<td>New</div>\
			            	<td><i class="fa-solid fa-chart-pie"></i></td>\
			            	<td><i class="fa-solid fa-image"></i></td>\
			            	<td>\
							<button class="btn btn-link btn-link-trash float-end text-danger text-decoration-none" ><i class="fa fa-trash"></i> Delete</button>\
			            	<button class="btn btn-link btn-link-hide float-end text-decoration-none" ><i class="fa-sharp fa-solid fa-eye-slash"></i> <span>Hide</span></button>\
			            	</td>\
			            	</tr>'
      );

      link.insertAfter($("tr.domain"));
      $(".add-site-link").val("");
      $("#site_links").find(".alert").addClass("d-none");
      $(".loading-block-overlay").css({ opacity: 1 }).show();
      submitLinkForm(true);
      //initLinkTrash(link)
    }
  }
}
function submitLinkForm(reload = false) {

  console.log("saving links...")
  var form = $("#site_links");

  var serialized = form.serializeArray();
  var data = { links: [], site_id: form.find("#site_id").val() };
  //console.log(data);
  form.find(".form-check-input").each(function () {
    if ($(this).val() && $(this).val() != "on") {
      var link = {
        snapshot_id: $(this).attr("data-snapshot_id"),
        page: $(this).val() ? $(this).val() : "/",
        is_active: $(this).prop("checked") ? 1 : 0,
        hide_status: $(this).hasClass("hideme") ? 1 : 0,
        is_dev: window.location.pathname.match(/\/live\//) ? 0 : 1,
      };
      data.links.push(link);
    }
  });
  //$(".loading-block-overlay").css({ opacity: 1 }).show();
  //$(".loading-block-overlay").find(".message").html("Validating new page...");

  jQuery.ajax({
    url: "/sites/links/save/" + data.site_id,
    method: "post",
    dataType: "json",
    data: data,
    success: function (result) {
      //$(".loading-block-overlay").css({ opacity: 0 }).hide();
      //$(".loading-block-overlay").find(".message").html("");
      $(".spinner-border").addClass("d-none");
      $(".num_of_pages").text($("tr.site-page").length);
      if (result.error) {
        Toast.fire({
          title: "Page Not Added",
          icon: "error",
          html: result.error,
          timer: "5000",
        });
        return;
      } else {
        if(!Swal.isVisible()){
          Toast.fire({
            icon: "info",
            title: "Saved ",
            timer: "1500",
          });
        }
       
      }
      if (reload) {
        window.location.reload();
      }
    },
    error: function (xhr) {
      popupError(xhr, form);
    },
  });
}
function initLinkTrash(link) {
  link
    .find(".btn-link-trash")
    .unbind()
    .on("click", function () {
      var th = $(this);
      Swal.fire({
        title: "Are you sure?",
        icon: "warning",
        html: "You are about to remove a link from being included in snapshots. You can always add it again in the future. ",
        showCancelButton: true,

        cancelButtonColor: "#d33",
        confirmButtonText: "Yes, remove it!",
      }).then((result) => {
        if (result.isConfirmed) {
          th.parent()
            .parent()
            .addClass("position-relative")
            .animate({ right: "200vw" }, 500, function () {
              $(this).remove();
              setTimeout(function () {
                submitLinkForm();
              }, 600);
            });
        }
      });
    });

  link
    .find(".btn-rediff")
    .unbind()
    .on("click", function () {
      var th = $(this);
      th.attr("disabled", true);
      th.siblings().attr("disabled", true);
      th.find(".spinner-border").removeClass("d-none");
      th.find(".fa-camera-rotate").addClass("d-none");
      var item = th.parent().parent();
      var path = th.data("path");
      var snapshot_id = item.data("snapshot_id");
      
      jQuery.ajax({
        url: "/recompare",
        method: "get",
        dataType: "json",
        data: { path: path, dev: (window.location.pathname.match(/dev/))?1:0 },
        success: function (result) {
          th.find(".spinner-border").addClass("d-none");
          th.find(".fa-camera-rotate").removeClass("d-none");
          th.removeAttr("disabled");
          th.siblings().removeAttr("disabled");
          if(result.error){
            Swal.fire({
              title: result.error,
              icon: "error"
            });
          }
          if(result.success){
            /* Swal.fire({
              title: result.success,
              icon: "success"
            }); */
            $(".loading-block-overlay")
              .find(".message")
              .html("Reloading...");
            $(".loading-block-overlay").css({ opacity: 1 }).show();
            clearInterval(compareInv);
            window.location.reload();
            return;
          }
          path = path.split("/");
          var snapshot_id = path[2];
         
          
          item
            .find(".image-diff")
            .html(
              '<i class="fa-solid fa-chart-pie"></i> ' +
                result.percent +
                "%"
          );
          var diff_image =  $(".snapshot-page.diff-snapshot-" + snapshot_id+"-png")
          var src = diff_image.attr("src");
          diff_image.attr("src", "");
          diff_image.on("load",function(){
            $(".btn-diff").trigger("click");
          })
          var nocache_string = new Date().getTime();
          diff_image.attr("src", src+"?nocache="+nocache_string);
         
        },
        error: function (xhr) {
          popupError(xhr);
        },
      });
    });
  link
    .find(".btn-link-delete")
    .unbind()
    .on("click", function () {
      var hideToggle = $(".btn-toggle-hidden")
        .find(".form-check-input")
        .prop("checked");
      var th = $(this);
      var item = th.parent().parent();
      var snapshot_id = item.data("snapshot_id");
      var domain_url = $("#domain_url").val();
      var page = item.data("page");
      //console.log(page);
      var whichpage = page == "/" ? "the home page" : "a page";
      item.fadeTo(300, 0.5);
      Swal.fire({
        title:
          "Delete <span class='text-primary'>" +
          domain_url +
          page +
          "</span> ?",
        icon: "warning",

        showCancelButton: true,

        cancelButtonColor: "#d33",
        confirmButtonText: "Yes, do it!",
        footer: "Note: You are only removing a page, not the site.",
      }).then((result) => {
        if (result.isConfirmed) {
          $(".btn-close-fs").trigger("click");
          jQuery.ajax({
            url: "/sites/links/delete/" + parseInt(snapshot_id),
            method: "post",
            dataType: "json",
            success: function (result) {
              item.remove();
              Toast.fire({
                icon: "info",
                title: "Deleted ",
                html: domain_url + page,
                timer: "3000",
              });
            },
            error: function (xhr) {
              popupError(xhr);
            },
          });
        } else {
          item.fadeTo(300, 1);
        }
      });
    });
}
function popupError(xhr, form = null) {
  var footer = "";
  var msg = "";
  var title = "";
  $(".loading-block-overlay").css({ opacity: 0 }).hide();
  if (xhr.responseJSON.errors) {
    title = xhr.responseJSON.message;
    if(title == "CSRF token mismatch"){
      window.location = "/login"
      return
    }
    Object.entries(xhr.responseJSON.errors).forEach(([key, value]) => {
      if (form != null) {
        if (form.find("[name='site[" + key + "]']").length) {
          form.find("[name='site[" + key + "]']").addClass("is-invalid");
          form
            .find("[name='site[" + key + "]']")
            .unbind("keypress")
            .on("keypress", function () {
              $(this).removeClass("is-invalid");
            });
        } else {
          form.find("[name='" + key + "']").addClass("is-invalid");
          form
            .find("[name='" + key + "']")
            .unbind("keypress")
            .on("keypress", function () {
              $(this).removeClass("is-invalid");
            });
        }
      }
      msg = value.join("<br>");
    });
  } else {
    msg = xhr.responseJSON.message;
    title = xhr.responseJSON.exception;

    if (msg.match(/Operation timed out/)) {
      title = "Could Not Connect";
      msg = "This page took too long to load.";
      footer =
        "Either your website is down or the connection is really slow. The screenshot process will terminate if it takes longer than 30 seconds to reach your page.";
    }
  }

  popupMsg(title, msg, "error", "", footer);
  if (form != null) {
    form.find(".spinner-border").addClass("d-none");
  }
  $(".loading-block-overlay").fadeTo(205, 0, function () {
    $(this).hide();
  });
}
/* generic popup messages */
function popupMsg(title, msg, icon, callBack = function () {}, footer) {
  if (title == "The given data was invalid.") {
    title = "There are some errors.";
  }
  var data = { text: [title, msg, footer] };
  jQuery.ajax({
    url: "/translate/",
    method: "get",
    dataType: "json",
    data: data,
    success: function (result) {
      if (result.translation) {
        Swal.fire({
          icon: icon,
          title: result.translation[0],
          html: result.translation[1],
          width: "50%",
          allowOutsideClick: false,
          footer: result.translation[2],
          willClose: callBack,
        });
      }
    },
  });
}

function resetLinksForm(site_id, $recount = true) {
  return false;
  var num_links = $("#site_links").find("list-group-item-action").length;
  $(".sites-table > tbody").removeClass("editing loading");
  $("tr[site_id]").show("fast");
  $(".loading-block-overlay").fadeTo(205, 0, function () {
    $(this).hide();
  });
  if ($recount) {
    //$("tr.site-"+site_id).find(".btn-site-links").text("Edit Links ("+num_links+")")
  }

  $("#site_links").find(".alert").addClass("d-none");
  $(".quick-links").removeClass("locked show");
  $("tr.site-" + site_id + ", .table-success").removeClass("table-success");
  $(".links-container").html("");
  $("#site_links").hide().appendTo($("body"));
  $(".links-row").remove();
}

function initDataQueue() {
  if (
    $("[data-inqueue-id][data-inqueue-id!='']").length ||
    $("[data-enqueue-id][data-enqueue-id!='']").length
  ) {
    /*  $(".in-queue").each(function(){
            var p = $(this).parent().parent();
            $(this).addClass("moved");
            p.addClass('table-success')
            var t = p.parent();
            p.prependTo(t)
        }) */

    var queued = {};
    var cycles = 0;
    multibatchInv = setInterval(function () {
      jQuery.ajax({
        url: "/inqueue",
        method: "get",
        dataType: "json",
        data: {},
        success: function (result) {
          cycles++;
          var sites = [];
          $("[data-inqueue-id]").each(function () {
            var el = $(this);
            el.addClass("completed");
            //el.siblings('.spinner-border').hide()
            el.removeClass("animate__flash");
            if (!el.hasClass("text-success")) {
              //el.addClass("text-success")
              el.text("Done");
            }
          });
          for (var i in result) {
            var site_id = result[i].site_id;
            sites.push(site_id);
            if ($("[data-enqueue-id=" + site_id + "]:not(.moved)").length) {
              $("[data-enqueue-id=" + site_id + "]")
                .parent()
                .html(
                  '<span class="moved"  data-inqueue-id="' +
                    site_id +
                    '">0%</span>'
                );
              /*  $("[data-inqueue-id]:not(.moved)").each(function(){
                                var p = $(this).parent().parent();
                                $(this).addClass("moved")
                                p.addClass('table-info')
                                var t = p.parent();
                                p.prependTo(t)
                            }) */
            }
            var pendingJobs = parseInt(result[i].pendingJobs);
            var finishedJobs = parseInt(result[i].finishedJobs);
            var totalJobs = parseInt(result[i].totalJobs);
            if (typeof queued[site_id] == "undefined") {
              queued[site_id] = 0;
            }
            queued[site_id] += 1;

            var progress = Math.floor((finishedJobs / totalJobs) * 100);
            var el = $("[data-inqueue-id=" + site_id + "]");
            if (progress == 0) {
              el.html(" Spooling...");
            } else {
              el.html(progress + "%");
            }
            if (el.siblings(".spinner-border").length == 0) {
              //$("<div class='spinner-border spinner-border-sm'></div> ").insertBefore(el);
            }

            if (progress == 100) {
              el.addClass("completed");
              el.siblings(".spinner-border").hide();
              el.addClass("text-success");
              //el.text(formatAMPM(new Date()));
              getPercent(site_id);
            }
          }

          if (result.length == 0) {
            for (var i = 0; i < 1000; i++) {
              clearInterval(i);
            }
            $("[data-inqueue-id]").each(function () {
              var site_id = $(this).data("inqueue-id");
              var percent = parseInt($(this).text().replace(/%/, ""));
              if (
                (!isNaN(percent) && percent > 0) ||
                sites.indexOf(site_id) < 0
              ) {
                var el = $(this);

                el.addClass("completed");
                el.siblings(".spinner-border").hide();

                if (!el.hasClass("text-success")) {
                  el.addClass("text-success");
                  //el.text(formatAMPM(new Date()));
                  getPercent(site_id);
                }
              }
            });
            //clearInterval(multibatchInv);
          }
        },
      });
    }, 2000);
  }

  $("[data-queue-id][data-queue-id!='']").each(function () {
    var site_id = $(this).attr("data-queue-id");
    queryQueue(site_id, $(this));
  });
}

function initCrawlComplete(){
  if ($(".awaiting-crawl[data-site_id]").length) {
    var site_id = $(".awaiting-crawl").data("site_id")
    multibatchInv = setInterval(function () {
      jQuery.ajax({
        url: "/awaiting-crawl",
        method: "get",
        dataType: "json",
        data: {site_id:site_id},
        success: function (result) {
          if(result.page){
            $(".loading-block-overlay")
            .find(".message")
            .html("Crawl Completed. Reloading...");
            $(".loading-block-overlay").css({ opacity: 1 }).show();
            clearInterval(multibatchInv);
            setTimeout(function(){
              window.location.reload();
            },10000)
            
          }
        },
      });
    }, 2000);
  }
}

function initCheckSnapshotComplete() {
  if ($(".awaiting-comparison[data-site_id]").length) {
    var site_id = $(".awaiting-comparison").data("site_id")
    multibatchInv = setInterval(function () {
      jQuery.ajax({
        url: "/awaiting-completion",
        method: "get",
        dataType: "json",
        data: {site_id:site_id},
        success: function (result) {
          if(result.is_complete){
            $(".loading-block-overlay")
            .find(".message")
            .html("Comparison Completed. Reloading...");
            $(".loading-block-overlay").css({ opacity: 1 }).show();
            clearInterval(multibatchInv);
            window.location.reload();
          }
        },
      });
    }, 2000);
  }

 
}

function queryQueue(site_id, th) {
  var progressbarElem = $(".progress-bar");
  var is_dashboard = false;
  var progressElem = $(".progress");
  var progressText = $(".progress-bar-progress");
  if (th.find(".progress-bar").length) {
    progressbarElem = th.find(".progress-bar");
    progressElem = th.find(".progress");
    progressText = th.find(".progress-bar-progress");
  } else if (th.is("span")) {
    progressText = th;
    is_dashboard = true;
  }
  jQuery.ajax({
    url: "/queue/" + site_id + "/0",
    method: "get",
    dataType: "json",
    data: {},
    async: true,
    success: function (result) {
      $(".request_seconds").text(reqSeconds);
      var last_page = decodeURI(result.last_page);
      if (result.speed && typeof speedData != "undefined") {
        speedData.setValue(0, 1, result.speed);
        speedChart.draw(speedData, speedOptions);
      }

      $(".last_snapshot_url").html(last_page);
      var progressbarElem = $(".progress-bar.bg-primary");
      var progress_progress = $(".progress_progress");
      var progressElem = $(".progress");
      //var progressText = $(".progress-bar-progress")
      var e = new Date().getTime();
      var pendingJobs = result.pendingJobs;
      var failedJobs = parseInt(result.failedJobs);
      if (failedJobs > 0) {
        $(".btn-batch-cancel").removeClass("d-none");
        $(".btn-batch-cancel")
          .find("span")
          .html("(" + failedJobs + " Jobs)");
      }

      var status = "Completed";
      var icon = "success";
      var progress = parseInt(result.progress);
      
      var previous_progress = parseInt(progressbarElem.attr("data-progress"))
      var progress_difference = progress - previous_progress
      console.log(progress,previous_progress,progress_difference)
      if(progress < 100){
        
        if(previous_progress > 0){
          progressbarElem.css({ width: previous_progress + "%" });
          progress_progress.css({ width: progress_difference + "%" });
        } else {
          progressbarElem.css({ width: progress + "%" });
        }
        progressbarElem.attr('data-progress',progress)
        if(progress == previous_progress){
          // ...
        }
        
      } else {
        progressbarElem.css({ width: progress + "%" });
        progress_progress.css({ width: "0%" });
      }
     
      //console.log(progress);
      
      

      if (progress == 0) {
        progressText.html("Spooling...");
      } else {
        progressText.html(progress + "%");
      }
      //progressText.append(estText);
      progressElem.attr("aria-valuenow", progress);
      if (progress == 100 && !Swal.isVisible()) {
        clearInterval(reqInv);
        clearInterval(batchInv);
        if (!is_dashboard) {
          Swal.fire({
            icon: icon,
            title: "Snapshot Capture " + status,
            html: "Refreshing Page...",
            timer: 5000,
            allowOutsideClick: false,
            timerProgressBar: true,
            didOpen: () => {
              Swal.showLoading();
              window.location.reload();
            },
          });
        } else {
          progressText.html(formatAMPM(new Date()));
          progressText.siblings(".spinner-border").hide();
        }
      } else {
        setTimeout(function(){
          queryQueue(site_id, th);
        },1000);
      }
      if (!result.pendingJobs) {
        clearInterval(reqInv);
        clearInterval(batchInv);
        progressText.html(formatAMPM(new Date()));
        progressText.siblings(".spinner-border").hide();
      }
    },
  });
}

function doLazyQueue(site_id, single = false) {
  jQuery.ajax({
    url: "/get_percent/" + site_id,
    method: "get",
    dataType: "json",
    data: {},
    success: function (result) {
      if(result.html == "error"){
        result.html = "Site Deleted - Refresh Page";
      }
      $("[data-lazy-queue=" + site_id + "]").html(result.html);
      $("[data-lazy-queue=" + site_id + "]").removeClass("lazypending");
      var any_left = $(".lazypending").length;
      if (any_left == 0) {
        const tooltipTriggerList = document.querySelectorAll("[data-bs-title]");
        const tooltipList = [...tooltipTriggerList].map(
          (tooltipTriggerEl) =>
            new bootstrap.Tooltip(tooltipTriggerEl, {
              trigger: "hover",
            })
        );
        if (!single) {
          initDataQueue();
        }
      }
    },
  });
}

function getPercent(site_id) {
  //var site_id = el.attr("data-lazy-queue");
  $("[data-lazy-queue=" + site_id + "]").html("...");

  doLazyQueue(site_id, true);
}

function formatAMPM(date) {
  // gets the hours
  var hours = date.getHours();
  // gets the day
  var days = date.getDay();
  // gets the month
  var minutes = date.getMinutes();
  var seconds = date.getSeconds();
  // gets AM/PM
  var ampm = hours >= 12 ? "pm" : "am";
  // converts hours to 12 hour instead of 24 hour
  //hours = hours % 12;
  // converts 0 (midnight) to 12
  //hours = hours ? hours : 12; // the hour '0' should be '12'
  // converts minutes to have leading 0
  minutes = minutes < 10 ? "0" + minutes : minutes;
  seconds = seconds < 10 ? "0" + seconds : seconds;
  // the time string
  var time = hours + ":" + minutes + ":" + seconds;

  // gets the match for the date string we want
  var match = date.toString().match(/\w{3} \d{1,2} \d{4}/);

  //the result
  return match[0] + " " + time;
}
function drawSpeedGauge(v) {
  speedData = google.visualization.arrayToDataTable([
    ["Label", "Value"],
    ["Avg Speed", v],
  ]);

  speedOptions = {
    width: 130,
    height: 130,
    redFrom: 5.8,
    redTo: 100,
    yellowFrom: 3.4,
    yellowTo: 5.8,
    greenFrom: 0,
    greenTo: 3.4,
    minorTicks: 5,
  };

  speedChart = new google.visualization.Gauge(
    document.getElementById("speedchart_div")
  );

  speedChart.draw(speedData, speedOptions);
}

// /https://www.jqueryscript.net/other/Image-Cropping-Library-Jcrop.html
var jcrop_api;
var scroll_debounce;
//var crops = {};
//crops = JSON.parse('{"85604":[null,{"x":872,"y":341,"x2":1345,"y2":695,"w":473,"h":354},{"x":874,"y":934,"x2":1345,"y2":1291,"w":471,"h":357},{"x":115,"y":341,"x2":824,"y2":1287,"w":709,"h":946}],"85606":[{"x":117,"y":474,"x2":1348,"y2":982,"w":1231,"h":508}],"85616":[{"x":375,"y":3091,"x2":600,"y2":3256,"w":225,"h":165},{"x":618,"y":3090,"x2":841,"y2":3257,"w":223,"h":167},{"x":376,"y":3594,"x2":1087,"y2":4127,"w":711,"h":533}]}');

function loadCrops(){
 
  if($("#snapshotCarousel").hasClass("fullscreen")){
    var snapshot_id = snapshot_id_popped;
    if(typeof crops[snapshot_id] != 'undefined'){
      for(var idx in  crops[snapshot_id]){
        var bounds = crops[snapshot_id][idx]
        if(bounds){
          makeCropMarker(idx,bounds,snapshot_id)
          sortCrops();
        }
        
      }
    }
  }
  
}

function hideCrops(){
  $(".cropmarker").remove();
}

function initCrop(){
    if(!$("#snapshotCarousel").hasClass("fullscreen")){
      $(".btn-fs").click();
      
    }
    var snapshot_id = snapshot_id_popped;
    if(typeof crops[snapshot_id] != 'undefined' && crops[snapshot_id].length > 0){
      Swal.fire({
        title: "Selection Exists",
        icon: "error",
        html: "A selection has already been made. To create a new one, please delete the existing one first.",
      });
      return;
    }
    try{
        jcrop_api.destroy()
    } catch(e){

    }
    var img = $(".ref-snapshot-"+snapshot_id+"-png")
    
   
    var src = img.attr("src");
    var i = new Image();
    
    img.Jcrop({
      onChange:   showCoords,
      onSelect:   showCoords,
      onRelease:  clearCoords
    },function(){
        jcrop_api = this;
        var st =  $("#snapshotCarousel").scrollTop()
        jcrop_api.setSelect([250,st+250,$(".screenshot:visible").width()-250,750+st]);
        $(".inline-labels").removeClass("d-none")
        $("#snapshotCarousel").off().on("scroll",function(e){
            var offset = 100;
            clearTimeout(scroll_debounce);
            var th = $(this)
            $("#st").val(th.scrollTop());
            scroll_debounce = setTimeout(function(){
                var st = th.scrollTop();
                offset
                var cropselect = jcrop_api.tellSelect();
                
                if(cropselect.h + cropselect.y - st >  th.height() - offset){
                    jcrop_api.animateTo([
                        cropselect.x,
                        th.height() - offset - cropselect.h + st,
                        cropselect.x2,
                        th.height() - offset + st
                    ]);
                }
                if(st > cropselect.y){
                    offset = 25
                    jcrop_api.animateTo([cropselect.x,st + offset,cropselect.x2,cropselect.h+st+offset]);
                }

                
            },100)
        });
    });

    $('#coords').off().on('change','input',function(e){
      var x1 = $('#x1').val(),
          x2 = $('#x2').val(),
          y1 = $('#y1').val(),
          y2 = $('#y2').val();
        
    });
   
    i.src = src
   
    

   
}

function showCoords(c) {
  /* $("#x1").val(c.x);
  $("#y1").val(c.y);
  $("#x2").val(c.x2);
  $("#y2").val(c.y2);
  $("#w").val(c.w);
  $("#h").val(c.h); */
  $(".coords").html("<strong>X1:</strong> "+parseInt(c.x)+" <strong>Y1:</strong> "+parseInt(c.y)+" <strong>X2:</strong> "+parseInt(c.x2)+" <strong>Y2:</strong> "+parseInt(c.y2)+" <strong>W:</strong> "+parseInt(c.w)+" <strong>H:</strong> "+parseInt(c.h))
}

function clearCoords() {
  $("#coords input").val("");
}

function deCrop() {
    $("#snapshotCarousel").off('scroll')
    $(".inline-labels").addClass("d-none")
    jcrop_api.destroy();
}

function capCrop(){
  var snapshot_id = snapshot_id_popped;
  //alert("Selected Area: " + JSON.stringify(jcrop_api.tellSelect()))
  var bounds = jcrop_api.tellSelect()
  if(typeof crops[snapshot_id] == 'undefined'){
    crops[snapshot_id] = [];
  }
  
  crops[snapshot_id].push(bounds)
  var idx = crops[snapshot_id].indexOf(bounds)
  makeCropMarker(idx,bounds,snapshot_id)
  saveCrop();
  deCrop()
}


function makeCropMarker(idx,bounds,snapshot_id){
  idx = parseInt(idx) + 1
  $("[data-crop-icon="+snapshot_id+"]").removeClass("d-none")
  var crop_marker = $("<div data-idx='"+idx+"' data-id='"+snapshot_id+"'></div>").addClass("cropmarker").css({
    left: bounds.x,
    top: bounds.y,
    width: bounds.w,
    height: bounds.h,
    
  })
  crop_marker.prependTo($("#snapshotCarousel > .card-body"))
  crop_marker.on("click",function(){
    var id = $(this).data("id");
    var idx = parseInt($(this).data("idx")) - 1;
    delete crops[id][idx]
    $(this).remove();
    saveCrop();
  })
}

function saveCrop(){
  var site_id = parseInt($("#site_links").find("#site_id").val())
  sortCrops()
  jQuery.ajax({
    url: "/sites/save/" + site_id,
    method: "post",
    dataType: "json",
    data: { cropdata: JSON.stringify(crops) },
    success: function (result) {
     
    }
  });
}

function sortCrops(){
  var sorted_crops = {}
  for(var id  in crops){
    if(typeof sorted_crops[id] == 'undefined'){
      sorted_crops[id] = [];
    }
    for(var idx  in crops[id]){
      
      if(crops[id][idx]){
        
        sorted_crops[id].push(crops[id][idx])
        var new_idx = sorted_crops[id].length
        idx = parseInt(idx) + 1
        var cropmarker = $("[data-id="+id+"][data-idx="+idx+"]")
        
        cropmarker.attr("data-idx",new_idx)
      }
    }
  }
  crops = sorted_crops
  $("[data-crop-icon]").not(".d-none").each(function(){
    var id = $(this).data("crop-icon");
    if(crops[id].length == 0){
      $(this).addClass("d-none");
    }
  })
}
