<!DOCTYPE html>

<!--
  Copyright 2018 The Chromium Authors. All rights reserved.
  Use of this source code is governed by a BSD-style license that can be
  found in the LICENSE file.
-->

<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- Note: This tag is replaced when served through DDS! -->
    <base href="/">

    <title></title>
    <link href="favicon.png" rel="icon" sizes="64x64">

    <!-- Global site tag (gtag.js) - Google Analytics -->	
    <script>	
      const GA_DEVTOOLS_PROPERTY = 'UA-26406144-34'; // Dart DevTools GA Property UA.	

      function getDevToolsPropertyID() {	
          return GA_DEVTOOLS_PROPERTY;	
      }	
    </script>	
    <!-- The below URI ?id= must match the GA_DEVTOOLS_PROPERTY above. -->	
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-26406144-34"></script>	
    <script type="text/javascript" src="devtools_analytics.js"></script>	
    <!-- End of DevTools Google Analytics -->

    <!-- DO NOT REMOVE: -->
    <!-- OBSERVER SCRIPT PLACEHOLDER -->

    <script type="text/javascript">
        function supportsES6Classes() {
            "use strict";
            try { eval("class Foo {}"); }
            catch (e) { return false; }
            return true;
        }

        if (!supportsES6Classes()) {
            window.location.href = '/unsupported-browser.html';
        }
    </script>
</head>

<body>
  <!-- This script installs service_worker.js to provide PWA functionality to
       application. For more information, see:
       https://developers.google.com/web/fundamentals/primers/service-workers -->
  <script>
    var version = '2.16.0';
    var scriptLoaded = false;
    function loadMainDartJs() {
      if (scriptLoaded) {
        return;
      }
      scriptLoaded = true;
      var scriptTag = document.createElement('script');
      scriptTag.src = 'main.dart.js';
      scriptTag.type = 'application/javascript';
      document.body.append(scriptTag);
    }

    if ('serviceWorker' in navigator) {
      if (window.location.href.includes('index.ddc.html')) {
        // If we are running DevTools locally, immediately load `main.dart.js` and
        // unregister any service workers:
        loadMainDartJs();
        navigator.serviceWorker.getRegistrations().then(function(registrations) {
          for (let registration of registrations) {
            registration.unregister();
          }
        });
      } else {
        // Service workers are supported. Use them.
        window.addEventListener('load', function() {
          // Wait for registration to finish before dropping the <script> tag.
          // Otherwise, the browser will load the script multiple times,
          // potentially different versions.
          var serviceWorkerUrl = 'service_worker.js?v=' + version;
          navigator.serviceWorker.register(serviceWorkerUrl)
              .then((reg) => {
                function waitForActivation(serviceWorker) {
                  serviceWorker.addEventListener('statechange', () => {
                    if (serviceWorker.state == 'activated') {
                      loadMainDartJs();
                    }
                  });
                }
                if (!reg.active && (reg.installing || reg.waiting)) {
                  // No active web worker and we have installed or are installing
                  // one for the first time. Simply wait for it to activate.
                  waitForActivation(reg.installing || reg.waiting);
                } else if (!reg.active.scriptURL.endsWith(version)) {
                  // When the app updates the version changes, so we
                  // need to ask the service worker to update.
                  reg.update();
                  waitForActivation(reg.installing);
                } else {
                  // Existing service worker is still good.
                  loadMainDartJs();
                }
              })
              .catch((err) => {
                console.warn(
                    ` Falling back to plain <script> tag. Error loading service worker: ${
                        err}`);
                loadMainDartJs();
              });

          // If service worker doesn't succeed in a reasonable amount of time,
          // fallback to plain <script> tag.
          setTimeout(() => {
            if (!scriptLoaded) {
              console.warn(
                  'Failed to load app from service worker. Falling back to plain <script> tag.',
              );
              loadMainDartJs();
            }
          }, 4000);
        });
      }
    } else {
      // Service workers not supported. Just drop the <script> tag.
      loadMainDartJs();
    }
  </script>
</body>
</html>
