function search(data) {

let text = new URL(location.href).searchParams.get("q");
let lang = new URL(location.href).searchParams.get("lang") || ui.lang;

$("input[name='q']").val(text);

let results = [];
let regexp = new RegExp();
try {
  regexp = new RegExp(text, "im");
} catch (e) {
  $(".search-results .content").empty();
  $(".search-results .summary").html(ui.i18n.search_results_not_found);
  $(".search-results h2").html(ui.i18n.search_results);
  return debug(e.message);
}

function slice(content, min, max) {
  return content
    .slice(min, max)
    .replace(regexp, (match) => `<span class="bg-yellow">${match}</span>`);
}
for (page of data) {
  let [title, content] = [null, null];
  try {
    if (page.title) {
      title = page.title.match(regexp);
    } else {
      if (page.url == "/") {
        page.title = ui.title;
      } else {
        page.title = page.url;
      }
    }
  } catch (e) {
    debug(e.message);
  }
  try {
    if (page.content) {
      page.content = $("<div/>").html(page.content).text();
      content = page.content.match(regexp);
    }
  } catch (e) {
    debug(e.message);
  }
  if (title || content) {
    let result = [
      `<a href="${ui.baseurl}${page.url}?highlight=${text}">${page.title}</a>`,
    ];
    if (content) {
      let [min, max] = [content.index - 100, content.index + 100];
      let [prefix, suffix] = ["...", "..."];

      if (min < 0) {
        prefix = "";
        min = 0;
      }
      if (max > page.content.length) {
        suffix = "";
        max = page.content.length;
      }
      result.push(
        `<p class="text-gray">${prefix}${slice(
          page.content,
          min,
          max
        )}${suffix}</p>`
      );
    }
    results.push(`<li class="border-top py-4">${result.join("")}</li>`);
  }
}
if (results.length > 0 && text.length > 0) {
  $(".search-results .content").html(results.join(""));
  $(".search-results .summary").html(
    ui.i18n.search_results_found.replace("#", results.length)
  );
} else {
  $(".search-results .content").empty();
  $(".search-results .summary").html(ui.i18n.search_results_not_found);
}
$(".search-results h2").html(ui.i18n.search_results);

}

function initialize(name) {

let link = $(".toctree").find(`[href="${decodeURI(name)}"]`);

if (link.length > 0) {
  $(".toctree .current").removeClass("current");
  link.addClass("current");
  link.closest(".level-1").parent().addClass("current");
  for (let i = 1; i <= 11; i++) {
    link.closest(`.level-${i}`).addClass("current");
  }
}

}

function toggleCurrent(link) {

let closest = link.closest("li");
closest.siblings("li.current").removeClass("current");
closest.siblings().find("li.current").removeClass("current");
closest.find("> ul li.current").removeClass("current");
closest.toggleClass("current");

}

function toc() {

$(".toctree li.current")
  .append('<ul class="content-toc"></ul>')
  .html(function () {
    let level = parseInt(this.dataset.level);
    let temp = 0;
    let stack = [$(this).find(".content-toc")];

    $(".markdown-body")
      .find("h2,h3,h4,h5,h6")
      .each(function () {
        let anchor = $("<a/>")
          .addClass("d-flex flex-items-baseline")
          .text($(this).text())
          .attr("href", `#${this.id}`);
        let tagLevel = parseInt(this.tagName.slice(1)) - 1;

        if (tagLevel > temp) {
          let parent = stack[0].children("li:last")[0];
          if (parent) {
            stack.unshift($("<ul/>").appendTo(parent));
          }
        } else {
          stack.splice(
            0,
            Math.min(temp - tagLevel, Math.max(stack.length - 1, 0))
          );
        }
        temp = tagLevel;

        $("<li/>")
          .addClass(`toc level-${level + tagLevel}`)
          .append(anchor)
          .appendTo(stack[0]);
      });
    if (!stack[0].html()) {
      stack[0].remove();
    }
  });

}

function set(name, value) {

return localStorage.setItem(name, value);

}

function get(name) {

return localStorage.getItem(name) || false;

}

function debug() {

console.debug.apply(console, arguments);

}

function restore() {

let scroll = get("scroll");
let scrollTime = get("scrollTime");
let scrollHost = get("scrollHost");

if (scroll && scrollTime && scrollHost) {
  if (scrollHost == location.host && Date.now() - scrollTime < 6e5) {
    $(".sidebar").scrollTop(scroll);
  }
}
$(".sidebar").scroll(function () {
  set("scroll", this.scrollTop);
  set("scrollTime", Date.now());
  set("scrollHost", location.host);
});

}

function highlight() {

let text = new URL(location.href).searchParams.get("highlight");

if (text) {
  $(".markdown-body")
    .find("*")
    .each(function () {
      try {
        if (this.outerHTML.match(new RegExp(text, "im"))) {
          $(this).addClass("search-result");
          $(this).parentsUntil(".markdown-body").removeClass("search-result");
        }
      } catch (e) {
        debug(e.message);
      }
    });
  // last node
  $(".search-result").each(function () {
    $(this).html(function (i, html) {
      return html.replace(text, `<span class="bg-yellow">${text}</span>`);
    });
  });
  $(".search input").val(text);
}

}

$(window).bind(“hashchange”, () =>

initialize(location.hash || location.pathname)

);

$(document).on(“scroll”, function () {

let start = $(this).scrollTop() + 5;
let items = [];

$(".markdown-body")
  .find("h1,h2,h3,h4,h5,h6")
  .each(function () {
    items.push({
      offset: $(this).offset().top,
      id: this.id,
      level: parseInt(this.tagName.slice(1)),
    });
  });
for (let i = 0; i < items.length; i++) {
  if (start > items[i].offset) {
    if (i < items.length - 1) {
      if (start < items[i + 1].offset) {
        if (items[i].level == 1) {
          initialize(location.pathname);
        } else {
          initialize("#" + items[i].id);
        }
      }
    } else {
      initialize("#" + items[i].id);
    }
  }
}

});

$(“#toggle”).click(function () {

$(".sidebar-wrap,.content-wrap,.addons-wrap").toggleClass("shift");

}); $(“.status”).click(function () {

$(".addons").toggleClass("d-none");

});

if (location.pathname == `${ui.baseurl}/search.html`) {

$.ajax(`${ui.baseurl}/data.json`)
  .done(search)
  .fail((xhr, message) => debug(message));

}

toc(); initialize(location.pathname); initialize(location.hash); restore(); highlight();

/* nested ul */ $(“.toc ul”)

.siblings("a")
.each(function () {
  let link = $(this);
  let expand = $('<i class="fa fa-plus-square-o"></i>');

  expand.on("click", function (e) {
    e.stopPropagation();
    toggleCurrent(link);
    return false;
  });
  link.prepend(expand);
});

$(“.markdown-body :header”).append(function () {

return `<a href="#${this.id}" class="anchor"><i class="octicon-link fa fa-link text-blue"></i></a>`;

});

$(“div.highlighter-rouge”).each(function () {

const match = $(this)
  .attr("class")
  .match(/language-(\w+)/);
if (match) {
  $(this).attr("data-lang", match[1]);
}

});

if (“serviceWorker” in navigator) {

navigator.serviceWorker.register(`${ui.baseurl}/sw.caches.js`);

} else {

debug("Service Worker not supported!");

}