{# @copyright   Copyright (C) 2010-2024 Combodo SAS #}
{# @license     http://opensource.org/licenses/AGPL-3.0 #}
<!DOCTYPE html>
<html lang="{{ aPage.aMetadata.sLang }}">
<head>
    <meta charset="{{ aPage.aMetadata.sCharset }}">
    {# This block can be used to add your own meta tags by extending the default template #}
    {% block iboPageExtraMetas %}
    {% endblock %}
    {% if aPage.aMetadata.sBaseUrl is defined or aPage.aMetadata.sBaseTarget is defined %}
        <base {% if aPage.aMetadata.sBaseUrl is defined %}href="{{ aPage.aMetadata.sBaseUrl }}"{% endif %} {% if aPage.aMetadata.sBaseTarget is defined %}target="{{ aPage.aMetadata.sBaseTarget }}"{% endif %}>
    {% endif %}
    <title>{{ aPage.sTitle }}</title>
    {% if aPage.sFaviconUrl is defined %}
        <link rel="shortcut icon" href="{{ aPage.sFaviconUrl|add_itop_version|raw }}">
    {% endif %}
    <link rel="search" type="application/opensearchdescription+xml" title="iTop" href="{{ aPage.sAbsoluteUrlAppRoot }}pages/opensearch.xml.php">
    {# Main fonts have to be preloaded to avoid blocking content rendering #}
    {% for aPreloadedFont in aPage.aPreloadedFonts %}
        <link rel="preload" href="{{ aPreloadedFont['font'] }}" as="font" type="font/{{ aPreloadedFont['type'] }}" crossorigin>
    {% endfor %}
    {# Stylesheets MUST be loaded before any scripts otherwise we may face problems such as
	- Visual glitches
	- jQuery scripts spurious problems (like failing on a 'reload') #}
    {% block iboPageCssFiles %}
	    {% for aCssFileData in aPage.aCssFiles %}
            {# Mind that CSS files are registered in a JS variable below (@see aLoadedCssFilesRegister), to ensure that a file isn't loaded twice through an async call #}
		    {% if aCssFileData['condition'] != '' %}<!--[if {{ aCssFileData['condition'] }}]>{% endif %}
			    <link type="text/css" href="{{ aCssFileData['link']|add_itop_version|raw }}" rel="stylesheet">
			{% if aCssFileData['condition'] != '' %}<![endif]-->{% endif %}
	    {% endfor %}
    {% endblock %}

    {% block iboPageCssInline %}
        {# We put each styles in a dedicated style tag to prevent massive failure if 1 style is broken (eg. missing semi-colon, bracket, ...) #}
        {% for sCssInline in aPage.aCssInline %}
            <style>
                {{ sCssInline|raw }}
            </style>
        {% endfor %}
    {% endblock %}

    {% block iboPageJsInlineEarly %}
        {% for sJsInline in aPage.aJsInlineEarly %}
            {# We put each scripts in a dedicated script tag to prevent massive failure if 1 script is broken (eg. missing semi-colon or non closed multi-line comment) #}
            <script type="text/javascript">
            {{ sJsInline|raw }}
            </script>
        {% endfor %}
    {% endblock %}
</head>
<body data-gui-type="backoffice">
{% if aPage.isPrintable %}<div class="printable-content" style="width: 27.7cm;">{% endif %}
    {% block iboPageBodyHtml %}
        <div id="ibo-page-container">
            {{ render_block(oLayout, {aPage: aPage}) }}
        </div>
    {% endblock %}
{% if aPage.isPrintable %}</div>{% endif %}

{% block iboDeferredBlocks %}
    {% for oBlock in aDeferredBlocks %}
        {{ render_block(oBlock, {aPage: aPage}) }}
    {% endfor %}
{% endblock %}

{% block iboPageTemplates %}
{% endblock %}

{# CSS files can either be loaded initially or requested by an XHR response                                                                    #}
{# In order to ensure that a file isn't loaded twice, we register them here so async calls can check if they to load their dependencies or not #}
{# Note that unlike for the JS files, we don't need to use promises, as we don't need them to wait for the previous one to be loaded           #}
{# (Having a CSS loaded again can lead to rule overloads being reverted)                                                                       #}
<script type="text/javascript">
/**
 * @var {Map} aLoadedCssFilesRegister
 * Register of all CSS files loaded in this page.
 * A CSS file MUST NOT be loaded more than once as it could compromise rules overloads loaded after the first time.
 */
const aLoadedCssFilesRegister = new Map();
{% for aCssFileData in aPage.aCssFiles %}
    aLoadedCssFilesRegister.set("{{ aCssFileData['link']|raw }}", true);
{% endfor %}
</script>

{# JS files can either be loaded initially or requested by an XHR response                                          #}
{# - For the initial page, all files are loaded before running inline snippets                                      #}
{# - For XHR responses, we need to ensure that all required files are fully loaded before running inline snippets   #}
<script type="text/javascript">
/**
 * @var {Map} aLoadedJsFilesRegister
 * Register of all JS files loaded in this page, including the Promise corresponding to the loading state of each file.
 * A JS file MUST NOT be loaded more than once as it could compromise settings / plugins loaded after the first time.
 */
const aLoadedJsFilesRegister = new Map();
/**
 * @var {Map} aLoadedJsFilesResolveCallbacks
 * Resolve callbacks of JS files registered in aLoadedJsFilesRegister. Used -mostly in AjaxPage- to know when a file is done loading so the depending snippets can run
 */
const aLoadedJsFilesResolveCallbacks = new Map();
{% for sJsFile in aPage.aJsFiles %}
    aLoadedJsFilesRegister.set("{{ sJsFile|raw }}", new Promise(function(resolve) {
        aLoadedJsFilesResolveCallbacks.set("{{ sJsFile|raw }}", resolve);
        // Resolve promise right away as these files are loaded immediately before any inline JS is executed
        aLoadedJsFilesResolveCallbacks.get("{{ sJsFile|raw }}")();
    }));
{% endfor %}
</script>

{% block iboPageJsFiles %}
    {% for sJsFile in aPage.aJsFiles %}
        <script type="text/javascript" src="{{ sJsFile|add_itop_version|raw }}"></script>
    {% endfor %}
{% endblock %}

{% block iboPageJsInlineScripts %}
    {% if aPage.aJsInlineOnInit is not empty or aPage.aJsInlineOnDomReady is not empty %}
        <script type="text/javascript">
            {# TODO 3.0.0: How to do this in native JS? #}
            $(document).ready(function () {
                {% block iboPageJsInlineOnInit %}
                    {% for sJsInline in aPage.aJsInlineOnInit %}
                        {{ sJsInline|raw }}
                    {% endfor %}
                {% endblock %}

                {% block iboPageJsInlineOnDomReady %}
                    setTimeout(function () {
                        {% for sJsInline in aPage.aJsInlineOnDomReady %}
                        {{ sJsInline|raw }}
                        {% endfor %}
                    }, 50);
                {% endblock %}
            });
        </script>
    {% endif %}
    {% block iboPageJsInlineLive %}
        {% for sJsInline in aPage.aJsInlineLive %}
            {# We put each scripts in a dedicated script tag to prevent massive failure if 1 script is broken (eg. missing semi-colon or non closed multi-line comment) #}
            <script type="text/javascript">
                {{ sJsInline|raw }}
            </script>
        {% endfor %}
    {% endblock %}
{% endblock %}

{% block iboCapturedOutput %}
    {{ aPage.sCapturedOutput|raw }}
{% endblock %}

</body>
</html>