{# Base template for (almost) all NetBox pages #}
{% load static %}
{% load helpers %}
<!DOCTYPE html>
<html
  lang="en"
  data-netbox-url-name="{{ request.resolver_match.url_name }}"
  data-netbox-base-path="{{ settings.BASE_PATH }}"
  {% with preferences|get_key:'ui.colormode' as color_mode %}
    {% if color_mode == 'dark'%}
      data-netbox-color-mode="dark"
    {% elif color_mode == 'light' %}
      data-netbox-color-mode="light"
    {% else %}
      data-netbox-color-mode="unset"
    {% endif %}
  {% endwith %}
  >
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width, viewport-fit=cover"
    />

    {# Page title #}
    <title>{% block title %}Home{% endblock %} | NetBox</title>

    <script type="text/javascript">
      /**
       * Set the color mode on the `<html/>` element and in local storage.
       *
       * @param mode {"dark" | "light"} NetBox Color Mode.
       * @param inferred {boolean} Value is inferred from browser/system preference.
       */
      function setMode(mode, inferred) {
          document.documentElement.setAttribute("data-netbox-color-mode", mode);
          localStorage.setItem("netbox-color-mode", mode);
          localStorage.setItem("netbox-color-mode-inferred", inferred);
      }
      /**
       * Determine the best initial color mode to use prior to rendering.
       */
      (function () {
          try {
              // Browser prefers dark color scheme.
              var preferDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
              // Browser prefers light color scheme.
              var preferLight = window.matchMedia("(prefers-color-scheme: light)").matches;
              // Client NetBox color-mode override.
              var clientMode = localStorage.getItem("netbox-color-mode");
              // NetBox server-rendered value.
              var serverMode = document.documentElement.getAttribute("data-netbox-color-mode");
              // Color mode is inferred from browser/system preference and not deterministically set by
              // the client or server.
              var inferred = JSON.parse(localStorage.getItem("netbox-color-mode-inferred"));
      
              if (inferred === true && (serverMode === "light" || serverMode === "dark")) {
                  // The color mode was previously inferred from browser/system preference, but
                  // the server now has a value, so we should use the server's value.
                  return setMode(serverMode, false);
              }
              if (clientMode === null && (serverMode === "light" || serverMode === "dark")) {
                  // If the client mode is not set but the server mode is, use the server mode.
                  return setMode(serverMode, false);
              }
              if (clientMode !== null && serverMode === "unset") {
                  // The color mode has been set, deterministically or otherwise, and the server
                  // has no preference or has not been set. Use the client mode, but allow it to
                  /// be overridden by the server if/when a server value exists.
                  return setMode(clientMode, true);
              }
              if (
                  clientMode !== null &&
                  (serverMode === "light" || serverMode === "dark") &&
                  clientMode !== serverMode
              ) {
                  // If the client mode is set and is different than the server mode (which is also set),
                  // use the client mode over the server mode, as it should be more recent.
                  return setMode(clientMode, false);
              }
              if (clientMode === serverMode) {
                  // If the client and server modes match, use that value.
                  return setMode(clientMode, false);
              }
              if (preferDark && serverMode === "unset") {
                  // If the server mode is not set but the browser prefers dark mode, use dark mode, but
                  // allow it to be overridden by an explicit preference.
                  return setMode("dark", true);
              }
              if (preferLight && serverMode === "unset") {
                  // If the server mode is not set but the browser prefers light mode, use light mode,
                  // but allow it to be overridden by an explicit preference.
                  return setMode("light", true);
              }
          } catch (error) {
              // In the event of an error, log it to the console and set the mode to light mode.
              console.error(error);
          }
          return setMode("light", true);
      })();
    </script>

    {# Static resources #}
    <link
      rel="stylesheet"
      href="{% static 'netbox-external.css'%}"
      onerror="window.location='{% url 'media_failure' %}?filename=netbox-external.css'"
    />
    <link
      rel="stylesheet"
      href="{% static 'netbox-light.css'%}"
      onerror="window.location='{% url 'media_failure' %}?filename=netbox-light.css'"
    />
    <link
      rel="stylesheet"
      href="{% static 'netbox-dark.css'%}"
      onerror="window.location='{% url 'media_failure' %}?filename=netbox-dark.css'"
    />
    <link
      rel="stylesheet"
      media="print"
      href="{% static 'netbox-print.css'%}"
      onerror="window.location='{% url 'media_failure' %}?filename=netbox-print.css'"
    />
    <link rel="icon" type="image/png" href="{% static 'netbox.ico' %}" />

    {# Javascript #}
    <script
      type="text/javascript"
      src="{% static 'netbox.js' %}"
      onerror="window.location='{% url 'media_failure' %}?filename=netbox.js'">
    </script>

    {# Additional <head> content #}
    {% block head %}{% endblock %}
  </head>

  <body>
    <script type="text/javascript">
      (function() {
        // Check localStorage to see if the sidebar should be pinned.
        var sideNavRaw = localStorage.getItem('netbox-sidenav');
        // Determine if the device has a small screeen. This media query is equivalent to
        // bootstrap's media-breakpoint-down(lg) breakpoint mixin, which is what the sidenav's
        // CSS uses.
        var isSmallScreen = window.matchMedia('(max-width: 991.98px)').matches;
        if (typeof sideNavRaw === 'string') {
          var sideNavState = JSON.parse(sideNavRaw);
          if (sideNavState.pinned === true && !isSmallScreen) {
            // If the sidebar should be pinned and this is not a small screen, set the appropriate
            // body attributes prior to the rest of the content rendering. This prevents
            // jumpy/glitchy behavior on page reloads.
            document.body.setAttribute('data-sidenav-pinned', '');
            document.body.setAttribute('data-sidenav-show', '');
          } else {
            document.body.setAttribute('data-sidenav-hidden', '');
          }
        }
      })();
    </script>

    {# Page layout #}
    {% block layout %}{% endblock %}

    {# Additional Javascript #}
    {% block javascript %}{% endblock %}

    {# User messages #}
    {% include 'inc/messages.html' %}

    {# Data container #}
    <div id="netbox-data" style="display: none!important; visibility: hidden!important">
      {% block data %}{% endblock %}
    </div>

  </body>
</html>
