From c43eb1cea3a6650a6adeefb061aef63ff6d03dc3 Mon Sep 17 00:00:00 2001 From: MFSY Date: Mon, 25 Feb 2019 14:20:02 +0100 Subject: [PATCH] updated site --- .../core/shacl20170720/prefixmapings.html | 4 +- code.11ceed35.map | 1 - code.11ceed35.css => code.296e2f08.css | 0 docs/contact.html | 4 +- .../brainatlas/brain-atlas-derivation.html | 4 +- docs/data-models/brainatlas/brain-atlas.html | 4 +- .../brainatlas/registering-brain-atlas.html | 4 +- .../registering-whole-brain-morphology.html | 4 +- .../electrophysiology/electrophysiology.html | 4 +- ...intracellularsharpelectrode-recording.html | 4 +- .../wholecellpatchclamp-recording.html | 4 +- docs/data-models/index.html | 4 +- .../morphology/morphology-reconstruction.html | 4 +- docs/data-models/morphology/morphology.html | 4 +- ...rain-neuron-morphology-reconstruction.html | 4 +- docs/datamodeling/index.html | 4 +- docs/gettingstarted/contribution.html | 4 +- docs/gettingstarted/download.html | 15 +- docs/gettingstarted/index.html | 4 +- docs/gettingstarted/overview.html | 4 +- docs/index-claat.html | 992 ++++++++++++++++++ docs/index.html | 4 +- docs/license.html | 4 +- docs/meetings.html | 4 +- docs/publication/index.html | 4 +- docs/shacl-tutorial/overview/index.html | 4 +- docs/tools/index.html | 4 +- index.html | 2 +- js.60833e22.js | 20 - js.b5eb6d5a.map | 1 - js.bfb090f7.js | 19 + paradox.json | 2 +- search/search_index.json | 2 +- style.60bcb90f.map | 1 - style.60bcb90f.css => style.7c46d1e4.css | 0 35 files changed, 1072 insertions(+), 75 deletions(-) delete mode 100644 code.11ceed35.map rename code.11ceed35.css => code.296e2f08.css (100%) create mode 100644 docs/index-claat.html delete mode 100644 js.60833e22.js delete mode 100644 js.b5eb6d5a.map create mode 100644 js.bfb090f7.js delete mode 100644 style.60bcb90f.map rename style.60bcb90f.css => style.7c46d1e4.css (100%) diff --git a/assets/contexts/nexus/core/shacl20170720/prefixmapings.html b/assets/contexts/nexus/core/shacl20170720/prefixmapings.html index 54118cc1..b5bf5973 100644 --- a/assets/contexts/nexus/core/shacl20170720/prefixmapings.html +++ b/assets/contexts/nexus/core/shacl20170720/prefixmapings.html @@ -141,7 +141,7 @@ @@ -217,7 +217,7 @@ diff --git a/code.11ceed35.map b/code.11ceed35.map deleted file mode 100644 index d682917b..00000000 --- a/code.11ceed35.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":[],"names":[],"mappings":"","file":"code.11ceed35.map","sourceRoot":"../product-page-src"} \ No newline at end of file diff --git a/code.11ceed35.css b/code.296e2f08.css similarity index 100% rename from code.11ceed35.css rename to code.296e2f08.css diff --git a/docs/contact.html b/docs/contact.html index 4d0d8365..935fc7fe 100644 --- a/docs/contact.html +++ b/docs/contact.html @@ -177,7 +177,7 @@ @@ -197,7 +197,7 @@

< diff --git a/docs/data-models/brainatlas/brain-atlas-derivation.html b/docs/data-models/brainatlas/brain-atlas-derivation.html index c4378819..8fd207ea 100644 --- a/docs/data-models/brainatlas/brain-atlas-derivation.html +++ b/docs/data-models/brainatlas/brain-atlas-derivation.html @@ -158,7 +158,7 @@
@@ -254,7 +254,7 @@

diff --git a/docs/data-models/brainatlas/brain-atlas.html b/docs/data-models/brainatlas/brain-atlas.html index e06ab760..471c3c99 100644 --- a/docs/data-models/brainatlas/brain-atlas.html +++ b/docs/data-models/brainatlas/brain-atlas.html @@ -184,7 +184,7 @@
@@ -226,7 +226,7 @@

-0.2.0+44-40e05df0 +0.2.0+50-06b793b7 diff --git a/docs/data-models/brainatlas/registering-brain-atlas.html b/docs/data-models/brainatlas/registering-brain-atlas.html index 0061a63f..e8f860b8 100644 --- a/docs/data-models/brainatlas/registering-brain-atlas.html +++ b/docs/data-models/brainatlas/registering-brain-atlas.html @@ -196,7 +196,7 @@
@@ -368,7 +368,7 @@

-0.2.0+44-40e05df0 +0.2.0+50-06b793b7 diff --git a/docs/data-models/brainatlas/registering-whole-brain-morphology.html b/docs/data-models/brainatlas/registering-whole-brain-morphology.html index 7c1c7024..734b5b90 100644 --- a/docs/data-models/brainatlas/registering-whole-brain-morphology.html +++ b/docs/data-models/brainatlas/registering-whole-brain-morphology.html @@ -196,7 +196,7 @@
@@ -349,7 +349,7 @@

-0.2.0+44-40e05df0 +0.2.0+50-06b793b7 diff --git a/docs/data-models/electrophysiology/electrophysiology.html b/docs/data-models/electrophysiology/electrophysiology.html index 2a35b336..b8b63190 100644 --- a/docs/data-models/electrophysiology/electrophysiology.html +++ b/docs/data-models/electrophysiology/electrophysiology.html @@ -184,7 +184,7 @@
@@ -225,7 +225,7 @@

-0.2.0+44-40e05df0 +0.2.0+50-06b793b7 diff --git a/docs/data-models/electrophysiology/intracellularsharpelectrode-recording.html b/docs/data-models/electrophysiology/intracellularsharpelectrode-recording.html index 77bdb245..d9c0dc6e 100644 --- a/docs/data-models/electrophysiology/intracellularsharpelectrode-recording.html +++ b/docs/data-models/electrophysiology/intracellularsharpelectrode-recording.html @@ -196,7 +196,7 @@
@@ -354,7 +354,7 @@

-0.2.0+44-40e05df0 +0.2.0+50-06b793b7 diff --git a/docs/data-models/electrophysiology/wholecellpatchclamp-recording.html b/docs/data-models/electrophysiology/wholecellpatchclamp-recording.html index 84142754..ea183337 100644 --- a/docs/data-models/electrophysiology/wholecellpatchclamp-recording.html +++ b/docs/data-models/electrophysiology/wholecellpatchclamp-recording.html @@ -196,7 +196,7 @@
@@ -355,7 +355,7 @@

-0.2.0+44-40e05df0 +0.2.0+50-06b793b7 diff --git a/docs/data-models/index.html b/docs/data-models/index.html index 36a51fb2..43e1d1b1 100644 --- a/docs/data-models/index.html +++ b/docs/data-models/index.html @@ -184,7 +184,7 @@
@@ -226,7 +226,7 @@

diff --git a/docs/data-models/morphology/morphology-reconstruction.html b/docs/data-models/morphology/morphology-reconstruction.html index 7760ca70..11b4df24 100644 --- a/docs/data-models/morphology/morphology-reconstruction.html +++ b/docs/data-models/morphology/morphology-reconstruction.html @@ -196,7 +196,7 @@
@@ -380,7 +380,7 @@

-0.2.0+44-40e05df0 +0.2.0+50-06b793b7 diff --git a/docs/data-models/morphology/morphology.html b/docs/data-models/morphology/morphology.html index 75f0597b..43c2a91a 100644 --- a/docs/data-models/morphology/morphology.html +++ b/docs/data-models/morphology/morphology.html @@ -177,7 +177,7 @@
@@ -201,7 +201,7 @@

diff --git a/docs/data-models/morphology/whole-brain-neuron-morphology-reconstruction.html b/docs/data-models/morphology/whole-brain-neuron-morphology-reconstruction.html index cd5331a6..c27f0aad 100644 --- a/docs/data-models/morphology/whole-brain-neuron-morphology-reconstruction.html +++ b/docs/data-models/morphology/whole-brain-neuron-morphology-reconstruction.html @@ -196,7 +196,7 @@
@@ -340,7 +340,7 @@

-0.2.0+44-40e05df0 +0.2.0+50-06b793b7 diff --git a/docs/datamodeling/index.html b/docs/datamodeling/index.html index 501ef2cc..a6682bc6 100644 --- a/docs/datamodeling/index.html +++ b/docs/datamodeling/index.html @@ -177,7 +177,7 @@
@@ -197,7 +197,7 @@

diff --git a/docs/gettingstarted/contribution.html b/docs/gettingstarted/contribution.html index 56c8acfc..54041d25 100644 --- a/docs/gettingstarted/contribution.html +++ b/docs/gettingstarted/contribution.html @@ -193,7 +193,7 @@
@@ -344,7 +344,7 @@

diff --git a/docs/gettingstarted/download.html b/docs/gettingstarted/download.html index a4dc38f9..9454f8c6 100644 --- a/docs/gettingstarted/download.html +++ b/docs/gettingstarted/download.html @@ -177,7 +177,7 @@
@@ -207,9 +207,18 @@

@@ -220,7 +229,7 @@

diff --git a/docs/gettingstarted/index.html b/docs/gettingstarted/index.html index 1a77c1a8..9431b592 100644 --- a/docs/gettingstarted/index.html +++ b/docs/gettingstarted/index.html @@ -177,7 +177,7 @@
@@ -196,7 +196,7 @@

diff --git a/docs/gettingstarted/overview.html b/docs/gettingstarted/overview.html index 2cc5280f..8d8d6453 100644 --- a/docs/gettingstarted/overview.html +++ b/docs/gettingstarted/overview.html @@ -177,7 +177,7 @@
@@ -204,7 +204,7 @@

diff --git a/docs/index-claat.html b/docs/index-claat.html new file mode 100644 index 00000000..41da2850 --- /dev/null +++ b/docs/index-claat.html @@ -0,0 +1,992 @@ + + + + + + + + + + + + + + + + + + + + + + + +Your First Progressive Web App + + + + + + + + + + + + + + + + + +
+ +
+ +
+
+
+ + +
+
+
+

Your First Progressive Web App

+

Codelab Feedback

+

Introduction

+

Progressive Web Apps are experiences that combine the best of the web and the best of apps. They are useful to users from the very first visit in a browser tab, no install required. As the user progressively builds a relationship with the app over time, it becomes more and more powerful. It loads quickly, even on flaky networks, sends relevant push notifications, has an icon on the home screen, and loads as a top-level, full screen experience.

+

What is a Progressive Web App?

+

A Progressive Web App is:

+
    +
  • Progressive - Works for every user, regardless of browser choice because it’s built with progressive enhancement as a core tenet.
  • +
  • Responsive - Fits any form factor: desktop, mobile, tablet, or whatever is next.
  • +
  • Connectivity independent - Enhanced with service workers to work offline or on low-quality networks.
  • +
  • App-like - Feels like an app, because the app shell model separates the application functionality from application content .
  • +
  • Fresh - Always up-to-date thanks to the service worker update process.
  • +
  • Safe - Served via HTTPS to prevent snooping and to ensure content hasn’t been tampered with.
  • +
  • Discoverable - Is identifiable as an “application” thanks to W3C manifest and service worker registration scope, allowing search engines to find it.
  • +
  • Re-engageable - Makes re-engagement easy through features like push notifications.
  • +
  • Installable - Allows users to add apps they find most useful to their home screen without the hassle of an app store.
  • +
  • Linkable - Easily share the application via URL, does not require complex installation.
  • +
+

This codelab will walk you through creating your own Progressive Web App, including the design considerations, as well as implementation details, to ensure that your app meets the above key principles of a Progressive Web App.

+ +

What you will build

+

What you’ll learn

+
    +
  • How to design and construct an app using the “app shell” method
  • +
  • How to make your app work offline
  • +
  • How to store data for later offline use
  • +
+

What you’ll need

+
    +
  • A recent version of Chrome. Note, this works in other browsers as well, but we’ll be using a few features of the Chrome DevTools to better understand what’s happening at the browser level.
  • +
  • Web Server for Chrome, or your own web server of choice
  • +
  • The sample code
  • +
  • A text editor
  • +
  • Basic knowledge of HTML, CSS, JavaScript, and Chrome DevTools
  • +
+

This codelab is focused on Progressive Web Apps. Non-relevant concepts and code blocks are glossed over and are provided for you to simply copy and paste.

+

Getting set up

+

Download the Code

+

Click the following link to download all the code for this codelab:

+

[](https://github.com/googlecodelabs/your-first-pwapp/archive/master.zip)

+

Unpack the downloaded zip file. This will unpack a root folder (your-first-pwapp-master), which contains one folder for each step of this codelab, along with all of the resources you will need.

+

The step-NN folders contain the desired end state of each step of this codelab. They are there for reference. We’ll be doing all our coding work in a directory called work.

+

Install and verify web server

+

While you’re free to use your own web server, this codelab is designed to work well with the Chrome Web Server. If you don’t have that app installed yet, you can install it from the Chrome Web Store.

+

[](https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb)

+

After installing the Web Server for Chrome app, click on the Apps shortcut on the bookmarks bar:

+Screen Shot 2016-04-11 at 4.01.20 PM.png + +

In the ensuing window, click on the Web Server icon:

+Screen Shot 2016-02-18 at 11.45.19 AM.png +

You’ll see this dialog next, which allows you to configure your local web server:

+

<img src=“img/433870360ad308d4.png” alt=“Screen Shot 2016-02-18 at 11.48.14 AM.png” title="“Web Server for Chrome Screenshot”“ width=”513.64" />

+

Click the choose folder button, and select the work folder. This will enable you to serve your work in progress via the URL highlighted in the web server dialog (in the Web Server URL(s) section).

+

Under Options, check the box next to “Automatically show index.html”, as shown below:

+39b4e0371e9703e6.png +

Then stop and restart the server by sliding the toggle labeled “Web Server: STARTED” to the left and then back to the right.

+Screen Shot 2016-02-18 at 12.22.18 PM.png +

Now visit your work site in your web browser (by clicking on the highlighted Web Server URL) and you should see a page that looks like this:

+aa64e93e8151b642.png +

This app is not yet doing anything interesting - so far, it’s just a minimal skeleton with a spinner we’re using to verify your web server functionality. We’ll add functionality and UI features in subsequent steps.

+ +

Architect your App Shell

+

What is the app shell?

+

The app’s shell is the minimal HTML, CSS, and JavaScript that is required to power the user interface of a progressive web app and is one of the components that ensures reliably good performance. Its first load should be extremely quick and immediately cached. “Cached” means that the shell files are loaded once over the network and then saved to the local device. Every subsequent time that the user opens the app, the shell files are loaded from the local device’s cache, which results in blazing-fast startup times.

+

App shell architecture separates the core application infrastructure and UI from the data. All of the UI and infrastructure is cached locally using a service worker so that on subsequent loads, the Progressive Web App only needs to retrieve the necessary data, instead of having to load everything.

+

A service worker is a script that your browser runs in the background, separate from a web page, opening the door to features that don’t need a web page or user interaction.

+appshell-1.jpg +

Put another way, the app shell is similar to the bundle of code that you’d publish to an app store when building a native app. It is the core components necessary to get your app off the ground, but likely does not contain the data.

+

Why use the App Shell architecture?

+

Using the app shell architecture allows you to focus on speed, giving your Progressive Web App similar properties to native apps: instant loading and regular updates, all without the need of an app store.

+

**Design the App Shell **

+

The first step is to break the design down into its core components.

+

Ask yourself:

+
    +
  • What needs to be on screen immediately?
  • +
  • What other UI components are key to our app?
  • +
  • What supporting resources are needed for the app shell? For example images, JavaScript, styles, etc.
  • +
+

We’re going to create a Weather app as our first Progressive Web App. The key components will consist of:

+

When designing a more complex app, content that isn’t needed for the initial load can be requested later and then cached for future use. For example, we could defer the loading of the New City dialog until after we’ve rendered the first run experience and have some idle cycles available.

+

Implement your App Shell

+

There are multiple ways to get started with any project, in this case, to keep our project as simple as possible and concentrate on Progressive Web Apps, we’ve provided you with all of the resources you’ll need.

+

Create the HTML for the App Shell

+

Now we’ll add the core components we discussed in Architect the App Shell.

+

Remember, the key components will consist of:

+
    +
  • Header with a title, and add/refresh buttons
  • +
  • Container for forecast cards
  • +
  • A forecast card template
  • +
  • A dialog for adding new cities
  • +
  • A loading indicator
  • +
+

The index.html file that is already in your work directory should look something like this (this is a subset of the actual contents, don’t copy this code into your file):

+
<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>Weather PWA</title>
+  <link rel="stylesheet" type="text/css" href="styles/inline.css">
+</head>
+<body>
+  <header class="header">
+    <h1 class="header__title">Weather PWA</h1>
+    <button id="butRefresh" class="headerButton"></button>
+    <button id="butAdd" class="headerButton"></button>
+  </header>
+
+  <main class="main">
+    <div class="card cardTemplate weather-forecast" hidden>
+    . . .
+    </div>
+  </main>
+
+  <div class="dialog-container">
+  . . .
+  </div>
+
+  <div class="loader">
+    <svg viewBox="0 0 32 32" width="32" height="32">
+      <circle id="spinner" cx="16" cy="16" r="14" fill="none"></circle>
+    </svg>
+  </div>
+
+  <!-- Insert link to app.js here -->
+</body>
+</html>
+
+

Notice the loader is visible by default. This ensures that the user sees the loader immediately as the page loads, giving them a clear indication that the content is loading.

+

To save time, we’ve also already created the stylesheet for you to use.

+ +

Check out the key JavaScript app code

+

Now that we have most of the UI ready, it’s time to start hooking up the code to make everything work. Like the rest of the app shell, be conscious about what code is necessary as part of the key experience and what can be loaded later.

+

Your work directory also already includes the app code (scripts/app.js), in it you’ll find:

+
    +
  • An app object that contains some of the key information necessary for the app.
  • +
  • The event listeners for all of the buttons in the header (add/refresh) and in the add city dialog (add/cancel).
  • +
  • A method to add or update forecast cards (app.updateForecastCard).
  • +
  • A method to get the latest weather forecast data from the Firebase Public Weather API (app.getForecast).
  • +
  • A method to iterate the current cards and call app.getForecast to get the latest forecast data (app.updateForecasts).
  • +
  • Some fake data (initialWeatherForecast) you can use to quickly test how things render.
  • +
+

Test it out

+

Now that you’ve got the core HTML, styles and JavaScript, it’s time to test the app.

+

To see how the fake weather data is rendered, uncomment the following line at the bottom of your index.html file:

+
<!--<script src="scripts/app.js" async></script>-->
+
+

Next, uncomment the following line at the bottom of your app.js file:

+
// app.updateForecastCard(initialWeatherForecast);
+
+

Reload your app. The result should be a nicely formatted (though fake, as you can tell by the date) forecast card with the spinner disabled, like this:

+166c3b4982e4a0ad.png +

[](https://weather-pwa-sample.firebaseapp.com/step-04/)

+

Once you’ve tried it and verified it works as expected, you can remove the call to app.updateForecastCard with the fake data again. We only needed it to ensure that everything worked as expected.

+

Start with a fast first load

+

Progressive Web Apps should start fast and be usable immediately. In its current state, our Weather App starts quickly, but it’s not useable. There’s no data. We could make an AJAX request to get that data, but that results in an extra request and makes the initial load longer. Instead, provide real data in the first load.

+

Inject the weather forecast data

+

For this code lab, we’ll simulate the server injecting the weather forecast directly into the JavaScript, but in a production app, the latest weather forecast data would be injected by the server based on the IP address geo-location of the user.

+

The code already contains the data that we’re going to inject. It’s the initialWeatherForecast that we used in the previous step.

+

Differentiating the first run

+

But, how do we know when to display this information, which may not be relevant on future loads when the weather app is pulled from the cache? When the user loads the app on subsequent visits, they may have changed cities, so we need to load the information for those cities, not necessarily the first city they ever looked up.

+

User preferences, like the list of cities a user has subscribed to, should be stored locally using IndexedDB or another fast storage mechanism. To simplify this code lab as much as possible, we’ve used localStorage, which is not ideal for production apps because it is a blocking, synchronous storage mechanism that is potentially very slow on some devices.

+ +

First, let’s add the code required to save user preferences. Find the following TODO comment in your code.

+
  // TODO add saveSelectedCities function here
+
+

And add the following code below the comment.

+
  // Save list of cities to localStorage.
+  app.saveSelectedCities = function() {
+    var selectedCities = JSON.stringify(app.selectedCities);
+    localStorage.selectedCities = selectedCities;
+  };
+
+

Next, let’s add the startup code to check if the user has any saved cities and render those, or use the injected data. Find the following comment:

+
  // TODO add startup code here
+
+

And add the following code below this comment:

+
/************************************************************************
+   *
+   * Code required to start the app
+   *
+   * NOTE: To simplify this codelab, we've used localStorage.
+   *   localStorage is a synchronous API and has serious performance
+   *   implications. It should not be used in production applications!
+   *   Instead, check out IDB (https://www.npmjs.com/package/idb) or
+   *   SimpleDB (https://gist.github.com/inexorabletash/c8069c042b734519680c)
+   ************************************************************************/
+
+  app.selectedCities = localStorage.selectedCities;
+  if (app.selectedCities) {
+    app.selectedCities = JSON.parse(app.selectedCities);
+    app.selectedCities.forEach(function(city) {
+      app.getForecast(city.key, city.label);
+    });
+  } else {
+    /* The user is using the app for the first time, or the user has not
+     * saved any cities, so show the user some fake data. A real app in this
+     * scenario could guess the user's location via IP lookup and then inject
+     * that data into the page.
+     */
+    app.updateForecastCard(initialWeatherForecast);
+    app.selectedCities = [
+      {key: initialWeatherForecast.key, label: initialWeatherForecast.label}
+    ];
+    app.saveSelectedCities();
+  }
+
+

The startup code checks if there are any cities saved in local storage. If so, then it parses the local storage data and then displays a forecast card for each of the saved cities. Else, the startup code just uses the fake forecast data and saves that as the default city.

+

Save the selected cities

+

Finally, you need to modify the “add city” button handler to save the selected city to local storage.

+

Update your butAddCity click handler so that it matches the following code:

+
document.getElementById('butAddCity').addEventListener('click', function() {
+    // Add the newly selected city
+    var select = document.getElementById('selectCityToAdd');
+    var selected = select.options[select.selectedIndex];
+    var key = selected.value;
+    var label = selected.textContent;
+    if (!app.selectedCities) {
+      app.selectedCities = [];
+    }
+    app.getForecast(key, label);
+    app.selectedCities.push({key: key, label: label});
+    app.saveSelectedCities();
+    app.toggleAddDialog(false);
+  });
+
+

The new additions are the initialization of app.selectedCities if it doesn’t exist, and the calls to app.selectedCities.push() and app.saveSelectedCities().

+

Test it out

+
    +
  • When first run, your app should immediately show the user the forecast from initialWeatherForecast.
  • +
  • Add a new city (by clicking the + icon on the upper right) and verify that two cards are shown.
  • +
  • Refresh the browser and verify that the app loads both forecasts and shows the latest information.
  • +
+

[](https://weather-pwa-sample.firebaseapp.com/step-05/)

+

Use service workers to pre-cache the App Shell

+

Progressive Web Apps have to be fast, and installable, which means that they work online, offline, and on intermittent, slow connections. To achieve this, we need to cache our app shell using service worker, so that it’s always available quickly and reliably.

+

If you’re unfamiliar with service workers, you can get a basic understanding by reading Introduction To Service Workers about what they can do, how their lifecycle works and more. Once you’ve completed this code lab, be sure to check out the Debugging Service Workers code lab for a more in-depth look at how to work with service workers.

+

Features provided via service workers should be considered a progressive enhancement, and added only if supported by the browser. For example, with service workers you can cache the app shell and data for your app, so that it’s available even when the network isn’t. When service workers aren’t supported, the offline code isn’t called, and the user gets a basic experience. Using feature detection to provide progressive enhancement has little overhead and it won’t break in older browsers that don’t support that feature.

+ +

Register the service worker if it’s available

+

The first step to making the app work offline is to register a service worker, a script that allows background functionality without the need for an open web page or user interaction.

+

This takes two simple steps:

+
    +
  1. Tell the browser to register the JavaScript file as the service worker.
  2. +
  3. Create a JavaScript file containing the service worker.
  4. +
+

First, we need to check if the browser supports service workers, and if it does, register the service worker. Add the following code to app.js (after the // TODO add service worker code here comment):

+
  if ('serviceWorker' in navigator) {
+    navigator.serviceWorker
+             .register('../service-worker.js')
+             .then(function() { console.log('Service Worker Registered'); });
+  }
+
+

Cache the site assets

+

When the service worker is registered, an install event is triggered the first time the user visits the page. In this event handler, we will cache all the assets that are needed for the application.

+ +

When the service worker is fired, it should open the caches object and populate it with the assets necessary to load the App Shell. Create a file called service-worker.js in your application root folder (which should be your-first-pwapp-master/work directory). This file must live in the application root because the scope for service workers is defined by the directory in which the file resides. Add this code to your new service-worker.js file:

+
var cacheName = 'weatherPWA-step-6-1';
+var filesToCache = [];
+
+self.addEventListener('install', function(e) {
+  console.log('[ServiceWorker] Install');
+  e.waitUntil(
+    caches.open(cacheName).then(function(cache) {
+      console.log('[ServiceWorker] Caching app shell');
+      return cache.addAll(filesToCache);
+    })
+  );
+});
+
+

First, we need to open the cache with caches.open() and provide a cache name. Providing a cache name allows us to version files, or separate data from the app shell so that we can easily update one but not affect the other.

+

Once the cache is open, we can then call cache.addAll(), which takes a list of URLs, then fetches them from the server and adds the response to the cache. Unfortunately, cache.addAll() is atomic, if any of the files fail, the entire cache step fails!

+

Alright, let’s start getting familiar with how you can use DevTools to understand and debug service workers. Before reloading your page, open up DevTools, go the Service Worker pane on the Application panel. It should look like this.

+ed4633f91ec1389f.png +

When you see a blank page like this, it means that the currently open page does not have any registered service workers.

+

Now, reload your page. The Service Worker pane should now look like this.

+bf15c2f18d7f945c.png +

When you see information like this, it means the page has a service worker running.

+

OK, now we’re are going to take a brief detour and demonstrate a gotcha that you may encounter when developing service workers. To demonstrate, let’s add an activate event listener below the install event listener in your service-worker.js file.

+
self.addEventListener('activate', function(e) {
+  console.log('[ServiceWorker] Activate');
+});
+
+

The activate event is fired when the service worker starts up.

+

Open up the DevTools Console and reload the page, switch to the Service Worker pane in the Application panel and click inspect on the activated service worker. You expect to see the [ServiceWorker] Activate message logged to the console, but it didn’t happen. Check out your Service Worker pane and you can see that the new service worker (that includes the activate event listener) appears to be in a “waiting” state.

+1f454b6807700695.png +

Basically, the old service worker continues to control the page as long as there is a tab open to the page. So, you could close and re-open the page or press the skipWaiting button, but a longer-term solution is to just enable the Update on Reload checkbox on the Service Worker pane of DevTools. When this checkbox is enabled, the service worker is forcibly updated every time that the page reloads.

+

Enable the Update on Reload checkbox now and reload the page to confirm that the new service worker gets activated.

+

Note: You may see an error in the Service Worker pane of the Application panel similar to the one below, it’s safe to ignore this error.

+b1728ef310c444f5.png +

That’s all for now regarding inspecting and debugging service workers in DevTools. We’ll show you some more tricks later. Let’s get back to building your app.

+

Let’s expand on the activate event listener to include some logic to update the cache. Update your code to match the code below.

+
self.addEventListener('activate', function(e) {
+  console.log('[ServiceWorker] Activate');
+  e.waitUntil(
+    caches.keys().then(function(keyList) {
+      return Promise.all(keyList.map(function(key) {
+        if (key !== cacheName) {
+          console.log('[ServiceWorker] Removing old cache', key);
+          return caches.delete(key);
+        }
+      }));
+    })
+  );
+  return self.clients.claim();
+});
+
+

This code ensures that your service worker updates its cache whenever any of the app shell files change. In order for this to work, you’d need to increment the cacheName variable at the top of your service worker file.

+

The last statement fixes a corner-case which you can read about in the (optional) information box below.

+ +

Finally, let’s update the list of files required for the app shell. In the array, we need to include all of the files our app needs, including images, JavaScript, stylesheets, etc. Near the top of your service-worker.js file, replace var filesToCache = []; with the code below:

+
var filesToCache = [
+  '/',
+  '/index.html',
+  '/scripts/app.js',
+  '/styles/inline.css',
+  '/images/clear.png',
+  '/images/cloudy-scattered-showers.png',
+  '/images/cloudy.png',
+  '/images/fog.png',
+  '/images/ic_add_white_24px.svg',
+  '/images/ic_refresh_white_24px.svg',
+  '/images/partly-cloudy.png',
+  '/images/rain.png',
+  '/images/scattered-showers.png',
+  '/images/sleet.png',
+  '/images/snow.png',
+  '/images/thunderstorm.png',
+  '/images/wind.png'
+];
+
+ +

Our app doesn’t work offline quite yet. We’ve cached the app shell components, but we still need to load them from the local cache.

+

Serve the app shell from the cache

+

Service workers provide the ability to intercept requests made from our Progressive Web App and handle them within the service worker. That means we can determine how we want to handle the request and potentially serve our own cached response.

+

For example:

+
self.addEventListener('fetch', function(e) {
+  // Do something interesting with the fetch here
+});
+
+

Let’s now serve the app shell from the cache. Add the following code to the bottom of your service-worker.js file:

+
self.addEventListener('fetch', function(e) {
+  console.log('[ServiceWorker] Fetch', e.request.url);
+  e.respondWith(
+    caches.match(e.request).then(function(response) {
+      return response || fetch(e.request);
+    })
+  );
+});
+
+

Stepping from inside, out, caches.match() evaluates the web request that triggered the fetch event, and checks to see if it’s available in the cache. It then either responds with the cached version, or uses fetch to get a copy from the network. The response is passed back to the web page with e.respondWith().

+ +

Test it out

+

Your app is now offline-capable! Let’s try it out.

+

Reload your page and then go to the Cache Storage pane on the Application panel of DevTools. Right click Cache Storage, pick Refresh Caches, expand the section and you should see the name of your app shell cache listed on the left-hand side. When you click on your app shell cache you can see all of the resources that it has currently cached.

+ab9c361527825fac.png +

Now, let’s test out offline mode. Go back to the Service Worker pane of DevTools and enable the Offline checkbox. After enabling it, you should see a little yellow warning icon next to the Network panel tab. This indicates that you’re offline.

+7656372ff6c6a0f7.png +

Reload your page and… it works! Kind of, at least. Notice how it loads the initial (fake) weather data.

+8a959b48e233bc93.png +

Check out the else clause in app.getForecast() to understand why the app is able to load the fake data.

+

The next step is to modify the app and service worker logic to be able to cache weather data, and return the most recent data from the cache when the app is offline.

+

Tip: To start fresh and clear all saved data (localStorage, indexedDB data, cached files) and remove any service workers, use the Clear storage pane in the Application tab.

+

[](https://weather-pwa-sample.firebaseapp.com/step-06/)

+

Beware of the edge cases

+

As previously mentioned, this code must not be used in production because of the many unhandled edge cases.

+

Cache depends on updating the cache key for every change

+

For example this caching method requires you to update the cache key every time content is changed, otherwise, the cache will not be updated, and the old content will be served. So be sure to change the cache key with every change as you’re working on your project!

+

Requires everything to be redownloaded for every change

+

Another downside is that the entire cache is invalidated and needs to be re-downloaded every time a file changes. That means fixing a simple single character spelling mistake will invalidate the cache and require everything to be downloaded again. Not exactly efficient.

+

Browser cache may prevent the service worker cache from updating

+

There’s another important caveat here. It’s crucial that the HTTPS request made during the install handler goes directly to the network and doesn’t return a response from the browser’s cache. Otherwise the browser may return the old, cached version, resulting in the service worker cache never actually updating!

+

Beware of cache-first strategies in production

+

Our app uses a cache-first strategy, which results in a copy of any cached content being returned without consulting the network. While a cache-first strategy is easy to implement, it can cause challenges in the future. Once the copy of the host page and service worker registration is cached, it can be extremely difficult to change the configuration of the service worker (since the configuration depends on where it was defined), and you could find yourself deploying sites that are extremely difficult to update!

+

How do I avoid these edge cases?

+

So how do we avoid these edge cases? Use a library like Workbox, which provides fine control over what gets expired, ensures requests go directly to the network and handles all of the hard work for you.

+

Tips for testing live service workers

+

Debugging service workers can be a challenge, and when it involves caching, things can become even more of a nightmare if the cache isn’t updated when you expect it. Between the typical service worker life cycle and bug in your code, you may become quickly frustrated. But don’t. There are some tools you can use to make your life easier.

+

Start Fresh

+

In some cases, you may find yourself loading cached data or that things aren’t updated as you expect. To clear all saved data (localStorage, indexedDB data, cached files) and remove any service workers, use the Clear storage pane in the Application tab.

+

Some other tips:

+
    +
  • Once a service worker has been unregistered, it may remain listed until its containing browser window is closed.
  • +
  • If multiple windows to your app are open, the new service worker will not take effect until they’ve all been reloaded and updated to the latest service worker.
  • +
  • Unregistering a service worker does not clear the cache, so it may be possible you’ll still get old data if the cache name hasn’t changed.
  • +
  • If a service worker exists and a new service worker is registered, the new service worker won’t take control until the page is reloaded, unless you take immediate control.
  • +
+

Use service workers to cache the forecast data

+

Choosing the right caching strategy for your data is vital and depends on the type of data your app presents. For example, time-sensitive data like weather or stock quotes should be as fresh as possible, while avatar images or article content can be updated less frequently.

+

The cache-first-then-network strategy is ideal for our app. It gets data on screen as quickly as possible, then updates that once the network has returned the latest data. In comparison to network-first-then-cache, the user does not have to wait until the fetch times out to get the cached data.

+

Cache-first-then-network means we need to kick off two asynchronous requests, one to the cache and one to the network. Our network request with the app doesn’t need to change much, but we need to modify the service worker to cache the response before returning it.

+

Under normal circumstances, the cached data will be returned almost immediately providing the app with recent data it can use. Then, when the network request returns, the app will be updated using the latest data from the network.

+

Intercept the network request and cache the response

+

We need to modify the service worker to intercept requests to the weather API and store their responses in the cache, so we can easily access them later. In the cache-then-network strategy, we expect the network response to be the ‘source of truth’, always providing us with the most recent information. If it can’t, it’s OK to fail because we’ve already retrieved the latest cached data in our app.

+

In the service worker, let’s add a dataCacheName so that we can separate our applications data from the app shell. When the app shell is updated and older caches are purged, our data will remain untouched, ready for a super fast load. Keep in mind, if your data format changes in the future, you’ll need a way to handle that and ensure the app shell and content stay in sync.

+

Add the following line to the top of your service-worker.js file:

+
var dataCacheName = 'weatherData-v1';
+
+

Next, update the activate event handler so that it doesn’t delete the data cache when it cleans up the app shell cache.

+
if (key !== cacheName && key !== dataCacheName) {
+
+

Finally, update the fetch event handler to handle requests to the data API separately from other requests.

+
self.addEventListener('fetch', function(e) {
+  console.log('[Service Worker] Fetch', e.request.url);
+  var dataUrl = 'https://query.yahooapis.com/v1/public/yql';
+  if (e.request.url.indexOf(dataUrl) > -1) {
+    /*
+     * When the request URL contains dataUrl, the app is asking for fresh
+     * weather data. In this case, the service worker always goes to the
+     * network and then caches the response. This is called the "Cache then
+     * network" strategy:
+     * https://jakearchibald.com/2014/offline-cookbook/#cache-then-network
+     */
+    e.respondWith(
+      caches.open(dataCacheName).then(function(cache) {
+        return fetch(e.request).then(function(response){
+          cache.put(e.request.url, response.clone());
+          return response;
+        });
+      })
+    );
+  } else {
+    /*
+     * The app is asking for app shell files. In this scenario the app uses the
+     * "Cache, falling back to the network" offline strategy:
+     * https://jakearchibald.com/2014/offline-cookbook/#cache-falling-back-to-network
+     */
+    e.respondWith(
+      caches.match(e.request).then(function(response) {
+        return response || fetch(e.request);
+      })
+    );
+  }
+});
+
+

The code intercepts the request and checks if the URL starts with the address of the weather API. If it does we’ll use fetch to make the request. Once the response is returned, our code opens the cache, clones the response, stores it in the cache, and finally returns the response to the original requestor.

+

Our app won’t work offline quite yet. We’ve implemented caching and retrieval for the app shell, but even though we’re caching the data, the app doesn’t yet check the cache to see if it has any weather data.

+

Making the requests

+

As mentioned previously, the app needs to kick off two asynchronous requests, one to the cache and one to the network. The app uses the caches object available in window to access the cache and retrieve the latest data. This is an excellent example of progressive enhancement as the caches object may not be available in all browsers, and if it’s not the network request should still work.

+

To do this, we need to:

+
    +
  1. Check if the caches object is available in the global window object.
  2. +
  3. Request data from the cache.
  4. +
+
    +
  • If the server request is still outstanding, update the app with the cached data.
  • +
+
    +
  1. Request data from the server.
  2. +
+
    +
  • Save the data for quick access later.
  • +
  • Update the app with the fresh data from the server.
  • +
+

Get data from the cache

+

Next, we need to check if the caches object exists and request the latest data from it. Find the TODO add cache logic here comment in app.getForecast(), and then add the code below under the comment.

+
    if ('caches' in window) {
+      /*
+       * Check if the service worker has already cached this city's weather
+       * data. If the service worker has the data, then display the cached
+       * data while the app fetches the latest data.
+       */
+      caches.match(url).then(function(response) {
+        if (response) {
+          response.json().then(function updateFromCache(json) {
+            var results = json.query.results;
+            results.key = key;
+            results.label = label;
+            results.created = json.query.created;
+            app.updateForecastCard(results);
+          });
+        }
+      });
+    }
+
+

Our weather app now makes two asynchronous requests for data, one from the cache and one via an XHR. If there’s data in the cache, it’ll be returned and rendered extremely quickly (tens of milliseconds) and update the card only if the XHR is still outstanding. Then, when the XHR responds, the card will be updated with the freshest data direct from the weather API.

+

Notice how the cache request and the XHR request both end with a call to update the forecast card. How does the app know whether it’s displaying the latest data? This is handled in the following code from app.updateForecastCard:

+
    var cardLastUpdatedElem = card.querySelector('.card-last-updated');
+    var cardLastUpdated = cardLastUpdatedElem.textContent;
+    if (cardLastUpdated) {
+      cardLastUpdated = new Date(cardLastUpdated);
+      // Bail if the card has more recent data then the data
+      if (dataLastUpdated.getTime() < cardLastUpdated.getTime()) {
+        return;
+      }
+    }
+
+

Every time that a card is updated, the app stores the timestamp of the data on a hidden attribute on the card. The app just bails if the timestamp that already exists on the card is newer than the data that was passed to the function.

+

Test it out

+

The app should be completely offline-functional now. Save a couple of cities and press the refresh button on the app to get fresh weather data, and then go offline and reload the page.

+

Then go to the Cache Storage pane on the Application panel of DevTools. Expand the section and you should see the name of your app shell and data cache listed on the left-hand side. Opening the data cache should should the data stored for each city.

+cf095c2153306fa7.png +

[](https://weather-pwa-sample.firebaseapp.com/step-07/)

+

Support native integration

+

Nobody likes to have to type in long URLs on a mobile keyboard if they don’t need to. With the Add To home screen feature, your users can choose to add a shortcut link to their device just as they would install a native app from a store, but with a lot less friction.

+

Web App Install Banners and Add to Homescreen for Chrome on Android

+

Web app install banners give you the ability to let your users quickly and seamlessly add your web app to their home screen, making it easy to launch and return to your app. Adding app install banners is easy, and Chrome handles most of the heavy lifting for you. We simply need to include a web app manifest file with details about the app.

+

Chrome then uses a set of criteria including the use of a service worker, SSL status and visit frequency heuristics to determine when to show the banner. In addition a user can manually add it via the “Add to Home Screen” menu button in Chrome.

+

Declare an app manifest with a manifest.json file

+

The web app manifest is a simple JSON file that gives you, the developer, the ability to control how your app appears to the user in the areas that they would expect to see apps (for example the mobile home screen), direct what the user can launch and more importantly how they can launch it.

+

Using the web app manifest, your web app can:

+
    +
  • Have a rich presence on the user’s Android home screen
  • +
  • Be launched in full-screen mode on Android with no URL bar
  • +
  • Control the screen orientation for optimal viewing
  • +
  • Define a “splash screen” launch experience and theme color for the site
  • +
  • Track whether you’re launched from the home screen or URL bar
  • +
+

Create a file named manifest.json in your work folder and copy/paste the following contents:

+
{
+  "name": "Weather",
+  "short_name": "Weather",
+  "icons": [{
+    "src": "images/icons/icon-128x128.png",
+      "sizes": "128x128",
+      "type": "image/png"
+    }, {
+      "src": "images/icons/icon-144x144.png",
+      "sizes": "144x144",
+      "type": "image/png"
+    }, {
+      "src": "images/icons/icon-152x152.png",
+      "sizes": "152x152",
+      "type": "image/png"
+    }, {
+      "src": "images/icons/icon-192x192.png",
+      "sizes": "192x192",
+      "type": "image/png"
+    }, {
+      "src": "images/icons/icon-256x256.png",
+      "sizes": "256x256",
+      "type": "image/png"
+    }],
+  "start_url": "/index.html",
+  "display": "standalone",
+  "background_color": "#3E4EB8",
+  "theme_color": "#2F3BA2"
+}
+
+

The manifest supports an array of icons, intended for different screen sizes. At the time of this writing, Chrome and Opera Mobile, the only browsers that support web app manifests, won’t use anything smaller than 192px.

+

An easy way to track how the app is launched is to add a query string to the start_url parameter and then use an analytics suite to track the query string. If you use this method, remember to update the list of files cached by the App Shell to ensure that the file with the query string is cached.

+

Tell the browser about your manifest file

+

Now add the following line to the bottom of the <head> element in your index.html file:

+
<link rel="manifest" href="/manifest.json">
+
+

Best Practices

+
    +
  • Place the manifest link on all your site’s pages, so it will be retrieved by Chrome right when the user first visits, no matter what page they land on.
  • +
  • The short_name is preferred on Chrome and will be used if present over the name field.
  • +
  • Define icon sets for different density screens. Chrome will attempt to use the icon closest to 48dp, for example, 96px on a 2x device or 144px for a 3x device.
  • +
  • Remember to include an icon with a size that is sensible for a splash screen and don’t forget to set the background_color.
  • +
+

Further Reading:

+

Using app install banners

+

Add to Homescreen elements for Safari on iOS

+

In your index.html, add the following to the bottom of the <head> element:

+
  <!-- Add to home screen for Safari on iOS -->
+  <meta name="apple-mobile-web-app-capable" content="yes">
+  <meta name="apple-mobile-web-app-status-bar-style" content="black">
+  <meta name="apple-mobile-web-app-title" content="Weather PWA">
+  <link rel="apple-touch-icon" href="images/icons/icon-152x152.png">
+
+

Tile Icon for Windows

+

In your index.html, add the following to the bottom of the <head> element:

+
  <meta name="msapplication-TileImage" content="images/icons/icon-144x144.png">
+  <meta name="msapplication-TileColor" content="#2F3BA2">
+
+

Test it out

+

In this section we’ll show you a couple of ways to test your web app manifest.

+

The first way is DevTools. Open up the Manifest pane on the Application panel. If you’ve added the manifest information correctly, you’ll be able to see it parsed and displayed in a human-friendly format on this pane.

+

You can also test the add to homescreen feature from this pane. Click on the Add to homescreen button. You should see a “add this site to your shelf” message below your URL bar, like in the screenshot below.

+cbfdd0302b611ab0.png +

This is the desktop equivalent of mobile’s add to homescreen feature. If you can successfully trigger this prompt on desktop, then you can be assured that mobile users can add your app to their devices.

+

The second way to test is via Web Server for Chrome. With this approach, you expose your local development server (on your desktop or laptop) to other computers, and then you just access your progressive web app from a real mobile device.

+ +

On Web Server for Chrome configuration dialog, select the Accessible on local network option:

+Screen Shot 2016-05-12 at 5.42.40 PM.png +

Toggle the Web Server to STOPPED and back to STARTED. You’ll see a new URL which can be used to access your app remotely.

+

Now, access your site from a mobile device, using the new URL.

+

You will see service worker errors in the console when testing this way because the service worker is not being served over HTTPS.

+

Using Chrome from an Android device, try adding the app to the homescreen and verifying that the launch screen appears properly and the right icons are used.

+

On Safari and Internet Explorer, you can also manually add the app to your homescreen.

+

[](https://weather-pwa-sample.firebaseapp.com/step-08/)

+

Deploy to a secure host and celebrate

+

The final step is to deploy our weather app to a server that supports HTTPS. If you don’t already have one, the absolute easiest (and free) approach is to use the static content hosting from Firebase. It’s super easy to use, serves content over HTTPS and is backed by a global CDN.

+

Extra credit: minify and inline CSS

+

There’s one more thing that you should consider, minifying the key styles and inlining them directly into index.html. Page Speed Insights recommends serving the above the fold content in the first 15k bytes of the request.

+

See how small you can get the initial request with everything inlined.

+

Further Reading: PageSpeed Insight Rules

+ +

Deploy to Firebase

+

If you’re new to Firebase, you’ll need to create your account and install some tools first.

+
    +
  1. Create a Firebase account at https://firebase.google.com/console/
  2. +
  3. Install the Firebase tools via npm: npm install -g firebase-tools
  4. +
+

Once your account has been created and you’ve signed in, you’re ready to deploy!

+
    +
  1. Create a new app at https://firebase.google.com/console/
  2. +
  3. If you haven’t recently signed in to the Firebase tools, update your credentials: firebase login
  4. +
  5. Initialize your app, and provide the directory (likely work) where your completed app lives: firebase init
  6. +
  7. Finally, deploy the app to Firebase: firebase deploy
  8. +
  9. Celebrate. You’re done! Your app will be deployed to the domain: https://YOUR-FIREBASE-APP.firebaseapp.com
  10. +
+

Further reading: Firebase Hosting Guide

+

Test it out

+
    +
  • Try adding the app to your home screen then disconnect the network and verify the app works offline as expected.
  • +
+

[](https://weather-pwa-sample.firebaseapp.com/final/)

+
+ + +
+
+
+
+
+ +
+ +
+ + + + + + + + + diff --git a/docs/index.html b/docs/index.html index 3861a5fb..6dcc185d 100644 --- a/docs/index.html +++ b/docs/index.html @@ -181,7 +181,7 @@
@@ -237,7 +237,7 @@

-0.2.0+44-40e05df0 +0.2.0+50-06b793b7 diff --git a/docs/license.html b/docs/license.html index f0a890ec..4a4429f4 100644 --- a/docs/license.html +++ b/docs/license.html @@ -177,7 +177,7 @@
@@ -197,7 +197,7 @@

< diff --git a/docs/meetings.html b/docs/meetings.html index 8d792981..8b820e6b 100644 --- a/docs/meetings.html +++ b/docs/meetings.html @@ -188,7 +188,7 @@
@@ -238,7 +238,7 @@

-0.2.0+44-40e05df0 +0.2.0+50-06b793b7 diff --git a/docs/publication/index.html b/docs/publication/index.html index 2f8be6f5..4238b3bb 100644 --- a/docs/publication/index.html +++ b/docs/publication/index.html @@ -143,7 +143,7 @@
@@ -162,7 +162,7 @@

-0.2.0+44-40e05df0 +0.2.0+50-06b793b7 diff --git a/docs/shacl-tutorial/overview/index.html b/docs/shacl-tutorial/overview/index.html index 2de72435..c9cf4856 100644 --- a/docs/shacl-tutorial/overview/index.html +++ b/docs/shacl-tutorial/overview/index.html @@ -177,7 +177,7 @@
@@ -225,7 +225,7 @@

diff --git a/docs/tools/index.html b/docs/tools/index.html index 1ca859c7..4fef923b 100644 --- a/docs/tools/index.html +++ b/docs/tools/index.html @@ -143,7 +143,7 @@
@@ -162,7 +162,7 @@

diff --git a/index.html b/index.html index 00973189..b2dc6438 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ - Neuroshapes | Open schemas for FAIR neuroscience data

Neuroshapes

Open schemas for FAIR neuroscience Data, Schemas and Vocabulary

Why Neuroshapes?

Motivation

Modern scientific data management requires comprehensive support for the FAIR (Findable, Accessible, Interoperable, Reusable) principles. Neuroshapes is a general approach, or design pattern, for supporting FAIR principles for diverse neuroscience data with the following benefits:

  • Neuroshapes ensures that the key scientific and technical activities and agents of the data generation process are expressed in a validatable provenance-based data model.

Neuroshapes captures the contextual information necessary to:

  • Interpret the scientific meaning of the data.
  • Infer the resulting data types.
  • Evaluate trust and quality.
  • Ensure attribution of all contributors.
  • Support data reuse, integration, interoperability and longevity.

Goals

The main goal is to provide design patterns, best practices as well as tools to promote:

  • The use of standard semantic markups and linked data principles as ways to structure metadata and related data.
  • The use of the W3C SHACL (Shapes Constraint Language) recommendation as a rich metadata schema language which is formal and expressive; interoperable; machine-readable; and domain-agnostic.
  • The reuse of existing schemas and semantic markups ( schema.org , W3C PROV-O ) and existing ontologies and controlled vocabularies (including NIFSTD - Neuroscience Information Framework Standard Ontologies).
  • The use of the W3C PROV-O recommendation as a format to record (meta)data provenance.

Get Involved

Join the INCF Neuroshapes Special Interest Group:

This SIG aims to coordinate community efforts for the development of open, use case driven and shared validatable data models (schemas, vocabularies) to enable the FAIR principles (Findable, Accessible, Interoperable and Reusable) for basic, computational and clinical neuroscience (meta)data.

How to Contribute

Found a bug ? Want a new feature ?


INCF SIG on Neuroshapes

This SIG aims to coordinate community efforts for the development of open, use case driven and shared validatable data models (schemas, vocabularies) to enable the FAIR principles (Findable, Accessible, Interoperable and Reusable) for basic, computational and clinical neuroscience (meta)data.

Acknowledgements

This work has been supported by ETH Board funding to the Blue Brain Project. Portions of this work have also been supported by the European Union’s Horizon 2020 research and innovation programme under grant agreement no.720270. (Human Brain Project).

Participants

Sean Hill, Krembil Centre for Neuroinformatics, CAMH, Chair
Andrew Davison, CNRS, Human Brain Project, Chair
Anna-Kristin Kaufmann, EPFL, Blue Brain Project
Huanxiang Lu, EPFL, Blue Brain Project
Tom Gillespie, UCSD, Neuroscience Information Framework
Genrich Ivaska, EPFL, Blue Brain Project
Oliver Schmid, EPFL, Human Brain Project
Jean-Denis Courcol, EPFL, Blue Brain Project
Samuel Kerrien, EPFL, Blue Brain Project
Jeff Muller, EPFL, Human Brain Project
Mohameth François Sy, EPFL, Blue Brain Project, Co-Chair
Bogdan Roman, EPFL, Blue Brain Project
Pierre-Alexandre Fonta, EPFL, Blue Brain Project
Coste Benoît Jean-Albert, EPFL, Blue Brain Project
Taylor MacMillan, Krembil Centre for Neuroinformatics, CAMH
David Rotenberg, Krembil Centre for Neuroinformatics, CAMH
+ Neuroshapes | Open schemas for FAIR neuroscience data

Neuroshapes

Open schemas for FAIR neuroscience Data, Schemas and Vocabulary

Why Neuroshapes?

Motivation

Modern scientific data management requires comprehensive support for the FAIR (Findable, Accessible, Interoperable, Reusable) principles. Neuroshapes is a general approach, or design pattern, for supporting FAIR principles for diverse neuroscience data with the following benefits:

  • Neuroshapes ensures that the key scientific and technical activities and agents of the data generation process are expressed in a validatable provenance-based data model.

Neuroshapes captures the contextual information necessary to:

  • Interpret the scientific meaning of the data.
  • Infer the resulting data types.
  • Evaluate trust and quality.
  • Ensure attribution of all contributors.
  • Support data reuse, integration, interoperability and longevity.

Goals

The main goal is to provide design patterns, best practices as well as tools to promote:

  • The use of standard semantic markups and linked data principles as ways to structure metadata and related data.
  • The use of the W3C SHACL (Shapes Constraint Language) recommendation as a rich metadata schema language which is formal and expressive; interoperable; machine-readable; and domain-agnostic.
  • The reuse of existing schemas and semantic markups ( schema.org , W3C PROV-O ) and existing ontologies and controlled vocabularies (including NIFSTD - Neuroscience Information Framework Standard Ontologies).
  • The use of the W3C PROV-O recommendation as a format to record (meta)data provenance.

Get Involved

Join the INCF Neuroshapes Special Interest Group:

This SIG aims to coordinate community efforts for the development of open, use case driven and shared validatable data models (schemas, vocabularies) to enable the FAIR principles (Findable, Accessible, Interoperable and Reusable) for basic, computational and clinical neuroscience (meta)data.

How to Contribute

Found a bug ? Want a new feature ?


INCF SIG on Neuroshapes

This SIG aims to coordinate community efforts for the development of open, use case driven and shared validatable data models (schemas, vocabularies) to enable the FAIR principles (Findable, Accessible, Interoperable and Reusable) for basic, computational and clinical neuroscience (meta)data.

Acknowledgements

This work has been supported by ETH Board funding to the Blue Brain Project. Portions of this work have also been supported by the European Union’s Horizon 2020 research and innovation programme under grant agreement no.720270. (Human Brain Project).

Participants

Sean Hill, Krembil Centre for Neuroinformatics, CAMH, Chair
Andrew Davison, CNRS, Human Brain Project, Chair
Anna-Kristin Kaufmann, EPFL, Blue Brain Project
Huanxiang Lu, EPFL, Blue Brain Project
Tom Gillespie, UCSD, Neuroscience Information Framework
Genrich Ivaska, EPFL, Blue Brain Project
Oliver Schmid, EPFL, Human Brain Project
Jean-Denis Courcol, EPFL, Blue Brain Project
Samuel Kerrien, EPFL, Blue Brain Project
Jeff Muller, EPFL, Human Brain Project
Mohameth François Sy, EPFL, Blue Brain Project, Co-Chair
Bogdan Roman, EPFL, Blue Brain Project
Pierre-Alexandre Fonta, EPFL, Blue Brain Project
Coste Benoît Jean-Albert, EPFL, Blue Brain Project
Taylor MacMillan, Krembil Centre for Neuroinformatics, CAMH
David Rotenberg, Krembil Centre for Neuroinformatics, CAMH
\ No newline at end of file diff --git a/js.60833e22.js b/js.60833e22.js deleted file mode 100644 index 7e58fb35..00000000 --- a/js.60833e22.js +++ /dev/null @@ -1,20 +0,0 @@ -parcelRequire=function(e,r,n,t){var i="function"==typeof parcelRequire&&parcelRequire,o="function"==typeof require&&require;function u(n,t){if(!r[n]){if(!e[n]){var f="function"==typeof parcelRequire&&parcelRequire;if(!t&&f)return f(n,!0);if(i)return i(n,!0);if(o&&"string"==typeof n)return o(n);var c=new Error("Cannot find module '"+n+"'");throw c.code="MODULE_NOT_FOUND",c}p.resolve=function(r){return e[n][1][r]||r},p.cache={};var l=r[n]=new u.Module(n);e[n][0].call(l.exports,p,l,l.exports,this)}return r[n].exports;function p(e){return u(p.resolve(e))}}u.isParcelRequire=!0,u.Module=function(e){this.id=e,this.bundle=u,this.exports={}},u.modules=e,u.cache=r,u.parent=i,u.register=function(r,n){e[r]=[function(e,r){r.exports=n},{}]};for(var f=0;ft)return!1;if((i+=e[s+1])>=t)return!0}}function u(t,e){return t<65?36===t:t<91||(t<97?95===t:t<123||(t<=65535?t>=170&&n.test(String.fromCharCode(t)):!1!==e&&c(t,h)))}function l(t,e){return t<48?36===t:t<58||!(t<65)&&(t<91||(t<97?95===t:t<123||(t<=65535?t>=170&&o.test(String.fromCharCode(t)):!1!==e&&(c(t,h)||c(t,p)))))}var d=function(t,e){void 0===e&&(e={}),this.label=t,this.keyword=e.keyword,this.beforeExpr=!!e.beforeExpr,this.startsExpr=!!e.startsExpr,this.isLoop=!!e.isLoop,this.isAssign=!!e.isAssign,this.prefix=!!e.prefix,this.postfix=!!e.postfix,this.binop=e.binop||null,this.updateContext=null};function f(t,e){return new d(t,{beforeExpr:!0,binop:e})}exports.TokenType=d;var m={beforeExpr:!0},x={startsExpr:!0},g={};function v(t,e){return void 0===e&&(e={}),e.keyword=t,g[t]=new d(t,e)}exports.keywordTypes=g;var y={num:new d("num",x),regexp:new d("regexp",x),string:new d("string",x),name:new d("name",x),eof:new d("eof"),bracketL:new d("[",{beforeExpr:!0,startsExpr:!0}),bracketR:new d("]"),braceL:new d("{",{beforeExpr:!0,startsExpr:!0}),braceR:new d("}"),parenL:new d("(",{beforeExpr:!0,startsExpr:!0}),parenR:new d(")"),comma:new d(",",m),semi:new d(";",m),colon:new d(":",m),dot:new d("."),question:new d("?",m),arrow:new d("=>",m),template:new d("template"),invalidTemplate:new d("invalidTemplate"),ellipsis:new d("...",m),backQuote:new d("`",x),dollarBraceL:new d("${",{beforeExpr:!0,startsExpr:!0}),eq:new d("=",{beforeExpr:!0,isAssign:!0}),assign:new d("_=",{beforeExpr:!0,isAssign:!0}),incDec:new d("++/--",{prefix:!0,postfix:!0,startsExpr:!0}),prefix:new d("!/~",{beforeExpr:!0,prefix:!0,startsExpr:!0}),logicalOR:f("||",1),logicalAND:f("&&",2),bitwiseOR:f("|",3),bitwiseXOR:f("^",4),bitwiseAND:f("&",5),equality:f("==/!=/===/!==",6),relational:f("/<=/>=",7),bitShift:f("<>/>>>",8),plusMin:new d("+/-",{beforeExpr:!0,binop:9,prefix:!0,startsExpr:!0}),modulo:f("%",10),star:f("*",10),slash:f("/",10),starstar:new d("**",{beforeExpr:!0}),_break:v("break"),_case:v("case",m),_catch:v("catch"),_continue:v("continue"),_debugger:v("debugger"),_default:v("default",m),_do:v("do",{isLoop:!0,beforeExpr:!0}),_else:v("else",m),_finally:v("finally"),_for:v("for",{isLoop:!0}),_function:v("function",x),_if:v("if"),_return:v("return",m),_switch:v("switch"),_throw:v("throw",m),_try:v("try"),_var:v("var"),_const:v("const"),_while:v("while",{isLoop:!0}),_with:v("with"),_new:v("new",{beforeExpr:!0,startsExpr:!0}),_this:v("this",x),_super:v("super",x),_class:v("class",x),_extends:v("extends",m),_export:v("export"),_import:v("import"),_null:v("null",x),_true:v("true",x),_false:v("false",x),_in:v("in",{beforeExpr:!0,binop:7}),_instanceof:v("instanceof",{beforeExpr:!0,binop:7}),_typeof:v("typeof",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_void:v("void",{beforeExpr:!0,prefix:!0,startsExpr:!0}),_delete:v("delete",{beforeExpr:!0,prefix:!0,startsExpr:!0})};exports.tokTypes=y;var _=/\r\n?|\n|\u2028|\u2029/;exports.lineBreak=_;var b=new RegExp(_.source,"g");function k(t,e){return 10===t||13===t||!e&&(8232===t||8233===t)}exports.lineBreakG=b;var C=/[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;exports.nonASCIIwhitespace=C;var S=/(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g,E=Object.prototype,w=E.hasOwnProperty,A=E.toString;function I(t,e){return w.call(t,e)}var P=Array.isArray||function(t){return"[object Array]"===A.call(t)},L=function(t,e){this.line=t,this.column=e};exports.Position=L,L.prototype.offset=function(t){return new L(this.line,this.column+t)};var N=function(t,e,i){this.start=e,this.end=i,null!==t.sourceFile&&(this.source=t.sourceFile)};function T(t,e){for(var i=1,s=0;;){b.lastIndex=s;var r=b.exec(t);if(!(r&&r.index=2015&&(e.ecmaVersion-=2009),null==e.allowReserved&&(e.allowReserved=e.ecmaVersion<5),P(e.onToken)){var s=e.onToken;e.onToken=function(t){return s.push(t)}}return P(e.onComment)&&(e.onComment=D(e,e.onComment)),e}function D(t,e){return function(i,s,r,a,n,o){var h={type:i?"Block":"Line",value:s,start:r,end:a};t.locations&&(h.loc=new N(this,n,o)),t.ranges&&(h.range=[r,a]),e.push(h)}}exports.defaultOptions=V;var O={};function B(t){return new RegExp("^(?:"+t.replace(/ /g,"|")+")$")}exports.plugins=O;var M=function(e,s,r){this.options=e=R(e),this.sourceFile=e.sourceFile,this.keywords=B(i[e.ecmaVersion>=6?6:5]);var a="";if(!e.allowReserved){for(var n=e.ecmaVersion;!(a=t[n]);n--);"module"===e.sourceType&&(a+=" await")}this.reservedWords=B(a);var o=(a?a+" ":"")+t.strict;this.reservedWordsStrict=B(o),this.reservedWordsStrictBind=B(o+" "+t.strictBind),this.input=String(s),this.containsEsc=!1,this.loadPlugins(e.plugins),r?(this.pos=r,this.lineStart=this.input.lastIndexOf("\n",r-1)+1,this.curLine=this.input.slice(0,this.lineStart).split(_).length):(this.pos=this.lineStart=0,this.curLine=1),this.type=y.eof,this.value=null,this.start=this.end=this.pos,this.startLoc=this.endLoc=this.curPosition(),this.lastTokEndLoc=this.lastTokStartLoc=null,this.lastTokStart=this.lastTokEnd=this.pos,this.context=this.initialContext(),this.exprAllowed=!0,this.inModule="module"===e.sourceType,this.strict=this.inModule||this.strictDirective(this.pos),this.potentialArrowAt=-1,this.inFunction=this.inGenerator=this.inAsync=!1,this.yieldPos=this.awaitPos=0,this.labels=[],0===this.pos&&e.allowHashBang&&"#!"===this.input.slice(0,2)&&this.skipLineComment(2),this.scopeStack=[],this.enterFunctionScope(),this.regexpState=null};exports.Parser=M,M.prototype.isKeyword=function(t){return this.keywords.test(t)},M.prototype.isReservedWord=function(t){return this.reservedWords.test(t)},M.prototype.extend=function(t,e){this[t]=e(this[t])},M.prototype.loadPlugins=function(t){for(var e in t){var i=O[e];if(!i)throw new Error("Plugin '"+e+"' not found");i(this,t[e])}},M.prototype.parse=function(){var t=this.options.program||this.startNode();return this.nextToken(),this.parseTopLevel(t)};var F=M.prototype,U=/^(?:'((?:\\.|[^'])*?)'|"((?:\\.|[^"])*?)"|;)/;function G(){this.shorthandAssign=this.trailingComma=this.parenthesizedAssign=this.parenthesizedBind=this.doubleProto=-1}F.strictDirective=function(t){for(;;){S.lastIndex=t,t+=S.exec(this.input)[0].length;var e=U.exec(this.input.slice(t));if(!e)return!1;if("use strict"===(e[1]||e[2]))return!0;t+=e[0].length}},F.eat=function(t){return this.type===t&&(this.next(),!0)},F.isContextual=function(t){return this.type===y.name&&this.value===t&&!this.containsEsc},F.eatContextual=function(t){return!!this.isContextual(t)&&(this.next(),!0)},F.expectContextual=function(t){this.eatContextual(t)||this.unexpected()},F.canInsertSemicolon=function(){return this.type===y.eof||this.type===y.braceR||_.test(this.input.slice(this.lastTokEnd,this.start))},F.insertSemicolon=function(){if(this.canInsertSemicolon())return this.options.onInsertedSemicolon&&this.options.onInsertedSemicolon(this.lastTokEnd,this.lastTokEndLoc),!0},F.semicolon=function(){this.eat(y.semi)||this.insertSemicolon()||this.unexpected()},F.afterTrailingComma=function(t,e){if(this.type===t)return this.options.onTrailingComma&&this.options.onTrailingComma(this.lastTokStart,this.lastTokStartLoc),e||this.next(),!0},F.expect=function(t){this.eat(t)||this.unexpected()},F.unexpected=function(t){this.raise(null!=t?t:this.start,"Unexpected token")},F.checkPatternErrors=function(t,e){if(t){t.trailingComma>-1&&this.raiseRecoverable(t.trailingComma,"Comma is not permitted after the rest element");var i=e?t.parenthesizedAssign:t.parenthesizedBind;i>-1&&this.raiseRecoverable(i,"Parenthesized pattern")}},F.checkExpressionErrors=function(t,e){if(!t)return!1;var i=t.shorthandAssign,s=t.doubleProto;if(!e)return i>=0||s>=0;i>=0&&this.raise(i,"Shorthand property assignments are valid only in destructuring patterns"),s>=0&&this.raiseRecoverable(s,"Redefinition of __proto__ property")},F.checkYieldAwaitInDefaultParams=function(){this.yieldPos&&(!this.awaitPos||this.yieldPos=6&&(t.sourceType=this.options.sourceType),this.finishNode(t,"Program")};var H={kind:"loop"},W={kind:"switch"};q.isLet=function(){if(this.options.ecmaVersion<6||!this.isContextual("let"))return!1;S.lastIndex=this.pos;var t=S.exec(this.input),e=this.pos+t[0].length,i=this.input.charCodeAt(e);if(91===i||123===i)return!0;if(u(i,!0)){for(var r=e+1;l(this.input.charCodeAt(r),!0);)++r;var a=this.input.slice(e,r);if(!s.test(a))return!0}return!1},q.isAsyncFunction=function(){if(this.options.ecmaVersion<8||!this.isContextual("async"))return!1;S.lastIndex=this.pos;var t=S.exec(this.input),e=this.pos+t[0].length;return!(_.test(this.input.slice(this.pos,e))||"function"!==this.input.slice(e,e+8)||e+8!==this.input.length&&l(this.input.charAt(e+8)))},q.parseStatement=function(t,e,i){var s,r=this.type,a=this.startNode();switch(this.isLet()&&(r=y._var,s="let"),r){case y._break:case y._continue:return this.parseBreakContinueStatement(a,r.keyword);case y._debugger:return this.parseDebuggerStatement(a);case y._do:return this.parseDoStatement(a);case y._for:return this.parseForStatement(a);case y._function:return!t&&this.options.ecmaVersion>=6&&this.unexpected(),this.parseFunctionStatement(a,!1);case y._class:return t||this.unexpected(),this.parseClass(a,!0);case y._if:return this.parseIfStatement(a);case y._return:return this.parseReturnStatement(a);case y._switch:return this.parseSwitchStatement(a);case y._throw:return this.parseThrowStatement(a);case y._try:return this.parseTryStatement(a);case y._const:case y._var:return s=s||this.value,t||"var"===s||this.unexpected(),this.parseVarStatement(a,s);case y._while:return this.parseWhileStatement(a);case y._with:return this.parseWithStatement(a);case y.braceL:return this.parseBlock();case y.semi:return this.parseEmptyStatement(a);case y._export:case y._import:return this.options.allowImportExportEverywhere||(e||this.raise(this.start,"'import' and 'export' may only appear at the top level"),this.inModule||this.raise(this.start,"'import' and 'export' may appear only with 'sourceType: module'")),r===y._import?this.parseImport(a):this.parseExport(a,i);default:if(this.isAsyncFunction())return t||this.unexpected(),this.next(),this.parseFunctionStatement(a,!0);var n=this.value,o=this.parseExpression();return r===y.name&&"Identifier"===o.type&&this.eat(y.colon)?this.parseLabeledStatement(a,n,o):this.parseExpressionStatement(a,o)}},q.parseBreakContinueStatement=function(t,e){var i="break"===e;this.next(),this.eat(y.semi)||this.insertSemicolon()?t.label=null:this.type!==y.name?this.unexpected():(t.label=this.parseIdent(),this.semicolon());for(var s=0;s=6?this.eat(y.semi):this.semicolon(),this.finishNode(t,"DoWhileStatement")},q.parseForStatement=function(t){this.next();var e=this.options.ecmaVersion>=9&&(this.inAsync||!this.inFunction&&this.options.allowAwaitOutsideFunction)&&this.eatContextual("await")?this.lastTokStart:-1;if(this.labels.push(H),this.enterLexicalScope(),this.expect(y.parenL),this.type===y.semi)return e>-1&&this.unexpected(e),this.parseFor(t,null);var i=this.isLet();if(this.type===y._var||this.type===y._const||i){var s=this.startNode(),r=i?"let":this.value;return this.next(),this.parseVar(s,!0,r),this.finishNode(s,"VariableDeclaration"),!(this.type===y._in||this.options.ecmaVersion>=6&&this.isContextual("of"))||1!==s.declarations.length||"var"!==r&&s.declarations[0].init?(e>-1&&this.unexpected(e),this.parseFor(t,s)):(this.options.ecmaVersion>=9&&(this.type===y._in?e>-1&&this.unexpected(e):t.await=e>-1),this.parseForIn(t,s))}var a=new G,n=this.parseExpression(!0,a);return this.type===y._in||this.options.ecmaVersion>=6&&this.isContextual("of")?(this.options.ecmaVersion>=9&&(this.type===y._in?e>-1&&this.unexpected(e):t.await=e>-1),this.toAssignable(n,!1,a),this.checkLVal(n),this.parseForIn(t,n)):(this.checkExpressionErrors(a,!0),e>-1&&this.unexpected(e),this.parseFor(t,n))},q.parseFunctionStatement=function(t,e){return this.next(),this.parseFunction(t,!0,!1,e)},q.parseIfStatement=function(t){return this.next(),t.test=this.parseParenExpression(),t.consequent=this.parseStatement(!this.strict&&this.type===y._function),t.alternate=this.eat(y._else)?this.parseStatement(!this.strict&&this.type===y._function):null,this.finishNode(t,"IfStatement")},q.parseReturnStatement=function(t){return this.inFunction||this.options.allowReturnOutsideFunction||this.raise(this.start,"'return' outside of function"),this.next(),this.eat(y.semi)||this.insertSemicolon()?t.argument=null:(t.argument=this.parseExpression(),this.semicolon()),this.finishNode(t,"ReturnStatement")},q.parseSwitchStatement=function(t){var e;this.next(),t.discriminant=this.parseParenExpression(),t.cases=[],this.expect(y.braceL),this.labels.push(W),this.enterLexicalScope();for(var i=!1;this.type!==y.braceR;)if(this.type===y._case||this.type===y._default){var s=this.type===y._case;e&&this.finishNode(e,"SwitchCase"),t.cases.push(e=this.startNode()),e.consequent=[],this.next(),s?e.test=this.parseExpression():(i&&this.raiseRecoverable(this.lastTokStart,"Multiple default clauses"),i=!0,e.test=null),this.expect(y.colon)}else e||this.unexpected(),e.consequent.push(this.parseStatement(!0));return this.exitLexicalScope(),e&&this.finishNode(e,"SwitchCase"),this.next(),this.labels.pop(),this.finishNode(t,"SwitchStatement")},q.parseThrowStatement=function(t){return this.next(),_.test(this.input.slice(this.lastTokEnd,this.start))&&this.raise(this.lastTokEnd,"Illegal newline after throw"),t.argument=this.parseExpression(),this.semicolon(),this.finishNode(t,"ThrowStatement")};var j=[];q.parseTryStatement=function(t){if(this.next(),t.block=this.parseBlock(),t.handler=null,this.type===y._catch){var e=this.startNode();this.next(),this.eat(y.parenL)?(e.param=this.parseBindingAtom(),this.enterLexicalScope(),this.checkLVal(e.param,"let"),this.expect(y.parenR)):(this.options.ecmaVersion<10&&this.unexpected(),e.param=null,this.enterLexicalScope()),e.body=this.parseBlock(!1),this.exitLexicalScope(),t.handler=this.finishNode(e,"CatchClause")}return t.finalizer=this.eat(y._finally)?this.parseBlock():null,t.handler||t.finalizer||this.raise(t.start,"Missing catch or finally clause"),this.finishNode(t,"TryStatement")},q.parseVarStatement=function(t,e){return this.next(),this.parseVar(t,!1,e),this.semicolon(),this.finishNode(t,"VariableDeclaration")},q.parseWhileStatement=function(t){return this.next(),t.test=this.parseParenExpression(),this.labels.push(H),t.body=this.parseStatement(!1),this.labels.pop(),this.finishNode(t,"WhileStatement")},q.parseWithStatement=function(t){return this.strict&&this.raise(this.start,"'with' in strict mode"),this.next(),t.object=this.parseParenExpression(),t.body=this.parseStatement(!1),this.finishNode(t,"WithStatement")},q.parseEmptyStatement=function(t){return this.next(),this.finishNode(t,"EmptyStatement")},q.parseLabeledStatement=function(t,e,i){for(var s=0,r=this.labels;s=0;n--){var o=this.labels[n];if(o.statementStart!==t.start)break;o.statementStart=this.start,o.kind=a}return this.labels.push({name:e,kind:a,statementStart:this.start}),t.body=this.parseStatement(!0),("ClassDeclaration"===t.body.type||"VariableDeclaration"===t.body.type&&"var"!==t.body.kind||"FunctionDeclaration"===t.body.type&&(this.strict||t.body.generator||t.body.async))&&this.raiseRecoverable(t.body.start,"Invalid labeled declaration"),this.labels.pop(),t.label=i,this.finishNode(t,"LabeledStatement")},q.parseExpressionStatement=function(t,e){return t.expression=e,this.semicolon(),this.finishNode(t,"ExpressionStatement")},q.parseBlock=function(t){void 0===t&&(t=!0);var e=this.startNode();for(e.body=[],this.expect(y.braceL),t&&this.enterLexicalScope();!this.eat(y.braceR);){var i=this.parseStatement(!0);e.body.push(i)}return t&&this.exitLexicalScope(),this.finishNode(e,"BlockStatement")},q.parseFor=function(t,e){return t.init=e,this.expect(y.semi),t.test=this.type===y.semi?null:this.parseExpression(),this.expect(y.semi),t.update=this.type===y.parenR?null:this.parseExpression(),this.expect(y.parenR),this.exitLexicalScope(),t.body=this.parseStatement(!1),this.labels.pop(),this.finishNode(t,"ForStatement")},q.parseForIn=function(t,e){var i=this.type===y._in?"ForInStatement":"ForOfStatement";return this.next(),"ForInStatement"===i&&("AssignmentPattern"===e.type||"VariableDeclaration"===e.type&&null!=e.declarations[0].init&&(this.strict||"Identifier"!==e.declarations[0].id.type))&&this.raise(e.start,"Invalid assignment in for-in loop head"),t.left=e,t.right="ForInStatement"===i?this.parseExpression():this.parseMaybeAssign(),this.expect(y.parenR),this.exitLexicalScope(),t.body=this.parseStatement(!1),this.labels.pop(),this.finishNode(t,i)},q.parseVar=function(t,e,i){for(t.declarations=[],t.kind=i;;){var s=this.startNode();if(this.parseVarId(s,i),this.eat(y.eq)?s.init=this.parseMaybeAssign(e):"const"!==i||this.type===y._in||this.options.ecmaVersion>=6&&this.isContextual("of")?"Identifier"===s.id.type||e&&(this.type===y._in||this.isContextual("of"))?s.init=null:this.raise(this.lastTokEnd,"Complex binding patterns require an initialization value"):this.unexpected(),t.declarations.push(this.finishNode(s,"VariableDeclarator")),!this.eat(y.comma))break}return t},q.parseVarId=function(t,e){t.id=this.parseBindingAtom(e),this.checkLVal(t.id,e,!1)},q.parseFunction=function(t,e,i,s){this.initFunction(t),(this.options.ecmaVersion>=9||this.options.ecmaVersion>=6&&!s)&&(t.generator=this.eat(y.star)),this.options.ecmaVersion>=8&&(t.async=!!s),e&&(t.id="nullableID"===e&&this.type!==y.name?null:this.parseIdent(),t.id&&this.checkLVal(t.id,this.inModule&&!this.inFunction?"let":"var"));var r=this.inGenerator,a=this.inAsync,n=this.yieldPos,o=this.awaitPos,h=this.inFunction;return this.inGenerator=t.generator,this.inAsync=t.async,this.yieldPos=0,this.awaitPos=0,this.inFunction=!0,this.enterFunctionScope(),e||(t.id=this.type===y.name?this.parseIdent():null),this.parseFunctionParams(t),this.parseFunctionBody(t,i),this.inGenerator=r,this.inAsync=a,this.yieldPos=n,this.awaitPos=o,this.inFunction=h,this.finishNode(t,e?"FunctionDeclaration":"FunctionExpression")},q.parseFunctionParams=function(t){this.expect(y.parenL),t.params=this.parseBindingList(y.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams()},q.parseClass=function(t,e){this.next(),this.parseClassId(t,e),this.parseClassSuper(t);var i=this.startNode(),s=!1;for(i.body=[],this.expect(y.braceL);!this.eat(y.braceR);){var r=this.parseClassMember(i);r&&"MethodDefinition"===r.type&&"constructor"===r.kind&&(s&&this.raise(r.start,"Duplicate constructor in the same class"),s=!0)}return t.body=this.finishNode(i,"ClassBody"),this.finishNode(t,e?"ClassDeclaration":"ClassExpression")},q.parseClassMember=function(t){var e=this;if(this.eat(y.semi))return null;var i=this.startNode(),s=function(t,s){void 0===s&&(s=!1);var r=e.start,a=e.startLoc;return!!e.eatContextual(t)&&(!(e.type===y.parenL||s&&e.canInsertSemicolon())||(i.key&&e.unexpected(),i.computed=!1,i.key=e.startNodeAt(r,a),i.key.name=t,e.finishNode(i.key,"Identifier"),!1))};i.kind="method",i.static=s("static");var r=this.eat(y.star),a=!1;r||(this.options.ecmaVersion>=8&&s("async",!0)?(a=!0,r=this.options.ecmaVersion>=9&&this.eat(y.star)):s("get")?i.kind="get":s("set")&&(i.kind="set")),i.key||this.parsePropertyName(i);var n=i.key;return i.computed||i.static||!("Identifier"===n.type&&"constructor"===n.name||"Literal"===n.type&&"constructor"===n.value)?i.static&&"Identifier"===n.type&&"prototype"===n.name&&this.raise(n.start,"Classes may not have a static property named prototype"):("method"!==i.kind&&this.raise(n.start,"Constructor can't have get/set modifier"),r&&this.raise(n.start,"Constructor can't be a generator"),a&&this.raise(n.start,"Constructor can't be an async method"),i.kind="constructor"),this.parseClassMethod(t,i,r,a),"get"===i.kind&&0!==i.value.params.length&&this.raiseRecoverable(i.value.start,"getter should have no params"),"set"===i.kind&&1!==i.value.params.length&&this.raiseRecoverable(i.value.start,"setter should have exactly one param"),"set"===i.kind&&"RestElement"===i.value.params[0].type&&this.raiseRecoverable(i.value.params[0].start,"Setter cannot use rest params"),i},q.parseClassMethod=function(t,e,i,s){e.value=this.parseMethod(i,s),t.body.push(this.finishNode(e,"MethodDefinition"))},q.parseClassId=function(t,e){t.id=this.type===y.name?this.parseIdent():!0===e?this.unexpected():null},q.parseClassSuper=function(t){t.superClass=this.eat(y._extends)?this.parseExprSubscripts():null},q.parseExport=function(t,e){if(this.next(),this.eat(y.star))return this.expectContextual("from"),this.type!==y.string&&this.unexpected(),t.source=this.parseExprAtom(),this.semicolon(),this.finishNode(t,"ExportAllDeclaration");if(this.eat(y._default)){var i;if(this.checkExport(e,"default",this.lastTokStart),this.type===y._function||(i=this.isAsyncFunction())){var s=this.startNode();this.next(),i&&this.next(),t.declaration=this.parseFunction(s,"nullableID",!1,i)}else if(this.type===y._class){var r=this.startNode();t.declaration=this.parseClass(r,"nullableID")}else t.declaration=this.parseMaybeAssign(),this.semicolon();return this.finishNode(t,"ExportDefaultDeclaration")}if(this.shouldParseExportStatement())t.declaration=this.parseStatement(!0),"VariableDeclaration"===t.declaration.type?this.checkVariableExport(e,t.declaration.declarations):this.checkExport(e,t.declaration.id.name,t.declaration.id.start),t.specifiers=[],t.source=null;else{if(t.declaration=null,t.specifiers=this.parseExportSpecifiers(e),this.eatContextual("from"))this.type!==y.string&&this.unexpected(),t.source=this.parseExprAtom();else{for(var a=0,n=t.specifiers;a=6&&t)switch(t.type){case"Identifier":this.inAsync&&"await"===t.name&&this.raise(t.start,"Can not use 'await' as identifier inside an async function");break;case"ObjectPattern":case"ArrayPattern":case"RestElement":break;case"ObjectExpression":t.type="ObjectPattern",i&&this.checkPatternErrors(i,!0);for(var s=0,r=t.properties;s=9&&"SpreadElement"===t.type||this.options.ecmaVersion>=6&&(t.computed||t.method||t.shorthand))){var s,r=t.key;switch(r.type){case"Identifier":s=r.name;break;case"Literal":s=String(r.value);break;default:return}var a=t.kind;if(this.options.ecmaVersion>=6)"__proto__"===s&&"init"===a&&(e.proto&&(i&&i.doubleProto<0?i.doubleProto=r.start:this.raiseRecoverable(r.start,"Redefinition of __proto__ property")),e.proto=!0);else{var n=e[s="$"+s];if(n)("init"===a?this.strict&&n.init||n.get||n.set:n.init||n[a])&&this.raiseRecoverable(r.start,"Redefinition of property");else n=e[s]={init:!1,get:!1,set:!1};n[a]=!0}}},Q.parseExpression=function(t,e){var i=this.start,s=this.startLoc,r=this.parseMaybeAssign(t,e);if(this.type===y.comma){var a=this.startNodeAt(i,s);for(a.expressions=[r];this.eat(y.comma);)a.expressions.push(this.parseMaybeAssign(t,e));return this.finishNode(a,"SequenceExpression")}return r},Q.parseMaybeAssign=function(t,e,i){if(this.inGenerator&&this.isContextual("yield"))return this.parseYield();var s=!1,r=-1,a=-1;e?(r=e.parenthesizedAssign,a=e.trailingComma,e.parenthesizedAssign=e.trailingComma=-1):(e=new G,s=!0);var n=this.start,o=this.startLoc;this.type!==y.parenL&&this.type!==y.name||(this.potentialArrowAt=this.start);var h=this.parseMaybeConditional(t,e);if(i&&(h=i.call(this,h,n,o)),this.type.isAssign){var p=this.startNodeAt(n,o);return p.operator=this.value,p.left=this.type===y.eq?this.toAssignable(h,!1,e):h,s||G.call(e),e.shorthandAssign=-1,this.checkLVal(h),this.next(),p.right=this.parseMaybeAssign(t),this.finishNode(p,"AssignmentExpression")}return s&&this.checkExpressionErrors(e,!0),r>-1&&(e.parenthesizedAssign=r),a>-1&&(e.trailingComma=a),h},Q.parseMaybeConditional=function(t,e){var i=this.start,s=this.startLoc,r=this.parseExprOps(t,e);if(this.checkExpressionErrors(e))return r;if(this.eat(y.question)){var a=this.startNodeAt(i,s);return a.test=r,a.consequent=this.parseMaybeAssign(),this.expect(y.colon),a.alternate=this.parseMaybeAssign(t),this.finishNode(a,"ConditionalExpression")}return r},Q.parseExprOps=function(t,e){var i=this.start,s=this.startLoc,r=this.parseMaybeUnary(e,!1);return this.checkExpressionErrors(e)?r:r.start===i&&"ArrowFunctionExpression"===r.type?r:this.parseExprOp(r,i,s,-1,t)},Q.parseExprOp=function(t,e,i,s,r){var a=this.type.binop;if(null!=a&&(!r||this.type!==y._in)&&a>s){var n=this.type===y.logicalOR||this.type===y.logicalAND,o=this.value;this.next();var h=this.start,p=this.startLoc,c=this.parseExprOp(this.parseMaybeUnary(null,!1),h,p,a,r),u=this.buildBinary(e,i,t,c,o,n);return this.parseExprOp(u,e,i,s,r)}return t},Q.buildBinary=function(t,e,i,s,r,a){var n=this.startNodeAt(t,e);return n.left=i,n.operator=r,n.right=s,this.finishNode(n,a?"LogicalExpression":"BinaryExpression")},Q.parseMaybeUnary=function(t,e){var i,s=this.start,r=this.startLoc;if(this.isContextual("await")&&(this.inAsync||!this.inFunction&&this.options.allowAwaitOutsideFunction))i=this.parseAwait(),e=!0;else if(this.type.prefix){var a=this.startNode(),n=this.type===y.incDec;a.operator=this.value,a.prefix=!0,this.next(),a.argument=this.parseMaybeUnary(null,!0),this.checkExpressionErrors(t,!0),n?this.checkLVal(a.argument):this.strict&&"delete"===a.operator&&"Identifier"===a.argument.type?this.raiseRecoverable(a.start,"Deleting local variable in strict mode"):e=!0,i=this.finishNode(a,n?"UpdateExpression":"UnaryExpression")}else{if(i=this.parseExprSubscripts(t),this.checkExpressionErrors(t))return i;for(;this.type.postfix&&!this.canInsertSemicolon();){var o=this.startNodeAt(s,r);o.operator=this.value,o.prefix=!1,o.argument=i,this.checkLVal(i),this.next(),i=this.finishNode(o,"UpdateExpression")}}return!e&&this.eat(y.starstar)?this.buildBinary(s,r,i,this.parseMaybeUnary(null,!1),"**",!1):i},Q.parseExprSubscripts=function(t){var e=this.start,i=this.startLoc,s=this.parseExprAtom(t),r="ArrowFunctionExpression"===s.type&&")"!==this.input.slice(this.lastTokStart,this.lastTokEnd);if(this.checkExpressionErrors(t)||r)return s;var a=this.parseSubscripts(s,e,i);return t&&"MemberExpression"===a.type&&(t.parenthesizedAssign>=a.start&&(t.parenthesizedAssign=-1),t.parenthesizedBind>=a.start&&(t.parenthesizedBind=-1)),a},Q.parseSubscripts=function(t,e,i,s){for(var r=this.options.ecmaVersion>=8&&"Identifier"===t.type&&"async"===t.name&&this.lastTokEnd===t.end&&!this.canInsertSemicolon()&&"async"===this.input.slice(t.start,t.end),a=void 0;;)if((a=this.eat(y.bracketL))||this.eat(y.dot)){var n=this.startNodeAt(e,i);n.object=t,n.property=a?this.parseExpression():this.parseIdent(!0),n.computed=!!a,a&&this.expect(y.bracketR),t=this.finishNode(n,"MemberExpression")}else if(!s&&this.eat(y.parenL)){var o=new G,h=this.yieldPos,p=this.awaitPos;this.yieldPos=0,this.awaitPos=0;var c=this.parseExprList(y.parenR,this.options.ecmaVersion>=8,!1,o);if(r&&!this.canInsertSemicolon()&&this.eat(y.arrow))return this.checkPatternErrors(o,!1),this.checkYieldAwaitInDefaultParams(),this.yieldPos=h,this.awaitPos=p,this.parseArrowExpression(this.startNodeAt(e,i),c,!0);this.checkExpressionErrors(o,!0),this.yieldPos=h||this.yieldPos,this.awaitPos=p||this.awaitPos;var u=this.startNodeAt(e,i);u.callee=t,u.arguments=c,t=this.finishNode(u,"CallExpression")}else{if(this.type!==y.backQuote)return t;var l=this.startNodeAt(e,i);l.tag=t,l.quasi=this.parseTemplate({isTagged:!0}),t=this.finishNode(l,"TaggedTemplateExpression")}},Q.parseExprAtom=function(t){var e,i=this.potentialArrowAt===this.start;switch(this.type){case y._super:return this.inFunction||this.raise(this.start,"'super' outside of function or class"),e=this.startNode(),this.next(),this.type!==y.dot&&this.type!==y.bracketL&&this.type!==y.parenL&&this.unexpected(),this.finishNode(e,"Super");case y._this:return e=this.startNode(),this.next(),this.finishNode(e,"ThisExpression");case y.name:var s=this.start,r=this.startLoc,a=this.containsEsc,n=this.parseIdent(this.type!==y.name);if(this.options.ecmaVersion>=8&&!a&&"async"===n.name&&!this.canInsertSemicolon()&&this.eat(y._function))return this.parseFunction(this.startNodeAt(s,r),!1,!1,!0);if(i&&!this.canInsertSemicolon()){if(this.eat(y.arrow))return this.parseArrowExpression(this.startNodeAt(s,r),[n],!1);if(this.options.ecmaVersion>=8&&"async"===n.name&&this.type===y.name&&!a)return n=this.parseIdent(),!this.canInsertSemicolon()&&this.eat(y.arrow)||this.unexpected(),this.parseArrowExpression(this.startNodeAt(s,r),[n],!0)}return n;case y.regexp:var o=this.value;return(e=this.parseLiteral(o.value)).regex={pattern:o.pattern,flags:o.flags},e;case y.num:case y.string:return this.parseLiteral(this.value);case y._null:case y._true:case y._false:return(e=this.startNode()).value=this.type===y._null?null:this.type===y._true,e.raw=this.type.keyword,this.next(),this.finishNode(e,"Literal");case y.parenL:var h=this.start,p=this.parseParenAndDistinguishExpression(i);return t&&(t.parenthesizedAssign<0&&!this.isSimpleAssignTarget(p)&&(t.parenthesizedAssign=h),t.parenthesizedBind<0&&(t.parenthesizedBind=h)),p;case y.bracketL:return e=this.startNode(),this.next(),e.elements=this.parseExprList(y.bracketR,!0,!0,t),this.finishNode(e,"ArrayExpression");case y.braceL:return this.parseObj(!1,t);case y._function:return e=this.startNode(),this.next(),this.parseFunction(e,!1);case y._class:return this.parseClass(this.startNode(),!1);case y._new:return this.parseNew();case y.backQuote:return this.parseTemplate();default:this.unexpected()}},Q.parseLiteral=function(t){var e=this.startNode();return e.value=t,e.raw=this.input.slice(this.start,this.end),this.next(),this.finishNode(e,"Literal")},Q.parseParenExpression=function(){this.expect(y.parenL);var t=this.parseExpression();return this.expect(y.parenR),t},Q.parseParenAndDistinguishExpression=function(t){var e,i=this.start,s=this.startLoc,r=this.options.ecmaVersion>=8;if(this.options.ecmaVersion>=6){this.next();var a,n=this.start,o=this.startLoc,h=[],p=!0,c=!1,u=new G,l=this.yieldPos,d=this.awaitPos;for(this.yieldPos=0,this.awaitPos=0;this.type!==y.parenR;){if(p?p=!1:this.expect(y.comma),r&&this.afterTrailingComma(y.parenR,!0)){c=!0;break}if(this.type===y.ellipsis){a=this.start,h.push(this.parseParenItem(this.parseRestBinding())),this.type===y.comma&&this.raise(this.start,"Comma is not permitted after the rest element");break}h.push(this.parseMaybeAssign(!1,u,this.parseParenItem))}var f=this.start,m=this.startLoc;if(this.expect(y.parenR),t&&!this.canInsertSemicolon()&&this.eat(y.arrow))return this.checkPatternErrors(u,!1),this.checkYieldAwaitInDefaultParams(),this.yieldPos=l,this.awaitPos=d,this.parseParenArrowList(i,s,h);h.length&&!c||this.unexpected(this.lastTokStart),a&&this.unexpected(a),this.checkExpressionErrors(u,!0),this.yieldPos=l||this.yieldPos,this.awaitPos=d||this.awaitPos,h.length>1?((e=this.startNodeAt(n,o)).expressions=h,this.finishNodeAt(e,"SequenceExpression",f,m)):e=h[0]}else e=this.parseParenExpression();if(this.options.preserveParens){var x=this.startNodeAt(i,s);return x.expression=e,this.finishNode(x,"ParenthesizedExpression")}return e},Q.parseParenItem=function(t){return t},Q.parseParenArrowList=function(t,e,i){return this.parseArrowExpression(this.startNodeAt(t,e),i)};var K=[];Q.parseNew=function(){var t=this.startNode(),e=this.parseIdent(!0);if(this.options.ecmaVersion>=6&&this.eat(y.dot)){t.meta=e;var i=this.containsEsc;return t.property=this.parseIdent(!0),("target"!==t.property.name||i)&&this.raiseRecoverable(t.property.start,"The only valid meta property for new is new.target"),this.inFunction||this.raiseRecoverable(t.start,"new.target can only be used in functions"),this.finishNode(t,"MetaProperty")}var s=this.start,r=this.startLoc;return t.callee=this.parseSubscripts(this.parseExprAtom(),s,r,!0),this.eat(y.parenL)?t.arguments=this.parseExprList(y.parenR,this.options.ecmaVersion>=8,!1):t.arguments=K,this.finishNode(t,"NewExpression")},Q.parseTemplateElement=function(t){var e=t.isTagged,i=this.startNode();return this.type===y.invalidTemplate?(e||this.raiseRecoverable(this.start,"Bad escape sequence in untagged template literal"),i.value={raw:this.value,cooked:null}):i.value={raw:this.input.slice(this.start,this.end).replace(/\r\n?/g,"\n"),cooked:this.value},this.next(),i.tail=this.type===y.backQuote,this.finishNode(i,"TemplateElement")},Q.parseTemplate=function(t){void 0===t&&(t={});var e=t.isTagged;void 0===e&&(e=!1);var i=this.startNode();this.next(),i.expressions=[];var s=this.parseTemplateElement({isTagged:e});for(i.quasis=[s];!s.tail;)this.type===y.eof&&this.raise(this.pos,"Unterminated template literal"),this.expect(y.dollarBraceL),i.expressions.push(this.parseExpression()),this.expect(y.braceR),i.quasis.push(s=this.parseTemplateElement({isTagged:e}));return this.next(),this.finishNode(i,"TemplateLiteral")},Q.isAsyncProp=function(t){return!t.computed&&"Identifier"===t.key.type&&"async"===t.key.name&&(this.type===y.name||this.type===y.num||this.type===y.string||this.type===y.bracketL||this.type.keyword||this.options.ecmaVersion>=9&&this.type===y.star)&&!_.test(this.input.slice(this.lastTokEnd,this.start))},Q.parseObj=function(t,e){var i=this.startNode(),s=!0,r={};for(i.properties=[],this.next();!this.eat(y.braceR);){if(s)s=!1;else if(this.expect(y.comma),this.afterTrailingComma(y.braceR))break;var a=this.parseProperty(t,e);t||this.checkPropClash(a,r,e),i.properties.push(a)}return this.finishNode(i,t?"ObjectPattern":"ObjectExpression")},Q.parseProperty=function(t,e){var i,s,r,a,n=this.startNode();if(this.options.ecmaVersion>=9&&this.eat(y.ellipsis))return t?(n.argument=this.parseIdent(!1),this.type===y.comma&&this.raise(this.start,"Comma is not permitted after the rest element"),this.finishNode(n,"RestElement")):(this.type===y.parenL&&e&&(e.parenthesizedAssign<0&&(e.parenthesizedAssign=this.start),e.parenthesizedBind<0&&(e.parenthesizedBind=this.start)),n.argument=this.parseMaybeAssign(!1,e),this.type===y.comma&&e&&e.trailingComma<0&&(e.trailingComma=this.start),this.finishNode(n,"SpreadElement"));this.options.ecmaVersion>=6&&(n.method=!1,n.shorthand=!1,(t||e)&&(r=this.start,a=this.startLoc),t||(i=this.eat(y.star)));var o=this.containsEsc;return this.parsePropertyName(n),!t&&!o&&this.options.ecmaVersion>=8&&!i&&this.isAsyncProp(n)?(s=!0,i=this.options.ecmaVersion>=9&&this.eat(y.star),this.parsePropertyName(n,e)):s=!1,this.parsePropertyValue(n,t,i,s,r,a,e,o),this.finishNode(n,"Property")},Q.parsePropertyValue=function(t,e,i,s,r,a,n,o){if((i||s)&&this.type===y.colon&&this.unexpected(),this.eat(y.colon))t.value=e?this.parseMaybeDefault(this.start,this.startLoc):this.parseMaybeAssign(!1,n),t.kind="init";else if(this.options.ecmaVersion>=6&&this.type===y.parenL)e&&this.unexpected(),t.kind="init",t.method=!0,t.value=this.parseMethod(i,s);else if(e||o||!(this.options.ecmaVersion>=5)||t.computed||"Identifier"!==t.key.type||"get"!==t.key.name&&"set"!==t.key.name||this.type===y.comma||this.type===y.braceR)this.options.ecmaVersion>=6&&!t.computed&&"Identifier"===t.key.type?(this.checkUnreserved(t.key),t.kind="init",e?t.value=this.parseMaybeDefault(r,a,t.key):this.type===y.eq&&n?(n.shorthandAssign<0&&(n.shorthandAssign=this.start),t.value=this.parseMaybeDefault(r,a,t.key)):t.value=t.key,t.shorthand=!0):this.unexpected();else{(i||s)&&this.unexpected(),t.kind=t.key.name,this.parsePropertyName(t),t.value=this.parseMethod(!1);var h="get"===t.kind?0:1;if(t.value.params.length!==h){var p=t.value.start;"get"===t.kind?this.raiseRecoverable(p,"getter should have no params"):this.raiseRecoverable(p,"setter should have exactly one param")}else"set"===t.kind&&"RestElement"===t.value.params[0].type&&this.raiseRecoverable(t.value.params[0].start,"Setter cannot use rest params")}},Q.parsePropertyName=function(t){if(this.options.ecmaVersion>=6){if(this.eat(y.bracketL))return t.computed=!0,t.key=this.parseMaybeAssign(),this.expect(y.bracketR),t.key;t.computed=!1}return t.key=this.type===y.num||this.type===y.string?this.parseExprAtom():this.parseIdent(!0)},Q.initFunction=function(t){t.id=null,this.options.ecmaVersion>=6&&(t.generator=!1,t.expression=!1),this.options.ecmaVersion>=8&&(t.async=!1)},Q.parseMethod=function(t,e){var i=this.startNode(),s=this.inGenerator,r=this.inAsync,a=this.yieldPos,n=this.awaitPos,o=this.inFunction;return this.initFunction(i),this.options.ecmaVersion>=6&&(i.generator=t),this.options.ecmaVersion>=8&&(i.async=!!e),this.inGenerator=i.generator,this.inAsync=i.async,this.yieldPos=0,this.awaitPos=0,this.inFunction=!0,this.enterFunctionScope(),this.expect(y.parenL),i.params=this.parseBindingList(y.parenR,!1,this.options.ecmaVersion>=8),this.checkYieldAwaitInDefaultParams(),this.parseFunctionBody(i,!1),this.inGenerator=s,this.inAsync=r,this.yieldPos=a,this.awaitPos=n,this.inFunction=o,this.finishNode(i,"FunctionExpression")},Q.parseArrowExpression=function(t,e,i){var s=this.inGenerator,r=this.inAsync,a=this.yieldPos,n=this.awaitPos,o=this.inFunction;return this.enterFunctionScope(),this.initFunction(t),this.options.ecmaVersion>=8&&(t.async=!!i),this.inGenerator=!1,this.inAsync=t.async,this.yieldPos=0,this.awaitPos=0,this.inFunction=!0,t.params=this.toAssignableList(e,!0),this.parseFunctionBody(t,!0),this.inGenerator=s,this.inAsync=r,this.yieldPos=a,this.awaitPos=n,this.inFunction=o,this.finishNode(t,"ArrowFunctionExpression")},Q.parseFunctionBody=function(t,e){var i=e&&this.type!==y.braceL,s=this.strict,r=!1;if(i)t.body=this.parseMaybeAssign(),t.expression=!0,this.checkParams(t,!1);else{var a=this.options.ecmaVersion>=7&&!this.isSimpleParamList(t.params);s&&!a||(r=this.strictDirective(this.end))&&a&&this.raiseRecoverable(t.start,"Illegal 'use strict' directive in function with non-simple parameter list");var n=this.labels;this.labels=[],r&&(this.strict=!0),this.checkParams(t,!s&&!r&&!e&&this.isSimpleParamList(t.params)),t.body=this.parseBlock(!1),t.expression=!1,this.adaptDirectivePrologue(t.body.body),this.labels=n}this.exitFunctionScope(),this.strict&&t.id&&this.checkLVal(t.id,"none"),this.strict=s},Q.isSimpleParamList=function(t){for(var e=0,i=t;e0;)e[i]=arguments[i+1];for(var s=0,r=e;s=1;t--){var e=this.context[t];if("function"===e.token)return e.generator}return!1},st.updateContext=function(t){var e,i=this.type;i.keyword&&t===y.dot?this.exprAllowed=!1:(e=i.updateContext)?e.call(this,t):this.exprAllowed=i.beforeExpr},y.parenR.updateContext=y.braceR.updateContext=function(){if(1!==this.context.length){var t=this.context.pop();t===it.b_stat&&"function"===this.curContext().token&&(t=this.context.pop()),this.exprAllowed=!t.isExpr}else this.exprAllowed=!0},y.braceL.updateContext=function(t){this.context.push(this.braceIsBlock(t)?it.b_stat:it.b_expr),this.exprAllowed=!0},y.dollarBraceL.updateContext=function(){this.context.push(it.b_tmpl),this.exprAllowed=!0},y.parenL.updateContext=function(t){var e=t===y._if||t===y._for||t===y._with||t===y._while;this.context.push(e?it.p_stat:it.p_expr),this.exprAllowed=!0},y.incDec.updateContext=function(){},y._function.updateContext=y._class.updateContext=function(t){t.beforeExpr&&t!==y.semi&&t!==y._else&&(t!==y.colon&&t!==y.braceL||this.curContext()!==it.b_stat)?this.context.push(it.f_expr):this.context.push(it.f_stat),this.exprAllowed=!1},y.backQuote.updateContext=function(){this.curContext()===it.q_tmpl?this.context.pop():this.context.push(it.q_tmpl),this.exprAllowed=!1},y.star.updateContext=function(t){if(t===y._function){var e=this.context.length-1;this.context[e]===it.f_expr?this.context[e]=it.f_expr_gen:this.context[e]=it.f_gen}this.exprAllowed=!0},y.name.updateContext=function(t){var e=!1;this.options.ecmaVersion>=6&&t!==y.dot&&("of"===this.value&&!this.exprAllowed||"yield"===this.value&&this.inGeneratorContext())&&(e=!0),this.exprAllowed=e};var rt={$LONE:["ASCII","ASCII_Hex_Digit","AHex","Alphabetic","Alpha","Any","Assigned","Bidi_Control","Bidi_C","Bidi_Mirrored","Bidi_M","Case_Ignorable","CI","Cased","Changes_When_Casefolded","CWCF","Changes_When_Casemapped","CWCM","Changes_When_Lowercased","CWL","Changes_When_NFKC_Casefolded","CWKCF","Changes_When_Titlecased","CWT","Changes_When_Uppercased","CWU","Dash","Default_Ignorable_Code_Point","DI","Deprecated","Dep","Diacritic","Dia","Emoji","Emoji_Component","Emoji_Modifier","Emoji_Modifier_Base","Emoji_Presentation","Extender","Ext","Grapheme_Base","Gr_Base","Grapheme_Extend","Gr_Ext","Hex_Digit","Hex","IDS_Binary_Operator","IDSB","IDS_Trinary_Operator","IDST","ID_Continue","IDC","ID_Start","IDS","Ideographic","Ideo","Join_Control","Join_C","Logical_Order_Exception","LOE","Lowercase","Lower","Math","Noncharacter_Code_Point","NChar","Pattern_Syntax","Pat_Syn","Pattern_White_Space","Pat_WS","Quotation_Mark","QMark","Radical","Regional_Indicator","RI","Sentence_Terminal","STerm","Soft_Dotted","SD","Terminal_Punctuation","Term","Unified_Ideograph","UIdeo","Uppercase","Upper","Variation_Selector","VS","White_Space","space","XID_Continue","XIDC","XID_Start","XIDS"],General_Category:["Cased_Letter","LC","Close_Punctuation","Pe","Connector_Punctuation","Pc","Control","Cc","cntrl","Currency_Symbol","Sc","Dash_Punctuation","Pd","Decimal_Number","Nd","digit","Enclosing_Mark","Me","Final_Punctuation","Pf","Format","Cf","Initial_Punctuation","Pi","Letter","L","Letter_Number","Nl","Line_Separator","Zl","Lowercase_Letter","Ll","Mark","M","Combining_Mark","Math_Symbol","Sm","Modifier_Letter","Lm","Modifier_Symbol","Sk","Nonspacing_Mark","Mn","Number","N","Open_Punctuation","Ps","Other","C","Other_Letter","Lo","Other_Number","No","Other_Punctuation","Po","Other_Symbol","So","Paragraph_Separator","Zp","Private_Use","Co","Punctuation","P","punct","Separator","Z","Space_Separator","Zs","Spacing_Mark","Mc","Surrogate","Cs","Symbol","S","Titlecase_Letter","Lt","Unassigned","Cn","Uppercase_Letter","Lu"],Script:["Adlam","Adlm","Ahom","Anatolian_Hieroglyphs","Hluw","Arabic","Arab","Armenian","Armn","Avestan","Avst","Balinese","Bali","Bamum","Bamu","Bassa_Vah","Bass","Batak","Batk","Bengali","Beng","Bhaiksuki","Bhks","Bopomofo","Bopo","Brahmi","Brah","Braille","Brai","Buginese","Bugi","Buhid","Buhd","Canadian_Aboriginal","Cans","Carian","Cari","Caucasian_Albanian","Aghb","Chakma","Cakm","Cham","Cherokee","Cher","Common","Zyyy","Coptic","Copt","Qaac","Cuneiform","Xsux","Cypriot","Cprt","Cyrillic","Cyrl","Deseret","Dsrt","Devanagari","Deva","Duployan","Dupl","Egyptian_Hieroglyphs","Egyp","Elbasan","Elba","Ethiopic","Ethi","Georgian","Geor","Glagolitic","Glag","Gothic","Goth","Grantha","Gran","Greek","Grek","Gujarati","Gujr","Gurmukhi","Guru","Han","Hani","Hangul","Hang","Hanunoo","Hano","Hatran","Hatr","Hebrew","Hebr","Hiragana","Hira","Imperial_Aramaic","Armi","Inherited","Zinh","Qaai","Inscriptional_Pahlavi","Phli","Inscriptional_Parthian","Prti","Javanese","Java","Kaithi","Kthi","Kannada","Knda","Katakana","Kana","Kayah_Li","Kali","Kharoshthi","Khar","Khmer","Khmr","Khojki","Khoj","Khudawadi","Sind","Lao","Laoo","Latin","Latn","Lepcha","Lepc","Limbu","Limb","Linear_A","Lina","Linear_B","Linb","Lisu","Lycian","Lyci","Lydian","Lydi","Mahajani","Mahj","Malayalam","Mlym","Mandaic","Mand","Manichaean","Mani","Marchen","Marc","Masaram_Gondi","Gonm","Meetei_Mayek","Mtei","Mende_Kikakui","Mend","Meroitic_Cursive","Merc","Meroitic_Hieroglyphs","Mero","Miao","Plrd","Modi","Mongolian","Mong","Mro","Mroo","Multani","Mult","Myanmar","Mymr","Nabataean","Nbat","New_Tai_Lue","Talu","Newa","Nko","Nkoo","Nushu","Nshu","Ogham","Ogam","Ol_Chiki","Olck","Old_Hungarian","Hung","Old_Italic","Ital","Old_North_Arabian","Narb","Old_Permic","Perm","Old_Persian","Xpeo","Old_South_Arabian","Sarb","Old_Turkic","Orkh","Oriya","Orya","Osage","Osge","Osmanya","Osma","Pahawh_Hmong","Hmng","Palmyrene","Palm","Pau_Cin_Hau","Pauc","Phags_Pa","Phag","Phoenician","Phnx","Psalter_Pahlavi","Phlp","Rejang","Rjng","Runic","Runr","Samaritan","Samr","Saurashtra","Saur","Sharada","Shrd","Shavian","Shaw","Siddham","Sidd","SignWriting","Sgnw","Sinhala","Sinh","Sora_Sompeng","Sora","Soyombo","Soyo","Sundanese","Sund","Syloti_Nagri","Sylo","Syriac","Syrc","Tagalog","Tglg","Tagbanwa","Tagb","Tai_Le","Tale","Tai_Tham","Lana","Tai_Viet","Tavt","Takri","Takr","Tamil","Taml","Tangut","Tang","Telugu","Telu","Thaana","Thaa","Thai","Tibetan","Tibt","Tifinagh","Tfng","Tirhuta","Tirh","Ugaritic","Ugar","Vai","Vaii","Warang_Citi","Wara","Yi","Yiii","Zanabazar_Square","Zanb"]};Array.prototype.push.apply(rt.$LONE,rt.General_Category),rt.gc=rt.General_Category,rt.sc=rt.Script_Extensions=rt.scx=rt.Script;var at=M.prototype,nt=function(t){this.parser=t,this.validFlags="gim"+(t.options.ecmaVersion>=6?"uy":"")+(t.options.ecmaVersion>=9?"s":""),this.source="",this.flags="",this.start=0,this.switchU=!1,this.switchN=!1,this.pos=0,this.lastIntValue=0,this.lastStringValue="",this.lastAssertionIsQuantifiable=!1,this.numCapturingParens=0,this.maxBackReference=0,this.groupNames=[],this.backReferenceNames=[]};function ot(t){return t<=65535?String.fromCharCode(t):(t-=65536,String.fromCharCode(55296+(t>>10),56320+(1023&t)))}function ht(t){return 36===t||t>=40&&t<=43||46===t||63===t||t>=91&&t<=94||t>=123&&t<=125}function pt(t){return u(t,!0)||36===t||95===t}function ct(t){return l(t,!0)||36===t||95===t||8204===t||8205===t}function ut(t){return t>=65&&t<=90||t>=97&&t<=122}function lt(t){return t>=0&&t<=1114111}function dt(t){return 100===t||68===t||115===t||83===t||119===t||87===t}function ft(t){return ut(t)||95===t}function mt(t){return ft(t)||xt(t)}function xt(t){return t>=48&&t<=57}function gt(t){return t>=48&&t<=57||t>=65&&t<=70||t>=97&&t<=102}function vt(t){return t>=65&&t<=70?t-65+10:t>=97&&t<=102?t-97+10:t-48}function yt(t){return t>=48&&t<=55}nt.prototype.reset=function(t,e,i){var s=-1!==i.indexOf("u");this.start=0|t,this.source=e+"",this.flags=i,this.switchU=s&&this.parser.options.ecmaVersion>=6,this.switchN=s&&this.parser.options.ecmaVersion>=9},nt.prototype.raise=function(t){this.parser.raiseRecoverable(this.start,"Invalid regular expression: /"+this.source+"/: "+t)},nt.prototype.at=function(t){var e=this.source,i=e.length;if(t>=i)return-1;var s=e.charCodeAt(t);return!this.switchU||s<=55295||s>=57344||t+1>=i?s:(s<<10)+e.charCodeAt(t+1)-56613888},nt.prototype.nextIndex=function(t){var e=this.source,i=e.length;if(t>=i)return i;var s=e.charCodeAt(t);return!this.switchU||s<=55295||s>=57344||t+1>=i?t+1:t+2},nt.prototype.current=function(){return this.at(this.pos)},nt.prototype.lookahead=function(){return this.at(this.nextIndex(this.pos))},nt.prototype.advance=function(){this.pos=this.nextIndex(this.pos)},nt.prototype.eat=function(t){return this.current()===t&&(this.advance(),!0)},at.validateRegExpFlags=function(t){for(var e=t.validFlags,i=t.flags,s=0;s-1&&this.raise(t.start,"Duplicate regular expression flag")}},at.validateRegExpPattern=function(t){this.regexp_pattern(t),!t.switchN&&this.options.ecmaVersion>=9&&t.groupNames.length>0&&(t.switchN=!0,this.regexp_pattern(t))},at.regexp_pattern=function(t){t.pos=0,t.lastIntValue=0,t.lastStringValue="",t.lastAssertionIsQuantifiable=!1,t.numCapturingParens=0,t.maxBackReference=0,t.groupNames.length=0,t.backReferenceNames.length=0,this.regexp_disjunction(t),t.pos!==t.source.length&&(t.eat(41)&&t.raise("Unmatched ')'"),(t.eat(93)||t.eat(125))&&t.raise("Lone quantifier brackets")),t.maxBackReference>t.numCapturingParens&&t.raise("Invalid escape");for(var e=0,i=t.backReferenceNames;e=9&&(i=t.eat(60)),t.eat(61)||t.eat(33))return this.regexp_disjunction(t),t.eat(41)||t.raise("Unterminated group"),t.lastAssertionIsQuantifiable=!i,!0}return t.pos=e,!1},at.regexp_eatQuantifier=function(t,e){return void 0===e&&(e=!1),!!this.regexp_eatQuantifierPrefix(t,e)&&(t.eat(63),!0)},at.regexp_eatQuantifierPrefix=function(t,e){return t.eat(42)||t.eat(43)||t.eat(63)||this.regexp_eatBracedQuantifier(t,e)},at.regexp_eatBracedQuantifier=function(t,e){var i=t.pos;if(t.eat(123)){var s=0,r=-1;if(this.regexp_eatDecimalDigits(t)&&(s=t.lastIntValue,t.eat(44)&&this.regexp_eatDecimalDigits(t)&&(r=t.lastIntValue),t.eat(125)))return-1!==r&&r=9?this.regexp_groupSpecifier(t):63===t.current()&&t.raise("Invalid group"),this.regexp_disjunction(t),t.eat(41))return t.numCapturingParens+=1,!0;t.raise("Unterminated group")}return!1},at.regexp_eatExtendedAtom=function(t){return t.eat(46)||this.regexp_eatReverseSolidusAtomEscape(t)||this.regexp_eatCharacterClass(t)||this.regexp_eatUncapturingGroup(t)||this.regexp_eatCapturingGroup(t)||this.regexp_eatInvalidBracedQuantifier(t)||this.regexp_eatExtendedPatternCharacter(t)},at.regexp_eatInvalidBracedQuantifier=function(t){return this.regexp_eatBracedQuantifier(t,!0)&&t.raise("Nothing to repeat"),!1},at.regexp_eatSyntaxCharacter=function(t){var e=t.current();return!!ht(e)&&(t.lastIntValue=e,t.advance(),!0)},at.regexp_eatPatternCharacters=function(t){for(var e=t.pos,i=0;-1!==(i=t.current())&&!ht(i);)t.advance();return t.pos!==e},at.regexp_eatExtendedPatternCharacter=function(t){var e=t.current();return!(-1===e||36===e||e>=40&&e<=43||46===e||63===e||91===e||94===e||124===e)&&(t.advance(),!0)},at.regexp_groupSpecifier=function(t){if(t.eat(63)){if(this.regexp_eatGroupName(t))return-1!==t.groupNames.indexOf(t.lastStringValue)&&t.raise("Duplicate capture group name"),void t.groupNames.push(t.lastStringValue);t.raise("Invalid group")}},at.regexp_eatGroupName=function(t){if(t.lastStringValue="",t.eat(60)){if(this.regexp_eatRegExpIdentifierName(t)&&t.eat(62))return!0;t.raise("Invalid capture group name")}return!1},at.regexp_eatRegExpIdentifierName=function(t){if(t.lastStringValue="",this.regexp_eatRegExpIdentifierStart(t)){for(t.lastStringValue+=ot(t.lastIntValue);this.regexp_eatRegExpIdentifierPart(t);)t.lastStringValue+=ot(t.lastIntValue);return!0}return!1},at.regexp_eatRegExpIdentifierStart=function(t){var e=t.pos,i=t.current();return t.advance(),92===i&&this.regexp_eatRegExpUnicodeEscapeSequence(t)&&(i=t.lastIntValue),pt(i)?(t.lastIntValue=i,!0):(t.pos=e,!1)},at.regexp_eatRegExpIdentifierPart=function(t){var e=t.pos,i=t.current();return t.advance(),92===i&&this.regexp_eatRegExpUnicodeEscapeSequence(t)&&(i=t.lastIntValue),ct(i)?(t.lastIntValue=i,!0):(t.pos=e,!1)},at.regexp_eatAtomEscape=function(t){return!!(this.regexp_eatBackReference(t)||this.regexp_eatCharacterClassEscape(t)||this.regexp_eatCharacterEscape(t)||t.switchN&&this.regexp_eatKGroupName(t))||(t.switchU&&(99===t.current()&&t.raise("Invalid unicode escape"),t.raise("Invalid escape")),!1)},at.regexp_eatBackReference=function(t){var e=t.pos;if(this.regexp_eatDecimalEscape(t)){var i=t.lastIntValue;if(t.switchU)return i>t.maxBackReference&&(t.maxBackReference=i),!0;if(i<=t.numCapturingParens)return!0;t.pos=e}return!1},at.regexp_eatKGroupName=function(t){if(t.eat(107)){if(this.regexp_eatGroupName(t))return t.backReferenceNames.push(t.lastStringValue),!0;t.raise("Invalid named reference")}return!1},at.regexp_eatCharacterEscape=function(t){return this.regexp_eatControlEscape(t)||this.regexp_eatCControlLetter(t)||this.regexp_eatZero(t)||this.regexp_eatHexEscapeSequence(t)||this.regexp_eatRegExpUnicodeEscapeSequence(t)||!t.switchU&&this.regexp_eatLegacyOctalEscapeSequence(t)||this.regexp_eatIdentityEscape(t)},at.regexp_eatCControlLetter=function(t){var e=t.pos;if(t.eat(99)){if(this.regexp_eatControlLetter(t))return!0;t.pos=e}return!1},at.regexp_eatZero=function(t){return 48===t.current()&&!xt(t.lookahead())&&(t.lastIntValue=0,t.advance(),!0)},at.regexp_eatControlEscape=function(t){var e=t.current();return 116===e?(t.lastIntValue=9,t.advance(),!0):110===e?(t.lastIntValue=10,t.advance(),!0):118===e?(t.lastIntValue=11,t.advance(),!0):102===e?(t.lastIntValue=12,t.advance(),!0):114===e&&(t.lastIntValue=13,t.advance(),!0)},at.regexp_eatControlLetter=function(t){var e=t.current();return!!ut(e)&&(t.lastIntValue=e%32,t.advance(),!0)},at.regexp_eatRegExpUnicodeEscapeSequence=function(t){var e=t.pos;if(t.eat(117)){if(this.regexp_eatFixedHexDigits(t,4)){var i=t.lastIntValue;if(t.switchU&&i>=55296&&i<=56319){var s=t.pos;if(t.eat(92)&&t.eat(117)&&this.regexp_eatFixedHexDigits(t,4)){var r=t.lastIntValue;if(r>=56320&&r<=57343)return t.lastIntValue=1024*(i-55296)+(r-56320)+65536,!0}t.pos=s,t.lastIntValue=i}return!0}if(t.switchU&&t.eat(123)&&this.regexp_eatHexDigits(t)&&t.eat(125)&<(t.lastIntValue))return!0;t.switchU&&t.raise("Invalid unicode escape"),t.pos=e}return!1},at.regexp_eatIdentityEscape=function(t){if(t.switchU)return!!this.regexp_eatSyntaxCharacter(t)||!!t.eat(47)&&(t.lastIntValue=47,!0);var e=t.current();return!(99===e||t.switchN&&107===e)&&(t.lastIntValue=e,t.advance(),!0)},at.regexp_eatDecimalEscape=function(t){t.lastIntValue=0;var e=t.current();if(e>=49&&e<=57){do{t.lastIntValue=10*t.lastIntValue+(e-48),t.advance()}while((e=t.current())>=48&&e<=57);return!0}return!1},at.regexp_eatCharacterClassEscape=function(t){var e=t.current();if(dt(e))return t.lastIntValue=-1,t.advance(),!0;if(t.switchU&&this.options.ecmaVersion>=9&&(80===e||112===e)){if(t.lastIntValue=-1,t.advance(),t.eat(123)&&this.regexp_eatUnicodePropertyValueExpression(t)&&t.eat(125))return!0;t.raise("Invalid property name")}return!1},at.regexp_eatUnicodePropertyValueExpression=function(t){var e=t.pos;if(this.regexp_eatUnicodePropertyName(t)&&t.eat(61)){var i=t.lastStringValue;if(this.regexp_eatUnicodePropertyValue(t)){var s=t.lastStringValue;return this.regexp_validateUnicodePropertyNameAndValue(t,i,s),!0}}if(t.pos=e,this.regexp_eatLoneUnicodePropertyNameOrValue(t)){var r=t.lastStringValue;return this.regexp_validateUnicodePropertyNameOrValue(t,r),!0}return!1},at.regexp_validateUnicodePropertyNameAndValue=function(t,e,i){rt.hasOwnProperty(e)&&-1!==rt[e].indexOf(i)||t.raise("Invalid property name")},at.regexp_validateUnicodePropertyNameOrValue=function(t,e){-1===rt.$LONE.indexOf(e)&&t.raise("Invalid property name")},at.regexp_eatUnicodePropertyName=function(t){var e=0;for(t.lastStringValue="";ft(e=t.current());)t.lastStringValue+=ot(e),t.advance();return""!==t.lastStringValue},at.regexp_eatUnicodePropertyValue=function(t){var e=0;for(t.lastStringValue="";mt(e=t.current());)t.lastStringValue+=ot(e),t.advance();return""!==t.lastStringValue},at.regexp_eatLoneUnicodePropertyNameOrValue=function(t){return this.regexp_eatUnicodePropertyValue(t)},at.regexp_eatCharacterClass=function(t){if(t.eat(91)){if(t.eat(94),this.regexp_classRanges(t),t.eat(93))return!0;t.raise("Unterminated character class")}return!1},at.regexp_classRanges=function(t){for(;this.regexp_eatClassAtom(t);){var e=t.lastIntValue;if(t.eat(45)&&this.regexp_eatClassAtom(t)){var i=t.lastIntValue;!t.switchU||-1!==e&&-1!==i||t.raise("Invalid character class"),-1!==e&&-1!==i&&e>i&&t.raise("Range out of order in character class")}}},at.regexp_eatClassAtom=function(t){var e=t.pos;if(t.eat(92)){if(this.regexp_eatClassEscape(t))return!0;if(t.switchU){var i=t.current();(99===i||yt(i))&&t.raise("Invalid class escape"),t.raise("Invalid escape")}t.pos=e}var s=t.current();return 93!==s&&(t.lastIntValue=s,t.advance(),!0)},at.regexp_eatClassEscape=function(t){var e=t.pos;if(t.eat(98))return t.lastIntValue=8,!0;if(t.switchU&&t.eat(45))return t.lastIntValue=45,!0;if(!t.switchU&&t.eat(99)){if(this.regexp_eatClassControlLetter(t))return!0;t.pos=e}return this.regexp_eatCharacterClassEscape(t)||this.regexp_eatCharacterEscape(t)},at.regexp_eatClassControlLetter=function(t){var e=t.current();return!(!xt(e)&&95!==e)&&(t.lastIntValue=e%32,t.advance(),!0)},at.regexp_eatHexEscapeSequence=function(t){var e=t.pos;if(t.eat(120)){if(this.regexp_eatFixedHexDigits(t,2))return!0;t.switchU&&t.raise("Invalid escape"),t.pos=e}return!1},at.regexp_eatDecimalDigits=function(t){var e=t.pos,i=0;for(t.lastIntValue=0;xt(i=t.current());)t.lastIntValue=10*t.lastIntValue+(i-48),t.advance();return t.pos!==e},at.regexp_eatHexDigits=function(t){var e=t.pos,i=0;for(t.lastIntValue=0;gt(i=t.current());)t.lastIntValue=16*t.lastIntValue+vt(i),t.advance();return t.pos!==e},at.regexp_eatLegacyOctalEscapeSequence=function(t){if(this.regexp_eatOctalDigit(t)){var e=t.lastIntValue;if(this.regexp_eatOctalDigit(t)){var i=t.lastIntValue;e<=3&&this.regexp_eatOctalDigit(t)?t.lastIntValue=64*e+8*i+t.lastIntValue:t.lastIntValue=8*e+i}else t.lastIntValue=e;return!0}return!1},at.regexp_eatOctalDigit=function(t){var e=t.current();return yt(e)?(t.lastIntValue=e-48,t.advance(),!0):(t.lastIntValue=0,!1)},at.regexp_eatFixedHexDigits=function(t,e){var i=t.pos;t.lastIntValue=0;for(var s=0;s>10),56320+(1023&t)))}bt.next=function(){this.options.onToken&&this.options.onToken(new _t(this)),this.lastTokEnd=this.end,this.lastTokStart=this.start,this.lastTokEndLoc=this.endLoc,this.lastTokStartLoc=this.startLoc,this.nextToken()},bt.getToken=function(){return this.next(),new _t(this)},"undefined"!=typeof Symbol&&(bt[Symbol.iterator]=function(){var t=this;return{next:function(){var e=t.getToken();return{done:e.type===y.eof,value:e}}}}),bt.curContext=function(){return this.context[this.context.length-1]},bt.nextToken=function(){var t=this.curContext();return t&&t.preserveSpace||this.skipSpace(),this.start=this.pos,this.options.locations&&(this.startLoc=this.curPosition()),this.pos>=this.input.length?this.finishToken(y.eof):t.override?t.override(this):void this.readToken(this.fullCharCodeAtPos())},bt.readToken=function(t){return u(t,this.options.ecmaVersion>=6)||92===t?this.readWord():this.getTokenFromCode(t)},bt.fullCharCodeAtPos=function(){var t=this.input.charCodeAt(this.pos);return t<=55295||t>=57344?t:(t<<10)+this.input.charCodeAt(this.pos+1)-56613888},bt.skipBlockComment=function(){var t,e=this.options.onComment&&this.curPosition(),i=this.pos,s=this.input.indexOf("*/",this.pos+=2);if(-1===s&&this.raise(this.pos-2,"Unterminated comment"),this.pos=s+2,this.options.locations)for(b.lastIndex=i;(t=b.exec(this.input))&&t.index8&&t<14||t>=5760&&C.test(String.fromCharCode(t))))break t;++this.pos}}},bt.finishToken=function(t,e){this.end=this.pos,this.options.locations&&(this.endLoc=this.curPosition());var i=this.type;this.type=t,this.value=e,this.updateContext(i)},bt.readToken_dot=function(){var t=this.input.charCodeAt(this.pos+1);if(t>=48&&t<=57)return this.readNumber(!0);var e=this.input.charCodeAt(this.pos+2);return this.options.ecmaVersion>=6&&46===t&&46===e?(this.pos+=3,this.finishToken(y.ellipsis)):(++this.pos,this.finishToken(y.dot))},bt.readToken_slash=function(){var t=this.input.charCodeAt(this.pos+1);return this.exprAllowed?(++this.pos,this.readRegexp()):61===t?this.finishOp(y.assign,2):this.finishOp(y.slash,1)},bt.readToken_mult_modulo_exp=function(t){var e=this.input.charCodeAt(this.pos+1),i=1,s=42===t?y.star:y.modulo;return this.options.ecmaVersion>=7&&42===t&&42===e&&(++i,s=y.starstar,e=this.input.charCodeAt(this.pos+2)),61===e?this.finishOp(y.assign,i+1):this.finishOp(s,i)},bt.readToken_pipe_amp=function(t){var e=this.input.charCodeAt(this.pos+1);return e===t?this.finishOp(124===t?y.logicalOR:y.logicalAND,2):61===e?this.finishOp(y.assign,2):this.finishOp(124===t?y.bitwiseOR:y.bitwiseAND,1)},bt.readToken_caret=function(){return 61===this.input.charCodeAt(this.pos+1)?this.finishOp(y.assign,2):this.finishOp(y.bitwiseXOR,1)},bt.readToken_plus_min=function(t){var e=this.input.charCodeAt(this.pos+1);return e===t?45!==e||this.inModule||62!==this.input.charCodeAt(this.pos+2)||0!==this.lastTokEnd&&!_.test(this.input.slice(this.lastTokEnd,this.pos))?this.finishOp(y.incDec,2):(this.skipLineComment(3),this.skipSpace(),this.nextToken()):61===e?this.finishOp(y.assign,2):this.finishOp(y.plusMin,1)},bt.readToken_lt_gt=function(t){var e=this.input.charCodeAt(this.pos+1),i=1;return e===t?(i=62===t&&62===this.input.charCodeAt(this.pos+2)?3:2,61===this.input.charCodeAt(this.pos+i)?this.finishOp(y.assign,i+1):this.finishOp(y.bitShift,i)):33!==e||60!==t||this.inModule||45!==this.input.charCodeAt(this.pos+2)||45!==this.input.charCodeAt(this.pos+3)?(61===e&&(i=2),this.finishOp(y.relational,i)):(this.skipLineComment(4),this.skipSpace(),this.nextToken())},bt.readToken_eq_excl=function(t){var e=this.input.charCodeAt(this.pos+1);return 61===e?this.finishOp(y.equality,61===this.input.charCodeAt(this.pos+2)?3:2):61===t&&62===e&&this.options.ecmaVersion>=6?(this.pos+=2,this.finishToken(y.arrow)):this.finishOp(61===t?y.eq:y.prefix,1)},bt.getTokenFromCode=function(t){switch(t){case 46:return this.readToken_dot();case 40:return++this.pos,this.finishToken(y.parenL);case 41:return++this.pos,this.finishToken(y.parenR);case 59:return++this.pos,this.finishToken(y.semi);case 44:return++this.pos,this.finishToken(y.comma);case 91:return++this.pos,this.finishToken(y.bracketL);case 93:return++this.pos,this.finishToken(y.bracketR);case 123:return++this.pos,this.finishToken(y.braceL);case 125:return++this.pos,this.finishToken(y.braceR);case 58:return++this.pos,this.finishToken(y.colon);case 63:return++this.pos,this.finishToken(y.question);case 96:if(this.options.ecmaVersion<6)break;return++this.pos,this.finishToken(y.backQuote);case 48:var e=this.input.charCodeAt(this.pos+1);if(120===e||88===e)return this.readRadixNumber(16);if(this.options.ecmaVersion>=6){if(111===e||79===e)return this.readRadixNumber(8);if(98===e||66===e)return this.readRadixNumber(2)}case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return this.readNumber(!1);case 34:case 39:return this.readString(t);case 47:return this.readToken_slash();case 37:case 42:return this.readToken_mult_modulo_exp(t);case 124:case 38:return this.readToken_pipe_amp(t);case 94:return this.readToken_caret();case 43:case 45:return this.readToken_plus_min(t);case 60:case 62:return this.readToken_lt_gt(t);case 61:case 33:return this.readToken_eq_excl(t);case 126:return this.finishOp(y.prefix,1)}this.raise(this.pos,"Unexpected character '"+kt(t)+"'")},bt.finishOp=function(t,e){var i=this.input.slice(this.pos,this.pos+e);return this.pos+=e,this.finishToken(t,i)},bt.readRegexp=function(){for(var t,e,i=this.pos;;){this.pos>=this.input.length&&this.raise(i,"Unterminated regular expression");var s=this.input.charAt(this.pos);if(_.test(s)&&this.raise(i,"Unterminated regular expression"),t)t=!1;else{if("["===s)e=!0;else if("]"===s&&e)e=!1;else if("/"===s&&!e)break;t="\\"===s}++this.pos}var r=this.input.slice(i,this.pos);++this.pos;var a=this.pos,n=this.readWord1();this.containsEsc&&this.unexpected(a);var o=this.regexpState||(this.regexpState=new nt(this));o.reset(i,r,n),this.validateRegExpFlags(o),this.validateRegExpPattern(o);var h=null;try{h=new RegExp(r,n)}catch(p){}return this.finishToken(y.regexp,{pattern:r,flags:n,value:h})},bt.readInt=function(t,e){for(var i=this.pos,s=0,r=0,a=null==e?1/0:e;r=97?n-97+10:n>=65?n-65+10:n>=48&&n<=57?n-48:1/0)>=t)break;++this.pos,s=s*t+o}return this.pos===i||null!=e&&this.pos-i!==e?null:s},bt.readRadixNumber=function(t){this.pos+=2;var e=this.readInt(t);return null==e&&this.raise(this.start+2,"Expected number in radix "+t),u(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(y.num,e)},bt.readNumber=function(t){var e=this.pos;t||null!==this.readInt(10)||this.raise(e,"Invalid number");var i=this.pos-e>=2&&48===this.input.charCodeAt(e);i&&this.strict&&this.raise(e,"Invalid number"),i&&/[89]/.test(this.input.slice(e,this.pos))&&(i=!1);var s=this.input.charCodeAt(this.pos);46!==s||i||(++this.pos,this.readInt(10),s=this.input.charCodeAt(this.pos)),69!==s&&101!==s||i||(43!==(s=this.input.charCodeAt(++this.pos))&&45!==s||++this.pos,null===this.readInt(10)&&this.raise(e,"Invalid number")),u(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number");var r=this.input.slice(e,this.pos),a=i?parseInt(r,8):parseFloat(r);return this.finishToken(y.num,a)},bt.readCodePoint=function(){var t;if(123===this.input.charCodeAt(this.pos)){this.options.ecmaVersion<6&&this.unexpected();var e=++this.pos;t=this.readHexChar(this.input.indexOf("}",this.pos)-this.pos),++this.pos,t>1114111&&this.invalidStringToken(e,"Code point out of bounds")}else t=this.readHexChar(4);return t},bt.readString=function(t){for(var e="",i=++this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated string constant");var s=this.input.charCodeAt(this.pos);if(s===t)break;92===s?(e+=this.input.slice(i,this.pos),e+=this.readEscapedChar(!1),i=this.pos):(k(s,this.options.ecmaVersion>=10)&&this.raise(this.start,"Unterminated string constant"),++this.pos)}return e+=this.input.slice(i,this.pos++),this.finishToken(y.string,e)};var Ct={};bt.tryReadTemplateToken=function(){this.inTemplateElement=!0;try{this.readTmplToken()}catch(t){if(t!==Ct)throw t;this.readInvalidTemplateToken()}this.inTemplateElement=!1},bt.invalidStringToken=function(t,e){if(this.inTemplateElement&&this.options.ecmaVersion>=9)throw Ct;this.raise(t,e)},bt.readTmplToken=function(){for(var t="",e=this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated template");var i=this.input.charCodeAt(this.pos);if(96===i||36===i&&123===this.input.charCodeAt(this.pos+1))return this.pos!==this.start||this.type!==y.template&&this.type!==y.invalidTemplate?(t+=this.input.slice(e,this.pos),this.finishToken(y.template,t)):36===i?(this.pos+=2,this.finishToken(y.dollarBraceL)):(++this.pos,this.finishToken(y.backQuote));if(92===i)t+=this.input.slice(e,this.pos),t+=this.readEscapedChar(!0),e=this.pos;else if(k(i)){switch(t+=this.input.slice(e,this.pos),++this.pos,i){case 13:10===this.input.charCodeAt(this.pos)&&++this.pos;case 10:t+="\n";break;default:t+=String.fromCharCode(i)}this.options.locations&&(++this.curLine,this.lineStart=this.pos),e=this.pos}else++this.pos}},bt.readInvalidTemplateToken=function(){for(;this.pos=48&&e<=55){var i=this.input.substr(this.pos-1,3).match(/^[0-7]+/)[0],s=parseInt(i,8);return s>255&&(i=i.slice(0,-1),s=parseInt(i,8)),this.pos+=i.length-1,e=this.input.charCodeAt(this.pos),"0"===i&&56!==e&&57!==e||!this.strict&&!t||this.invalidStringToken(this.pos-1-i.length,t?"Octal literal in template string":"Octal literal in strict mode"),String.fromCharCode(s)}return String.fromCharCode(e)}},bt.readHexChar=function(t){var e=this.pos,i=this.readInt(16,t);return null===i&&this.invalidStringToken(e,"Bad character escape sequence"),i},bt.readWord1=function(){this.containsEsc=!1;for(var t="",e=!0,i=this.pos,s=this.options.ecmaVersion>=6;this.pos1)for(var n=1;n0||u+r0?[["dictionary",i.definitions],r]:r},deserialize:function(t,e,n,i,r){var s=t,o=!n,h=o&&t&&t.length&&"dictionary"===t[0][0];if(n=n||{},Array.isArray(t)){var u=t[0],l="dictionary"===u;if(1==t.length&&/^#/.test(u))return n.dictionary[u];s=[];for(var c=(u=a.exports[u])?1:0,f=t.length;ct.length&&(i=t.length);for(var h=0;h0){var s=e[r],a=s&&s[i];a&&a.call(this,r)}},statics:{inject:function t(e){var n=e._events;if(n){var i={};a.each(n,function(t,n){var r="string"==typeof t,s=r?t:n,o=a.capitalize(s),h=s.substring(2).toLowerCase();i[h]=r?{}:t,s="_"+s,e["get"+o]=function(){return this[s]},e["set"+o]=function(t){var e=this[s];e&&this.off(h,e),t&&this.on(h,t),this[s]=t}}),e._eventTypes=i}return t.base.apply(this,arguments)}}},h=a.extend({_class:"PaperScope",initialize:function t(){at=this,this.settings=new a({applyMatrix:!0,insertItems:!0,handleSize:4,hitTolerance:0}),this.project=null,this.projects=[],this.tools=[],this._id=t._id++,t._scopes[this._id]=this;var n=t.prototype;if(!this.support){var i=nt.getContext(1,1)||{};n.support={nativeDash:"setLineDash"in i||"mozDash"in i,nativeBlendModes:it.nativeModes},nt.release(i)}if(!this.agent){var r=e.navigator.userAgent.toLowerCase(),s=(/(darwin|win|mac|linux|freebsd|sunos)/.exec(r)||[])[0],o="darwin"===s?"mac":s,h=n.agent=n.browser={platform:o};o&&(h[o]=!0),r.replace(/(opera|chrome|safari|webkit|firefox|msie|trident|atom|node)\/?\s*([.\d]+)(?:.*version\/([.\d]+))?(?:.*rv\:v?([.\d]+))?/g,function(t,e,n,i,r){if(!h.chrome){var s="opera"===e?i:/^(node|trident)$/.test(e)?r:n;h.version=s,h.versionNumber=parseFloat(s),e="trident"===e?"msie":e,h.name=e,h[e]=!0}}),h.chrome&&delete h.webkit,h.atom&&delete h.chrome}},version:"0.11.8",getView:function(){var t=this.project;return t&&t._view},getPaper:function(){return this},execute:function(t,e){var n=at.PaperScript.execute(t,this,e);return $.updateFocus(),n},install:function(t){var e=this;for(var n in a.each(["project","view","tool"],function(n){a.define(t,n,{configurable:!0,get:function(){return e[n]}})}),this)!/^_/.test(n)&&this[n]&&(t[n]=this[n])},setup:function(t){return at=this,this.project=new x(t),this},createCanvas:function(t,e){return nt.getCanvas(t,e)},activate:function(){at=this},clear:function(){for(var t=this.projects,e=this.tools,n=t.length-1;n>=0;n--)t[n].remove();for(n=e.length-1;n>=0;n--)e[n].remove()},remove:function(){this.clear(),delete h._scopes[this._id]},statics:new function(){function t(t){return t+="Attribute",function(e,n){return e[t](n)||e[t]("data-paper-"+n)}}return{_scopes:{},_id:0,get:function(t){return this._scopes[t]||null},getAttribute:t("get"),hasAttribute:t("has")}}}),u=a.extend(o,{initialize:function(t){this._scope=at,this._index=this._scope[this._list].push(this)-1,!t&&this._scope[this._reference]||this.activate()},activate:function(){if(!this._scope)return!1;var t=this._scope[this._reference];return t&&t!==this&&t.emit("deactivate"),this._scope[this._reference]=this,this.emit("activate",t),!0},isActive:function(){return this._scope[this._reference]===this},remove:function(){return null!=this._index&&(a.splice(this._scope[this._list],null,this._index,1),this._scope[this._reference]==this&&(this._scope[this._reference]=null),this._scope=null,!0)},getView:function(){return this._scope.getView()}}),l=a.extend({initialize:function(t){this.precision=a.pick(t,5),this.multiplier=Math.pow(10,this.precision)},number:function(t){return this.precision<16?Math.round(t*this.multiplier)/this.multiplier:t},pair:function(t,e,n){return this.number(t)+(n||",")+this.number(e)},point:function(t,e){return this.number(t.x)+(e||",")+this.number(t.y)},size:function(t,e){return this.number(t.width)+(e||",")+this.number(t.height)},rectangle:function(t,e){return this.point(t,e)+(e||",")+this.size(t,e)}});l.instance=new l;var c=new function(){var t=[[.5773502691896257],[0,.7745966692414834],[.33998104358485626,.8611363115940526],[0,.5384693101056831,.906179845938664],[.2386191860831969,.6612093864662645,.932469514203152],[0,.4058451513773972,.7415311855993945,.9491079123427585],[.1834346424956498,.525532409916329,.7966664774136267,.9602898564975363],[0,.3242534234038089,.6133714327005904,.8360311073266358,.9681602395076261],[.14887433898163122,.4333953941292472,.6794095682990244,.8650633666889845,.9739065285171717],[0,.26954315595234496,.5190961292068118,.7301520055740494,.8870625997680953,.978228658146057],[.1252334085114689,.3678314989981802,.5873179542866175,.7699026741943047,.9041172563704749,.9815606342467192],[0,.2304583159551348,.44849275103644687,.6423493394403402,.8015780907333099,.9175983992229779,.9841830547185881],[.10805494870734367,.31911236892788974,.5152486363581541,.6872929048116855,.827201315069765,.9284348836635735,.9862838086968123],[0,.20119409399743451,.3941513470775634,.5709721726085388,.7244177313601701,.8482065834104272,.937273392400706,.9879925180204854],[.09501250983763744,.2816035507792589,.45801677765722737,.6178762444026438,.755404408355003,.8656312023878318,.9445750230732326,.9894009349916499]],e=[[1],[.8888888888888888,.5555555555555556],[.6521451548625461,.34785484513745385],[.5688888888888889,.47862867049936647,.23692688505618908],[.46791393457269104,.3607615730481386,.17132449237917036],[.4179591836734694,.3818300505051189,.27970539148927664,.1294849661688697],[.362683783378362,.31370664587788727,.22238103445337448,.10122853629037626],[.3302393550012598,.31234707704000286,.26061069640293544,.1806481606948574,.08127438836157441],[.29552422471475287,.26926671930999635,.21908636251598204,.1494513491505806,.06667134430868814],[.2729250867779006,.26280454451024665,.23319376459199048,.18629021092773426,.1255803694649046,.05566856711617366],[.24914704581340277,.2334925365383548,.20316742672306592,.16007832854334622,.10693932599531843,.04717533638651183],[.2325515532308739,.22628318026289723,.2078160475368885,.17814598076194574,.13887351021978725,.09212149983772845,.04048400476531588],[.2152638534631578,.2051984637212956,.18553839747793782,.15720316715819355,.12151857068790319,.08015808715976021,.03511946033175186],[.2025782419255613,.19843148532711158,.1861610000155622,.16626920581699392,.13957067792615432,.10715922046717194,.07036604748810812,.03075324199611727],[.1894506104550685,.18260341504492358,.16915651939500254,.14959598881657674,.12462897125553388,.09515851168249279,.062253523938647894,.027152459411754096]],n=Math.abs,i=Math.sqrt,r=Math.pow,s=Math.log2||function(t){return Math.log(t)*Math.LOG2E};function a(t,e,n){return tn?n:t}function o(t,e,i){function r(t){var e=134217729*t,n=t-e+e;return[n,t-n]}var s=e*e-t*i,a=e*e+t*i;if(3*n(s)1e8)?r(2,-Math.round(s(t))):0}return{EPSILON:1e-12,MACHINE_EPSILON:1.12e-16,CURVETIME_EPSILON:1e-8,GEOMETRIC_EPSILON:1e-7,TRIGONOMETRIC_EPSILON:1e-8,KAPPA:4*(i(2)-1)/3,isZero:function(t){return t>=-1e-12&&t<=1e-12},clamp:a,integrate:function(n,i,r,s){for(var a=t[s-2],o=e[s-2],h=.5*(r-i),u=h+i,l=0,c=s+1>>1,f=1&s?o[l++]*n(u):0;l0?(s=i,i=f<=r?.5*(r+s):f):(r=i,i=f>=s?.5*(r+s):f)}return a(i,r,s)},solveQuadratic:function(t,e,r,s,u,l){var c,f=1/0;if(n(t)<1e-12){if(n(e)<1e-12)return n(r)<1e-12?-1:0;c=-r/e}else{var d=o(t,e*=-.5,r);if(d&&n(d)<1.12e-16){var _=h(n(t),n(e),n(r));_&&(d=o(t*=_,e*=_,r*=_))}if(d>=-1.12e-16){var g=d<0?0:i(d),v=e+(e<0?-g:g);0===v?f=-(c=r/t):(c=v/t,f=r/v)}}var p=0,m=null==u,y=u-1e-12,w=l+1e-12;return isFinite(c)&&(m||c>y&&cy&&f0?1.324717957244746*Math.max(x,i(C)):x,k=d-b*S;if(k!==d){do{y(k),k=0===v?d:d-p/v/(1+1.12e-16)}while(b*k>b*d);n(t)*d*d>n(o/d)&&(_=((g=-o/d)-s)/d)}}var I=c.solveQuadratic(t,_,g,u,l,f),P=null==l;return isFinite(d)&&(0===I||I>0&&d!==u[0]&&d!==u[1])&&(P||d>l-1e-12&&d1?o[1]:o[0])):"x"in o?this._set(o.x||0,o.y||0):"width"in o?this._set(o.width||0,o.height||0):"angle"in o?(this._set(o.length||0,0),this.setAngle(o.angle||0)):(this._set(0,0),s=0)}return r&&(this.__read=s),this},set:"#initialize",_set:function(t,e){return this.x=t,this.y=e,this},equals:function(t){return this===t||t&&(this.x===t.x&&this.y===t.y||Array.isArray(t)&&this.x===t[0]&&this.y===t[1])||!1},clone:function(){return new d(this.x,this.y)},toString:function(){var t=l.instance;return"{ x: "+t.number(this.x)+", y: "+t.number(this.y)+" }"},_serialize:function(t){var e=t.formatter;return[e.number(this.x),e.number(this.y)]},getLength:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},setLength:function(t){if(this.isZero()){var e=this._angle||0;this._set(Math.cos(e)*t,Math.sin(e)*t)}else{var n=t/this.getLength();c.isZero(n)&&this.getAngle(),this._set(this.x*n,this.y*n)}},getAngle:function(){return 180*this.getAngleInRadians.apply(this,arguments)/Math.PI},setAngle:function(t){this.setAngleInRadians.call(this,t*Math.PI/180)},getAngleInDegrees:"#getAngle",setAngleInDegrees:"#setAngle",getAngleInRadians:function(){if(arguments.length){var t=d.read(arguments),e=this.getLength()*t.getLength();if(c.isZero(e))return NaN;var n=this.dot(t)/e;return Math.acos(n<-1?-1:n>1?1:n)}return this.isZero()?this._angle||0:this._angle=Math.atan2(this.y,this.x)},setAngleInRadians:function(t){if(this._angle=t,!this.isZero()){var e=this.getLength();this._set(Math.cos(t)*e,Math.sin(t)*e)}},getQuadrant:function(){return this.x>=0?this.y>=0?1:4:this.y>=0?2:3}},{beans:!1,getDirectedAngle:function(){var t=d.read(arguments);return 180*Math.atan2(this.cross(t),this.dot(t))/Math.PI},getDistance:function(){var t=d.read(arguments),e=t.x-this.x,n=t.y-this.y,i=e*e+n*n;return a.read(arguments)?i:Math.sqrt(i)},normalize:function(t){t===n&&(t=1);var e=this.getLength(),i=0!==e?t/e:0,r=new d(this.x*i,this.y*i);return i>=0&&(r._angle=this._angle),r},rotate:function(t,e){if(0===t)return this.clone();t=t*Math.PI/180;var n=e?this.subtract(e):this,i=Math.sin(t),r=Math.cos(t);return n=new d(n.x*r-n.y*i,n.x*i+n.y*r),e?n.add(e):n},transform:function(t){return t?t._transformPoint(this):this},add:function(){var t=d.read(arguments);return new d(this.x+t.x,this.y+t.y)},subtract:function(){var t=d.read(arguments);return new d(this.x-t.x,this.y-t.y)},multiply:function(){var t=d.read(arguments);return new d(this.x*t.x,this.y*t.y)},divide:function(){var t=d.read(arguments);return new d(this.x/t.x,this.y/t.y)},modulo:function(){var t=d.read(arguments);return new d(this.x%t.x,this.y%t.y)},negate:function(){return new d(-this.x,-this.y)},isInside:function(){return p.read(arguments).contains(this)},isClose:function(){var t=d.read(arguments),e=a.read(arguments);return this.getDistance(t)<=e},isCollinear:function(){var t=d.read(arguments);return d.isCollinear(this.x,this.y,t.x,t.y)},isColinear:"#isCollinear",isOrthogonal:function(){var t=d.read(arguments);return d.isOrthogonal(this.x,this.y,t.x,t.y)},isZero:function(){var t=c.isZero;return t(this.x)&&t(this.y)},isNaN:function(){return isNaN(this.x)||isNaN(this.y)},isInQuadrant:function(t){return this.x*(t>1&&t<4?-1:1)>=0&&this.y*(t>2?-1:1)>=0},dot:function(){var t=d.read(arguments);return this.x*t.x+this.y*t.y},cross:function(){var t=d.read(arguments);return this.x*t.y-this.y*t.x},project:function(){var t=d.read(arguments),e=t.isZero()?0:this.dot(t)/t.dot(t);return new d(t.x*e,t.y*e)},statics:{min:function(){var t=d.read(arguments),e=d.read(arguments);return new d(Math.min(t.x,e.x),Math.min(t.y,e.y))},max:function(){var t=d.read(arguments),e=d.read(arguments);return new d(Math.max(t.x,e.x),Math.max(t.y,e.y))},random:function(){return new d(Math.random(),Math.random())},isCollinear:function(t,e,n,i){return Math.abs(t*i-e*n)<=1e-8*Math.sqrt((t*t+e*e)*(n*n+i*i))},isOrthogonal:function(t,e,n,i){return Math.abs(t*n+e*i)<=1e-8*Math.sqrt((t*t+e*e)*(n*n+i*i))}}},a.each(["round","ceil","floor","abs"],function(t){var e=Math[t];this[t]=function(){return new d(e(this.x),e(this.y))}},{})),_=d.extend({initialize:function(t,e,n,i){this._x=t,this._y=e,this._owner=n,this._setter=i},_set:function(t,e,n){return this._x=t,this._y=e,n||this._owner[this._setter](this),this},getX:function(){return this._x},setX:function(t){this._x=t,this._owner[this._setter](this)},getY:function(){return this._y},setY:function(t){this._y=t,this._owner[this._setter](this)},isSelected:function(){return!!(this._owner._selection&this._getSelection())},setSelected:function(t){this._owner._changeSelection(this._getSelection(),t)},_getSelection:function(){return"setPosition"===this._setter?4:0}}),g=a.extend({_class:"Size",_readIndex:!0,initialize:function(t,e){var n=i(t),r=this.__read,s=0;if("number"===n){var a="number"==typeof e;this._set(t,a?e:t),r&&(s=a?2:1)}else if("undefined"===n||null===t)this._set(0,0),r&&(s=null===t?1:0);else{var o="string"===n?t.split(/[\s,]+/)||[]:t;s=1,Array.isArray(o)?this._set(+o[0],+(o.length>1?o[1]:o[0])):"width"in o?this._set(o.width||0,o.height||0):"x"in o?this._set(o.x||0,o.y||0):(this._set(0,0),s=0)}return r&&(this.__read=s),this},set:"#initialize",_set:function(t,e){return this.width=t,this.height=e,this},equals:function(t){return t===this||t&&(this.width===t.width&&this.height===t.height||Array.isArray(t)&&this.width===t[0]&&this.height===t[1])||!1},clone:function(){return new g(this.width,this.height)},toString:function(){var t=l.instance;return"{ width: "+t.number(this.width)+", height: "+t.number(this.height)+" }"},_serialize:function(t){var e=t.formatter;return[e.number(this.width),e.number(this.height)]},add:function(){var t=g.read(arguments);return new g(this.width+t.width,this.height+t.height)},subtract:function(){var t=g.read(arguments);return new g(this.width-t.width,this.height-t.height)},multiply:function(){var t=g.read(arguments);return new g(this.width*t.width,this.height*t.height)},divide:function(){var t=g.read(arguments);return new g(this.width/t.width,this.height/t.height)},modulo:function(){var t=g.read(arguments);return new g(this.width%t.width,this.height%t.height)},negate:function(){return new g(-this.width,-this.height)},isZero:function(){var t=c.isZero;return t(this.width)&&t(this.height)},isNaN:function(){return isNaN(this.width)||isNaN(this.height)},statics:{min:function(t,e){return new g(Math.min(t.width,e.width),Math.min(t.height,e.height))},max:function(t,e){return new g(Math.max(t.width,e.width),Math.max(t.height,e.height))},random:function(){return new g(Math.random(),Math.random())}}},a.each(["round","ceil","floor","abs"],function(t){var e=Math[t];this[t]=function(){return new g(e(this.width),e(this.height))}},{})),v=g.extend({initialize:function(t,e,n,i){this._width=t,this._height=e,this._owner=n,this._setter=i},_set:function(t,e,n){return this._width=t,this._height=e,n||this._owner[this._setter](this),this},getWidth:function(){return this._width},setWidth:function(t){this._width=t,this._owner[this._setter](this)},getHeight:function(){return this._height},setHeight:function(t){this._height=t,this._owner[this._setter](this)}}),p=a.extend({_class:"Rectangle",_readIndex:!0,beans:!0,initialize:function(t,e,r,s){var o,h=i(t);if("number"===h?(this._set(t,e,r,s),o=4):"undefined"===h||null===t?(this._set(0,0,0,0),o=null===t?1:0):1===arguments.length&&(Array.isArray(t)?(this._set.apply(this,t),o=1):t.x!==n||t.width!==n?(this._set(t.x||0,t.y||0,t.width||0,t.height||0),o=1):t.from===n&&t.to===n&&(this._set(0,0,0,0),a.filter(this,t),o=1)),o===n){var u,l,c=d.readNamed(arguments,"from"),f=a.peek(arguments),_=c.x,v=c.y;if(f&&f.x!==n||a.hasNamed(arguments,"to")){var p=d.readNamed(arguments,"to");u=p.x-_,l=p.y-v,u<0&&(_=p.x,u=-u),l<0&&(v=p.y,l=-l)}else{var m=g.read(arguments);u=m.width,l=m.height}this._set(_,v,u,l),o=arguments.__index;var y=arguments.__filtered;y&&(this.__filtered=y)}return this.__read&&(this.__read=o),this},set:"#initialize",_set:function(t,e,n,i){return this.x=t,this.y=e,this.width=n,this.height=i,this},clone:function(){return new p(this.x,this.y,this.width,this.height)},equals:function(t){var e=a.isPlainValue(t)?p.read(arguments):t;return e===this||e&&this.x===e.x&&this.y===e.y&&this.width===e.width&&this.height===e.height||!1},toString:function(){var t=l.instance;return"{ x: "+t.number(this.x)+", y: "+t.number(this.y)+", width: "+t.number(this.width)+", height: "+t.number(this.height)+" }"},_serialize:function(t){var e=t.formatter;return[e.number(this.x),e.number(this.y),e.number(this.width),e.number(this.height)]},getPoint:function(t){return new(t?d:_)(this.x,this.y,this,"setPoint")},setPoint:function(){var t=d.read(arguments);this.x=t.x,this.y=t.y},getSize:function(t){return new(t?g:v)(this.width,this.height,this,"setSize")},_fw:1,_fh:1,setSize:function(){var t=g.read(arguments),e=this._sx,n=this._sy,i=t.width,r=t.height;e&&(this.x+=(this.width-i)*e),n&&(this.y+=(this.height-r)*n),this.width=i,this.height=r,this._fw=this._fh=1},getLeft:function(){return this.x},setLeft:function(t){if(!this._fw){var e=t-this.x;this.width-=.5===this._sx?2*e:e}this.x=t,this._sx=this._fw=0},getTop:function(){return this.y},setTop:function(t){if(!this._fh){var e=t-this.y;this.height-=.5===this._sy?2*e:e}this.y=t,this._sy=this._fh=0},getRight:function(){return this.x+this.width},setRight:function(t){if(!this._fw){var e=t-this.x;this.width=.5===this._sx?2*e:e}this.x=t-this.width,this._sx=1,this._fw=0},getBottom:function(){return this.y+this.height},setBottom:function(t){if(!this._fh){var e=t-this.y;this.height=.5===this._sy?2*e:e}this.y=t-this.height,this._sy=1,this._fh=0},getCenterX:function(){return this.x+this.width/2},setCenterX:function(t){this._fw||.5===this._sx?this.x=t-this.width/2:(this._sx&&(this.x+=2*(t-this.x)*this._sx),this.width=2*(t-this.x)),this._sx=.5,this._fw=0},getCenterY:function(){return this.y+this.height/2},setCenterY:function(t){this._fh||.5===this._sy?this.y=t-this.height/2:(this._sy&&(this.y+=2*(t-this.y)*this._sy),this.height=2*(t-this.y)),this._sy=.5,this._fh=0},getCenter:function(t){return new(t?d:_)(this.getCenterX(),this.getCenterY(),this,"setCenter")},setCenter:function(){var t=d.read(arguments);return this.setCenterX(t.x),this.setCenterY(t.y),this},getArea:function(){return this.width*this.height},isEmpty:function(){return 0===this.width||0===this.height},contains:function(t){return t&&t.width!==n||4===(Array.isArray(t)?t:arguments).length?this._containsRectangle(p.read(arguments)):this._containsPoint(d.read(arguments))},_containsPoint:function(t){var e=t.x,n=t.y;return e>=this.x&&n>=this.y&&e<=this.x+this.width&&n<=this.y+this.height},_containsRectangle:function(t){var e=t.x,n=t.y;return e>=this.x&&n>=this.y&&e+t.width<=this.x+this.width&&n+t.height<=this.y+this.height},intersects:function(){var t=p.read(arguments),e=a.read(arguments)||0;return t.x+t.width>this.x-e&&t.y+t.height>this.y-e&&t.x=4&&(t[1]+=i?"Y":"X");var r=t[i?0:1],s=t[i?1:0],a="get"+r,o="get"+s,h="set"+r,u="set"+s,l="set"+n;this["get"+n]=function(t){return new(t?d:_)(this[a](),this[o](),this,l)},this[l]=function(){var t=d.read(arguments);this[h](t.x),this[u](t.y)}},{beans:!0})),m=p.extend({initialize:function(t,e,n,i,r,s){this._set(t,e,n,i,!0),this._owner=r,this._setter=s},_set:function(t,e,n,i,r){return this._x=t,this._y=e,this._width=n,this._height=i,r||this._owner[this._setter](this),this}},new function(){var t=p.prototype;return a.each(["x","y","width","height"],function(t){var e=a.capitalize(t),n="_"+t;this["get"+e]=function(){return this[n]},this["set"+e]=function(t){this[n]=t,this._dontNotify||this._owner[this._setter](this)}},a.each(["Point","Size","Center","Left","Top","Right","Bottom","CenterX","CenterY","TopLeft","TopRight","BottomLeft","BottomRight","LeftCenter","TopCenter","RightCenter","BottomCenter"],function(e){var n="set"+e;this[n]=function(){this._dontNotify=!0,t[n].apply(this,arguments),this._dontNotify=!1,this._owner[this._setter](this)}},{isSelected:function(){return!!(2&this._owner._selection)},setSelected:function(t){var e=this._owner;e._changeSelection&&e._changeSelection(2,t)}}))}),y=a.extend({_class:"Matrix",initialize:function t(e,n){var i=arguments.length,r=!0;if(i>=6?this._set.apply(this,arguments):1===i||2===i?e instanceof t?this._set(e._a,e._b,e._c,e._d,e._tx,e._ty,n):Array.isArray(e)?this._set.apply(this,n?e.concat([n]):e):r=!1:i?r=!1:this.reset(),!r)throw new Error("Unsupported matrix parameters");return this},set:"#initialize",_set:function(t,e,n,i,r,s,a){return this._a=t,this._b=e,this._c=n,this._d=i,this._tx=r,this._ty=s,a||this._changed(),this},_serialize:function(t,e){return a.serialize(this.getValues(),t,!0,e)},_changed:function(){var t=this._owner;t&&(t._applyMatrix?t.transform(null,!0):t._changed(25))},clone:function(){return new y(this._a,this._b,this._c,this._d,this._tx,this._ty)},equals:function(t){return t===this||t&&this._a===t._a&&this._b===t._b&&this._c===t._c&&this._d===t._d&&this._tx===t._tx&&this._ty===t._ty},toString:function(){var t=l.instance;return"[["+[t.number(this._a),t.number(this._c),t.number(this._tx)].join(", ")+"], ["+[t.number(this._b),t.number(this._d),t.number(this._ty)].join(", ")+"]]"},reset:function(t){return this._a=this._d=1,this._b=this._c=this._tx=this._ty=0,t||this._changed(),this},apply:function(t,e){var n=this._owner;return!!n&&(n.transform(null,!0,a.pick(t,!0),e),this.isIdentity())},translate:function(){var t=d.read(arguments),e=t.x,n=t.y;return this._tx+=e*this._a+n*this._c,this._ty+=e*this._b+n*this._d,this._changed(),this},scale:function(){var t=d.read(arguments),e=d.read(arguments,0,{readNull:!0});return e&&this.translate(e),this._a*=t.x,this._b*=t.x,this._c*=t.y,this._d*=t.y,e&&this.translate(e.negate()),this._changed(),this},rotate:function(t){t*=Math.PI/180;var e=d.read(arguments,1),n=e.x,i=e.y,r=Math.cos(t),s=Math.sin(t),a=n-n*r+i*s,o=i-n*s-i*r,h=this._a,u=this._b,l=this._c,c=this._d;return this._a=r*h+s*l,this._b=r*u+s*c,this._c=-s*h+r*l,this._d=-s*u+r*c,this._tx+=a*h+o*l,this._ty+=a*u+o*c,this._changed(),this},shear:function(){var t=d.read(arguments),e=d.read(arguments,0,{readNull:!0});e&&this.translate(e);var n=this._a,i=this._b;return this._a+=t.y*this._c,this._b+=t.y*this._d,this._c+=t.x*n,this._d+=t.x*i,e&&this.translate(e.negate()),this._changed(),this},skew:function(){var t=d.read(arguments),e=d.read(arguments,0,{readNull:!0}),n=Math.PI/180,i=new d(Math.tan(t.x*n),Math.tan(t.y*n));return this.shear(i,e)},append:function(t,e){if(t){var n=this._a,i=this._b,r=this._c,s=this._d,a=t._a,o=t._c,h=t._b,u=t._d,l=t._tx,c=t._ty;this._a=a*n+h*r,this._c=o*n+u*r,this._b=a*i+h*s,this._d=o*i+u*s,this._tx+=l*n+c*r,this._ty+=l*i+c*s,e||this._changed()}return this},prepend:function(t,e){if(t){var n=this._a,i=this._b,r=this._c,s=this._d,a=this._tx,o=this._ty,h=t._a,u=t._c,l=t._b,c=t._d,f=t._tx,d=t._ty;this._a=h*n+u*i,this._c=h*r+u*s,this._b=l*n+c*i,this._d=l*r+c*s,this._tx=h*a+u*o+f,this._ty=l*a+c*o+d,e||this._changed()}return this},appended:function(t){return this.clone().append(t)},prepended:function(t){return this.clone().prepend(t)},invert:function(){var t=this._a,e=this._b,n=this._c,i=this._d,r=this._tx,s=this._ty,a=t*i-e*n,o=null;return a&&!isNaN(a)&&isFinite(r)&&isFinite(s)&&(this._a=i/a,this._b=-e/a,this._c=-n/a,this._d=t/a,this._tx=(n*s-i*r)/a,this._ty=(e*r-t*s)/a,o=this),o},inverted:function(){return this.clone().invert()},concatenate:"#append",preConcatenate:"#prepend",chain:"#appended",_shiftless:function(){return new y(this._a,this._b,this._c,this._d,0,0)},_orNullIfIdentity:function(){return this.isIdentity()?null:this},isIdentity:function(){return 1===this._a&&0===this._b&&0===this._c&&1===this._d&&0===this._tx&&0===this._ty},isInvertible:function(){var t=this._a*this._d-this._c*this._b;return t&&!isNaN(t)&&isFinite(this._tx)&&isFinite(this._ty)},isSingular:function(){return!this.isInvertible()},transform:function(t,e,n){return arguments.length<3?this._transformPoint(d.read(arguments)):this._transformCoordinates(t,e,n)},_transformPoint:function(t,e,n){var i=t.x,r=t.y;return e||(e=new d),e._set(i*this._a+r*this._c+this._tx,i*this._b+r*this._d+this._ty,n)},_transformCoordinates:function(t,e,n){for(var i=0,r=2*n;is[h]&&(s[h]=o)}return e||(e=new p),e._set(r[0],r[1],s[0]-r[0],s[1]-r[1],n)},inverseTransform:function(){return this._inverseTransform(d.read(arguments))},_inverseTransform:function(t,e,n){var i=this._a,r=this._b,s=this._c,a=this._d,o=this._tx,h=this._ty,u=i*a-r*s,l=null;if(u&&!isNaN(u)&&isFinite(o)&&isFinite(h)){var c=t.x-this._tx,f=t.y-this._ty;e||(e=new d),l=e._set((c*a-f*s)/u,(f*i-c*r)/u,n)}return l},decompose:function(){var t,e,n,i=this._a,r=this._b,s=this._c,a=this._d,o=i*a-r*s,h=Math.sqrt,u=Math.atan2,l=180/Math.PI;if(0!==i||0!==r){var c=h(i*i+r*r);t=Math.acos(i/c)*(r>0?1:-1),e=[c,o/c],n=[u(i*s+r*a,c*c),0]}else if(0!==s||0!==a){var f=h(s*s+a*a);t=Math.asin(s/f)*(a>0?1:-1),e=[o/f,f],n=[0,u(i*s+r*a,f*f)]}else t=0,n=e=[0,0];return{translation:this.getTranslation(),rotation:t*l,scaling:new d(e),skewing:new d(n[0]*l,n[1]*l)}},getValues:function(){return[this._a,this._b,this._c,this._d,this._tx,this._ty]},getTranslation:function(){return new d(this._tx,this._ty)},getScaling:function(){return(this.decompose()||{}).scaling},getRotation:function(){return(this.decompose()||{}).rotation},applyToContext:function(t){this.isIdentity()||t.transform(this._a,this._b,this._c,this._d,this._tx,this._ty)}},a.each(["a","b","c","d","tx","ty"],function(t){var e=a.capitalize(t),n="_"+t;this["get"+e]=function(){return this[n]},this["set"+e]=function(t){this[n]=t,this._changed()}},{})),w=a.extend({_class:"Line",initialize:function(t,e,n,i,r){var s=!1;arguments.length>=4?(this._px=t,this._py=e,this._vx=n,this._vy=i,s=r):(this._px=t.x,this._py=t.y,this._vx=e.x,this._vy=e.y,s=n),s||(this._vx-=this._px,this._vy-=this._py)},getPoint:function(){return new d(this._px,this._py)},getVector:function(){return new d(this._vx,this._vy)},getLength:function(){return this.getVector().getLength()},intersect:function(t,e){return w.intersect(this._px,this._py,this._vx,this._vy,t._px,t._py,t._vx,t._vy,!0,e)},getSide:function(t,e){return w.getSide(this._px,this._py,this._vx,this._vy,t.x,t.y,!0,e)},getDistance:function(t){return Math.abs(this.getSignedDistance(t))},getSignedDistance:function(t){return w.getSignedDistance(this._px,this._py,this._vx,this._vy,t.x,t.y,!0)},isCollinear:function(t){return d.isCollinear(this._vx,this._vy,t._vx,t._vy)},isOrthogonal:function(t){return d.isOrthogonal(this._vx,this._vy,t._vx,t._vy)},statics:{intersect:function(t,e,n,i,r,s,a,o,h,u){h||(n-=t,i-=e,a-=r,o-=s);var l=n*o-i*a;if(!c.isZero(l)){var f=t-r,_=e-s,g=(a*_-o*f)/l,v=(n*_-i*f)/l;if(u||-1e-12=1?1:g),new d(t+g*n,e+g*i)}},getSide:function(t,e,n,i,r,s,a,o){a||(n-=t,i-=e);var h=r-t,u=h*i-(s-e)*n;return!o&&c.isZero(u)&&(u=(h*n+h*n)/(n*n+i*i))>=0&&u<=1&&(u=0),u<0?-1:u>0?1:0},getSignedDistance:function(t,e,n,i,r,s,a){return a||(n-=t,i-=e),0===n?i>0?r-t:t-r:0===i?n<0?s-e:e-s:((r-t)*i-(s-e)*n)/Math.sqrt(n*n+i*i)},getDistance:function(t,e,n,i,r,s,a){return Math.abs(w.getSignedDistance(t,e,n,i,r,s,a))}}}),x=u.extend({_class:"Project",_list:"projects",_reference:"project",_compactSerialize:!0,initialize:function(t){u.call(this,!0),this._children=[],this._namedChildren={},this._activeLayer=null,this._currentStyle=new H(null,null,this),this._view=$.create(this,t||nt.getCanvas(1,1)),this._selectionItems={},this._selectionCount=0,this._updateVersion=0},_serialize:function(t,e){return a.serialize(this._children,t,!0,e)},_changed:function(t,e){if(1&t){var n=this._view;n&&(n._needsUpdate=!0,!n._requested&&n._autoUpdate&&n.requestUpdate())}var i=this._changes;if(i&&e){var r=this._changesById,s=e._id,a=r[s];a?a.flags|=t:i.push(r[s]={item:e,flags:t})}},clear:function(){for(var t=this._children,e=t.length-1;e>=0;e--)t[e].remove()},isEmpty:function(){return!this._children.length},remove:function t(){return!!t.base.call(this)&&(this._view&&this._view.remove(),!0)},getView:function(){return this._view},getCurrentStyle:function(){return this._currentStyle},setCurrentStyle:function(t){this._currentStyle.set(t)},getIndex:function(){return this._index},getOptions:function(){return this._scope.settings},getLayers:function(){return this._children},getActiveLayer:function(){return this._activeLayer||new S({project:this,insert:!0})},getSymbolDefinitions:function(){var t=[],e={};return this.getItems({class:P,match:function(n){var i=n._definition,r=i._id;return e[r]||(e[r]=!0,t.push(i)),!1}}),t},getSymbols:"getSymbolDefinitions",getSelectedItems:function(){var t=this._selectionItems,e=[];for(var n in t){var i=t[n],r=i._selection;1&r&&i.isInserted()?e.push(i):r||this._updateSelection(i)}return e},_updateSelection:function(t){var e=t._id,n=this._selectionItems;t._selection?n[e]!==t&&(this._selectionCount++,n[e]=t):n[e]===t&&(this._selectionCount--,delete n[e])},selectAll:function(){for(var t=this._children,e=0,n=t.length;e0){t.save(),t.strokeWidth=1;var h=this._selectionItems,u=this._scope.settings.handleSize,l=this._updateVersion;for(var c in h)h[c]._drawSelection(t,e,u,h,l);t.restore()}}}),b=a.extend(o,{statics:{extend:function t(e){return e._serializeFields&&(e._serializeFields=a.set({},this.prototype._serializeFields,e._serializeFields)),t.base.apply(this,arguments)},NO_INSERT:{insert:!1}},_class:"Item",_name:null,_applyMatrix:!0,_canApplyMatrix:!0,_canScaleStroke:!1,_pivot:null,_visible:!0,_blendMode:"normal",_opacity:1,_locked:!1,_guide:!1,_clipMask:!1,_selection:0,_selectBounds:!0,_selectChildren:!1,_serializeFields:{name:null,applyMatrix:null,matrix:new y,pivot:null,visible:!0,blendMode:"normal",opacity:1,locked:!1,guide:!1,clipMask:!1,selected:!1,data:{}},_prioritize:["applyMatrix"]},new function(){var t=["onMouseDown","onMouseUp","onMouseDrag","onClick","onDoubleClick","onMouseMove","onMouseEnter","onMouseLeave"];return a.each(t,function(t){this._events[t]={install:function(t){this.getView()._countItemEvent(t,1)},uninstall:function(t){this.getView()._countItemEvent(t,-1)}}},{_events:{onFrame:{install:function(){this.getView()._animateItem(this,!0)},uninstall:function(){this.getView()._animateItem(this,!1)}},onLoad:{},onError:{}},statics:{_itemHandlers:t}})},{initialize:function(){},_initialize:function(t,e){var i=t&&a.isPlainObject(t),r=i&&!0===t.internal,s=this._matrix=new y,o=i&&t.project||at.project,h=at.settings;return this._id=r?null:f.get(),this._parent=this._index=null,this._applyMatrix=this._canApplyMatrix&&h.applyMatrix,e&&s.translate(e),s._owner=this,this._style=new H(o._currentStyle,this,o),r||i&&0==t.insert||!h.insertItems&&(!i||!0!==t.insert)?this._setProject(o):(i&&t.parent||o)._insertItem(n,this,!0),i&&t!==b.NO_INSERT&&this.set(t,{internal:!0,insert:!0,project:!0,parent:!0}),i},_serialize:function(t,e){var n={},i=this;function r(r){for(var s in r){var o=i[s];a.equals(o,"leading"===s?1.2*r.fontSize:r[s])||(n[s]=a.serialize(o,t,"data"!==s,e))}}return r(this._serializeFields),this instanceof C||r(this._style._defaults),[this._class,n]},_changed:function(t){var e=this._symbol,i=this._parent||e,r=this._project;8&t&&(this._bounds=this._position=this._decomposed=n),16&t&&(this._globalMatrix=n),i&&72&t&&b._clearBoundsCache(i),2&t&&b._clearBoundsCache(this),r&&r._changed(t,this),e&&e._changed(t)},getId:function(){return this._id},getName:function(){return this._name},setName:function(t){if(this._name&&this._removeNamed(),t===+t+"")throw new Error("Names consisting only of numbers are not supported.");var e=this._getOwner();if(t&&e){var i=e._children,r=e._namedChildren;(r[t]=r[t]||[]).push(this),t in i||(i[t]=this)}this._name=t||n,this._changed(256)},getStyle:function(){return this._style},setStyle:function(t){this.getStyle().set(t)}},a.each(["locked","visible","blendMode","opacity","guide"],function(t){var e=a.capitalize(t),n="_"+t,i={locked:256,visible:265};this["get"+e]=function(){return this[n]},this["set"+e]=function(e){e!=this[n]&&(this[n]=e,this._changed(i[t]||257))}},{}),{beans:!0,getSelection:function(){return this._selection},setSelection:function(t){if(t!==this._selection){this._selection=t;var e=this._project;e&&(e._updateSelection(this),this._changed(257))}},_changeSelection:function(t,e){var n=this._selection;this.setSelection(e?n|t:n&~t)},isSelected:function(){if(this._selectChildren)for(var t=this._children,e=0,n=t.length;e=0;n--)if(e[n].contains(t))return!0;return!1}return t.isInside(this.getInternalBounds())},isInside:function(){return p.read(arguments).contains(this.getBounds())},_asPathItem:function(){return new N.Rectangle({rectangle:this.getInternalBounds(),matrix:this._matrix,insert:!1})},intersects:function(t,e){return t instanceof b&&this._asPathItem().getIntersections(t._asPathItem(),null,e,!0).length>0}},new function(){function t(){return this._hitTest(d.read(arguments),T.getOptions(arguments))}function e(){var t=d.read(arguments),e=T.getOptions(arguments),n=[];return this._hitTest(t,a.set({all:n},e)),n}function n(t,e,n,i){var r=this._children;if(r)for(var s=r.length-1;s>=0;s--){var a=r[s],o=a!==i&&a._hitTest(t,e,n);if(o&&!e.all)return o}return null}return x.inject({hitTest:t,hitTestAll:e,_hitTest:n}),{hitTest:t,hitTestAll:e,_hitTestChildren:n}},{_hitTest:function(t,e,n){if(this._locked||!this._visible||this._guide&&!e.guides||this.isEmpty())return null;var i=this._matrix,r=n?n.appended(i):this.getGlobalMatrix().prepend(this.getView()._matrix),s=Math.max(e.tolerance,1e-12),o=e._tolerancePadding=new g(N._getStrokePadding(s,i._shiftless().invert()));if(!(t=i._inverseTransform(t))||!this._children&&!this.getBounds({internal:!0,stroke:!0,handle:!0}).expand(o.multiply(2))._containsPoint(t))return null;var h,u,l=!(e.guides&&!this._guide||e.selected&&!this.isSelected()||e.type&&e.type!==a.hyphenate(this._class)||e.class&&!(this instanceof e.class)),c=e.match,f=this;function d(t){return t&&c&&!c(t)&&(t=null),t&&e.all&&e.all.push(t),t}function _(e,n){var i=n?h["get"+n]():f.getPosition();if(t.subtract(i).divide(o).length<=1)return new T(e,f,{name:n?a.hyphenate(n):e,point:i})}var v=e.position,p=e.center,m=e.bounds;if(l&&this._parent&&(v||p||m)){if((p||m)&&(h=this.getInternalBounds()),!(u=v&&_("position")||p&&_("center","Center"))&&m)for(var y=["TopLeft","TopRight","BottomLeft","BottomRight","LeftCenter","TopCenter","RightCenter","BottomCenter"],w=0;w<8&&!u;w++)u=_("bounds",y[w]);u=d(u)}return u||(u=this._hitTestChildren(t,e,r)||l&&d(this._hitTestSelf(t,e,r,this.getStrokeScaling()?null:r._shiftless().invert()))||null),u&&u.point&&(u.point=i.transform(u.point)),u},_hitTestSelf:function(t,e){if(e.fill&&this.hasFill()&&this._contains(t))return new T("fill",this)},matches:function(t,e){var n=i(t);if("object"===n){for(var r in t)if(t.hasOwnProperty(r)&&!this.matches(r,t[r]))return!1;return!0}if("function"===n)return t(this);if("match"===t)return e(this);var s=/^(empty|editable)$/.test(t)?this["is"+a.capitalize(t)]():"type"===t?a.hyphenate(this._class):this[t];if("class"===t){if("function"==typeof e)return this instanceof e;s=this._class}if("function"==typeof e)return!!e(s);if(e){if(e.test)return e.test(s);if(a.isPlainObject(e))return function t(e,n){for(var i in e)if(e.hasOwnProperty(i)){var r=e[i],s=n[i];if(a.isPlainObject(r)&&a.isPlainObject(s)){if(!t(r,s))return!1}else if(!a.equals(r,s))return!1}return!0}(e,s)}return a.equals(s,e)},getItems:function(t){return b._getItems(this,t,this._matrix)},getItem:function(t){return b._getItems(this,t,this._matrix,null,!0)[0]||null},statics:{_getItems:function t(e,n,r,s,o){if(!s){var h="object"===i(n)&&n,u=h&&h.overlapping,l=h&&h.inside,c=(x=u||l)&&p.read([x]);s={items:[],recursive:h&&!1!==h.recursive,inside:!!l,overlapping:!!u,rect:c,path:u&&new N.Rectangle({rectangle:c,insert:!1})},h&&(n=a.filter({},n,{recursive:!0,inside:!0,overlapping:!0}))}var f=e._children,d=s.items;r=(c=s.rect)&&(r||new y);for(var _=0,g=f&&f.length;_0)break}return d}}},{importJSON:function(t){var e=a.importJSON(t,this);return e!==this?this.addChild(e):e},addChild:function(t){return this.insertChild(n,t)},insertChild:function(t,e){var n=e?this.insertChildren(t,[e]):null;return n&&n[0]},addChildren:function(t){return this.insertChildren(this._children.length,t)},insertChildren:function(t,e){var n=this._children;if(n&&e&&e.length>0){for(var i={},r=(e=a.slice(e)).length-1;r>=0;r--){var s=(l=e[r])&&l._id;!l||i[s]?e.splice(r,1):(l._remove(!1,!0),i[s]=!0)}a.splice(n,e,t,0);for(var o=this._project,h=o._changes,u=(r=0,e.length);r=0;i--)n[i]._remove(!0,!1);return n.length>0&&this._changed(11),n},clear:"#removeChildren",reverseChildren:function(){if(this._children){this._children.reverse();for(var t=0,e=this._children.length;t0},isInserted:function(){return!!this._parent&&this._parent.isInserted()},isAbove:function(t){return-1===this._getOrder(t)},isBelow:function(t){return 1===this._getOrder(t)},isParent:function(t){return this._parent===t},isChild:function(t){return t&&t._parent===this},isDescendant:function(t){for(var e=this;e=e._parent;)if(e===t)return!0;return!1},isAncestor:function(t){return!!t&&t.isDescendant(this)},isSibling:function(t){return this._parent===t._parent},isGroupedWith:function(t){for(var e=this._parent;e;){if(e._parent&&/^(Group|Layer|CompoundPath)$/.test(e._class)&&t.isDescendant(e))return!0;e=e._parent}return!1}},a.each(["rotate","scale","shear","skew"],function(t){var e="rotate"===t;this[t]=function(){var n=(e?a:d).read(arguments),i=d.read(arguments,0,{readNull:!0});return this.transform((new y)[t](n,i||this.getPosition(!0)))}},{translate:function(){var t=new y;return this.transform(t.translate.apply(t,arguments))},transform:function(t,e,n,i){var r=this._matrix,s=t&&!t.isIdentity(),a=(e||this._applyMatrix)&&(!r.isIdentity()||s||e&&n&&this._children);if(!s&&!a)return this;if(s){!t.isInvertible()&&r.isInvertible()&&(r._backup=r.getValues()),r.prepend(t,!0);var o=this._style,h=o.getFillColor(!0),u=o.getStrokeColor(!0);h&&h.transform(t),u&&u.transform(t)}if(a&&(a=this._transformContent(r,n,i))){var l=this._pivot;l&&r._transformPoint(l,l,!0),r.reset(!0),i&&this._canApplyMatrix&&(this._applyMatrix=!0)}var c=this._bounds,f=this._position;(s||a)&&this._changed(25);var d=s&&c&&t.decompose();if(d&&d.skewing.isZero()&&d.rotation%90==0){for(var _ in c){var g=c[_];if(g.nonscaling)delete c[_];else if(a||!g.internal){var v=g.rect;t._transformBounds(v,v)}}this._bounds=c;var p=c[this._getBoundsCacheKey(this._boundsOptions||{})];p&&(this._position=this._getPositionFromBounds(p.rect))}else s&&f&&this._pivot&&(this._position=t._transformPoint(f,f));return this},_transformContent:function(t,e,n){var i=this._children;if(i){for(var r=0,s=i.length;rr:i1&&s<4?-1:1,s>2?-1:1),o=a.multiply(r),h=o.subtract(a.multiply(i));if(new p(n?o.add(a.multiply(n)):o,h).contains(e))return{point:h,quadrant:s}}}function e(t,e,n,i){var r=t.divide(e);return(!i||r.isInQuadrant(i))&&r.subtract(r.normalize()).multiply(e).divide(n).length<=1}return{_contains:function e(n){if("rectangle"===this._type){var i=t(this,n);return i?n.subtract(i.point).divide(this._radius).getLength()<=1:e.base.call(this,n)}return n.divide(this.size).getLength()<=.5},_hitTestSelf:function n(i,r,s,a){var o=!1,h=this._style,u=r.stroke&&h.hasStroke(),l=r.fill&&h.hasFill();if(u||l){var c=this._type,f=this._radius,d=u?h.getStrokeWidth()/2:0,_=r._tolerancePadding.add(N._getStrokePadding(d,!h.getStrokeScaling()&&a));if("rectangle"===c){var g=_.multiply(2),v=t(this,i,g);if(v)o=e(i.subtract(v.point),f,_,v.quadrant);else{var m=new p(this._size).setCenter(0,0),y=m.expand(g),w=m.expand(g.negate());o=y._containsPoint(i)&&!w._containsPoint(i)}}else o=e(i,f,_)}return o?new T(u?"stroke":"fill",this):n.base.apply(this,arguments)}}},{statics:new function(){function t(t,e,n,i,r){var s=new k(a.getNamed(r),e);return s._type=t,s._size=n,s._radius=i,s}return{Circle:function(){var e=d.readNamed(arguments,"center"),n=a.readNamed(arguments,"radius");return t("circle",e,new g(2*n),n,arguments)},Rectangle:function(){var e=p.readNamed(arguments,"rectangle"),n=g.min(g.readNamed(arguments,"radius"),e.getSize(!0).divide(2));return t("rectangle",e.getCenter(!0),e.getSize(!0),n,arguments)},Ellipse:function(){var e=k._readEllipse(arguments),n=e.radius;return t("ellipse",e.center,n.multiply(2),n,arguments)},_readEllipse:function(t){var e,n;if(a.hasNamed(t,"radius"))e=d.readNamed(t,"center"),n=g.readNamed(t,"radius");else{var i=p.readNamed(t,"rectangle");e=i.getCenter(!0),n=i.getSize(!0).divide(2)}return{center:e,radius:n}}}}}),I=b.extend({_class:"Raster",_applyMatrix:!1,_canApplyMatrix:!1,_boundsOptions:{stroke:!1,handle:!1},_serializeFields:{crossOrigin:null,source:null},_prioritize:["crossOrigin"],_smoothing:!0,initialize:function(t,e){if(!this._initialize(t,e!==n&&d.read(arguments,1))){var i="string"==typeof t?s.getElementById(t):t;i?this.setImage(i):this.setSource(t)}this._size||(this._size=new g,this._loaded=!1)},_equals:function(t){return this.getSource()===t.getSource()},copyContent:function(t){var e=t._image,n=t._canvas;if(e)this._setImage(e);else if(n){var i=nt.getCanvas(t._size);i.getContext("2d").drawImage(n,0,0),this._setImage(i)}this._crossOrigin=t._crossOrigin},getSize:function(){var t=this._size;return new v(t?t.width:0,t?t.height:0,this,"setSize")},setSize:function(){var t=g.read(arguments);if(!t.equals(this._size))if(t.width>0&&t.height>0){var e=this.getElement();this._setImage(nt.getCanvas(t)),e&&this.getContext(!0).drawImage(e,0,0,t.width,t.height)}else this._canvas&&nt.release(this._canvas),this._size=t.clone()},getWidth:function(){return this._size?this._size.width:0},setWidth:function(t){this.setSize(t,this.getHeight())},getHeight:function(){return this._size?this._size.height:0},setHeight:function(t){this.setSize(this.getWidth(),t)},getLoaded:function(){return this._loaded},isEmpty:function(){var t=this._size;return!t||0===t.width&&0===t.height},getResolution:function(){var t=this._matrix,e=new d(0,0).transform(t),n=new d(1,0).transform(t).subtract(e),i=new d(0,1).transform(t).subtract(e);return new g(72/n.getLength(),72/i.getLength())},getPpi:"#getResolution",getImage:function(){return this._image},setImage:function(t){var e=this;function n(t){var n=e.getView(),i=t&&t.type||"load";n&&e.responds(i)&&(at=n._scope,e.emit(i,new J(t)))}this._setImage(t),this._loaded?setTimeout(n,0):t&&W.add(t,{load:function(i){e._setImage(t),n(i)},error:n})},_setImage:function(t){this._canvas&&nt.release(this._canvas),t&&t.getContext?(this._image=null,this._canvas=t,this._loaded=!0):(this._image=t,this._canvas=null,this._loaded=!!(t&&t.src&&t.complete)),this._size=new g(t?t.naturalWidth||t.width:0,t?t.naturalHeight||t.height:0),this._context=null,this._changed(1033)},getCanvas:function(){if(!this._canvas){var t=nt.getContext(this._size);try{this._image&&t.drawImage(this._image,0,0),this._canvas=t.canvas}catch(e){nt.release(t)}}return this._canvas},setCanvas:"#setImage",getContext:function(t){return this._context||(this._context=this.getCanvas().getContext("2d")),t&&(this._image=null,this._changed(1025)),this._context},setContext:function(t){this._context=t},getSource:function(){var t=this._image;return t&&t.src||this.toDataURL()},setSource:function(t){var n=new e.Image,i=this._crossOrigin;i&&(n.crossOrigin=i),n.src=t,this.setImage(n)},getCrossOrigin:function(){var t=this._image;return t&&t.crossOrigin||this._crossOrigin||""},setCrossOrigin:function(t){this._crossOrigin=t;var e=this._image;e&&(e.crossOrigin=t)},getSmoothing:function(){return this._smoothing},setSmoothing:function(t){this._smoothing=t,this._changed(257)},getElement:function(){return this._canvas||this._loaded&&this._image}},{beans:!1,getSubCanvas:function(){var t=p.read(arguments),e=nt.getContext(t.getSize());return e.drawImage(this.getCanvas(),t.x,t.y,t.width,t.height,0,0,t.width,t.height),e.canvas},getSubRaster:function(){var t=p.read(arguments),e=new I(b.NO_INSERT);return e._setImage(this.getSubCanvas(t)),e.translate(t.getCenter().subtract(this.getSize().divide(2))),e._matrix.prepend(this._matrix),e.insertAbove(this),e},toDataURL:function(){var t=this._image,e=t&&t.src;if(/^data:/.test(e))return e;var n=this.getCanvas();return n?n.toDataURL.apply(n,arguments):null},drawImage:function(t){var e=d.read(arguments,1);this.getContext(!0).drawImage(t,e.x,e.y)},getAverageColor:function(t){var e,n;if(t?t instanceof E?(n=t,e=t.getBounds()):"object"===i(t)&&("width"in t?e=new p(t):"x"in t&&(e=new p(t.x-.5,t.y-.5,1,1))):e=this.getBounds(),!e)return null;var r=Math.min(e.width,32),s=Math.min(e.height,32),o=I._sampleContext;o?o.clearRect(0,0,33,33):o=I._sampleContext=nt.getContext(new g(32)),o.save();var h=(new y).scale(r/e.width,s/e.height).translate(-e.x,-e.y);h.applyToContext(o),n&&n.draw(o,new a({clip:!0,matrices:[h]})),this._matrix.applyToContext(o);var u=this.getElement(),l=this._size;u&&o.drawImage(u,-l.width/2,-l.height/2),o.restore();for(var c=o.getImageData(.5,.5,Math.ceil(r),Math.ceil(s)).data,f=[0,0,0],d=0,_=0,v=c.length;_0&&(null==t||"object"===i(t)?1===f&&t&&"point"in t?(h=t.point,u=t.handleIn,l=t.handleOut,c=t.selection):(h=t,u=e,l=r,c=s):(h=[t,e],u=r!==n?[r,s]:null,l=a!==n?[a,o]:null)),new z(h,this,"_point"),new z(u,this,"_handleIn"),new z(l,this,"_handleOut"),c&&this.setSelection(c)},_serialize:function(t,e){var n=this._point,i=this._selection,r=i||this.hasHandles()?[n,this._handleIn,this._handleOut]:n;return i&&r.push(i),a.serialize(r,t,!0,e)},_changed:function(t){var e=this._path;if(e){var n,i=e._curves,r=this._index;i&&(t&&t!==this._point&&t!==this._handleIn||!(n=r>0?i[r-1]:e._closed?i[i.length-1]:null)||n._changed(),t&&t!==this._point&&t!==this._handleOut||!(n=i[r])||n._changed()),e._changed(41)}},getPoint:function(){return this._point},setPoint:function(){this._point.set(d.read(arguments))},getHandleIn:function(){return this._handleIn},setHandleIn:function(){this._handleIn.set(d.read(arguments))},getHandleOut:function(){return this._handleOut},setHandleOut:function(){this._handleOut.set(d.read(arguments))},hasHandles:function(){return!this._handleIn.isZero()||!this._handleOut.isZero()},isSmooth:function(){var t=this._handleIn,e=this._handleOut;return!t.isZero()&&!e.isZero()&&t.isCollinear(e)},clearHandles:function(){this._handleIn._set(0,0),this._handleOut._set(0,0)},getSelection:function(){return this._selection},setSelection:function(t){var e=this._selection,n=this._path;this._selection=t=t||0,n&&t!==e&&(n._updateSelection(this,e,t),n._changed(257))},_changeSelection:function(t,e){var n=this._selection;this.setSelection(e?n|t:n&~t)},isSelected:function(){return!!(7&this._selection)},setSelected:function(t){this._changeSelection(7,t)},getIndex:function(){return this._index!==n?this._index:null},getPath:function(){return this._path||null},getCurve:function(){var t=this._path,e=this._index;return t?(e>0&&!t._closed&&e===t._segments.length-1&&e--,t.getCurves()[e]||null):null},getLocation:function(){var t=this.getCurve();return t?new L(t,this===t._segment1?0:1):null},getNext:function(){var t=this._path&&this._path._segments;return t&&(t[this._index+1]||this._path._closed&&t[0])||null},smooth:function(t,e,i){var r=t||{},s=r.type,a=r.factor,o=this.getPrevious(),h=this.getNext(),u=(o||this)._point,l=this._point,c=(h||this)._point,f=u.getDistance(l),_=l.getDistance(c);if(s&&"catmull-rom"!==s){if("geometric"!==s)throw new Error("Smoothing method '"+s+"' not supported.");if(o&&h){var g=u.subtract(c),v=a===n?.4:a,p=v*f/(f+_);e||this.setHandleIn(g.multiply(p)),i||this.setHandleOut(g.multiply(p-v))}}else{var m=a===n?.5:a,y=Math.pow(f,m),w=y*y,x=Math.pow(_,m),b=x*x;if(!e&&o){var C=2*b+3*x*y+w,S=3*x*(x+y);this.setHandleIn(0!==S?new d((b*u._x+C*l._x-w*c._x)/S-l._x,(b*u._y+C*l._y-w*c._y)/S-l._y):new d)}if(!i&&h){C=2*w+3*y*x+b,S=3*y*(y+x);this.setHandleOut(0!==S?new d((w*c._x+C*l._x-b*u._x)/S-l._x,(w*c._y+C*l._y-b*u._y)/S-l._y):new d)}}},getPrevious:function(){var t=this._path&&this._path._segments;return t&&(t[this._index-1]||this._path._closed&&t[t.length-1])||null},isFirst:function(){return!this._index},isLast:function(){var t=this._path;return t&&this._index===t._segments.length-1||!1},reverse:function(){var t=this._handleIn,e=this._handleOut,n=t.clone();t.set(e),e.set(n)},reversed:function(){return new A(this._point,this._handleOut,this._handleIn)},remove:function(){return!!this._path&&!!this._path.removeSegment(this._index)},clone:function(){return new A(this._point,this._handleIn,this._handleOut)},equals:function(t){return t===this||t&&this._class===t._class&&this._point.equals(t._point)&&this._handleIn.equals(t._handleIn)&&this._handleOut.equals(t._handleOut)||!1},toString:function(){var t=["point: "+this._point];return this._handleIn.isZero()||t.push("handleIn: "+this._handleIn),this._handleOut.isZero()||t.push("handleOut: "+this._handleOut),"{ "+t.join(", ")+" }"},transform:function(t){this._transformCoordinates(t,new Array(6),!0),this._changed()},interpolate:function(t,e,n){var i=1-n,r=n,s=t._point,a=e._point,o=t._handleIn,h=e._handleIn,u=e._handleOut,l=t._handleOut;this._point._set(i*s._x+r*a._x,i*s._y+r*a._y,!0),this._handleIn._set(i*o._x+r*h._x,i*o._y+r*h._y,!0),this._handleOut._set(i*l._x+r*u._x,i*l._y+r*u._y,!0),this._changed()},_transformCoordinates:function(t,e,n){var i=this._point,r=n&&this._handleIn.isZero()?null:this._handleIn,s=n&&this._handleOut.isZero()?null:this._handleOut,a=i._x,o=i._y,h=2;return e[0]=a,e[1]=o,r&&(e[h++]=r._x+a,e[h++]=r._y+o),s&&(e[h++]=s._x+a,e[h++]=s._y+o),t&&(t._transformCoordinates(e,e,h/2),a=e[0],o=e[1],n?(i._x=a,i._y=o,h=2,r&&(r._x=e[h++]-a,r._y=e[h++]-o),s&&(s._x=e[h++]-a,s._y=e[h++]-o)):(r||(e[h++]=a,e[h++]=o),s||(e[h++]=a,e[h++]=o))),e}}),z=d.extend({initialize:function(t,e,i){var r,s,a;if(t)if((r=t[0])!==n)s=t[1];else{var o=t;(r=o.x)===n&&(r=(o=d.read(arguments)).x),s=o.y,a=o.selected}else r=s=0;this._x=r,this._y=s,this._owner=e,e[i]=this,a&&this.setSelected(!0)},_set:function(t,e){return this._x=t,this._y=e,this._owner._changed(this),this},getX:function(){return this._x},setX:function(t){this._x=t,this._owner._changed(this)},getY:function(){return this._y},setY:function(t){this._y=t,this._owner._changed(this)},isZero:function(){var t=c.isZero;return t(this._x)&&t(this._y)},isSelected:function(){return!!(this._owner._selection&this._getSelection())},setSelected:function(t){this._owner._changeSelection(this._getSelection(),t)},_getSelection:function(){var t=this._owner;return this===t._point?1:this===t._handleIn?2:this===t._handleOut?4:0}}),O=a.extend({_class:"Curve",beans:!0,initialize:function(t,e,n,i,r,s,a,o){var h,u,l,c,f,d,_=arguments.length;3===_?(this._path=t,h=e,u=n):_?1===_?"segment1"in t?(h=new A(t.segment1),u=new A(t.segment2)):"point1"in t?(l=t.point1,f=t.handle1,d=t.handle2,c=t.point2):Array.isArray(t)&&(l=[t[0],t[1]],c=[t[6],t[7]],f=[t[2]-t[0],t[3]-t[1]],d=[t[4]-t[6],t[5]-t[7]]):2===_?(h=new A(t),u=new A(e)):4===_?(l=t,f=e,d=n,c=i):8===_&&(l=[t,e],c=[a,o],f=[n-t,i-e],d=[r-a,s-o]):(h=new A,u=new A),this._segment1=h||new A(l,null,f),this._segment2=u||new A(c,d,null)},_serialize:function(t,e){return a.serialize(this.hasHandles()?[this.getPoint1(),this.getHandle1(),this.getHandle2(),this.getPoint2()]:[this.getPoint1(),this.getPoint2()],t,!0,e)},_changed:function(){this._length=this._bounds=n},clone:function(){return new O(this._segment1,this._segment2)},toString:function(){var t=["point1: "+this._segment1._point];return this._segment1._handleOut.isZero()||t.push("handle1: "+this._segment1._handleOut),this._segment2._handleIn.isZero()||t.push("handle2: "+this._segment2._handleIn),t.push("point2: "+this._segment2._point),"{ "+t.join(", ")+" }"},classify:function(){return O.classify(this.getValues())},remove:function(){var t=!1;if(this._path){var e=this._segment2,n=e._handleOut;(t=e.remove())&&this._segment1._handleOut.set(n)}return t},getPoint1:function(){return this._segment1._point},setPoint1:function(){this._segment1._point.set(d.read(arguments))},getPoint2:function(){return this._segment2._point},setPoint2:function(){this._segment2._point.set(d.read(arguments))},getHandle1:function(){return this._segment1._handleOut},setHandle1:function(){this._segment1._handleOut.set(d.read(arguments))},getHandle2:function(){return this._segment2._handleIn},setHandle2:function(){this._segment2._handleIn.set(d.read(arguments))},getSegment1:function(){return this._segment1},getSegment2:function(){return this._segment2},getPath:function(){return this._path},getIndex:function(){return this._segment1._index},getNext:function(){var t=this._path&&this._path._curves;return t&&(t[this._segment1._index+1]||this._path._closed&&t[0])||null},getPrevious:function(){var t=this._path&&this._path._curves;return t&&(t[this._segment1._index-1]||this._path._closed&&t[t.length-1])||null},isFirst:function(){return!this._segment1._index},isLast:function(){var t=this._path;return t&&this._segment1._index===t._curves.length-1||!1},isSelected:function(){return this.getPoint1().isSelected()&&this.getHandle1().isSelected()&&this.getHandle2().isSelected()&&this.getPoint2().isSelected()},setSelected:function(t){this.getPoint1().setSelected(t),this.getHandle1().setSelected(t),this.getHandle2().setSelected(t),this.getPoint2().setSelected(t)},getValues:function(t){return O.getValues(this._segment1,this._segment2,t)},getPoints:function(){for(var t=this.getValues(),e=[],n=0;n<8;n+=2)e.push(new d(t[n],t[n+1]));return e}},{getLength:function(){return null==this._length&&(this._length=O.getLength(this.getValues(),0,1)),this._length},getArea:function(){return O.getArea(this.getValues())},getLine:function(){return new w(this._segment1._point,this._segment2._point)},getPart:function(t,e){return new O(O.getPart(this.getValues(),t,e))},getPartLength:function(t,e){return O.getLength(this.getValues(),t,e)},divideAt:function(t){return this.divideAtTime(t&&t.curve===this?t.time:this.getTimeAt(t))},divideAtTime:function(t,e){var n=null;if(t>=1e-8&&t<=1-1e-8){var i=O.subdivide(this.getValues(),t),r=i[0],s=i[1],a=e||this.hasHandles(),o=this._segment1,h=this._segment2,u=this._path;a&&(o._handleOut._set(r[2]-r[0],r[3]-r[1]),h._handleIn._set(s[4]-s[6],s[5]-s[7]));var l=r[6],c=r[7],f=new A(new d(l,c),a&&new d(r[4]-l,r[5]-c),a&&new d(s[2]-l,s[3]-c));u?(u.insert(o._index+1,f),n=this.getNext()):(this._segment2=f,this._changed(),n=new O(f,h))}return n},splitAt:function(t){var e=this._path;return e?e.splitAt(t):null},splitAtTime:function(t){return this.splitAt(this.getLocationAtTime(t))},divide:function(t,e){return this.divideAtTime(t===n?.5:e?t:this.getTimeAt(t))},split:function(t,e){return this.splitAtTime(t===n?.5:e?t:this.getTimeAt(t))},reversed:function(){return new O(this._segment2.reversed(),this._segment1.reversed())},clearHandles:function(){this._segment1._handleOut._set(0,0),this._segment2._handleIn._set(0,0)},statics:{getValues:function(t,e,n,i){var r=t._point,s=t._handleOut,a=e._handleIn,o=e._point,h=r.x,u=r.y,l=o.x,c=o.y,f=i?[h,u,h,u,l,c,l,c]:[h,u,h+s._x,u+s._y,l+a._x,c+a._y,l,c];return n&&n._transformCoordinates(f,f,4),f},subdivide:function(t,e){var i=t[0],r=t[1],s=t[2],a=t[3],o=t[4],h=t[5],u=t[6],l=t[7];e===n&&(e=.5);var c=1-e,f=c*i+e*s,d=c*r+e*a,_=c*s+e*o,g=c*a+e*h,v=c*o+e*u,p=c*h+e*l,m=c*f+e*_,y=c*d+e*g,w=c*_+e*v,x=c*g+e*p,b=c*m+e*w,C=c*y+e*x;return[[i,r,f,d,m,y,b,C],[b,C,w,x,v,p,u,l]]},getMonoCurves:function(t,e){var n=[],i=e?0:1,r=t[i+0],s=t[i+2],a=t[i+4],o=t[i+6];if(r>=s==s>=a&&s>=a==a>=o||O.isStraight(t))n.push(t);else{var h=3*(s-a)-r+o,u=2*(r+a)-4*s,l=s-r,f=[],d=c.solveQuadratic(h,u,l,f,1e-8,1-1e-8);if(d){f.sort();var _=f[0],g=O.subdivide(t,_);n.push(g[0]),d>1&&(_=(f[1]-_)/(1-_),g=O.subdivide(g[1],_),n.push(g[0])),n.push(g[1])}else n.push(t)}return n},solveCubic:function(t,e,n,i,r,s){var a=t[e],o=t[e+2],h=t[e+4],u=t[e+6],l=0;if(!(an&&u>n&&o>n&&h>n)){var f=3*(o-a),d=3*(h-o)-f,_=u-a-f-d;l=c.solveCubic(_,d,f,a-n,i,r,s)}return l},getTimeOf:function(t,e){var n=new d(t[0],t[1]),i=new d(t[6],t[7]);if(null===(e.isClose(n,1e-12)?0:e.isClose(i,1e-12)?1:null))for(var r=[e.x,e.y],s=[],a=0;a<2;a++)for(var o=O.solveCubic(t,a,r[a],s,0,1),h=0;h.999999999999?1:O.getTimeOf(t,new d(n+o*r,i+o*s))}var h=1/0,u=0;function l(n){if(n>=0&&n<=1){var i=e.getDistance(O.getPoint(t,n),!0);if(i1e-8;)l(u-f)||l(u+f)||(f/=2);return u},getPart:function(t,e,n){var i=e>n;if(i){var r=e;e=n,n=r}return e>0&&(t=O.subdivide(t,e)[1]),n<1&&(t=O.subdivide(t,(n-e)/(1-e))[0]),i?[t[6],t[7],t[4],t[5],t[2],t[3],t[0],t[1]]:t},isFlatEnough:function(t,e){var n=t[0],i=t[1],r=t[2],s=t[3],a=t[4],o=t[5],h=t[6],u=t[7],l=3*r-2*n-h,c=3*s-2*i-u,f=3*a-2*h-n,d=3*o-2*u-i;return Math.max(l*l,f*f)+Math.max(c*c,d*d)<=16*e*e},getArea:function(t){var e=t[0],n=t[1],i=t[2],r=t[3],s=t[4],a=t[5],o=t[6],h=t[7];return 3*((h-n)*(i+s)-(o-e)*(r+a)+r*(e-s)-i*(n-a)+h*(s+e/3)-o*(a+n/3))/20},getBounds:function(t){for(var e=t.slice(0,2),n=e.slice(),i=[0,0],r=0;r<2;r++)O._addBounds(t[r],t[r+2],t[r+4],t[r+6],r,0,e,n,i);return new p(e[0],e[1],n[0]-e[0],n[1]-e[1])},_addBounds:function(t,e,n,i,r,s,a,o,h){function u(t,e){var n=t-e,i=t+e;no[r]&&(o[r]=i)}s/=2;var l=a[r]-s,f=o[r]+s;if(tf||e>f||n>f||i>f)if(e=0&&o<=1&&h<=0&&h>=-1}}return!1},isLinear:function(t,e,n,i){var r=i.subtract(t).divide(3);return e.equals(r)&&n.negate().equals(r)}},function(t,e){this[e]=function(e){var n=this._segment1,i=this._segment2;return t(n._point,n._handleOut,i._handleIn,i._point,e)},this.statics[e]=function(e,n){var i=e[0],r=e[1],s=e[6],a=e[7];return t(new d(i,r),new d(e[2]-i,e[3]-r),new d(e[4]-s,e[5]-a),new d(s,a),n)}},{statics:{},hasHandles:function(){return!this._segment1._handleOut.isZero()||!this._segment2._handleIn.isZero()},hasLength:function(t){return(!this.getPoint1().equals(this.getPoint2())||this.hasHandles())&&this.getLength()>(t||0)},isCollinear:function(t){return t&&this.isStraight()&&t.isStraight()&&this.getLine().isCollinear(t.getLine())},isHorizontal:function(){return this.isStraight()&&Math.abs(this.getTangentAtTime(.5).y)<1e-8},isVertical:function(){return this.isStraight()&&Math.abs(this.getTangentAtTime(.5).x)<1e-8}}),{beans:!1,getLocationAt:function(t,e){return this.getLocationAtTime(e?t:this.getTimeAt(t))},getLocationAtTime:function(t){return null!=t&&t>=0&&t<=1?new L(this,t):null},getTimeAt:function(t,e){return O.getTimeAt(this.getValues(),t,e)},getParameterAt:"#getTimeAt",getTimesWithTangent:function(){var t=d.read(arguments);return t.isZero()?[]:O.getTimesWithTangent(this.getValues(),t)},getOffsetAtTime:function(t){return this.getPartLength(0,t)},getLocationOf:function(){return this.getLocationAtTime(this.getTimeOf(d.read(arguments)))},getOffsetOf:function(){var t=this.getLocationOf.apply(this,arguments);return t?t.getOffset():null},getTimeOf:function(){return O.getTimeOf(this.getValues(),d.read(arguments))},getParameterOf:"#getTimeOf",getNearestLocation:function(){var t=d.read(arguments),e=this.getValues(),n=O.getNearestTime(e,t),i=O.getPoint(e,n);return new L(this,n,i,null,t.getDistance(i))},getNearestPoint:function(){var t=this.getNearestLocation.apply(this,arguments);return t?t.getPoint():t}},new function(){var t=["getPoint","getTangent","getNormal","getWeightedTangent","getWeightedNormal","getCurvature"];return a.each(t,function(t){this[t+"At"]=function(e,n){var i=this.getValues();return O[t](i,n?e:O.getTimeAt(i,e))},this[t+"AtTime"]=function(e){return O[t](this.getValues(),e)}},{statics:{_evaluateMethods:t}})},new function(){function t(t){var e=t[0],n=t[1],i=t[2],r=t[3],s=t[4],a=t[5],o=t[6],h=t[7],u=9*(i-s)+3*(o-e),l=6*(e+s)-12*i,c=3*(i-e),f=9*(r-a)+3*(h-n),d=6*(n+a)-12*r,_=3*(r-n);return function(t){var e=(u*t+l)*t+c,n=(f*t+d)*t+_;return Math.sqrt(e*e+n*n)}}function e(t,e){return Math.max(2,Math.min(16,Math.ceil(32*Math.abs(e-t))))}function i(t,e,n,i){if(null==e||e<0||e>1)return null;var r=t[0],s=t[1],a=t[2],o=t[3],h=t[4],u=t[5],l=t[6],f=t[7],_=c.isZero;_(a-r)&&_(o-s)&&(a=r,o=s),_(h-l)&&_(u-f)&&(h=l,u=f);var g,v,p=3*(a-r),m=3*(h-a)-p,y=l-r-p-m,w=3*(o-s),x=3*(u-o)-w,b=f-s-w-x;if(0===n)g=0===e?r:1===e?l:((y*e+m)*e+p)*e+r,v=0===e?s:1===e?f:((b*e+x)*e+w)*e+s;else{if(e<1e-8?(g=p,v=w):e>1-1e-8?(g=3*(l-h),v=3*(f-u)):(g=(3*y*e+2*m)*e+p,v=(3*b*e+2*x)*e+w),i){0===g&&0===v&&(e<1e-8||e>1-1e-8)&&(g=h-a,v=u-o);var C=Math.sqrt(g*g+v*v);C&&(g/=C,v/=C)}if(3===n){h=6*y*e+2*m,u=6*b*e+2*x;var S=Math.pow(g*g+v*v,1.5);g=0!==S?(g*u-v*h)/S:0,v=0}}return 2===n?new d(v,-g):new d(g,v)}return{statics:{classify:function(t){var e=t[0],i=t[1],r=t[2],s=t[3],a=t[4],o=t[5],h=t[6],u=t[7],l=r*(i-u)+s*(h-e)+e*u-i*h,f=3*(a*(s-i)+o*(e-r)+r*i-s*e),d=f-l,_=d-l+(e*(u-o)+i*(a-h)+h*o-u*a),g=Math.sqrt(_*_+d*d+f*f),v=0!==g?1/g:0,p=c.isZero;function m(t,e,i){var r=e!==n,s=r&&e>0&&e<1,a=r&&i>0&&i<1;return!r||(s||a)&&("loop"!==t||s&&a)||(t="arch",s=a=!1),{type:t,roots:s||a?s&&a?e0?Math.sqrt(y/3):Math.sqrt(-y),x=2*_;return m(y>0?"serpentine":"loop",(d+w)/x,(d-w)/x)},getLength:function(i,r,s,a){if(r===n&&(r=0),s===n&&(s=1),O.isStraight(i)){var o=i;s<1&&(o=O.subdivide(o,s)[0],r/=s),r>0&&(o=O.subdivide(o,r)[1]);var h=o[6]-o[0],u=o[7]-o[1];return Math.sqrt(h*h+u*u)}return c.integrate(a||t(i),r,s,e(r,s))},getTimeAt:function(i,r,s){if(s===n&&(s=r<0?1:0),0===r)return s;var a=Math.abs,o=r>0,h=o?s:0,u=o?1:s,l=t(i),f=O.getLength(i,h,u,l),d=a(r)-f;if(a(d)<1e-12)return o?u:h;if(d>1e-12)return null;var _=r/f,g=0;return c.findRoot(function(t){return g+=c.integrate(l,s,t,e(s,t)),s=t,g-r},l,s+_,h,u,32,1e-12)},getPoint:function(t,e){return i(t,e,0,!1)},getTangent:function(t,e){return i(t,e,1,!0)},getWeightedTangent:function(t,e){return i(t,e,1,!1)},getNormal:function(t,e){return i(t,e,2,!0)},getWeightedNormal:function(t,e){return i(t,e,2,!1)},getCurvature:function(t,e){return i(t,e,3,!1).x},getPeaks:function(t){var e=t[0],n=t[1],i=t[2],r=t[3],s=t[4],a=t[5],o=3*i-e-3*s+t[6],h=3*e-6*i+3*s,u=-3*e+3*i,l=3*r-n-3*a+t[7],f=3*n-6*r+3*a,d=-3*n+3*r,_=[];return c.solveCubic(9*(o*o+l*l),9*(o*h+f*l),2*(h*h+f*f)+3*(u*o+d*l),u*h+f*d,_,1e-8,1-1e-8),_.sort()}}}},new function(){function t(t,e,n,i,r,s,a){var o=!a&&n.getPrevious()===r,h=!a&&n!==r&&n.getNext()===r;if(null!==i&&i>=(o?1e-8:0)&&i<=(h?1-1e-8:1)&&null!==s&&s>=(h?1e-8:0)&&s<=(o?1-1e-8:1)){var u=new L(n,i,null,a),l=new L(r,s,null,a);u._intersection=l,l._intersection=u,e&&!e(u)||L.insert(t,u,!0)}}function e(t,e,i,r){return t[0][1]r?n(e,!1,r):t[0][0]}function n(t,e,n){for(var i=t[0][0],r=t[0][1],s=1,a=t.length;s=n:h<=n)return h===n?o:i+(n-r)*(o-i)/(h-r);i=o,r=h}return null}function i(t,e,n,i,r){var s=c.isZero;if(s(i)&&s(r)){var a=O.getTimeOf(t,new d(e,n));return null===a?[]:[a]}for(var o=Math.atan2(-r,i),h=Math.sin(o),u=Math.cos(o),l=[],f=[],_=0;_<8;_+=2){var g=t[_]-e,v=t[_+1]-n;l.push(g*u-v*h,g*h+v*u)}return O.solveCubic(l,1,0,f,0,1),f}function r(n,r,s,a,h,u){var l=Math.min,c=Math.max;if(c(n[0],n[2],n[4],n[6])+1e-12>l(r[0],r[2],r[4],r[6])&&l(n[0],n[2],n[4],n[6])-1e-12l(r[1],r[3],r[5],r[7])&&l(n[1],n[3],n[5],n[7])-1e-12=4096||++l>=40)return c;var v,p,m=r[0],y=r[1],x=r[6],b=r[7],C=w.getSignedDistance,S=C(m,y,x,b,r[2],r[3]),k=C(m,y,x,b,r[4],r[5]),I=S*k>0?.75:4/9,P=I*Math.min(0,S,k),M=I*Math.max(0,S,k),T=C(m,y,x,b,i[0],i[1]),A=C(m,y,x,b,i[2],i[3]),z=C(m,y,x,b,i[4],i[5]),L=C(m,y,x,b,i[6],i[7]),E=function(t,e,n,i){var r,s=[0,t],a=[1/3,e],o=[2/3,n],h=[1,i],u=e-(2*t+i)/3,l=n-(t+2*i)/3;if(u*l<0)r=[[s,a,h],[s,o,h]];else{var c=u/l;r=[c>=2?[s,a,h]:c<=.5?[s,o,h]:[s,a,o,h],[s,h]]}return(u||l)<0?r.reverse():r}(T,A,z,L),N=E[0],B=E[1];if(0===S&&0===k&&0===T&&0===A&&0===z&&0===L||null==(v=e(N,B,P,M))||null==(p=e(N.reverse(),B.reverse(),P,M)))return c;var F=f+(d-f)*v,j=f+(d-f)*p;if(Math.max(g-_,j-F)<1e-9){var D=(F+j)/2,R=(_+g)/2;t(o,h,u?a:s,u?R:D,u?s:a,u?D:R)}else if(i=O.getPart(i,v,p),p-v>.8)if(j-F>g-_)D=(F+j)/2,c=n(r,(q=O.subdivide(i,.5))[0],a,s,o,h,!u,l,c,_,g,F,D),c=n(r,q[1],a,s,o,h,!u,l,c,_,g,D,j);else{var q;R=(_+g)/2,c=n((q=O.subdivide(r,.5))[0],i,a,s,o,h,!u,l,c,_,R,F,j),c=n(q[1],i,a,s,o,h,!u,l,c,R,g,F,j)}else c=g-_>=1e-9?n(r,i,a,s,o,h,!u,l,c,_,g,F,j):n(i,r,s,a,o,h,u,l,c,F,j,_,g);return c})(y?r:n,y?n:r,y?a:s,y?s:a,h,u,y,0,0,0,1,0,1),!m||h.length===x)for(_=0;_<4;_++){var b=_>>1,C=1&_,S=6*b,k=6*C,I=new d(n[S],n[S+1]),P=new d(r[k],r[k+1]);I.isClose(P,1e-12)&&t(h,u,s,b,a,C)}}}return h}function s(e,n,i,r){var s=O.classify(e);if("loop"===s.type){var a=s.roots;t(i,r,n,a[0],n,a[1])}return i}function o(t,e){function n(t){var e=t[6]-t[0],n=t[7]-t[1];return e*e+n*n}var i=Math.abs,r=w.getDistance,s=O.isStraight(t),a=O.isStraight(e),o=s&&a,h=n(t)>1,C=O.getTimeOf(v[y],new d(v[x][b?6:0],v[x][b?7:1]));if(null!=C){var S=y?[b,C]:[C,b];(!p.length||i(S[0]-p[0][0])>1e-8&&i(S[1]-p[0][1])>1e-8)&&p.push(S)}if(m>2&&!p.length)break}if(2!==p.length)p=null;else if(!o){var k=O.getPart(t,p[0][0],p[1][0]),I=O.getPart(e,p[0][1],p[1][1]);(i(I[2]-k[2])>1e-7||i(I[3]-k[3])>1e-7||i(I[4]-k[4])>1e-7||i(I[5]-k[5])>1e-7)&&(p=null)}return p}return{getIntersections:function(t){var e=this.getValues(),n=t&&t!==this&&t.getValues();return n?r(e,n,this,t,[]):s(e,this,[])},statics:{getOverlaps:o,getIntersections:function(t,e,n,i,o,h){var u=!e;u&&(e=t);for(var l,c,f=t.length,d=e.length,_=[],g=[],v=0;v=0&&b<=1&&x.push(b)}}else{var C=(v*v-4*_*m)*d*d+(-2*v*p+4*g*m+4*_*y)*f*d+(p*p-4*g*y)*f*f,S=v*d-p*f;if(C>=0&&0!=w){var k=Math.sqrt(C),I=-(S+k)/w,P=(-S+k)/w;I>=0&&I<=1&&x.push(I),P>=0&&P<=1&&x.push(P)}}return x}}}}),L=a.extend({_class:"CurveLocation",initialize:function(t,e,n,i,r){if(e>=.99999999){var s=t.getNext();s&&(e=0,t=s)}this._setCurve(t),this._time=e,this._point=n||t.getPointAtTime(e),this._overlap=i,this._distance=r,this._intersection=this._next=this._previous=null},_setCurve:function(t){var e=t._path;this._path=e,this._version=e?e._version:0,this._curve=t,this._segment=null,this._segment1=t._segment1,this._segment2=t._segment2},_setSegment:function(t){this._setCurve(t.getCurve()),this._segment=t,this._time=t===this._segment1?0:1,this._point=t._point.clone()},getSegment:function(){var t=this._segment;if(!t){var e=this.getCurve(),n=this.getTime();0===n?t=e._segment1:1===n?t=e._segment2:null!=n&&(t=e.getPartLength(0,n)=1e-8&&e<=1-1e-8,r=n>=1e-8&&n<=1-1e-8;if(i&&r)return!this.isTouching();var s=this.getCurve(),a=e<1e-8?s.getPrevious():s,o=t.getCurve(),h=n<1e-8?o.getPrevious():o;if(e>1-1e-8&&(s=s.getNext()),n>1-1e-8&&(o=o.getNext()),!(a&&s&&h&&o))return!1;var u=[];function l(t,e){var n=t.getValues(),i=O.classify(n).roots||O.getPeaks(n),r=i.length,s=e&&r>1?i[r-1]:r>0?i[0]:.5;u.push(O.getLength(n,e?s:0,e?1:s)/2)}function c(t,e,n){return ee&&te||t=-1&&s<=i;s+=r){var a=t[(s%i+i)%i];if(!e.getPoint().isClose(a.getPoint(),1e-7))break;if(e.equals(a))return a}return null}for(;r<=s;){var o,h=r+s>>>1,u=t[h];if(n&&(o=e.equals(u)?u:a(h,-1)||a(h,1)))return e._overlap&&(o._overlap=o._intersection._overlap=!0),o;var l=e.getPath(),c=u.getPath();(l!==c?l._id-c._id:e.getIndex()+e.getTime()-(u.getIndex()+u.getTime()))<0?s=h-1:r=h+1}return t.splice(r,0,e),e}return{statics:{insert:t,expand:function(e){for(var n=e.slice(),i=e.length-1;i>=0;i--)t(n,e[i]._intersection,!1);return n}}}}),E=b.extend({_class:"PathItem",_selectBounds:!1,_canScaleStroke:!0,beans:!0,initialize:function(){},statics:{create:function(t){var e,n,i;if(a.isPlainObject(t)?(n=t.segments,e=t.pathData):Array.isArray(t)?n=t:"string"==typeof t&&(e=t),n){var r=n[0];i=r&&Array.isArray(r[0])}else e&&(i=(e.match(/m/gi)||[]).length>1||/z\s*\S+/i.test(e));return new(i?B:N)(t)}},_asPathItem:function(){return this},isClockwise:function(){return this.getArea()>=0},setClockwise:function(t){this.isClockwise()!=(t=!!t)&&this.reverse()},setPathData:function(t){var e,n,i,r=t&&t.match(/[mlhvcsqtaz][^mlhvcsqtaz]*/gi),s=!1,a=new d,o=new d;function h(t,n){var i=+e[t];return s&&(i+=a[n]),i}function u(t){return new d(h(t,"x"),h(t+1,"y"))}this.clear();for(var l=0,c=r&&r.length;lu&&this[i?"removeSegments":"removeChildren"](u,h);for(c=0;c=0&&e;h--){var u=n[h];e=!1;for(var l=s-1;l>=0&&!e;l--)u.compare(i[l])&&(a[l]||(a[l]=!0,o++),e=!0)}e=e&&o===s}return e}}),N=E.extend({_class:"Path",_serializeFields:{segments:[],closed:!1},initialize:function(t){this._closed=!1,this._segments=[],this._version=0;var e=Array.isArray(t)?"object"===i(t[0])?t:arguments:!t||t.size!==n||t.x===n&&t.point===n?null:arguments;e&&e.length>0?this.setSegments(e):(this._curves=n,this._segmentSelection=0,e||"string"!=typeof t||(this.setPathData(t),t=null)),this._initialize(!e&&t)},_equals:function(t){return this._closed===t._closed&&a.equals(this._segments,t._segments)},copyContent:function(t){this.setSegments(t._segments),this._closed=t._closed},_changed:function t(e){if(t.base.call(this,e),8&e){if(this._length=this._area=n,32&e)this._version++;else if(this._curves)for(var i=0,r=this._curves.length;i0&&(p(c[0],!0),v.push("z")),v.join("")},isEmpty:function(){return!this._segments.length},_transformContent:function(t){for(var e=this._segments,n=new Array(6),i=0,r=e.length;i0&&e+r-1===l?e-1:e,f=c,d=Math.min(c+r,l);t._curves&&(i.splice.apply(i,[c,0].concat(t._curves)),f+=t._curves.length);for(o=f;o0?t-1:t},add:function(t){return arguments.length>1&&"number"!=typeof t?this._add(A.readList(arguments)):this._add([A.read(arguments)])[0]},insert:function(t,e){return arguments.length>2&&"number"!=typeof e?this._add(A.readList(arguments,1),t):this._add([A.read(arguments,1)],t)[0]},addSegment:function(){return this._add([A.read(arguments)])[0]},insertSegment:function(t){return this._add([A.read(arguments,1)],t)[0]},addSegments:function(t){return this._add(A.readList(t))},insertSegments:function(t,e){return this._add(A.readList(e),t)},removeSegment:function(t){return this.removeSegments(t,t+1)[0]||null},removeSegments:function(t,e,n){t=t||0,e=a.pick(e,this._segments.length);var i=this._segments,r=this._curves,s=i.length,o=i.splice(t,e-t),h=o.length;if(!h)return o;for(var u=0;u0&&e===s+(this._closed?1:0)?t-1:t;for(u=(r=r.splice(f,h)).length-1;u>=0;u--)r[u]._path=null;n&&(o._curves=r.slice(1)),this._adjustCurves(f,f)}return this._changed(41),o},clear:"#removeSegments",hasHandles:function(){for(var t=this._segments,e=0,n=t.length;e0&&this._segmentSelection===7*t},setFullySelected:function(t){t&&this._selectSegments(!0),this.setSelected(t)},setSelection:function t(e){1&e||this._selectSegments(!1),t.base.call(this,e)},_selectSegments:function(t){var e=this._segments,n=e.length,i=t?7:0;this._segmentSelection=i*n;for(var r=0;r0&&this.setSelected(!0)},divideAt:function(t){var e,n=this.getLocationAt(t);return n&&(e=n.getCurve().divideAt(n.getCurveOffset()))?e._segment1:null},splitAt:function(t){var e=this.getLocationAt(t),n=e&&e.index,i=e&&e.time;i>1-1e-8&&(n++,i=0);var r=this.getCurves();if(n>=0&&n=1e-8&&r[n++].divideAtTime(i);var s,a=this.removeSegments(n,this._segments.length,!0);return this._closed?(this.setClosed(!1),s=this):((s=new N(b.NO_INSERT)).insertAbove(this),s.copyAttributes(this)),s._add(a,0),this.addSegment(a[0]),s}return null},split:function(t,e){var i,r=e===n?t:(i=this.getCurves()[t])&&i.getLocationAtTime(e);return null!=r?this.splitAt(r):null},join:function(t,e){var n=e||0;if(t&&t!==this){var i=t._segments,r=this.getLastSegment(),s=t.getLastSegment();if(!s)return this;r&&r._point.isClose(s._point,n)&&t.reverse();var a=t.getFirstSegment();if(r&&r._point.isClose(a._point,n))r.setHandleOut(a._handleOut),this._add(i.slice(1));else{var o=this.getFirstSegment();o&&o._point.isClose(a._point,n)&&t.reverse(),s=t.getLastSegment(),o&&o._point.isClose(s._point,n)?(o.setHandleIn(s._handleIn),this._add(i.slice(0,i.length-1),0)):this._add(i.slice())}t._closed&&this._add([i[0]]),t.remove()}var h=this.getFirstSegment(),u=this.getLastSegment();return h!==u&&h._point.isClose(u._point,n)&&(h.setHandleIn(u._handleIn),u.remove(),this.setClosed(!0)),this},reduce:function(t){for(var e=this.getCurves(),n=t&&t.simplify,i=n?1e-7:0,r=e.length-1;r>=0;r--){var s=e[r];!s.hasHandles()&&(!s.hasLength(i)||n&&s.isCollinear(s.getNext()))&&s.remove()}return this},reverse:function(){this._segments.reverse();for(var t=0,e=this._segments.length;t0&&i.push(new A(e[n-1].curve.slice(6))),this.setSegments(i)},simplify:function(t){var e=new j(this).fit(t||2.5);return e&&this.setSegments(e),!!e},smooth:function(t){var e=this,i=t||{},r=i.type||"asymmetric",s=this._segments,a=s.length,o=this._closed;function h(t,n){var i=t&&t.index;if(null!=i){var r=t.path;if(r&&r!==e)throw new Error(t._class+" "+i+" of "+r+" is not part of "+e);n&&t instanceof O&&i++}else i="number"==typeof t?t:n;return Math.min(i<0&&o?i%a:i<0?i+a:i,a-1)}var u=o&&i.from===n&&i.to===n,l=h(i.from,0),c=h(i.to,a-1);if(l>c)if(o)l-=a;else{var f=l;l=c,c=f}if(/^(?:asymmetric|continuous)$/.test(r)){var d="asymmetric"===r,_=Math.min,g=c-l+1,v=g-1,p=u?_(g,4):1,m=p,y=p,w=[];if(o||(m=_(1,l),y=_(1,a-c-1)),(v+=m+y)<=1)return;for(var x=0,b=l-m;x<=v;x++,b++)w[x]=s[(b<0?b+a:b)%a]._point;var C=w[0]._x+2*w[1]._x,S=w[0]._y+2*w[1]._y,k=2,I=v-1,P=[C],M=[S],T=[k],A=[],z=[];for(x=1;x=0;x--)A[x]=(P[x]-A[x+1])/T[x],z[x]=(M[x]-z[x+1])/T[x];A[v]=(3*w[v]._x-A[I])/2,z[v]=(3*w[v]._y-z[I])/2;x=m;var j=v-y;for(b=l;x<=j;x++,b++){var D=s[b<0?b+a:b],R=D._point,q=A[x]-R._x,V=z[x]-R._y;(u||xm)&&D.setHandleIn(-q,-V)}}else for(x=l;x<=c;x++)s[x<0?x+a:x].smooth(i,!u&&x===l,!u&&x===c)},toShape:function(t){if(!this._closed)return null;var e,i,r,s,a,o,h,u=this._segments;function l(t,e){var n=u[t],i=n.getNext(),r=u[e],s=r.getNext();return n._handleOut.isZero()&&i._handleIn.isZero()&&r._handleOut.isZero()&&s._handleIn.isZero()&&i._point.subtract(n._point).isCollinear(s._point.subtract(r._point))}function f(t){var e=u[t],n=e.getNext(),i=e._handleOut,r=n._handleIn;if(i.isOrthogonal(r)){var s=e._point,a=n._point,o=new w(s,i,!0).intersect(new w(a,r,!0),!0);return o&&c.isZero(i.getLength()/o.subtract(s).getLength()-.5522847498307936)&&c.isZero(r.getLength()/o.subtract(a).getLength()-.5522847498307936)}return!1}function d(t,e){return u[t]._point.getDistance(u[e]._point)}if(!this.hasHandles()&&4===u.length&&l(0,2)&&l(1,3)&&(a=u[1],o=a.getPrevious(),h=a.getNext(),o._handleOut.isZero()&&a._handleIn.isZero()&&a._handleOut.isZero()&&h._handleIn.isZero()&&a._point.subtract(o._point).isOrthogonal(h._point.subtract(a._point)))?(e=k.Rectangle,i=new g(d(0,3),d(0,1)),s=u[1]._point.add(u[2]._point).divide(2)):8===u.length&&f(0)&&f(2)&&f(4)&&f(6)&&l(1,5)&&l(3,7)?(e=k.Rectangle,r=(i=new g(d(1,6),d(0,3))).subtract(new g(d(0,7),d(1,2))).divide(2),s=u[3]._point.add(u[4]._point).divide(2)):4===u.length&&f(0)&&f(1)&&f(2)&&f(3)&&(c.isZero(d(0,2)-d(1,3))?(e=k.Circle,r=d(0,2)/2):(e=k.Ellipse,r=new g(d(2,0)/2,d(3,1)/2)),s=u[1]._point),e){var _=this.getPosition(!0),v=new e({center:_,size:i,radius:r,insert:!1});return v.copyAttributes(this,!0),v._matrix.prepend(this._matrix),v.rotate(s.subtract(_).getAngle()+90),(t===n||t)&&v.insertAbove(this),v}return null},toPath:"#clone",compare:function t(e){if(!e||e instanceof B)return t.base.call(this,e);var n=this.getCurves(),i=e.getCurves(),r=n.length,s=i.length;if(!r||!s)return r==s;for(var a,o,h=n[0].getValues(),u=[],l=0,c=0,f=0;f0?s-1:f,o=v[0][1];break}}var _,g=Math.abs;for(d=u[a];h&&d;){var v;if(v=O.getOverlaps(h,d))if(g(v[0][0]-c)<1e-8){1===(c=v[1][0])&&(h=++l=s&&(a=0),d=u[a]||i[a].getValues(),o=0),!h)return _[0]===a&&_[1]===o;continue}}break}return!1},_hitTestSelf:function(t,e,n,i){var r,s,a,o,h,u,l=this,c=this.getStyle(),f=this._segments,d=f.length,_=this._closed,g=e._tolerancePadding,v=g,p=e.stroke&&c.hasStroke(),m=e.fill&&c.hasFill(),y=e.curves,w=p?c.getStrokeWidth()/2:m&&e.tolerance>0||y?0:null;function x(e,n){return t.subtract(e).divide(n).length<=1}function b(t,n,i){if(!e.selected||n.isSelected()){var r=t._point;if(n!==r&&(n=n.add(r)),x(n,v))return new T(i,l,{segment:t,point:n})}}function C(t,n){return(n||e.segments)&&b(t,t._point,"segment")||!n&&e.handles&&(b(t,t._handleIn,"handle-in")||b(t,t._handleOut,"handle-out"))}function S(t){o.add(t)}function k(e){var n,h=_||e._index>0&&e._index0?(r=c.getStrokeJoin(),s=c.getStrokeCap(),a=c.getMiterLimit(),v=v.add(N._getStrokePadding(w,i))):r=s="round"),!e.ends||e.segments||_){if(e.segments||e.handles)for(var I=0;I1?k(h.getSegment())||(h=null):x(h.getPoint(),v)||(h=null)}if(!h&&"miter"===r&&d>1)for(I=0;It)return a.getLocationAt(t-s)}if(e.length>0&&t<=this.getLength())return new L(e[e.length-1],1)}else if(t&&t.getPath&&t.getPath()===this)return t;return null},getOffsetsWithTangent:function(){var t=d.read(arguments);if(t.isZero())return[];for(var e=[],n=0,i=this.getCurves(),r=0,s=i.length;r0&&g(c[0])}return{_draw:function(e,n,i,r){var s=n.dontStart,a=n.dontFinish||n.clip,o=this.getStyle(),h=o.hasFill(),u=o.hasStroke(),l=o.getDashArray(),c=!at.support.nativeDash&&u&&l&&l.length;function f(t){return l[(t%c+c)%c]}if(s||e.beginPath(),(h||u&&!c||a)&&(t(e,this,r),this._closed&&e.closePath()),!a&&(h||u)&&(this._setStyles(e,n,i),h&&(e.fill(o.getFillRule()),e.shadowColor="rgba(0,0,0,0)"),u)){if(c){s||e.beginPath();var d,_=new F(this,.25,32,!1,r),g=_.length,v=-o.getDashOffset(),p=0;for(v%=g;v>0;)v-=f(p--)+f(p--);for(;v0||d>0)&&_.drawPart(e,Math.max(v,0),Math.max(d,0)),v=d+f(p++)}e.stroke()}},_drawSelected:function(e,n){e.beginPath(),t(e,this,n),e.stroke(),function(t,e,n,i){var r,s,a=i/2,o=new Array(6);function h(e){var n=o[e],i=o[e+1];r==n&&s==i||(t.beginPath(),t.moveTo(r,s),t.lineTo(n,i),t.stroke(),t.beginPath(),t.arc(n,i,a,0,2*Math.PI,!0),t.fill())}for(var u=0,l=e.length;u1&&(M=(I*=L)*I,T=(P*=L)*P),s(L=(M*T-M*O-T*z)/(M*O+T*z))<1e-12&&(L=0),L<0)throw new Error("Cannot create an arc with the given arguments");e=new d(I*k/P,-P*S/I).multiply((b===x?-1:1)*o(L)).rotate(m).add(C),n=(i=(r=(new y).translate(e).rotate(m).scale(I,P))._inverseTransform(u)).getDirectedAngle(r._inverseTransform(l)),!x&&n>0?n-=360:x&&n<0&&(n+=360)}if(_){var E=new w(u.add(_).divide(2),_.subtract(u).rotate(90),!0),N=new w(_.add(l).divide(2),l.subtract(_).rotate(90),!0),B=new w(u,l),F=B.getSide(_);if(!(e=E.intersect(N,!0))){if(!F)return this.lineTo(l);throw new Error("Cannot create an arc with the given arguments")}n=(i=u.subtract(e)).getDirectedAngle(l.subtract(e));var j=B.getSide(e,!0);0===j?n=F*s(n):F===j&&(n+=n<0?360:-360)}for(var D=s(n),R=D>=360?4:Math.ceil((D-1e-7)/90),q=n/R,V=q*Math.PI/360,U=4/3*Math.sin(V)/(1+Math.cos(V)),H=[],Z=0;Z<=R;Z++){var W=l,$=null;if(Z0&&(x(t[0],d),x(t[t.length-1],d)),l},_getStrokePadding:function(t,e){if(!e)return[t,t];var n=new d(t,0).transform(e),i=new d(0,t).transform(e),r=n.getAngleInRadians(),s=n.getLength(),a=i.getLength(),o=Math.sin(r),h=Math.cos(r),u=Math.tan(r),l=Math.atan2(a*u,s),c=Math.atan2(a,u*s);return[Math.abs(s*Math.cos(l)*h+a*Math.sin(l)*o),Math.abs(a*Math.sin(c)*h+s*Math.cos(c)*o)]},_addBevelJoin:function(t,e,n,i,r,s,a,o){var h=t.getCurve(),u=h.getPrevious(),l=h.getPoint1().transform(r),c=u.getNormalAtTime(1).multiply(n).transform(s),f=h.getNormalAtTime(0).multiply(n).transform(s);if(c.getDirectedAngle(f)<0&&(c=c.negate(),f=f.negate()),o&&a(l),a(l.add(c)),"miter"===e){var _=new w(l.add(c),new d(-c.y,c.x),!0).intersect(new w(l.add(f),new d(-f.y,f.x),!0),!0);_&&l.getDistance(_)<=i*n&&a(_)}a(l.add(f))},_addSquareCap:function(t,e,n,i,r,s,a){var o=t._point.transform(i),h=t.getLocation(),u=h.getNormal().multiply(0===h.getTime()?n:-n).transform(r);"square"===e&&(a&&(s(o.subtract(u)),s(o.add(u))),o=o.add(u.rotate(-90))),s(o.add(u)),s(o.subtract(u))},getHandleBounds:function(t,e,n,i,r){var s,a,o=n.getStyle();if(r.stroke&&o.hasStroke()){var h=n._getStrokeMatrix(i,r),u=o.getStrokeWidth()/2,l=u;"miter"===o.getStrokeJoin()&&(l=u*o.getMiterLimit()),"square"===o.getStrokeCap()&&(l=Math.max(l,u*Math.SQRT2)),s=N._getStrokePadding(u,h),a=N._getStrokePadding(l,h)}for(var c=new Array(6),f=1/0,d=-f,_=f,g=d,v=0,m=t.length;vd&&(d=I),P<_&&(_=P),M>g&&(g=M)}}return new p(f,_,d-f,g-_)}}});N.inject({statics:new function(){var t=.5522847498307936,e=[new A([-1,0],[0,t],[0,-t]),new A([0,-1],[-t,0],[t,0]),new A([1,0],[0,-t],[0,t]),new A([0,1],[t,0],[-t,0])];function n(t,e,n){var i=a.getNamed(n),r=new N(i&&0==i.insert&&b.NO_INSERT);return r._add(t),r._closed=e,r.set(i,{insert:!0})}function i(t,i,r){for(var s=new Array(4),a=0;a<4;a++){var o=e[a];s[a]=new A(o._point.multiply(i).add(t),o._handleIn.multiply(i),o._handleOut.multiply(i))}return n(s,!0,r)}return{Line:function(){return n([new A(d.readNamed(arguments,"from")),new A(d.readNamed(arguments,"to"))],!1,arguments)},Circle:function(){var t=d.readNamed(arguments,"center"),e=a.readNamed(arguments,"radius");return i(t,new g(e),arguments)},Rectangle:function(){var e,i=p.readNamed(arguments,"rectangle"),r=g.readNamed(arguments,"radius",0,{readNull:!0}),s=i.getBottomLeft(!0),a=i.getTopLeft(!0),o=i.getTopRight(!0),h=i.getBottomRight(!0);if(!r||r.isZero())e=[new A(s),new A(a),new A(o),new A(h)];else{var u=(r=g.min(r,i.getSize(!0).divide(2))).width,l=r.height,c=u*t,f=l*t;e=[new A(s.add(u,0),null,[-c,0]),new A(s.subtract(0,l),[0,f]),new A(a.add(0,l),null,[0,-f]),new A(a.add(u,0),[-c,0],null),new A(o.subtract(u,0),null,[c,0]),new A(o.add(0,l),[0,-f],null),new A(h.subtract(0,l),null,[0,f]),new A(h.subtract(u,0),[c,0])]}return n(e,!0,arguments)},RoundRectangle:"#Rectangle",Ellipse:function(){var t=k._readEllipse(arguments);return i(t.center,t.radius,arguments)},Oval:"#Ellipse",Arc:function(){var t=d.readNamed(arguments,"from"),e=d.readNamed(arguments,"through"),n=d.readNamed(arguments,"to"),i=a.getNamed(arguments),r=new N(i&&0==i.insert&&b.NO_INSERT);return r.moveTo(t),r.arcTo(e,n),r.set(i)},RegularPolygon:function(){for(var t=d.readNamed(arguments,"center"),e=a.readNamed(arguments,"sides"),i=a.readNamed(arguments,"radius"),r=360/e,s=e%3==0,o=new d(0,s?-i:i),h=s?-1:.5,u=new Array(e),l=0;l=0;s--){var o=i[s];i!==n||o instanceof N||(i=a.slice(i)),Array.isArray(o)?i[s]=new N({segments:o,insert:!1}):o instanceof B&&(i.splice.apply(i,[s,1].concat(o.removeChildren())),o.remove())}return t.base.call(this,e,i)},reduce:function t(e){for(var n=this._children,i=n.length-1;i>=0;i--){var r;(r=n[i].reduce(e)).isEmpty()&&r.remove()}return n.length?t.base.call(this):((r=new N(b.NO_INSERT)).copyAttributes(this),r.insertAbove(this),this.remove(),r)},isClosed:function(){for(var t=this._children,e=0,n=t.length;e=0;d--){var _=a[d].split();_&&(f(_)&&_.getFirstSegment().setHandleIn(0,0),i.getLastSegment().setHandleOut(0,0))}return f(i),o(c,!1,t,e)}function l(t,e){for(var n=t;n;){if(n===e)return;n=n._previous}for(;t._next&&t._next!==e;)t=t._next;if(!t._next){for(;e._previous;)e=e._previous;t._next=e,e._previous=t}}function f(t){for(var e=t.length-1;e>=0;e--)t[e].clearHandles()}function d(t,e,n){var r=t&&t.length;if(r){var s=a.each(t,function(t,e){this[t._id]={container:null,winding:t.isClockwise()?1:-1,index:e}},{}),o=t.slice().sort(function(t,e){return i(e.getArea())-i(t.getArea())}),h=o[0];null==n&&(n=h.isClockwise());for(var u=0;u=0;_--){var g=o[_];if(g.contains(f)){var v=s[g._id];d=v.winding,c.winding+=d,c.container=v.exclude?v.container:g;break}}if(e(c.winding)===e(d))c.exclude=!0,t[c.index]=null;else{var p=c.container;l.setClockwise(p?!p.isClockwise():n)}}}return t}function _(t,e,n){var i,r,s,a=e&&[],o=!1,h=n||[],u=n&&{};function c(t){return t._path._id+"."+t._segment1._index}for(var d=(n&&n.length)-1;d>=0;d--){(_=n[d])._path&&(u[c(_)]=!0)}for(d=t.length-1;d>=0;d--){var _,g,v=t[d],p=v._time,m=p,y=e&&!e(v);if((_=v._curve)&&(_!==r?(o=!_.hasHandles()||u&&u[c(_)],i=[],s=null,r=_):s>=1e-8&&(p/=s)),y)i&&i.push(v);else{if(e&&a.unshift(v),s=m,p<1e-8)g=_._segment1;else if(p>1-1e-8)g=_._segment2;else{var w=_.divideAtTime(p,!0);o&&h.push(_,w),g=w._segment1;for(var x=i.length-1;x>=0;x--){var b=i[x];b._time=(b._time-p)/(1-p)}}v._setSegment(g);var C=g._intersection,S=v._intersection;if(C){l(C,S);for(var k=C;k;)l(k._intersection,C),k=k._next}else g._intersection=S}}return n||f(h),a||t}function g(n,r,s,a,o){var h,u,l=s?1:0,c=1^l,f=[n.x,n.y],d=f[l],_=f[c],v=1e-6,p=d-1e-9,m=d+1e-9,y=0,w=0,x=0,b=0,C=!1,S=!1,k=1,I=[];function P(i){var u=i[c+0],f=i[c+6];if(!(_e(u,f))){var y=i[l+0],w=i[l+2],S=i[l+4],P=i[l+6];if(u!==f){var M=_===u?0:_===f?1:p>e(y,w,S,P)||m0?I[0]:1,T=0===M?y:1===M?P:O.getPoint(i,M)[s?"y":"x"],A=u>f?1:-1,z=h[c]>h[c+6]?1:-1,L=h[l+6];return _!==u?(Tm?b+=A:C=!0,T>d-v&&Tm&&(b+=A):y!=L&&(Lm?(b+=A,C=!0):L>p&&Tp&&Tp||Pp)&&(C=!0)}}function M(n){var i=n[c+0],r=n[c+2],a=n[c+4],o=n[c+6];if(_<=e(i,r,a,o)&&_>=t(i,r,a,o))for(var h,u=n[l+0],f=n[l+2],d=n[l+4],g=n[l+6],v=p>e(u,f,d,g)||mf.quality&&(f=I);break}u-=m}}for(_=a.length-1;_>=0;_--)a[_].segment._winding=f}function p(t,e){var n,i=[];function r(t){var n;return!(!t||t._visited||e&&(!e[(n=t._winding||{}).winding]||e.unite&&2===n.winding&&n.windingL&&n.windingR))}function s(t){if(t)for(var e=0,i=n.length;e=0;u--){var l=h[u],c=l._path,d=l._segment,g=d.getPrevious(),v=d.getNext();n(g,c)&&n(v,c)&&(d.remove(),g._handleOut._set(0,0),v._handleIn._set(0,0),g===d||g.getCurve().hasLength()||(v._handleIn.set(g._handleIn),g.remove()))}r&&(_(s,i&&function(t){var e=t.getCurve(),n=t.getSegment(),i=t._intersection,r=i._curve,s=i._segment;if(e&&r&&e._path&&r._path)return!0;n&&(n._intersection=null),s&&(s._intersection=null)},o),o&&f(o),e=p(a.each(e,function(t){a.push(this,t._segments)},[])));var m,y=e.length;return y>1&&t?(e!==t&&this.setChildren(e),m=this):1!==y||t||(e[0]!==this&&this.setSegments(e[0].removeSegments()),m=this),m||((m=new B(b.NO_INSERT)).addChildren(e),(m=m.reduce()).copyAttributes(this),this.replaceWith(m)),m},reorient:function(t,e){var i=this._children;return i&&i.length?this.setChildren(d(this.removeChildren(),function(e){return!!(t?e:1&e)},e)):e!==n&&this.setClockwise(e),this},getInteriorPoint:function(){var n=this.getBounds().getCenter(!0);if(!this.contains(n)){for(var i=this.getCurves(),r=n.y,s=[],a=[],o=0,h=i.length;o=t(l,c,f,d)&&r<=e(l,c,f,d))for(var _=O.getMonoCurves(u),g=0,v=_.length;g=m&&r<=y||r>=y&&r<=m)){var w=r===m?p[0]:r===y?p[6]:1===O.solveCubic(p,1,r,a,0,1)?O.getPoint(p,a[0]).x:(p[0]+p[6])/2;s.push(w)}}}s.length>1&&(s.sort(function(t,e){return t-e}),n.x=(s[0]+s[1])/2)}return n}}});var F=a.extend({_class:"PathFlattener",initialize:function(t,e,n,i,r){var s,a=[],o=[],h=0,u=1/(n||32),l=t._segments,c=l[0];function f(t,n){var s=O.getValues(t,n,r);a.push(s),function t(n,r,s,a){if(!(a-s>u)||i&&O.isStraight(n)||O.isFlatEnough(n,e||.25)){var l=n[6]-n[0],c=n[7]-n[1],f=Math.sqrt(l*l+c*c);f>0&&(h+=f,o.push({offset:h,curve:n,index:r,time:a}))}else{var d=O.subdivide(n,.5),_=(s+a)/2;t(d[0],r,s,_),t(d[1],r,_,a)}}(s,t._index,0,1)}for(var d=1,_=l.length;d<_;d++)f(c,s=l[d]),c=s;t._closed&&f(s||c,l[0]),this.curves=a,this.parts=o,this.length=h,this.index=0},_get:function(t){for(var e,n=this.parts,i=n.length,r=this.index;e=r,r&&!(n[--r].offset=t){this.index=e;var a=n[e-1],o=a&&a.index===s.index?a.time:0,h=a?a.offset:0;return{index:s.index,time:o+(s.time-o)*(t-h)/(s.offset-h)}}}return{index:n[i-1].index,time:1}},drawPart:function(t,e,n){for(var i=this._get(e),r=this._get(n),s=i.index,a=r.index;s<=a;s++){var o=O.getPart(this.curves[s],s===i.index?i.time:0,s===r.index?r.time:1);s===i.index&&t.moveTo(o[0],o[1]),t.bezierCurveTo.apply(t,o.slice(2))}}},a.each(O._evaluateMethods,function(t){this[t+"At"]=function(e){var n=this._get(e);return O[t](this.curves[n.index],n.time)}},{})),j=a.extend({initialize:function(t){for(var e,n=this.points=[],i=t._segments,r=t._closed,s=0,a=i.length;s0&&(i=[new A(e[0])],n>1&&(this.fitCubic(i,t,0,n-1,e[1].subtract(e[0]),e[n-2].subtract(e[n-1])),this.closed&&(i.shift(),i.pop()))),i},fitCubic:function(t,e,n,i,r,s){var a=this.points;if(i-n!=1){for(var o,h=this.chordLengthParameterize(n,i),u=Math.max(e,e*e),l=!0,c=0;c<=4;c++){var f=this.generateBezier(n,i,h,r,s),d=this.findMaxError(n,i,f,h);if(d.error=u)break;l=this.reparameterize(n,i,h,f),u=d.error}var _=a[o-1].subtract(a[o+1]);this.fitCubic(t,e,n,o,r,_),this.fitCubic(t,e,o,i,_.negate(),s)}else{var g=a[n],v=a[i],p=g.getDistance(v)/3;this.addCurve(t,[g,g.add(r.normalize(p)),v.add(s.normalize(p)),v])}},addCurve:function(t,e){t[t.length-1].setHandleOut(e[1].subtract(e[0])),t.push(new A(e[3],e[2].subtract(e[3])))},generateBezier:function(t,e,n,i,r){for(var s=Math.abs,a=this.points,o=a[t],h=a[e],u=[[0,0],[0,0]],l=[0,0],c=0,f=e-t+1;c1e-12){var I=u[0][0]*l[1]-u[1][0]*l[0];C=(l[0]*u[1][1]-l[1]*u[0][1])/k,S=I/k}else{var P=u[0][0]+u[0][1],M=u[1][0]+u[1][1];C=S=s(P)>1e-12?l[0]/P:s(M)>1e-12?l[1]/M:0}var T,A,z=h.getDistance(o),O=1e-12*z;if(Cz*z&&(C=S=z/3,T=A=null)}return[o,o.add(T||i.normalize(C)),h.add(A||r.normalize(S)),h]},reparameterize:function(t,e,n,i){for(var r=t;r<=e;r++)n[r-t]=this.findRoot(i,this.points[r],n[r-t]);r=1;for(var s=n.length;r=s&&(s=h,r=a)}return{error:s,index:r}}}),D=b.extend({_class:"TextItem",_applyMatrix:!1,_canApplyMatrix:!1,_serializeFields:{content:null},_boundsOptions:{stroke:!1,handle:!1},initialize:function(t){this._content="",this._lines=[];var e=t&&a.isPlainObject(t)&&t.x===n&&t.y===n;this._initialize(e&&t,!e&&d.read(arguments))},_equals:function(t){return this._content===t._content},copyContent:function(t){this.setContent(t._content)},getContent:function(){return this._content},setContent:function(t){this._content=""+t,this._lines=this._content.split(/\r\n|\n|\r/gm),this._changed(521)},isEmpty:function(){return!this._content},getCharacterStyle:"#getStyle",setCharacterStyle:"#setStyle",getParagraphStyle:"#getStyle",setParagraphStyle:"#setStyle"}),R=D.extend({_class:"PointText",initialize:function(){D.apply(this,arguments)},getPoint:function(){var t=this._matrix.getTranslation();return new _(t.x,t.y,this,"setPoint")},setPoint:function(){var t=d.read(arguments);this.translate(t.subtract(this._matrix.getTranslation()))},_draw:function(t,e,n){if(this._content){this._setStyles(t,e,n);var i=this._lines,r=this._style,s=r.hasFill(),a=r.hasStroke(),o=r.getLeading(),h=t.shadowColor;t.font=r.getFontStyle(),t.textAlign=r.getJustification();for(var u=0,l=i.length;u1&&(h-=1),a[o]=6*h<1?s+6*(r-s)*h:2*h<1?r:3*h<2?s+(r-s)*(2/3-h)*6:s}return a},"rgb-gray":function(t,e,n){return[.2989*t+.587*e+.114*n]},"gray-rgb":function(t){return[t,t,t]},"gray-hsb":function(t){return[0,0,t]},"gray-hsl":function(t){return[0,0,t]},"gradient-rgb":function(){return[]},"rgb-gradient":function(){return[]}};return a.each(e,function(t,i){n[i]=[],a.each(t,function(t,r){var s=a.capitalize(t),o=/^(hue|saturation)$/.test(t),h=n[i][r]="gradient"===i?"gradient"===t?function(t){var e=this._components[0];return e!==(t=V.read(Array.isArray(t)?t:arguments,0,{readNull:!0}))&&(e&&e._removeOwner(this),t&&t._addOwner(this)),t}:function(){return d.read(arguments,0,{readNull:"highlight"===t,clone:!0})}:function(t){return null==t||isNaN(t)?0:+t};this["get"+s]=function(){return this._type===i||o&&/^hs[bl]$/.test(this._type)?this._components[r]:this._convert(i)[r]},this["set"+s]=function(t){this._type===i||o&&/^hs[bl]$/.test(this._type)||(this._components=this._convert(i),this._properties=e[i],this._type=i),this._components[r]=h.call(this,t),this._changed()}},this)},{_class:"Color",_readIndex:!0,initialize:function o(h){var u,l,c,f,d=arguments,_=this.__read,g=0;Array.isArray(h)&&(h=(d=h)[0]);var v=null!=h&&i(h);if("string"===v&&h in e&&(u=h,h=d[1],Array.isArray(h)?(l=h,c=d[2]):(_&&(g=1),d=a.slice(d,1),v=i(h))),!l){if(f="number"===v?d:"object"===v&&null!=h.length?h:null){u||(u=f.length>=3?"rgb":"gray");var p=e[u].length;c=f[p],_&&(g+=f===arguments?p+(null!=c?1:0):1),f.length>p&&(f=a.slice(f,0,p))}else if("string"===v){var m=function(e){var n,i=e.match(/^#([\da-f]{2})([\da-f]{2})([\da-f]{2})([\da-f]{2})?$/i)||e.match(/^#([\da-f])([\da-f])([\da-f])([\da-f])?$/i),a="rgb";if(i){var o=i[4]?4:3;n=new Array(o);for(var h=0;h1?1:t))}return e=[i(e[0]),i(e[1]),i(e[2])],n<1&&e.push(n<0?0:n),t?"#"+((1<<24)+(e[0]<<16)+(e[1]<<8)+e[2]).toString(16).slice(1):(4==e.length?"rgba(":"rgb(")+e.join(",")+")"},toCanvasStyle:function(t,e){if(this._canvasStyle)return this._canvasStyle;if("gradient"!==this._type)return this._canvasStyle=this.toCSS();var n,i=this._components,r=i[0],s=r._stops,a=i[1],o=i[2],h=i[3],u=e&&e.inverted();if(u&&(a=u._transformPoint(a),o=u._transformPoint(o),h&&(h=u._transformPoint(h))),r._radial){var l=o.getDistance(a);if(h){var c=h.subtract(a);c.getLength()>l&&(h=a.add(c.normalize(l-.1)))}var f=h||a;n=t.createRadialGradient(f.x,f.y,0,a.x,a.y,l)}else n=t.createLinearGradient(a.x,a.y,o.x,o.y);for(var d=0,_=s.length;d<_;d++){var g=s[d],v=g._offset;n.addColorStop(null==v?d/(_-1):v,g._color.toCanvasStyle())}return this._canvasStyle=n},transform:function(t){if("gradient"===this._type){for(var e=this._components,n=1,i=e.length;n0&&!(r instanceof B))for(var a=0,o=s.length;a0},hasStroke:function(){var t=this.getStrokeColor();return!!t&&t.alpha>0&&this.getStrokeWidth()>0},hasShadow:function(){var t=this.getShadowColor();return!!t&&t.alpha>0&&(this.getShadowBlur()>0||!this.getShadowOffset().isZero())},getView:function(){return this._project._view},getFontStyle:function(){var t=this.getFontSize();return this.getFontWeight()+" "+t+(/[a-z]/i.test(t+"")?" ":"px ")+this.getFontFamily()},getFont:"#getFontFamily",setFont:"#setFontFamily",getLeading:function t(){var e=t.base.call(this),n=this.getFontSize();return/pt|em|%|px/.test(n)&&(n=this.getView().getPixelSize(n)),null!=e?e:1.2*n}}),Z=new function(){function t(t,e,n,i){for(var r=["","webkit","moz","Moz","ms","o"],s=e[0].toUpperCase()+e.substring(1),a=0;a<6;a++){var o=r[a],h=o?o+s:e;if(h in t){if(!n)return t[h];t[h]=i;break}}}return{getStyles:function(t){var e=t&&9!==t.nodeType?t.ownerDocument:t,n=e&&e.defaultView;return n&&n.getComputedStyle(t,"")},getBounds:function(t,e){var n,i=t.ownerDocument,r=i.body,s=i.documentElement;try{n=t.getBoundingClientRect()}catch(u){n={left:0,top:0,width:0,height:0}}var a=n.left-(s.clientLeft||r.clientLeft||0),o=n.top-(s.clientTop||r.clientTop||0);if(!e){var h=i.defaultView;a+=h.pageXOffset||s.scrollLeft||r.scrollLeft,o+=h.pageYOffset||s.scrollTop||r.scrollTop}return new p(a,o,n.width,n.height)},getViewportBounds:function(t){var e=t.ownerDocument,n=e.defaultView,i=e.documentElement;return new p(0,0,n.innerWidth||i.clientWidth,n.innerHeight||i.clientHeight)},getOffset:function(t,e){return Z.getBounds(t,e).getPoint()},getSize:function(t){return Z.getBounds(t,!0).getSize()},isInvisible:function(t){return Z.getSize(t).equals(new g(0,0))},isInView:function(t){return!Z.isInvisible(t)&&Z.getViewportBounds(t).intersects(Z.getBounds(t,!0))},isInserted:function(t){return s.body.contains(t)},getPrefixed:function(e,n){return e&&t(e,n)},setPrefixed:function(e,n,r){if("object"===i(n))for(var s in n)t(e,s,!0,n[s]);else t(e,n,!0,r)}}},W={add:function(t,e){if(t)for(var n in e)for(var i=e[n],r=n.split(/[\s,]+/g),a=0,o=r.length;a1?a.hyphenate(e):e.toLowerCase())}function f(e,n,i,r){var s,o=$._focused;if(h[n]=e,e?u[n]=i:delete u[n],n.length>1&&(s=a.camelize(n))in l){l[s]=e;var c=at&&at.agent;if("meta"===s&&c&&c.mac)if(e)t={};else{for(var d in t)d in u&&f(!1,d,t[d],r);t=null}}else e&&t&&(t[n]=i);o&&o._handleKeyEvent(e?"keydown":"keyup",r,n,i)}return W.add(s,{keydown:function(t){var n=c(t),i=at&&at.agent;n.length>1||i&&i.chrome&&(t.altKey||i.mac&&t.metaKey||!i.mac&&t.ctrlKey)?f(!0,n,o[n]||(n.length>1?"":n),t):e=n},keypress:function(t){if(e){var n=c(t),i=t.charCode,r=i>=32?String.fromCharCode(i):n.length>1?"":n;n!==e&&(n=r.toLowerCase()),f(!0,n,r,t),e=null}},keyup:function(t){var e=c(t);e in u&&f(!1,e,u[e],t)}}),W.add(r,{blur:function(t){for(var e in u)f(!1,e,u[e],t)}}),{modifiers:l,isDown:function(t){return!!h[t]}}},Y=J.extend({_class:"MouseEvent",initialize:function(t,e,n,i,r){this.type=t,this.event=e,this.point=n,this.target=i,this.delta=r},toString:function(){return"{ type: '"+this.type+"', point: "+this.point+", target: "+this.target+(this.delta?", delta: "+this.delta:"")+", modifiers: "+this.getModifiers()+" }"}}),Q=J.extend({_class:"ToolEvent",_item:null,initialize:function(t,e,n){this.tool=t,this.type=e,this.event=n},_choosePoint:function(t,e){return t||(e?e.clone():null)},getPoint:function(){return this._choosePoint(this._point,this.tool._point)},setPoint:function(t){this._point=t},getLastPoint:function(){return this._choosePoint(this._lastPoint,this.tool._lastPoint)},setLastPoint:function(t){this._lastPoint=t},getDownPoint:function(){return this._choosePoint(this._downPoint,this.tool._downPoint)},setDownPoint:function(t){this._downPoint=t},getMiddlePoint:function(){return!this._middlePoint&&this.tool._lastPoint?this.tool._point.add(this.tool._lastPoint).divide(2):this._middlePoint},setMiddlePoint:function(t){this._middlePoint=t},getDelta:function(){return!this._delta&&this.tool._lastPoint?this.tool._point.subtract(this.tool._lastPoint):this._delta},setDelta:function(t){this._delta=t},getCount:function(){return this.tool[/^mouse(down|up)$/.test(this.type)?"_downCount":"_moveCount"]},setCount:function(t){this.tool[/^mouse(down|up)$/.test(this.type)?"downCount":"count"]=t},getItem:function(){if(!this._item){var t=this.tool._scope.project.hitTest(this.getPoint());if(t){for(var e=t.item,n=e._parent;/^(Group|CompoundPath)$/.test(n._class);)e=n,n=n._parent;this._item=e}}return this._item},setItem:function(t){this._item=t},toString:function(){return"{ type: "+this.type+", point: "+this.getPoint()+", count: "+this.getCount()+", modifiers: "+this.getModifiers()+" }"}}),tt=u.extend({_class:"Tool",_list:"tools",_reference:"tool",_events:["onMouseDown","onMouseUp","onMouseDrag","onMouseMove","onActivate","onDeactivate","onEditOptions","onKeyDown","onKeyUp"],initialize:function(t){u.call(this),this._moveCount=-1,this._downCount=-1,this.set(t)},getMinDistance:function(){return this._minDistance},setMinDistance:function(t){this._minDistance=t,null!=t&&null!=this._maxDistance&&t>this._maxDistance&&(this._maxDistance=t)},getMaxDistance:function(){return this._maxDistance},setMaxDistance:function(t){this._maxDistance=t,null!=this._minDistance&&null!=t&&t=0&&s.equals(a))return!1;if(a&&(null!=t||null!=e)){var o=s.subtract(a),h=o.getLength();if(h<(t||0))return!1;e&&(s=a.add(o.normalize(Math.min(h,e))))}u._moveCount++}return u._point=s,u._lastPoint=a||s,i.down&&(u._moveCount=-1,u._downPoint=s,u._downCount++),!0}function c(){s&&(h=u.emit(t,new Q(u,t,e))||h)}if(i.down)l(),c();else if(i.up)l(null,o),c();else if(s)for(;l(a,o);)c();return h}}),et={request:function(t){var n=new e.XMLHttpRequest;return n.open((t.method||"get").toUpperCase(),t.url,a.pick(t.async,!0)),t.mimeType&&n.overrideMimeType(t.mimeType),n.onload=function(){var e=n.status;0===e||200===e?t.onLoad&&t.onLoad.call(n,n.responseText):n.onerror()},n.onerror=function(){var e=n.status,i='Could not load "'+t.url+'" (Status: '+e+")";if(!t.onError)throw new Error(i);t.onError(i,e)},n.send(null)}},nt={canvases:[],getCanvas:function(t,e){if(!r)return null;var n,a=!0;"object"===i(t)&&(e=t.height,t=t.width),this.canvases.length?n=this.canvases.pop():(n=s.createElement("canvas"),a=!1);var o=n.getContext("2d");if(!o)throw new Error("Canvas "+n+" is unable to provide a 2D context.");return n.width===t&&n.height===e?a&&o.clearRect(0,0,t+1,e+1):(n.width=t,n.height=e),o.save(),n},getContext:function(t,e){var n=this.getCanvas(t,e);return n?n.getContext("2d"):null},release:function(t){var e=t&&t.canvas?t.canvas:t;e&&e.getContext&&(e.getContext("2d").restore(),this.canvases.push(e))}},it=new function(){var t,e,n,i,r,s,o,h,u,l,c,f=Math.min,d=Math.max,_=Math.abs;function g(t,e,n){return.2989*t+.587*e+.114*n}function v(t,e,n,i){var r=i-g(t,e,n),s=(i=g(u=t+r,l=e+r,c=n+r),f(u,l,c)),a=d(u,l,c);if(s<0){var o=i-s;u=i+(u-i)*i/o,l=i+(l-i)*i/o,c=i+(c-i)*i/o}if(a>255){var h=255-i,_=a-i;u=i+(u-i)*h/_,l=i+(l-i)*h/_,c=i+(c-i)*h/_}}function p(t,e,n){return d(t,e,n)-f(t,e,n)}function m(t,e,n,i){var r,s=[t,e,n],a=d(t,e,n),o=f(t,e,n);r=0===f(o=o===t?0:o===e?1:2,a=a===t?0:a===e?1:2)?1===d(o,a)?2:1:0,s[a]>s[o]?(s[r]=(s[r]-s[o])*i/(s[a]-s[o]),s[a]=i):s[r]=s[a]=0,s[o]=0,u=s[0],l=s[1],c=s[2]}var y={multiply:function(){u=r*t/255,l=s*e/255,c=o*n/255},screen:function(){u=r+t-r*t/255,l=s+e-s*e/255,c=o+n-o*n/255},overlay:function(){u=r<128?2*r*t/255:255-2*(255-r)*(255-t)/255,l=s<128?2*s*e/255:255-2*(255-s)*(255-e)/255,c=o<128?2*o*n/255:255-2*(255-o)*(255-n)/255},"soft-light":function(){var i=t*r/255;u=i+r*(255-(255-r)*(255-t)/255-i)/255,l=(i=e*s/255)+s*(255-(255-s)*(255-e)/255-i)/255,c=(i=n*o/255)+o*(255-(255-o)*(255-n)/255-i)/255},"hard-light":function(){u=t<128?2*t*r/255:255-2*(255-t)*(255-r)/255,l=e<128?2*e*s/255:255-2*(255-e)*(255-s)/255,c=n<128?2*n*o/255:255-2*(255-n)*(255-o)/255},"color-dodge":function(){u=0===r?0:255===t?255:f(255,255*r/(255-t)),l=0===s?0:255===e?255:f(255,255*s/(255-e)),c=0===o?0:255===n?255:f(255,255*o/(255-n))},"color-burn":function(){u=255===r?255:0===t?0:d(0,255-255*(255-r)/t),l=255===s?255:0===e?0:d(0,255-255*(255-s)/e),c=255===o?255:0===n?0:d(0,255-255*(255-o)/n)},darken:function(){u=rt?r:t,l=s>e?s:e,c=o>n?o:n},difference:function(){(u=r-t)<0&&(u=-u),(l=s-e)<0&&(l=-l),(c=o-n)<0&&(c=-c)},exclusion:function(){u=r+t*(255-r-r)/255,l=s+e*(255-s-s)/255,c=o+n*(255-o-o)/255},hue:function(){m(t,e,n,p(r,s,o)),v(u,l,c,g(r,s,o))},saturation:function(){m(r,s,o,p(t,e,n)),v(u,l,c,g(r,s,o))},luminosity:function(){v(r,s,o,g(t,e,n))},color:function(){v(t,e,n,g(r,s,o))},add:function(){u=f(r+t,255),l=f(s+e,255),c=f(o+n,255)},subtract:function(){u=d(r-t,0),l=d(s-e,0),c=d(o-n,0)},average:function(){u=(r+t)/2,l=(s+e)/2,c=(o+n)/2},negation:function(){u=255-_(255-t-r),l=255-_(255-e-s),c=255-_(255-n-o)}},w=this.nativeModes=a.each(["source-over","source-in","source-out","source-atop","destination-over","destination-in","destination-out","destination-atop","lighter","darker","copy","xor"],function(t){this[t]=!0},{}),x=nt.getContext(1,1);x&&(a.each(y,function(t,e){var n="darken"===e,i=!1;x.save();try{x.fillStyle=n?"#300":"#a00",x.fillRect(0,0,1,1),x.globalCompositeOperation=e,x.globalCompositeOperation===e&&(x.fillStyle=n?"#a00":"#300",x.fillRect(0,0,1,1),i=x.getImageData(0,0,1,1).data[0]!==n?170:51)}catch(r){}x.restore(),w[e]=i}),nt.release(x)),this.process=function(a,f,d,_,g){var v=f.canvas,p="normal"===a;if(p||w[a])d.save(),d.setTransform(1,0,0,1,0,0),d.globalAlpha=_,p||(d.globalCompositeOperation=a),d.drawImage(v,g.x,g.y),d.restore();else{var m=y[a];if(!m)return;for(var x=d.getImageData(g.x,g.y,v.width,v.height),b=x.data,C=f.getImageData(0,0,v.width,v.height).data,S=0,k=b.length;S=2&&!e.hasHandles())if(u>2){o=e._closed?"polygon":"polyline";for(var c=[],f=0;f3){for(n.sort(function(t,e){return e.length-t.length}),e+="switch(str.length){",i=0;i=170&&Rt.test(String.fromCharCode(t)))},Zt=t.isIdentifierChar=function(t){return t<48?36===t:t<58||!(t<65)&&(t<91||(t<97?95===t:t<123||t>=170&&qt.test(String.fromCharCode(t))))};function Wt(){this.line=g,this.column=o-v}function $t(){g=1,o=v=0,_=!0,Kt()}function Gt(t,n){u=o,e.locations&&(c=new Wt),f=t,Kt(),d=n,_=t.beforeExpr}function Jt(){var t,i=e.onComment&&e.locations&&new Wt,r=o,s=n.indexOf("*/",o+=2);if(-1===s&&S(o-2,"Unterminated comment"),o=s+2,e.locations)for(Ut.lastIndex=r;(t=Ut.exec(n))&&t.index8&&t<14)++o;else if(47===t){var r;if(42===(r=n.charCodeAt(o+1)))Jt();else{if(47!==r)break;Xt()}}else if(160===t)++o;else{if(!(t>=5760&&jt.test(String.fromCharCode(t))))break;++o}}}function Yt(t){switch(t){case 46:return function(){var t=n.charCodeAt(o+1);return t>=48&&t<=57?ie(!0):(++o,Gt(dt))}();case 40:return++o,Gt(ht);case 41:return++o,Gt(ut);case 59:return++o,Gt(ct);case 44:return++o,Gt(lt);case 91:return++o,Gt(rt);case 93:return++o,Gt(st);case 123:return++o,Gt(at);case 125:return++o,Gt(ot);case 58:return++o,Gt(ft);case 63:return++o,Gt(_t);case 48:var r=n.charCodeAt(o+1);if(120===r||88===r)return function(){o+=2;var t=ne(16);return null==t&&S(h+2,"Expected hexadecimal number"),Ht(n.charCodeAt(o))&&S(o,"Identifier directly after number"),Gt(P,t)}();case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return ie(!1);case 34:case 39:return function(t){o++;for(var r="";;){o>=i&&S(h,"Unterminated string constant");var s=n.charCodeAt(o);if(s===t)return++o,Gt(T,r);if(92===s){s=n.charCodeAt(++o);var a=/^[0-7]+/.exec(n.slice(o,o+3));for(a&&(a=a[0]);a&&parseInt(a,8)>255;)a=a.slice(0,-1);if("0"===a&&(a=null),++o,a)b&&S(o-2,"Octal literal in strict mode"),r+=String.fromCharCode(parseInt(a,8)),o+=a.length-1;else switch(s){case 110:r+="\n";break;case 114:r+="\r";break;case 120:r+=String.fromCharCode(re(2));break;case 117:r+=String.fromCharCode(re(4));break;case 85:r+=String.fromCharCode(re(8));break;case 116:r+="\t";break;case 98:r+="\b";break;case 118:r+="\v";break;case 102:r+="\f";break;case 48:r+="\0";break;case 13:10===n.charCodeAt(o)&&++o;case 10:e.locations&&(v=o,++g);break;default:r+=String.fromCharCode(s)}}else 13!==s&&10!==s&&8232!==s&&8233!==s||S(h,"Unterminated string constant"),r+=String.fromCharCode(s),++o}}(t);case 47:return function(){var t=n.charCodeAt(o+1);return _?(++o,ee()):61===t?te(pt,2):te(gt,1)}();case 37:case 42:return 61===n.charCodeAt(o+1)?te(pt,2):te(Tt,1);case 124:case 38:return function(t){var e=n.charCodeAt(o+1);return e===t?te(124===t?wt:xt,2):61===e?te(pt,2):te(124===t?bt:St,1)}(t);case 94:return 61===n.charCodeAt(o+1)?te(pt,2):te(Ct,1);case 43:case 45:return function(t){var e=n.charCodeAt(o+1);return e===t?45==e&&62==n.charCodeAt(o+2)&&Vt.test(n.slice(m,o))?(o+=3,Xt(),Kt(),Qt()):te(mt,2):61===e?te(pt,2):te(Mt,1)}(t);case 60:case 62:return function(t){var e=n.charCodeAt(o+1),i=1;return e===t?(i=62===t&&62===n.charCodeAt(o+2)?3:2,61===n.charCodeAt(o+i)?te(pt,i+1):te(Pt,i)):33==e&&60==t&&45==n.charCodeAt(o+2)&&45==n.charCodeAt(o+3)?(o+=4,Xt(),Kt(),Qt()):(61===e&&(i=61===n.charCodeAt(o+2)?3:2),te(It,i))}(t);case 61:case 33:return function(t){return 61===n.charCodeAt(o+1)?te(kt,61===n.charCodeAt(o+2)?3:2):te(61===t?vt:yt,1)}(t);case 126:return te(yt,1)}return!1}function Qt(t){if(t?o=h+1:h=o,e.locations&&(l=new Wt),t)return ee();if(o>=i)return Gt(z);var r=n.charCodeAt(o);if(Ht(r)||92===r)return ae();var s=Yt(r);if(!1===s){var a=String.fromCharCode(r);if("\\"===a||Rt.test(a))return ae();S(o,"Unexpected character '"+a+"'")}return s}function te(t,e){var i=n.slice(o,o+e);o+=e,Gt(t,i)}function ee(){for(var t,e,r=o;;){o>=i&&S(r,"Unterminated regular expression");var s=n.charAt(o);if(Vt.test(s)&&S(r,"Unterminated regular expression"),t)t=!1;else{if("["===s)e=!0;else if("]"===s&&e)e=!1;else if("/"===s&&!e)break;t="\\"===s}++o}var a=n.slice(r,o);++o;var h=se();h&&!/^[gmsiy]*$/.test(h)&&S(r,"Invalid regexp flag");try{var u=new RegExp(a,h)}catch(k){k instanceof SyntaxError&&S(r,k.message),S(k)}return Gt(M,u)}function ne(t,e){for(var i=o,r=0,s=0,a=null==e?1/0:e;s=97?u-97+10:u>=65?u-65+10:u>=48&&u<=57?u-48:1/0)>=t)break;++o,r=r*t+h}return o===i||null!=e&&o-i!==e?null:r}function ie(t){var e=o,i=!1,r=48===n.charCodeAt(o);t||null!==ne(10)||S(e,"Invalid number"),46===n.charCodeAt(o)&&(++o,ne(10),i=!0);var s=n.charCodeAt(o);69!==s&&101!==s||(43!==(s=n.charCodeAt(++o))&&45!==s||++o,null===ne(10)&&S(e,"Invalid number"),i=!0),Ht(n.charCodeAt(o))&&S(o,"Identifier directly after number");var a,h=n.slice(e,o);return i?a=parseFloat(h):r&&1!==h.length?/[89]/.test(h)||b?S(e,"Invalid number"):a=parseInt(h,8):a=parseInt(h,10),Gt(P,a)}function re(t){var e=ne(16,t);return null===e&&S(h,"Bad character escape sequence"),e}function se(){Ot=!1;for(var t,e=!0,i=o;;){var r=n.charCodeAt(o);if(Zt(r))Ot&&(t+=n.charAt(o)),++o;else{if(92!==r)break;Ot||(t=n.slice(i,o)),Ot=!0,117!=n.charCodeAt(++o)&&S(o,"Expecting Unicode escape sequence \\uXXXX"),++o;var s=re(4),a=String.fromCharCode(s);a||S(o-1,"Invalid Unicode escape"),(e?Ht(s):Zt(s))||S(o-4,"Invalid Unicode escape"),t+=a}e=!1}return Ot?t:n.slice(i,o)}function ae(){var t=se(),e=A;return!Ot&&Ft(t)&&(e=it[t]),Gt(e,t)}function oe(){p=h,m=u,y=c,Qt()}function he(t){if(b=t,o=h,e.locations)for(;o=5&&"ExpressionStatement"===t.type&&"Literal"===t.expression.type&&"use strict"===t.expression.value}function ge(t){if(f===t)return oe(),!0}function ve(){return!e.strictSemicolons&&(f===z||f===ot||Vt.test(n.slice(m,h)))}function pe(){ge(ct)||ve()||ye()}function me(t){f===t?oe():ye()}function ye(){S(h,"Unexpected token")}function we(t){"Identifier"!==t.type&&"MemberExpression"!==t.type&&S(t.start,"Assigning to rvalue"),b&&"Identifier"===t.type&&Bt(t.name)&&S(t.start,"Assigning to "+t.name+" in strict mode")}var xe={kind:"loop"},be={kind:"switch"};function Ce(){(f===gt||f===pt&&"/="==d)&&Qt(!0);var t=f,i=ce();switch(t){case O:case N:oe();var r=t===O;ge(ct)||ve()?i.label=null:f!==A?ye():(i.label=Fe(),pe());for(var s=0;sn){var s=fe(e);s.left=e,s.operator=d;var a=f;oe(),s.right=t(ze(),r,i);var o=de(s,a===wt||a===xt?"LogicalExpression":"BinaryExpression");return t(o,n,i)}return e}(ze(),-1,t)}(t);if(ge(_t)){var n=fe(e);return n.test=e,n.consequent=Te(!0),me(ft),n.alternate=Te(!0,t),de(n,"ConditionalExpression")}return e}(t);if(f.isAssign){var n=fe(e);return n.operator=d,n.left=e,oe(),n.right=Ae(t),we(e),de(n,"AssignmentExpression")}return e}function ze(){if(f.prefix){var t=ce(),e=f.isUpdate;return t.operator=d,t.prefix=!0,_=!0,oe(),t.argument=ze(),e?we(t.argument):b&&"delete"===t.operator&&"Identifier"===t.argument.type&&S(t.start,"Deleting local variable in strict mode"),de(t,e?"UpdateExpression":"UnaryExpression")}for(var n=Oe(Le());f.postfix&&!ve();)(t=fe(n)).operator=d,t.prefix=!1,t.argument=n,we(n),oe(),n=de(t,"UpdateExpression");return n}function Oe(t,e){var n;return ge(dt)?((n=fe(t)).object=t,n.property=Fe(!0),n.computed=!1,Oe(de(n,"MemberExpression"),e)):ge(rt)?((n=fe(t)).object=t,n.property=Te(),n.computed=!0,me(st),Oe(de(n,"MemberExpression"),e)):!e&&ge(ht)?((n=fe(t)).callee=t,n.arguments=Be(ut,!1),Oe(de(n,"CallExpression"),e)):t}function Le(){switch(f){case Y:var t=ce();return oe(),de(t,"ThisExpression");case A:return Fe();case P:case T:case M:return(t=ce()).value=d,t.raw=n.slice(h,u),oe(),de(t,"Literal");case Q:case tt:case et:return(t=ce()).value=f.atomValue,t.raw=f.keyword,oe(),de(t,"Literal");case ht:var i=l,r=h;oe();var s=Te();return s.start=r,s.end=u,e.locations&&(s.loc.start=i,s.loc.end=c),e.ranges&&(s.range=[r,u]),me(ut),s;case rt:return t=ce(),oe(),t.elements=Be(st,!0,!0),de(t,"ArrayExpression");case at:return function(){var t=ce(),n=!0,i=!1;for(t.properties=[],oe();!ge(ot);){if(n)n=!1;else if(me(lt),e.allowTrailingCommas&&ge(ot))break;var r,s={key:Ee()},a=!1;if(ge(ft)?(s.value=Te(!0),r=s.kind="init"):e.ecmaVersion>=5&&"Identifier"===s.key.type&&("get"===s.key.name||"set"===s.key.name)?(a=i=!0,r=s.kind=s.key.name,s.key=Ee(),f!==ht&&ye(),s.value=Ne(ce(),!1)):ye(),"Identifier"===s.key.type&&(b||i))for(var o=0;o=0)for(var o=0;o=t)break;t+=i[1]}return t}function h(e){return t.substring(o(e.range[0]),o(e.range[1]))}function u(e,n){for(var i=o(e.range[0]),r=o(e.range[1]),s=0,h=a.length-1;h>=0;h--)if(i>a[h][0]){s=h+1;break}a.splice(s,0,[i,n.length-r+i]),t=t.substring(0,i)+n+t.substring(r)}var l,c=(n=n||{}).url||"",f=at.agent,d=f.versionNumber,g=!1,m=n.sourceMaps,y=n.source||t,w=/\r\n|\n|\r/gm,x=n.offset||0;if(m&&(f.chrome&&d>=30||f.webkit&&d>=537.76||f.firefox&&d>=23||f.node)){if(f.node)x-=2;else if(r&&c&&!r.location.href.indexOf(c)){var b=s.getElementsByTagName("html")[0].innerHTML;x=b.substr(0,b.indexOf(t)+1).match(w).length+1}var C=["AA"+function(t){var e="";for(t=(Math.abs(t)<<1)+(t<0?1:0);t||!e;){var n=31&t;(t>>=5)&&(n|=32),e+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[n]}return e}((g=x>0&&!(f.chrome&&d>=36||f.safari&&d>=600||f.firefox&&d>=40||f.node))?0:x)+"A"];C.length=(t.match(w)||[]).length+1+(g?x:0),l={version:3,file:c,names:[],mappings:C.join(";AACA"),sourceRoot:"",sources:[c],sourcesContent:[y]}}return function e(n,r){if(n){for(var s in n)if("range"!==s&&"loc"!==s){var a=n[s];if(Array.isArray(a))for(var l=0,c=a.length;l]/.test(r.operator)||"MemberExpression"===y&&r.computed))if("UpdateExpression"===n.type){var w=(f=h(n.argument))+" = "+(x="__$__("+f+', "'+n.operator[0]+'", 1)');n.prefix||"AssignmentExpression"!==y&&"VariableDeclarator"!==y||(h(r.left||r.id)===f&&(w=x),w=f+"; "+w),u(n,w)}else if(/^.=$/.test(n.operator)&&"Literal"!==n.left.type){d=h(n.left),_=h(n.right);var x=d+" = __$__("+d+', "'+n.operator[0]+'", '+_+")";u(n,/^\(.*\)$/.test(h(n))?"("+x+")":x)}break;case"ExportDefaultDeclaration":u({range:[n.start,n.declaration.start]},"module.exports = ");break;case"ExportNamedDeclaration":var b=n.declaration,C=n.specifiers;if(b){var S=b.declarations;S&&(S.forEach(function(t){u(t,"module.exports."+h(t))}),u({range:[n.start,b.start+b.kind.length]},""))}else if(C){var k=C.map(function(t){var e=h(t);return"module.exports."+e+" = "+e+"; "}).join("");k&&u(n,k)}}}}(_(t,{ranges:!0,preserveParens:!0,sourceType:"module"})),l&&(g&&(t=new Array(x+1).join("\n")+t),/^(inline|both)$/.test(m)&&(t+="\n"+e.btoa(unescape(encodeURIComponent(JSON.stringify(l))))),t+="\n//# sourceURL="+(c||"paperscript")),{url:c,source:y,code:t,map:l}}function b(t,e,n){at=e;var r,o=e.getView(),h=/\btool\.\w+|\s+on(?:Key|Mouse)(?:Up|Down|Move|Drag)\b/.test(t)&&!/\bnew\s+Tool\b/.test(t)?new tt:null,u=h?h._events:[],l=["onFrame","onResize"].concat(u),c=[],f=[],_="object"===i(t)?t:x(t,n);function g(e,n){for(var i in e)!n&&/^_/.test(i)||!new RegExp("([\\b\\s\\W]|^)"+i.replace(/\$/g,"\\$")+"\\b").test(t)||(c.push(i),f.push(e[i]))}t=_.code,g({__$__:y,$__:w,paper:e,view:o,tool:h},!0),g(e),t="var module = { exports: {} }; "+t,(b=a.each(l,function(e){new RegExp("\\s+"+e+"\\b").test(t)&&(c.push(e),this.push("module.exports."+e+" = "+e+";"))},[]).join("\n"))&&(t+="\n"+b),t+="\nreturn module.exports;";var v=at.agent;if(s&&(v.chrome||v.firefox&&v.versionNumber<40)){var p=s.createElement("script"),m=s.head||s.getElementsByTagName("head")[0];v.firefox&&(t="\n"+t),p.appendChild(s.createTextNode("document.__paperscript__ = function("+c+") {"+t+"\n}")),m.appendChild(p),r=s.__paperscript__,delete s.__paperscript__,m.removeChild(p)}else r=Function(c,t);var b,C=(b=r&&r.apply(e,f))||{};return a.each(u,function(t){var e=C[t];e&&(h[t]=e)}),o&&(C.onResize&&o.setOnResize(C.onResize),o.emit("resize",{size:o.size,delta:new d}),C.onFrame&&o.setOnFrame(C.onFrame),o.requestUpdate()),b}function C(t){if(/^text\/(?:x-|)paperscript$/.test(t.type)&&"true"!==h.getAttribute(t,"ignore")){var e=h.getAttribute(t,"canvas"),n=s.getElementById(e),i=t.src||t.getAttribute("data-src"),r=h.hasAttribute(t,"async");if(!n)throw new Error('Unable to find canvas with id "'+e+'"');var a=h.get(n.getAttribute("data-paper-scope"))||(new h).setup(n);return n.setAttribute("data-paper-scope",a._id),i?et.request({url:i,async:r,mimeType:"text/plain",onLoad:function(t){b(t,a,i)}}):b(t.innerHTML,a,t.baseURI),t.setAttribute("data-paper-ignore","true"),a}}function S(){a.each(s&&s.getElementsByTagName("script"),C)}return d.inject(m),g.inject(m),q.inject(m),r&&("complete"===s.readyState?setTimeout(S):W.add(r,{load:S})),{compile:x,execute:b,load:function(t){return t?C(t):S()},parse:_}}.call(this);var at=new(h.inject(a.exports,{Base:a,Numerical:c,Key:K,DomEvent:W,DomElement:Z,document:s,window:r,Symbol:M,PlacedSymbol:P}));return at.agent.node&&require("./node/extend.js")(at),"function"==typeof t&&t.amd?t("paper",at):"object"===("undefined"==typeof module?"undefined":i(module))&&module&&(module.exports=at),at}.call(this,"object"===("undefined"==typeof self?"undefined":i(self))?self:null); -},{"./node/self.js":"sC8V","acorn":"8W3y","./node/extend.js":"sC8V","process":"g5I+"}],"2Rhj":[function(require,module,exports) { -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=void 0;var t=e(require("paper"));function e(t){return t&&t.__esModule?t:{default:t}}function n(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(t){return!1}}function r(t,e,i){return(r=n()?Reflect.construct:function(t,e,n){var r=[null];r.push.apply(r,e);var i=new(Function.bind.apply(t,r));return n&&o(i,n.prototype),i}).apply(null,arguments)}function o(t,e){return(o=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function i(t){return c(t)||a(t)||u()}function u(){throw new TypeError("Invalid attempt to spread non-iterable instance")}function a(t){if(Symbol.iterator in Object(t)||"[object Arguments]"===Object.prototype.toString.call(t))return Array.from(t)}function c(t){if(Array.isArray(t)){for(var e=0,n=new Array(t.length);e0xffff code points that are a valid part of identifiers. The\n// offset starts at 0x10000, and each pair of numbers represents an\n// offset to the next range, and then a size of the range. They were\n// generated by bin/generate-identifier-regex.js\n\n// eslint-disable-next-line comma-spacing\nvar astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,477,28,11,0,9,21,190,52,76,44,33,24,27,35,30,0,12,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,26,230,43,117,63,32,0,257,0,11,39,8,0,22,0,12,39,3,3,20,0,35,56,264,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,328,18,270,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,689,63,129,68,12,0,67,12,65,1,31,6129,15,754,9486,286,82,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,60,67,1213,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,15,7472,3104,541];\n\n// eslint-disable-next-line comma-spacing\nvar astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,525,10,176,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,4,9,83,11,7,0,161,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,243,14,166,9,280,9,41,6,2,3,9,0,10,10,47,15,406,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,330,3,19306,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,2214,6,110,6,6,9,792487,239];\n\n// This has a complexity linear to the value of the code. The\n// assumption is that looking up astral identifier characters is\n// rare.\nfunction isInAstralSet(code, set) {\n var pos = 0x10000;\n for (var i = 0; i < set.length; i += 2) {\n pos += set[i];\n if (pos > code) { return false }\n pos += set[i + 1];\n if (pos >= code) { return true }\n }\n}\n\n// Test whether a given character code starts an identifier.\n\nfunction isIdentifierStart(code, astral) {\n if (code < 65) { return code === 36 }\n if (code < 91) { return true }\n if (code < 97) { return code === 95 }\n if (code < 123) { return true }\n if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) }\n if (astral === false) { return false }\n return isInAstralSet(code, astralIdentifierStartCodes)\n}\n\n// Test whether a given character is part of an identifier.\n\nfunction isIdentifierChar(code, astral) {\n if (code < 48) { return code === 36 }\n if (code < 58) { return true }\n if (code < 65) { return false }\n if (code < 91) { return true }\n if (code < 97) { return code === 95 }\n if (code < 123) { return true }\n if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) }\n if (astral === false) { return false }\n return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes)\n}\n\n// ## Token types\n\n// The assignment of fine-grained, information-carrying type objects\n// allows the tokenizer to store the information it has about a\n// token in a way that is very cheap for the parser to look up.\n\n// All token type variables start with an underscore, to make them\n// easy to recognize.\n\n// The `beforeExpr` property is used to disambiguate between regular\n// expressions and divisions. It is set on all token types that can\n// be followed by an expression (thus, a slash after them would be a\n// regular expression).\n//\n// The `startsExpr` property is used to check if the token ends a\n// `yield` expression. It is set on all token types that either can\n// directly start an expression (like a quotation mark) or can\n// continue an expression (like the body of a string).\n//\n// `isLoop` marks a keyword as starting a loop, which is important\n// to know when parsing a label, in order to allow or disallow\n// continue jumps to that label.\n\nvar TokenType = function TokenType(label, conf) {\n if ( conf === void 0 ) conf = {};\n\n this.label = label;\n this.keyword = conf.keyword;\n this.beforeExpr = !!conf.beforeExpr;\n this.startsExpr = !!conf.startsExpr;\n this.isLoop = !!conf.isLoop;\n this.isAssign = !!conf.isAssign;\n this.prefix = !!conf.prefix;\n this.postfix = !!conf.postfix;\n this.binop = conf.binop || null;\n this.updateContext = null;\n};\n\nfunction binop(name, prec) {\n return new TokenType(name, {beforeExpr: true, binop: prec})\n}\nvar beforeExpr = {beforeExpr: true};\nvar startsExpr = {startsExpr: true};\n\n// Map keyword names to token types.\n\nvar keywords$1 = {};\n\n// Succinct definitions of keyword token types\nfunction kw(name, options) {\n if ( options === void 0 ) options = {};\n\n options.keyword = name;\n return keywords$1[name] = new TokenType(name, options)\n}\n\nvar types = {\n num: new TokenType(\"num\", startsExpr),\n regexp: new TokenType(\"regexp\", startsExpr),\n string: new TokenType(\"string\", startsExpr),\n name: new TokenType(\"name\", startsExpr),\n eof: new TokenType(\"eof\"),\n\n // Punctuation token types.\n bracketL: new TokenType(\"[\", {beforeExpr: true, startsExpr: true}),\n bracketR: new TokenType(\"]\"),\n braceL: new TokenType(\"{\", {beforeExpr: true, startsExpr: true}),\n braceR: new TokenType(\"}\"),\n parenL: new TokenType(\"(\", {beforeExpr: true, startsExpr: true}),\n parenR: new TokenType(\")\"),\n comma: new TokenType(\",\", beforeExpr),\n semi: new TokenType(\";\", beforeExpr),\n colon: new TokenType(\":\", beforeExpr),\n dot: new TokenType(\".\"),\n question: new TokenType(\"?\", beforeExpr),\n arrow: new TokenType(\"=>\", beforeExpr),\n template: new TokenType(\"template\"),\n invalidTemplate: new TokenType(\"invalidTemplate\"),\n ellipsis: new TokenType(\"...\", beforeExpr),\n backQuote: new TokenType(\"`\", startsExpr),\n dollarBraceL: new TokenType(\"${\", {beforeExpr: true, startsExpr: true}),\n\n // Operators. These carry several kinds of properties to help the\n // parser use them properly (the presence of these properties is\n // what categorizes them as operators).\n //\n // `binop`, when present, specifies that this operator is a binary\n // operator, and will refer to its precedence.\n //\n // `prefix` and `postfix` mark the operator as a prefix or postfix\n // unary operator.\n //\n // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as\n // binary operators with a very low precedence, that should result\n // in AssignmentExpression nodes.\n\n eq: new TokenType(\"=\", {beforeExpr: true, isAssign: true}),\n assign: new TokenType(\"_=\", {beforeExpr: true, isAssign: true}),\n incDec: new TokenType(\"++/--\", {prefix: true, postfix: true, startsExpr: true}),\n prefix: new TokenType(\"!/~\", {beforeExpr: true, prefix: true, startsExpr: true}),\n logicalOR: binop(\"||\", 1),\n logicalAND: binop(\"&&\", 2),\n bitwiseOR: binop(\"|\", 3),\n bitwiseXOR: binop(\"^\", 4),\n bitwiseAND: binop(\"&\", 5),\n equality: binop(\"==/!=/===/!==\", 6),\n relational: binop(\"/<=/>=\", 7),\n bitShift: binop(\"<>/>>>\", 8),\n plusMin: new TokenType(\"+/-\", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),\n modulo: binop(\"%\", 10),\n star: binop(\"*\", 10),\n slash: binop(\"/\", 10),\n starstar: new TokenType(\"**\", {beforeExpr: true}),\n\n // Keyword token types.\n _break: kw(\"break\"),\n _case: kw(\"case\", beforeExpr),\n _catch: kw(\"catch\"),\n _continue: kw(\"continue\"),\n _debugger: kw(\"debugger\"),\n _default: kw(\"default\", beforeExpr),\n _do: kw(\"do\", {isLoop: true, beforeExpr: true}),\n _else: kw(\"else\", beforeExpr),\n _finally: kw(\"finally\"),\n _for: kw(\"for\", {isLoop: true}),\n _function: kw(\"function\", startsExpr),\n _if: kw(\"if\"),\n _return: kw(\"return\", beforeExpr),\n _switch: kw(\"switch\"),\n _throw: kw(\"throw\", beforeExpr),\n _try: kw(\"try\"),\n _var: kw(\"var\"),\n _const: kw(\"const\"),\n _while: kw(\"while\", {isLoop: true}),\n _with: kw(\"with\"),\n _new: kw(\"new\", {beforeExpr: true, startsExpr: true}),\n _this: kw(\"this\", startsExpr),\n _super: kw(\"super\", startsExpr),\n _class: kw(\"class\", startsExpr),\n _extends: kw(\"extends\", beforeExpr),\n _export: kw(\"export\"),\n _import: kw(\"import\"),\n _null: kw(\"null\", startsExpr),\n _true: kw(\"true\", startsExpr),\n _false: kw(\"false\", startsExpr),\n _in: kw(\"in\", {beforeExpr: true, binop: 7}),\n _instanceof: kw(\"instanceof\", {beforeExpr: true, binop: 7}),\n _typeof: kw(\"typeof\", {beforeExpr: true, prefix: true, startsExpr: true}),\n _void: kw(\"void\", {beforeExpr: true, prefix: true, startsExpr: true}),\n _delete: kw(\"delete\", {beforeExpr: true, prefix: true, startsExpr: true})\n};\n\n// Matches a whole line break (where CRLF is considered a single\n// line break). Used to count lines.\n\nvar lineBreak = /\\r\\n?|\\n|\\u2028|\\u2029/;\nvar lineBreakG = new RegExp(lineBreak.source, \"g\");\n\nfunction isNewLine(code, ecma2019String) {\n return code === 10 || code === 13 || (!ecma2019String && (code === 0x2028 || code === 0x2029))\n}\n\nvar nonASCIIwhitespace = /[\\u1680\\u180e\\u2000-\\u200a\\u202f\\u205f\\u3000\\ufeff]/;\n\nvar skipWhiteSpace = /(?:\\s|\\/\\/.*|\\/\\*[^]*?\\*\\/)*/g;\n\nvar ref = Object.prototype;\nvar hasOwnProperty = ref.hasOwnProperty;\nvar toString = ref.toString;\n\n// Checks if an object has a property.\n\nfunction has(obj, propName) {\n return hasOwnProperty.call(obj, propName)\n}\n\nvar isArray = Array.isArray || (function (obj) { return (\n toString.call(obj) === \"[object Array]\"\n); });\n\n// These are used when `options.locations` is on, for the\n// `startLoc` and `endLoc` properties.\n\nvar Position = function Position(line, col) {\n this.line = line;\n this.column = col;\n};\n\nPosition.prototype.offset = function offset (n) {\n return new Position(this.line, this.column + n)\n};\n\nvar SourceLocation = function SourceLocation(p, start, end) {\n this.start = start;\n this.end = end;\n if (p.sourceFile !== null) { this.source = p.sourceFile; }\n};\n\n// The `getLineInfo` function is mostly useful when the\n// `locations` option is off (for performance reasons) and you\n// want to find the line/column position for a given character\n// offset. `input` should be the code string that the offset refers\n// into.\n\nfunction getLineInfo(input, offset) {\n for (var line = 1, cur = 0;;) {\n lineBreakG.lastIndex = cur;\n var match = lineBreakG.exec(input);\n if (match && match.index < offset) {\n ++line;\n cur = match.index + match[0].length;\n } else {\n return new Position(line, offset - cur)\n }\n }\n}\n\n// A second optional argument can be given to further configure\n// the parser process. These options are recognized:\n\nvar defaultOptions = {\n // `ecmaVersion` indicates the ECMAScript version to parse. Must\n // be either 3, 5, 6 (2015), 7 (2016), or 8 (2017). This influences support\n // for strict mode, the set of reserved words, and support for\n // new syntax features. The default is 7.\n ecmaVersion: 7,\n // `sourceType` indicates the mode the code should be parsed in.\n // Can be either `\"script\"` or `\"module\"`. This influences global\n // strict mode and parsing of `import` and `export` declarations.\n sourceType: \"script\",\n // `onInsertedSemicolon` can be a callback that will be called\n // when a semicolon is automatically inserted. It will be passed\n // th position of the comma as an offset, and if `locations` is\n // enabled, it is given the location as a `{line, column}` object\n // as second argument.\n onInsertedSemicolon: null,\n // `onTrailingComma` is similar to `onInsertedSemicolon`, but for\n // trailing commas.\n onTrailingComma: null,\n // By default, reserved words are only enforced if ecmaVersion >= 5.\n // Set `allowReserved` to a boolean value to explicitly turn this on\n // an off. When this option has the value \"never\", reserved words\n // and keywords can also not be used as property names.\n allowReserved: null,\n // When enabled, a return at the top level is not considered an\n // error.\n allowReturnOutsideFunction: false,\n // When enabled, import/export statements are not constrained to\n // appearing at the top of the program.\n allowImportExportEverywhere: false,\n // When enabled, await identifiers are allowed to appear at the top-level scope,\n // but they are still not allowed in non-async functions.\n allowAwaitOutsideFunction: false,\n // When enabled, hashbang directive in the beginning of file\n // is allowed and treated as a line comment.\n allowHashBang: false,\n // When `locations` is on, `loc` properties holding objects with\n // `start` and `end` properties in `{line, column}` form (with\n // line being 1-based and column 0-based) will be attached to the\n // nodes.\n locations: false,\n // A function can be passed as `onToken` option, which will\n // cause Acorn to call that function with object in the same\n // format as tokens returned from `tokenizer().getToken()`. Note\n // that you are not allowed to call the parser from the\n // callback—that will corrupt its internal state.\n onToken: null,\n // A function can be passed as `onComment` option, which will\n // cause Acorn to call that function with `(block, text, start,\n // end)` parameters whenever a comment is skipped. `block` is a\n // boolean indicating whether this is a block (`/* */`) comment,\n // `text` is the content of the comment, and `start` and `end` are\n // character offsets that denote the start and end of the comment.\n // When the `locations` option is on, two more parameters are\n // passed, the full `{line, column}` locations of the start and\n // end of the comments. Note that you are not allowed to call the\n // parser from the callback—that will corrupt its internal state.\n onComment: null,\n // Nodes have their start and end characters offsets recorded in\n // `start` and `end` properties (directly on the node, rather than\n // the `loc` object, which holds line/column data. To also add a\n // [semi-standardized][range] `range` property holding a `[start,\n // end]` array with the same numbers, set the `ranges` option to\n // `true`.\n //\n // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678\n ranges: false,\n // It is possible to parse multiple files into a single AST by\n // passing the tree produced by parsing the first file as\n // `program` option in subsequent parses. This will add the\n // toplevel forms of the parsed file to the `Program` (top) node\n // of an existing parse tree.\n program: null,\n // When `locations` is on, you can pass this to record the source\n // file in every node's `loc` object.\n sourceFile: null,\n // This value, if given, is stored in every node, whether\n // `locations` is on or off.\n directSourceFile: null,\n // When enabled, parenthesized expressions are represented by\n // (non-standard) ParenthesizedExpression nodes\n preserveParens: false,\n plugins: {}\n};\n\n// Interpret and default an options object\n\nfunction getOptions(opts) {\n var options = {};\n\n for (var opt in defaultOptions)\n { options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; }\n\n if (options.ecmaVersion >= 2015)\n { options.ecmaVersion -= 2009; }\n\n if (options.allowReserved == null)\n { options.allowReserved = options.ecmaVersion < 5; }\n\n if (isArray(options.onToken)) {\n var tokens = options.onToken;\n options.onToken = function (token) { return tokens.push(token); };\n }\n if (isArray(options.onComment))\n { options.onComment = pushComment(options, options.onComment); }\n\n return options\n}\n\nfunction pushComment(options, array) {\n return function(block, text, start, end, startLoc, endLoc) {\n var comment = {\n type: block ? \"Block\" : \"Line\",\n value: text,\n start: start,\n end: end\n };\n if (options.locations)\n { comment.loc = new SourceLocation(this, startLoc, endLoc); }\n if (options.ranges)\n { comment.range = [start, end]; }\n array.push(comment);\n }\n}\n\n// Registered plugins\nvar plugins = {};\n\nfunction keywordRegexp(words) {\n return new RegExp(\"^(?:\" + words.replace(/ /g, \"|\") + \")$\")\n}\n\nvar Parser = function Parser(options, input, startPos) {\n this.options = options = getOptions(options);\n this.sourceFile = options.sourceFile;\n this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]);\n var reserved = \"\";\n if (!options.allowReserved) {\n for (var v = options.ecmaVersion;; v--)\n { if (reserved = reservedWords[v]) { break } }\n if (options.sourceType === \"module\") { reserved += \" await\"; }\n }\n this.reservedWords = keywordRegexp(reserved);\n var reservedStrict = (reserved ? reserved + \" \" : \"\") + reservedWords.strict;\n this.reservedWordsStrict = keywordRegexp(reservedStrict);\n this.reservedWordsStrictBind = keywordRegexp(reservedStrict + \" \" + reservedWords.strictBind);\n this.input = String(input);\n\n // Used to signal to callers of `readWord1` whether the word\n // contained any escape sequences. This is needed because words with\n // escape sequences must not be interpreted as keywords.\n this.containsEsc = false;\n\n // Load plugins\n this.loadPlugins(options.plugins);\n\n // Set up token state\n\n // The current position of the tokenizer in the input.\n if (startPos) {\n this.pos = startPos;\n this.lineStart = this.input.lastIndexOf(\"\\n\", startPos - 1) + 1;\n this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;\n } else {\n this.pos = this.lineStart = 0;\n this.curLine = 1;\n }\n\n // Properties of the current token:\n // Its type\n this.type = types.eof;\n // For tokens that include more information than their type, the value\n this.value = null;\n // Its start and end offset\n this.start = this.end = this.pos;\n // And, if locations are used, the {line, column} object\n // corresponding to those offsets\n this.startLoc = this.endLoc = this.curPosition();\n\n // Position information for the previous token\n this.lastTokEndLoc = this.lastTokStartLoc = null;\n this.lastTokStart = this.lastTokEnd = this.pos;\n\n // The context stack is used to superficially track syntactic\n // context to predict whether a regular expression is allowed in a\n // given position.\n this.context = this.initialContext();\n this.exprAllowed = true;\n\n // Figure out if it's a module code.\n this.inModule = options.sourceType === \"module\";\n this.strict = this.inModule || this.strictDirective(this.pos);\n\n // Used to signify the start of a potential arrow function\n this.potentialArrowAt = -1;\n\n // Flags to track whether we are in a function, a generator, an async function.\n this.inFunction = this.inGenerator = this.inAsync = false;\n // Positions to delayed-check that yield/await does not exist in default parameters.\n this.yieldPos = this.awaitPos = 0;\n // Labels in scope.\n this.labels = [];\n\n // If enabled, skip leading hashbang line.\n if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === \"#!\")\n { this.skipLineComment(2); }\n\n // Scope tracking for duplicate variable names (see scope.js)\n this.scopeStack = [];\n this.enterFunctionScope();\n\n // For RegExp validation\n this.regexpState = null;\n};\n\n// DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them\nParser.prototype.isKeyword = function isKeyword (word) { return this.keywords.test(word) };\nParser.prototype.isReservedWord = function isReservedWord (word) { return this.reservedWords.test(word) };\n\nParser.prototype.extend = function extend (name, f) {\n this[name] = f(this[name]);\n};\n\nParser.prototype.loadPlugins = function loadPlugins (pluginConfigs) {\n var this$1 = this;\n\n for (var name in pluginConfigs) {\n var plugin = plugins[name];\n if (!plugin) { throw new Error(\"Plugin '\" + name + \"' not found\") }\n plugin(this$1, pluginConfigs[name]);\n }\n};\n\nParser.prototype.parse = function parse () {\n var node = this.options.program || this.startNode();\n this.nextToken();\n return this.parseTopLevel(node)\n};\n\nvar pp = Parser.prototype;\n\n// ## Parser utilities\n\nvar literal = /^(?:'((?:\\\\.|[^'])*?)'|\"((?:\\\\.|[^\"])*?)\"|;)/;\npp.strictDirective = function(start) {\n var this$1 = this;\n\n for (;;) {\n skipWhiteSpace.lastIndex = start;\n start += skipWhiteSpace.exec(this$1.input)[0].length;\n var match = literal.exec(this$1.input.slice(start));\n if (!match) { return false }\n if ((match[1] || match[2]) === \"use strict\") { return true }\n start += match[0].length;\n }\n};\n\n// Predicate that tests whether the next token is of the given\n// type, and if yes, consumes it as a side effect.\n\npp.eat = function(type) {\n if (this.type === type) {\n this.next();\n return true\n } else {\n return false\n }\n};\n\n// Tests whether parsed token is a contextual keyword.\n\npp.isContextual = function(name) {\n return this.type === types.name && this.value === name && !this.containsEsc\n};\n\n// Consumes contextual keyword if possible.\n\npp.eatContextual = function(name) {\n if (!this.isContextual(name)) { return false }\n this.next();\n return true\n};\n\n// Asserts that following token is given contextual keyword.\n\npp.expectContextual = function(name) {\n if (!this.eatContextual(name)) { this.unexpected(); }\n};\n\n// Test whether a semicolon can be inserted at the current position.\n\npp.canInsertSemicolon = function() {\n return this.type === types.eof ||\n this.type === types.braceR ||\n lineBreak.test(this.input.slice(this.lastTokEnd, this.start))\n};\n\npp.insertSemicolon = function() {\n if (this.canInsertSemicolon()) {\n if (this.options.onInsertedSemicolon)\n { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); }\n return true\n }\n};\n\n// Consume a semicolon, or, failing that, see if we are allowed to\n// pretend that there is a semicolon at this position.\n\npp.semicolon = function() {\n if (!this.eat(types.semi) && !this.insertSemicolon()) { this.unexpected(); }\n};\n\npp.afterTrailingComma = function(tokType, notNext) {\n if (this.type === tokType) {\n if (this.options.onTrailingComma)\n { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); }\n if (!notNext)\n { this.next(); }\n return true\n }\n};\n\n// Expect a token of a given type. If found, consume it, otherwise,\n// raise an unexpected token error.\n\npp.expect = function(type) {\n this.eat(type) || this.unexpected();\n};\n\n// Raise an unexpected token error.\n\npp.unexpected = function(pos) {\n this.raise(pos != null ? pos : this.start, \"Unexpected token\");\n};\n\nfunction DestructuringErrors() {\n this.shorthandAssign =\n this.trailingComma =\n this.parenthesizedAssign =\n this.parenthesizedBind =\n this.doubleProto =\n -1;\n}\n\npp.checkPatternErrors = function(refDestructuringErrors, isAssign) {\n if (!refDestructuringErrors) { return }\n if (refDestructuringErrors.trailingComma > -1)\n { this.raiseRecoverable(refDestructuringErrors.trailingComma, \"Comma is not permitted after the rest element\"); }\n var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind;\n if (parens > -1) { this.raiseRecoverable(parens, \"Parenthesized pattern\"); }\n};\n\npp.checkExpressionErrors = function(refDestructuringErrors, andThrow) {\n if (!refDestructuringErrors) { return false }\n var shorthandAssign = refDestructuringErrors.shorthandAssign;\n var doubleProto = refDestructuringErrors.doubleProto;\n if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 }\n if (shorthandAssign >= 0)\n { this.raise(shorthandAssign, \"Shorthand property assignments are valid only in destructuring patterns\"); }\n if (doubleProto >= 0)\n { this.raiseRecoverable(doubleProto, \"Redefinition of __proto__ property\"); }\n};\n\npp.checkYieldAwaitInDefaultParams = function() {\n if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos))\n { this.raise(this.yieldPos, \"Yield expression cannot be a default value\"); }\n if (this.awaitPos)\n { this.raise(this.awaitPos, \"Await expression cannot be a default value\"); }\n};\n\npp.isSimpleAssignTarget = function(expr) {\n if (expr.type === \"ParenthesizedExpression\")\n { return this.isSimpleAssignTarget(expr.expression) }\n return expr.type === \"Identifier\" || expr.type === \"MemberExpression\"\n};\n\nvar pp$1 = Parser.prototype;\n\n// ### Statement parsing\n\n// Parse a program. Initializes the parser, reads any number of\n// statements, and wraps them in a Program node. Optionally takes a\n// `program` argument. If present, the statements will be appended\n// to its body instead of creating a new node.\n\npp$1.parseTopLevel = function(node) {\n var this$1 = this;\n\n var exports = {};\n if (!node.body) { node.body = []; }\n while (this.type !== types.eof) {\n var stmt = this$1.parseStatement(true, true, exports);\n node.body.push(stmt);\n }\n this.adaptDirectivePrologue(node.body);\n this.next();\n if (this.options.ecmaVersion >= 6) {\n node.sourceType = this.options.sourceType;\n }\n return this.finishNode(node, \"Program\")\n};\n\nvar loopLabel = {kind: \"loop\"};\nvar switchLabel = {kind: \"switch\"};\n\npp$1.isLet = function() {\n if (this.options.ecmaVersion < 6 || !this.isContextual(\"let\")) { return false }\n skipWhiteSpace.lastIndex = this.pos;\n var skip = skipWhiteSpace.exec(this.input);\n var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);\n if (nextCh === 91 || nextCh === 123) { return true } // '{' and '['\n if (isIdentifierStart(nextCh, true)) {\n var pos = next + 1;\n while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; }\n var ident = this.input.slice(next, pos);\n if (!keywordRelationalOperator.test(ident)) { return true }\n }\n return false\n};\n\n// check 'async [no LineTerminator here] function'\n// - 'async /*foo*/ function' is OK.\n// - 'async /*\\n*/ function' is invalid.\npp$1.isAsyncFunction = function() {\n if (this.options.ecmaVersion < 8 || !this.isContextual(\"async\"))\n { return false }\n\n skipWhiteSpace.lastIndex = this.pos;\n var skip = skipWhiteSpace.exec(this.input);\n var next = this.pos + skip[0].length;\n return !lineBreak.test(this.input.slice(this.pos, next)) &&\n this.input.slice(next, next + 8) === \"function\" &&\n (next + 8 === this.input.length || !isIdentifierChar(this.input.charAt(next + 8)))\n};\n\n// Parse a single statement.\n//\n// If expecting a statement and finding a slash operator, parse a\n// regular expression literal. This is to handle cases like\n// `if (foo) /blah/.exec(foo)`, where looking at the previous token\n// does not help.\n\npp$1.parseStatement = function(declaration, topLevel, exports) {\n var starttype = this.type, node = this.startNode(), kind;\n\n if (this.isLet()) {\n starttype = types._var;\n kind = \"let\";\n }\n\n // Most types of statements are recognized by the keyword they\n // start with. Many are trivial to parse, some require a bit of\n // complexity.\n\n switch (starttype) {\n case types._break: case types._continue: return this.parseBreakContinueStatement(node, starttype.keyword)\n case types._debugger: return this.parseDebuggerStatement(node)\n case types._do: return this.parseDoStatement(node)\n case types._for: return this.parseForStatement(node)\n case types._function:\n if (!declaration && this.options.ecmaVersion >= 6) { this.unexpected(); }\n return this.parseFunctionStatement(node, false)\n case types._class:\n if (!declaration) { this.unexpected(); }\n return this.parseClass(node, true)\n case types._if: return this.parseIfStatement(node)\n case types._return: return this.parseReturnStatement(node)\n case types._switch: return this.parseSwitchStatement(node)\n case types._throw: return this.parseThrowStatement(node)\n case types._try: return this.parseTryStatement(node)\n case types._const: case types._var:\n kind = kind || this.value;\n if (!declaration && kind !== \"var\") { this.unexpected(); }\n return this.parseVarStatement(node, kind)\n case types._while: return this.parseWhileStatement(node)\n case types._with: return this.parseWithStatement(node)\n case types.braceL: return this.parseBlock()\n case types.semi: return this.parseEmptyStatement(node)\n case types._export:\n case types._import:\n if (!this.options.allowImportExportEverywhere) {\n if (!topLevel)\n { this.raise(this.start, \"'import' and 'export' may only appear at the top level\"); }\n if (!this.inModule)\n { this.raise(this.start, \"'import' and 'export' may appear only with 'sourceType: module'\"); }\n }\n return starttype === types._import ? this.parseImport(node) : this.parseExport(node, exports)\n\n // If the statement does not start with a statement keyword or a\n // brace, it's an ExpressionStatement or LabeledStatement. We\n // simply start parsing an expression, and afterwards, if the\n // next token is a colon and the expression was a simple\n // Identifier node, we switch to interpreting it as a label.\n default:\n if (this.isAsyncFunction()) {\n if (!declaration) { this.unexpected(); }\n this.next();\n return this.parseFunctionStatement(node, true)\n }\n\n var maybeName = this.value, expr = this.parseExpression();\n if (starttype === types.name && expr.type === \"Identifier\" && this.eat(types.colon))\n { return this.parseLabeledStatement(node, maybeName, expr) }\n else { return this.parseExpressionStatement(node, expr) }\n }\n};\n\npp$1.parseBreakContinueStatement = function(node, keyword) {\n var this$1 = this;\n\n var isBreak = keyword === \"break\";\n this.next();\n if (this.eat(types.semi) || this.insertSemicolon()) { node.label = null; }\n else if (this.type !== types.name) { this.unexpected(); }\n else {\n node.label = this.parseIdent();\n this.semicolon();\n }\n\n // Verify that there is an actual destination to break or\n // continue to.\n var i = 0;\n for (; i < this.labels.length; ++i) {\n var lab = this$1.labels[i];\n if (node.label == null || lab.name === node.label.name) {\n if (lab.kind != null && (isBreak || lab.kind === \"loop\")) { break }\n if (node.label && isBreak) { break }\n }\n }\n if (i === this.labels.length) { this.raise(node.start, \"Unsyntactic \" + keyword); }\n return this.finishNode(node, isBreak ? \"BreakStatement\" : \"ContinueStatement\")\n};\n\npp$1.parseDebuggerStatement = function(node) {\n this.next();\n this.semicolon();\n return this.finishNode(node, \"DebuggerStatement\")\n};\n\npp$1.parseDoStatement = function(node) {\n this.next();\n this.labels.push(loopLabel);\n node.body = this.parseStatement(false);\n this.labels.pop();\n this.expect(types._while);\n node.test = this.parseParenExpression();\n if (this.options.ecmaVersion >= 6)\n { this.eat(types.semi); }\n else\n { this.semicolon(); }\n return this.finishNode(node, \"DoWhileStatement\")\n};\n\n// Disambiguating between a `for` and a `for`/`in` or `for`/`of`\n// loop is non-trivial. Basically, we have to parse the init `var`\n// statement or expression, disallowing the `in` operator (see\n// the second parameter to `parseExpression`), and then check\n// whether the next token is `in` or `of`. When there is no init\n// part (semicolon immediately after the opening parenthesis), it\n// is a regular `for` loop.\n\npp$1.parseForStatement = function(node) {\n this.next();\n var awaitAt = (this.options.ecmaVersion >= 9 && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction)) && this.eatContextual(\"await\")) ? this.lastTokStart : -1;\n this.labels.push(loopLabel);\n this.enterLexicalScope();\n this.expect(types.parenL);\n if (this.type === types.semi) {\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n return this.parseFor(node, null)\n }\n var isLet = this.isLet();\n if (this.type === types._var || this.type === types._const || isLet) {\n var init$1 = this.startNode(), kind = isLet ? \"let\" : this.value;\n this.next();\n this.parseVar(init$1, true, kind);\n this.finishNode(init$1, \"VariableDeclaration\");\n if ((this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual(\"of\"))) && init$1.declarations.length === 1 &&\n !(kind !== \"var\" && init$1.declarations[0].init)) {\n if (this.options.ecmaVersion >= 9) {\n if (this.type === types._in) {\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n } else { node.await = awaitAt > -1; }\n }\n return this.parseForIn(node, init$1)\n }\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n return this.parseFor(node, init$1)\n }\n var refDestructuringErrors = new DestructuringErrors;\n var init = this.parseExpression(true, refDestructuringErrors);\n if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual(\"of\"))) {\n if (this.options.ecmaVersion >= 9) {\n if (this.type === types._in) {\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n } else { node.await = awaitAt > -1; }\n }\n this.toAssignable(init, false, refDestructuringErrors);\n this.checkLVal(init);\n return this.parseForIn(node, init)\n } else {\n this.checkExpressionErrors(refDestructuringErrors, true);\n }\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n return this.parseFor(node, init)\n};\n\npp$1.parseFunctionStatement = function(node, isAsync) {\n this.next();\n return this.parseFunction(node, true, false, isAsync)\n};\n\npp$1.parseIfStatement = function(node) {\n this.next();\n node.test = this.parseParenExpression();\n // allow function declarations in branches, but only in non-strict mode\n node.consequent = this.parseStatement(!this.strict && this.type === types._function);\n node.alternate = this.eat(types._else) ? this.parseStatement(!this.strict && this.type === types._function) : null;\n return this.finishNode(node, \"IfStatement\")\n};\n\npp$1.parseReturnStatement = function(node) {\n if (!this.inFunction && !this.options.allowReturnOutsideFunction)\n { this.raise(this.start, \"'return' outside of function\"); }\n this.next();\n\n // In `return` (and `break`/`continue`), the keywords with\n // optional arguments, we eagerly look for a semicolon or the\n // possibility to insert one.\n\n if (this.eat(types.semi) || this.insertSemicolon()) { node.argument = null; }\n else { node.argument = this.parseExpression(); this.semicolon(); }\n return this.finishNode(node, \"ReturnStatement\")\n};\n\npp$1.parseSwitchStatement = function(node) {\n var this$1 = this;\n\n this.next();\n node.discriminant = this.parseParenExpression();\n node.cases = [];\n this.expect(types.braceL);\n this.labels.push(switchLabel);\n this.enterLexicalScope();\n\n // Statements under must be grouped (by label) in SwitchCase\n // nodes. `cur` is used to keep the node that we are currently\n // adding statements to.\n\n var cur;\n for (var sawDefault = false; this.type !== types.braceR;) {\n if (this$1.type === types._case || this$1.type === types._default) {\n var isCase = this$1.type === types._case;\n if (cur) { this$1.finishNode(cur, \"SwitchCase\"); }\n node.cases.push(cur = this$1.startNode());\n cur.consequent = [];\n this$1.next();\n if (isCase) {\n cur.test = this$1.parseExpression();\n } else {\n if (sawDefault) { this$1.raiseRecoverable(this$1.lastTokStart, \"Multiple default clauses\"); }\n sawDefault = true;\n cur.test = null;\n }\n this$1.expect(types.colon);\n } else {\n if (!cur) { this$1.unexpected(); }\n cur.consequent.push(this$1.parseStatement(true));\n }\n }\n this.exitLexicalScope();\n if (cur) { this.finishNode(cur, \"SwitchCase\"); }\n this.next(); // Closing brace\n this.labels.pop();\n return this.finishNode(node, \"SwitchStatement\")\n};\n\npp$1.parseThrowStatement = function(node) {\n this.next();\n if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start)))\n { this.raise(this.lastTokEnd, \"Illegal newline after throw\"); }\n node.argument = this.parseExpression();\n this.semicolon();\n return this.finishNode(node, \"ThrowStatement\")\n};\n\n// Reused empty array added for node fields that are always empty.\n\nvar empty = [];\n\npp$1.parseTryStatement = function(node) {\n this.next();\n node.block = this.parseBlock();\n node.handler = null;\n if (this.type === types._catch) {\n var clause = this.startNode();\n this.next();\n if (this.eat(types.parenL)) {\n clause.param = this.parseBindingAtom();\n this.enterLexicalScope();\n this.checkLVal(clause.param, \"let\");\n this.expect(types.parenR);\n } else {\n if (this.options.ecmaVersion < 10) { this.unexpected(); }\n clause.param = null;\n this.enterLexicalScope();\n }\n clause.body = this.parseBlock(false);\n this.exitLexicalScope();\n node.handler = this.finishNode(clause, \"CatchClause\");\n }\n node.finalizer = this.eat(types._finally) ? this.parseBlock() : null;\n if (!node.handler && !node.finalizer)\n { this.raise(node.start, \"Missing catch or finally clause\"); }\n return this.finishNode(node, \"TryStatement\")\n};\n\npp$1.parseVarStatement = function(node, kind) {\n this.next();\n this.parseVar(node, false, kind);\n this.semicolon();\n return this.finishNode(node, \"VariableDeclaration\")\n};\n\npp$1.parseWhileStatement = function(node) {\n this.next();\n node.test = this.parseParenExpression();\n this.labels.push(loopLabel);\n node.body = this.parseStatement(false);\n this.labels.pop();\n return this.finishNode(node, \"WhileStatement\")\n};\n\npp$1.parseWithStatement = function(node) {\n if (this.strict) { this.raise(this.start, \"'with' in strict mode\"); }\n this.next();\n node.object = this.parseParenExpression();\n node.body = this.parseStatement(false);\n return this.finishNode(node, \"WithStatement\")\n};\n\npp$1.parseEmptyStatement = function(node) {\n this.next();\n return this.finishNode(node, \"EmptyStatement\")\n};\n\npp$1.parseLabeledStatement = function(node, maybeName, expr) {\n var this$1 = this;\n\n for (var i$1 = 0, list = this$1.labels; i$1 < list.length; i$1 += 1)\n {\n var label = list[i$1];\n\n if (label.name === maybeName)\n { this$1.raise(expr.start, \"Label '\" + maybeName + \"' is already declared\");\n } }\n var kind = this.type.isLoop ? \"loop\" : this.type === types._switch ? \"switch\" : null;\n for (var i = this.labels.length - 1; i >= 0; i--) {\n var label$1 = this$1.labels[i];\n if (label$1.statementStart === node.start) {\n // Update information about previous labels on this node\n label$1.statementStart = this$1.start;\n label$1.kind = kind;\n } else { break }\n }\n this.labels.push({name: maybeName, kind: kind, statementStart: this.start});\n node.body = this.parseStatement(true);\n if (node.body.type === \"ClassDeclaration\" ||\n node.body.type === \"VariableDeclaration\" && node.body.kind !== \"var\" ||\n node.body.type === \"FunctionDeclaration\" && (this.strict || node.body.generator || node.body.async))\n { this.raiseRecoverable(node.body.start, \"Invalid labeled declaration\"); }\n this.labels.pop();\n node.label = expr;\n return this.finishNode(node, \"LabeledStatement\")\n};\n\npp$1.parseExpressionStatement = function(node, expr) {\n node.expression = expr;\n this.semicolon();\n return this.finishNode(node, \"ExpressionStatement\")\n};\n\n// Parse a semicolon-enclosed block of statements, handling `\"use\n// strict\"` declarations when `allowStrict` is true (used for\n// function bodies).\n\npp$1.parseBlock = function(createNewLexicalScope) {\n var this$1 = this;\n if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true;\n\n var node = this.startNode();\n node.body = [];\n this.expect(types.braceL);\n if (createNewLexicalScope) {\n this.enterLexicalScope();\n }\n while (!this.eat(types.braceR)) {\n var stmt = this$1.parseStatement(true);\n node.body.push(stmt);\n }\n if (createNewLexicalScope) {\n this.exitLexicalScope();\n }\n return this.finishNode(node, \"BlockStatement\")\n};\n\n// Parse a regular `for` loop. The disambiguation code in\n// `parseStatement` will already have parsed the init statement or\n// expression.\n\npp$1.parseFor = function(node, init) {\n node.init = init;\n this.expect(types.semi);\n node.test = this.type === types.semi ? null : this.parseExpression();\n this.expect(types.semi);\n node.update = this.type === types.parenR ? null : this.parseExpression();\n this.expect(types.parenR);\n this.exitLexicalScope();\n node.body = this.parseStatement(false);\n this.labels.pop();\n return this.finishNode(node, \"ForStatement\")\n};\n\n// Parse a `for`/`in` and `for`/`of` loop, which are almost\n// same from parser's perspective.\n\npp$1.parseForIn = function(node, init) {\n var type = this.type === types._in ? \"ForInStatement\" : \"ForOfStatement\";\n this.next();\n if (type === \"ForInStatement\") {\n if (init.type === \"AssignmentPattern\" ||\n (init.type === \"VariableDeclaration\" && init.declarations[0].init != null &&\n (this.strict || init.declarations[0].id.type !== \"Identifier\")))\n { this.raise(init.start, \"Invalid assignment in for-in loop head\"); }\n }\n node.left = init;\n node.right = type === \"ForInStatement\" ? this.parseExpression() : this.parseMaybeAssign();\n this.expect(types.parenR);\n this.exitLexicalScope();\n node.body = this.parseStatement(false);\n this.labels.pop();\n return this.finishNode(node, type)\n};\n\n// Parse a list of variable declarations.\n\npp$1.parseVar = function(node, isFor, kind) {\n var this$1 = this;\n\n node.declarations = [];\n node.kind = kind;\n for (;;) {\n var decl = this$1.startNode();\n this$1.parseVarId(decl, kind);\n if (this$1.eat(types.eq)) {\n decl.init = this$1.parseMaybeAssign(isFor);\n } else if (kind === \"const\" && !(this$1.type === types._in || (this$1.options.ecmaVersion >= 6 && this$1.isContextual(\"of\")))) {\n this$1.unexpected();\n } else if (decl.id.type !== \"Identifier\" && !(isFor && (this$1.type === types._in || this$1.isContextual(\"of\")))) {\n this$1.raise(this$1.lastTokEnd, \"Complex binding patterns require an initialization value\");\n } else {\n decl.init = null;\n }\n node.declarations.push(this$1.finishNode(decl, \"VariableDeclarator\"));\n if (!this$1.eat(types.comma)) { break }\n }\n return node\n};\n\npp$1.parseVarId = function(decl, kind) {\n decl.id = this.parseBindingAtom(kind);\n this.checkLVal(decl.id, kind, false);\n};\n\n// Parse a function declaration or literal (depending on the\n// `isStatement` parameter).\n\npp$1.parseFunction = function(node, isStatement, allowExpressionBody, isAsync) {\n this.initFunction(node);\n if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync)\n { node.generator = this.eat(types.star); }\n if (this.options.ecmaVersion >= 8)\n { node.async = !!isAsync; }\n\n if (isStatement) {\n node.id = isStatement === \"nullableID\" && this.type !== types.name ? null : this.parseIdent();\n if (node.id) {\n this.checkLVal(node.id, this.inModule && !this.inFunction ? \"let\" : \"var\");\n }\n }\n\n var oldInGen = this.inGenerator, oldInAsync = this.inAsync,\n oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction;\n this.inGenerator = node.generator;\n this.inAsync = node.async;\n this.yieldPos = 0;\n this.awaitPos = 0;\n this.inFunction = true;\n this.enterFunctionScope();\n\n if (!isStatement)\n { node.id = this.type === types.name ? this.parseIdent() : null; }\n\n this.parseFunctionParams(node);\n this.parseFunctionBody(node, allowExpressionBody);\n\n this.inGenerator = oldInGen;\n this.inAsync = oldInAsync;\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n this.inFunction = oldInFunc;\n return this.finishNode(node, isStatement ? \"FunctionDeclaration\" : \"FunctionExpression\")\n};\n\npp$1.parseFunctionParams = function(node) {\n this.expect(types.parenL);\n node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);\n this.checkYieldAwaitInDefaultParams();\n};\n\n// Parse a class declaration or literal (depending on the\n// `isStatement` parameter).\n\npp$1.parseClass = function(node, isStatement) {\n var this$1 = this;\n\n this.next();\n\n this.parseClassId(node, isStatement);\n this.parseClassSuper(node);\n var classBody = this.startNode();\n var hadConstructor = false;\n classBody.body = [];\n this.expect(types.braceL);\n while (!this.eat(types.braceR)) {\n var member = this$1.parseClassMember(classBody);\n if (member && member.type === \"MethodDefinition\" && member.kind === \"constructor\") {\n if (hadConstructor) { this$1.raise(member.start, \"Duplicate constructor in the same class\"); }\n hadConstructor = true;\n }\n }\n node.body = this.finishNode(classBody, \"ClassBody\");\n return this.finishNode(node, isStatement ? \"ClassDeclaration\" : \"ClassExpression\")\n};\n\npp$1.parseClassMember = function(classBody) {\n var this$1 = this;\n\n if (this.eat(types.semi)) { return null }\n\n var method = this.startNode();\n var tryContextual = function (k, noLineBreak) {\n if ( noLineBreak === void 0 ) noLineBreak = false;\n\n var start = this$1.start, startLoc = this$1.startLoc;\n if (!this$1.eatContextual(k)) { return false }\n if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true }\n if (method.key) { this$1.unexpected(); }\n method.computed = false;\n method.key = this$1.startNodeAt(start, startLoc);\n method.key.name = k;\n this$1.finishNode(method.key, \"Identifier\");\n return false\n };\n\n method.kind = \"method\";\n method.static = tryContextual(\"static\");\n var isGenerator = this.eat(types.star);\n var isAsync = false;\n if (!isGenerator) {\n if (this.options.ecmaVersion >= 8 && tryContextual(\"async\", true)) {\n isAsync = true;\n isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);\n } else if (tryContextual(\"get\")) {\n method.kind = \"get\";\n } else if (tryContextual(\"set\")) {\n method.kind = \"set\";\n }\n }\n if (!method.key) { this.parsePropertyName(method); }\n var key = method.key;\n if (!method.computed && !method.static && (key.type === \"Identifier\" && key.name === \"constructor\" ||\n key.type === \"Literal\" && key.value === \"constructor\")) {\n if (method.kind !== \"method\") { this.raise(key.start, \"Constructor can't have get/set modifier\"); }\n if (isGenerator) { this.raise(key.start, \"Constructor can't be a generator\"); }\n if (isAsync) { this.raise(key.start, \"Constructor can't be an async method\"); }\n method.kind = \"constructor\";\n } else if (method.static && key.type === \"Identifier\" && key.name === \"prototype\") {\n this.raise(key.start, \"Classes may not have a static property named prototype\");\n }\n this.parseClassMethod(classBody, method, isGenerator, isAsync);\n if (method.kind === \"get\" && method.value.params.length !== 0)\n { this.raiseRecoverable(method.value.start, \"getter should have no params\"); }\n if (method.kind === \"set\" && method.value.params.length !== 1)\n { this.raiseRecoverable(method.value.start, \"setter should have exactly one param\"); }\n if (method.kind === \"set\" && method.value.params[0].type === \"RestElement\")\n { this.raiseRecoverable(method.value.params[0].start, \"Setter cannot use rest params\"); }\n return method\n};\n\npp$1.parseClassMethod = function(classBody, method, isGenerator, isAsync) {\n method.value = this.parseMethod(isGenerator, isAsync);\n classBody.body.push(this.finishNode(method, \"MethodDefinition\"));\n};\n\npp$1.parseClassId = function(node, isStatement) {\n node.id = this.type === types.name ? this.parseIdent() : isStatement === true ? this.unexpected() : null;\n};\n\npp$1.parseClassSuper = function(node) {\n node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null;\n};\n\n// Parses module export declaration.\n\npp$1.parseExport = function(node, exports) {\n var this$1 = this;\n\n this.next();\n // export * from '...'\n if (this.eat(types.star)) {\n this.expectContextual(\"from\");\n if (this.type !== types.string) { this.unexpected(); }\n node.source = this.parseExprAtom();\n this.semicolon();\n return this.finishNode(node, \"ExportAllDeclaration\")\n }\n if (this.eat(types._default)) { // export default ...\n this.checkExport(exports, \"default\", this.lastTokStart);\n var isAsync;\n if (this.type === types._function || (isAsync = this.isAsyncFunction())) {\n var fNode = this.startNode();\n this.next();\n if (isAsync) { this.next(); }\n node.declaration = this.parseFunction(fNode, \"nullableID\", false, isAsync);\n } else if (this.type === types._class) {\n var cNode = this.startNode();\n node.declaration = this.parseClass(cNode, \"nullableID\");\n } else {\n node.declaration = this.parseMaybeAssign();\n this.semicolon();\n }\n return this.finishNode(node, \"ExportDefaultDeclaration\")\n }\n // export var|const|let|function|class ...\n if (this.shouldParseExportStatement()) {\n node.declaration = this.parseStatement(true);\n if (node.declaration.type === \"VariableDeclaration\")\n { this.checkVariableExport(exports, node.declaration.declarations); }\n else\n { this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); }\n node.specifiers = [];\n node.source = null;\n } else { // export { x, y as z } [from '...']\n node.declaration = null;\n node.specifiers = this.parseExportSpecifiers(exports);\n if (this.eatContextual(\"from\")) {\n if (this.type !== types.string) { this.unexpected(); }\n node.source = this.parseExprAtom();\n } else {\n // check for keywords used as local names\n for (var i = 0, list = node.specifiers; i < list.length; i += 1) {\n var spec = list[i];\n\n this$1.checkUnreserved(spec.local);\n }\n\n node.source = null;\n }\n this.semicolon();\n }\n return this.finishNode(node, \"ExportNamedDeclaration\")\n};\n\npp$1.checkExport = function(exports, name, pos) {\n if (!exports) { return }\n if (has(exports, name))\n { this.raiseRecoverable(pos, \"Duplicate export '\" + name + \"'\"); }\n exports[name] = true;\n};\n\npp$1.checkPatternExport = function(exports, pat) {\n var this$1 = this;\n\n var type = pat.type;\n if (type === \"Identifier\")\n { this.checkExport(exports, pat.name, pat.start); }\n else if (type === \"ObjectPattern\")\n { for (var i = 0, list = pat.properties; i < list.length; i += 1)\n {\n var prop = list[i];\n\n this$1.checkPatternExport(exports, prop);\n } }\n else if (type === \"ArrayPattern\")\n { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) {\n var elt = list$1[i$1];\n\n if (elt) { this$1.checkPatternExport(exports, elt); }\n } }\n else if (type === \"Property\")\n { this.checkPatternExport(exports, pat.value); }\n else if (type === \"AssignmentPattern\")\n { this.checkPatternExport(exports, pat.left); }\n else if (type === \"RestElement\")\n { this.checkPatternExport(exports, pat.argument); }\n else if (type === \"ParenthesizedExpression\")\n { this.checkPatternExport(exports, pat.expression); }\n};\n\npp$1.checkVariableExport = function(exports, decls) {\n var this$1 = this;\n\n if (!exports) { return }\n for (var i = 0, list = decls; i < list.length; i += 1)\n {\n var decl = list[i];\n\n this$1.checkPatternExport(exports, decl.id);\n }\n};\n\npp$1.shouldParseExportStatement = function() {\n return this.type.keyword === \"var\" ||\n this.type.keyword === \"const\" ||\n this.type.keyword === \"class\" ||\n this.type.keyword === \"function\" ||\n this.isLet() ||\n this.isAsyncFunction()\n};\n\n// Parses a comma-separated list of module exports.\n\npp$1.parseExportSpecifiers = function(exports) {\n var this$1 = this;\n\n var nodes = [], first = true;\n // export { x, y as z } [from '...']\n this.expect(types.braceL);\n while (!this.eat(types.braceR)) {\n if (!first) {\n this$1.expect(types.comma);\n if (this$1.afterTrailingComma(types.braceR)) { break }\n } else { first = false; }\n\n var node = this$1.startNode();\n node.local = this$1.parseIdent(true);\n node.exported = this$1.eatContextual(\"as\") ? this$1.parseIdent(true) : node.local;\n this$1.checkExport(exports, node.exported.name, node.exported.start);\n nodes.push(this$1.finishNode(node, \"ExportSpecifier\"));\n }\n return nodes\n};\n\n// Parses import declaration.\n\npp$1.parseImport = function(node) {\n this.next();\n // import '...'\n if (this.type === types.string) {\n node.specifiers = empty;\n node.source = this.parseExprAtom();\n } else {\n node.specifiers = this.parseImportSpecifiers();\n this.expectContextual(\"from\");\n node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected();\n }\n this.semicolon();\n return this.finishNode(node, \"ImportDeclaration\")\n};\n\n// Parses a comma-separated list of module imports.\n\npp$1.parseImportSpecifiers = function() {\n var this$1 = this;\n\n var nodes = [], first = true;\n if (this.type === types.name) {\n // import defaultObj, { x, y as z } from '...'\n var node = this.startNode();\n node.local = this.parseIdent();\n this.checkLVal(node.local, \"let\");\n nodes.push(this.finishNode(node, \"ImportDefaultSpecifier\"));\n if (!this.eat(types.comma)) { return nodes }\n }\n if (this.type === types.star) {\n var node$1 = this.startNode();\n this.next();\n this.expectContextual(\"as\");\n node$1.local = this.parseIdent();\n this.checkLVal(node$1.local, \"let\");\n nodes.push(this.finishNode(node$1, \"ImportNamespaceSpecifier\"));\n return nodes\n }\n this.expect(types.braceL);\n while (!this.eat(types.braceR)) {\n if (!first) {\n this$1.expect(types.comma);\n if (this$1.afterTrailingComma(types.braceR)) { break }\n } else { first = false; }\n\n var node$2 = this$1.startNode();\n node$2.imported = this$1.parseIdent(true);\n if (this$1.eatContextual(\"as\")) {\n node$2.local = this$1.parseIdent();\n } else {\n this$1.checkUnreserved(node$2.imported);\n node$2.local = node$2.imported;\n }\n this$1.checkLVal(node$2.local, \"let\");\n nodes.push(this$1.finishNode(node$2, \"ImportSpecifier\"));\n }\n return nodes\n};\n\n// Set `ExpressionStatement#directive` property for directive prologues.\npp$1.adaptDirectivePrologue = function(statements) {\n for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) {\n statements[i].directive = statements[i].expression.raw.slice(1, -1);\n }\n};\npp$1.isDirectiveCandidate = function(statement) {\n return (\n statement.type === \"ExpressionStatement\" &&\n statement.expression.type === \"Literal\" &&\n typeof statement.expression.value === \"string\" &&\n // Reject parenthesized strings.\n (this.input[statement.start] === \"\\\"\" || this.input[statement.start] === \"'\")\n )\n};\n\nvar pp$2 = Parser.prototype;\n\n// Convert existing expression atom to assignable pattern\n// if possible.\n\npp$2.toAssignable = function(node, isBinding, refDestructuringErrors) {\n var this$1 = this;\n\n if (this.options.ecmaVersion >= 6 && node) {\n switch (node.type) {\n case \"Identifier\":\n if (this.inAsync && node.name === \"await\")\n { this.raise(node.start, \"Can not use 'await' as identifier inside an async function\"); }\n break\n\n case \"ObjectPattern\":\n case \"ArrayPattern\":\n case \"RestElement\":\n break\n\n case \"ObjectExpression\":\n node.type = \"ObjectPattern\";\n if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }\n for (var i = 0, list = node.properties; i < list.length; i += 1) {\n var prop = list[i];\n\n this$1.toAssignable(prop, isBinding);\n // Early error:\n // AssignmentRestProperty[Yield, Await] :\n // `...` DestructuringAssignmentTarget[Yield, Await]\n //\n // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|.\n if (\n prop.type === \"RestElement\" &&\n (prop.argument.type === \"ArrayPattern\" || prop.argument.type === \"ObjectPattern\")\n ) {\n this$1.raise(prop.argument.start, \"Unexpected token\");\n }\n }\n break\n\n case \"Property\":\n // AssignmentProperty has type === \"Property\"\n if (node.kind !== \"init\") { this.raise(node.key.start, \"Object pattern can't contain getter or setter\"); }\n this.toAssignable(node.value, isBinding);\n break\n\n case \"ArrayExpression\":\n node.type = \"ArrayPattern\";\n if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }\n this.toAssignableList(node.elements, isBinding);\n break\n\n case \"SpreadElement\":\n node.type = \"RestElement\";\n this.toAssignable(node.argument, isBinding);\n if (node.argument.type === \"AssignmentPattern\")\n { this.raise(node.argument.start, \"Rest elements cannot have a default value\"); }\n break\n\n case \"AssignmentExpression\":\n if (node.operator !== \"=\") { this.raise(node.left.end, \"Only '=' operator can be used for specifying default value.\"); }\n node.type = \"AssignmentPattern\";\n delete node.operator;\n this.toAssignable(node.left, isBinding);\n // falls through to AssignmentPattern\n\n case \"AssignmentPattern\":\n break\n\n case \"ParenthesizedExpression\":\n this.toAssignable(node.expression, isBinding);\n break\n\n case \"MemberExpression\":\n if (!isBinding) { break }\n\n default:\n this.raise(node.start, \"Assigning to rvalue\");\n }\n } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }\n return node\n};\n\n// Convert list of expression atoms to binding list.\n\npp$2.toAssignableList = function(exprList, isBinding) {\n var this$1 = this;\n\n var end = exprList.length;\n for (var i = 0; i < end; i++) {\n var elt = exprList[i];\n if (elt) { this$1.toAssignable(elt, isBinding); }\n }\n if (end) {\n var last = exprList[end - 1];\n if (this.options.ecmaVersion === 6 && isBinding && last && last.type === \"RestElement\" && last.argument.type !== \"Identifier\")\n { this.unexpected(last.argument.start); }\n }\n return exprList\n};\n\n// Parses spread element.\n\npp$2.parseSpread = function(refDestructuringErrors) {\n var node = this.startNode();\n this.next();\n node.argument = this.parseMaybeAssign(false, refDestructuringErrors);\n return this.finishNode(node, \"SpreadElement\")\n};\n\npp$2.parseRestBinding = function() {\n var node = this.startNode();\n this.next();\n\n // RestElement inside of a function parameter must be an identifier\n if (this.options.ecmaVersion === 6 && this.type !== types.name)\n { this.unexpected(); }\n\n node.argument = this.parseBindingAtom();\n\n return this.finishNode(node, \"RestElement\")\n};\n\n// Parses lvalue (assignable) atom.\n\npp$2.parseBindingAtom = function() {\n if (this.options.ecmaVersion >= 6) {\n switch (this.type) {\n case types.bracketL:\n var node = this.startNode();\n this.next();\n node.elements = this.parseBindingList(types.bracketR, true, true);\n return this.finishNode(node, \"ArrayPattern\")\n\n case types.braceL:\n return this.parseObj(true)\n }\n }\n return this.parseIdent()\n};\n\npp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma) {\n var this$1 = this;\n\n var elts = [], first = true;\n while (!this.eat(close)) {\n if (first) { first = false; }\n else { this$1.expect(types.comma); }\n if (allowEmpty && this$1.type === types.comma) {\n elts.push(null);\n } else if (allowTrailingComma && this$1.afterTrailingComma(close)) {\n break\n } else if (this$1.type === types.ellipsis) {\n var rest = this$1.parseRestBinding();\n this$1.parseBindingListItem(rest);\n elts.push(rest);\n if (this$1.type === types.comma) { this$1.raise(this$1.start, \"Comma is not permitted after the rest element\"); }\n this$1.expect(close);\n break\n } else {\n var elem = this$1.parseMaybeDefault(this$1.start, this$1.startLoc);\n this$1.parseBindingListItem(elem);\n elts.push(elem);\n }\n }\n return elts\n};\n\npp$2.parseBindingListItem = function(param) {\n return param\n};\n\n// Parses assignment pattern around given atom if possible.\n\npp$2.parseMaybeDefault = function(startPos, startLoc, left) {\n left = left || this.parseBindingAtom();\n if (this.options.ecmaVersion < 6 || !this.eat(types.eq)) { return left }\n var node = this.startNodeAt(startPos, startLoc);\n node.left = left;\n node.right = this.parseMaybeAssign();\n return this.finishNode(node, \"AssignmentPattern\")\n};\n\n// Verify that a node is an lval — something that can be assigned\n// to.\n// bindingType can be either:\n// 'var' indicating that the lval creates a 'var' binding\n// 'let' indicating that the lval creates a lexical ('let' or 'const') binding\n// 'none' indicating that the binding should be checked for illegal identifiers, but not for duplicate references\n\npp$2.checkLVal = function(expr, bindingType, checkClashes) {\n var this$1 = this;\n\n switch (expr.type) {\n case \"Identifier\":\n if (this.strict && this.reservedWordsStrictBind.test(expr.name))\n { this.raiseRecoverable(expr.start, (bindingType ? \"Binding \" : \"Assigning to \") + expr.name + \" in strict mode\"); }\n if (checkClashes) {\n if (has(checkClashes, expr.name))\n { this.raiseRecoverable(expr.start, \"Argument name clash\"); }\n checkClashes[expr.name] = true;\n }\n if (bindingType && bindingType !== \"none\") {\n if (\n bindingType === \"var\" && !this.canDeclareVarName(expr.name) ||\n bindingType !== \"var\" && !this.canDeclareLexicalName(expr.name)\n ) {\n this.raiseRecoverable(expr.start, (\"Identifier '\" + (expr.name) + \"' has already been declared\"));\n }\n if (bindingType === \"var\") {\n this.declareVarName(expr.name);\n } else {\n this.declareLexicalName(expr.name);\n }\n }\n break\n\n case \"MemberExpression\":\n if (bindingType) { this.raiseRecoverable(expr.start, \"Binding member expression\"); }\n break\n\n case \"ObjectPattern\":\n for (var i = 0, list = expr.properties; i < list.length; i += 1)\n {\n var prop = list[i];\n\n this$1.checkLVal(prop, bindingType, checkClashes);\n }\n break\n\n case \"Property\":\n // AssignmentProperty has type === \"Property\"\n this.checkLVal(expr.value, bindingType, checkClashes);\n break\n\n case \"ArrayPattern\":\n for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) {\n var elem = list$1[i$1];\n\n if (elem) { this$1.checkLVal(elem, bindingType, checkClashes); }\n }\n break\n\n case \"AssignmentPattern\":\n this.checkLVal(expr.left, bindingType, checkClashes);\n break\n\n case \"RestElement\":\n this.checkLVal(expr.argument, bindingType, checkClashes);\n break\n\n case \"ParenthesizedExpression\":\n this.checkLVal(expr.expression, bindingType, checkClashes);\n break\n\n default:\n this.raise(expr.start, (bindingType ? \"Binding\" : \"Assigning to\") + \" rvalue\");\n }\n};\n\n// A recursive descent parser operates by defining functions for all\n// syntactic elements, and recursively calling those, each function\n// advancing the input stream and returning an AST node. Precedence\n// of constructs (for example, the fact that `!x[1]` means `!(x[1])`\n// instead of `(!x)[1]` is handled by the fact that the parser\n// function that parses unary prefix operators is called first, and\n// in turn calls the function that parses `[]` subscripts — that\n// way, it'll receive the node for `x[1]` already parsed, and wraps\n// *that* in the unary operator node.\n//\n// Acorn uses an [operator precedence parser][opp] to handle binary\n// operator precedence, because it is much more compact than using\n// the technique outlined above, which uses different, nesting\n// functions to specify precedence, for all of the ten binary\n// precedence levels that JavaScript defines.\n//\n// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser\n\nvar pp$3 = Parser.prototype;\n\n// Check if property name clashes with already added.\n// Object/class getters and setters are not allowed to clash —\n// either with each other or with an init property — and in\n// strict mode, init properties are also not allowed to be repeated.\n\npp$3.checkPropClash = function(prop, propHash, refDestructuringErrors) {\n if (this.options.ecmaVersion >= 9 && prop.type === \"SpreadElement\")\n { return }\n if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))\n { return }\n var key = prop.key;\n var name;\n switch (key.type) {\n case \"Identifier\": name = key.name; break\n case \"Literal\": name = String(key.value); break\n default: return\n }\n var kind = prop.kind;\n if (this.options.ecmaVersion >= 6) {\n if (name === \"__proto__\" && kind === \"init\") {\n if (propHash.proto) {\n if (refDestructuringErrors && refDestructuringErrors.doubleProto < 0) { refDestructuringErrors.doubleProto = key.start; }\n // Backwards-compat kludge. Can be removed in version 6.0\n else { this.raiseRecoverable(key.start, \"Redefinition of __proto__ property\"); }\n }\n propHash.proto = true;\n }\n return\n }\n name = \"$\" + name;\n var other = propHash[name];\n if (other) {\n var redefinition;\n if (kind === \"init\") {\n redefinition = this.strict && other.init || other.get || other.set;\n } else {\n redefinition = other.init || other[kind];\n }\n if (redefinition)\n { this.raiseRecoverable(key.start, \"Redefinition of property\"); }\n } else {\n other = propHash[name] = {\n init: false,\n get: false,\n set: false\n };\n }\n other[kind] = true;\n};\n\n// ### Expression parsing\n\n// These nest, from the most general expression type at the top to\n// 'atomic', nondivisible expression types at the bottom. Most of\n// the functions will simply let the function(s) below them parse,\n// and, *if* the syntactic construct they handle is present, wrap\n// the AST node that the inner parser gave them in another node.\n\n// Parse a full expression. The optional arguments are used to\n// forbid the `in` operator (in for loops initalization expressions)\n// and provide reference for storing '=' operator inside shorthand\n// property assignment in contexts where both object expression\n// and object pattern might appear (so it's possible to raise\n// delayed syntax error at correct position).\n\npp$3.parseExpression = function(noIn, refDestructuringErrors) {\n var this$1 = this;\n\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseMaybeAssign(noIn, refDestructuringErrors);\n if (this.type === types.comma) {\n var node = this.startNodeAt(startPos, startLoc);\n node.expressions = [expr];\n while (this.eat(types.comma)) { node.expressions.push(this$1.parseMaybeAssign(noIn, refDestructuringErrors)); }\n return this.finishNode(node, \"SequenceExpression\")\n }\n return expr\n};\n\n// Parse an assignment expression. This includes applications of\n// operators like `+=`.\n\npp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) {\n if (this.inGenerator && this.isContextual(\"yield\")) { return this.parseYield() }\n\n var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1;\n if (refDestructuringErrors) {\n oldParenAssign = refDestructuringErrors.parenthesizedAssign;\n oldTrailingComma = refDestructuringErrors.trailingComma;\n refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1;\n } else {\n refDestructuringErrors = new DestructuringErrors;\n ownDestructuringErrors = true;\n }\n\n var startPos = this.start, startLoc = this.startLoc;\n if (this.type === types.parenL || this.type === types.name)\n { this.potentialArrowAt = this.start; }\n var left = this.parseMaybeConditional(noIn, refDestructuringErrors);\n if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); }\n if (this.type.isAssign) {\n var node = this.startNodeAt(startPos, startLoc);\n node.operator = this.value;\n node.left = this.type === types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left;\n if (!ownDestructuringErrors) { DestructuringErrors.call(refDestructuringErrors); }\n refDestructuringErrors.shorthandAssign = -1; // reset because shorthand default was used correctly\n this.checkLVal(left);\n this.next();\n node.right = this.parseMaybeAssign(noIn);\n return this.finishNode(node, \"AssignmentExpression\")\n } else {\n if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); }\n }\n if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; }\n if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; }\n return left\n};\n\n// Parse a ternary conditional (`?:`) operator.\n\npp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) {\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseExprOps(noIn, refDestructuringErrors);\n if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }\n if (this.eat(types.question)) {\n var node = this.startNodeAt(startPos, startLoc);\n node.test = expr;\n node.consequent = this.parseMaybeAssign();\n this.expect(types.colon);\n node.alternate = this.parseMaybeAssign(noIn);\n return this.finishNode(node, \"ConditionalExpression\")\n }\n return expr\n};\n\n// Start the precedence parser.\n\npp$3.parseExprOps = function(noIn, refDestructuringErrors) {\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseMaybeUnary(refDestructuringErrors, false);\n if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }\n return expr.start === startPos && expr.type === \"ArrowFunctionExpression\" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn)\n};\n\n// Parse binary operators with the operator precedence parsing\n// algorithm. `left` is the left-hand side of the operator.\n// `minPrec` provides context that allows the function to stop and\n// defer further parser to one of its callers when it encounters an\n// operator that has a lower precedence than the set it is parsing.\n\npp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) {\n var prec = this.type.binop;\n if (prec != null && (!noIn || this.type !== types._in)) {\n if (prec > minPrec) {\n var logical = this.type === types.logicalOR || this.type === types.logicalAND;\n var op = this.value;\n this.next();\n var startPos = this.start, startLoc = this.startLoc;\n var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn);\n var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical);\n return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn)\n }\n }\n return left\n};\n\npp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) {\n var node = this.startNodeAt(startPos, startLoc);\n node.left = left;\n node.operator = op;\n node.right = right;\n return this.finishNode(node, logical ? \"LogicalExpression\" : \"BinaryExpression\")\n};\n\n// Parse unary operators, both prefix and postfix.\n\npp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) {\n var this$1 = this;\n\n var startPos = this.start, startLoc = this.startLoc, expr;\n if (this.isContextual(\"await\") && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction))) {\n expr = this.parseAwait();\n sawUnary = true;\n } else if (this.type.prefix) {\n var node = this.startNode(), update = this.type === types.incDec;\n node.operator = this.value;\n node.prefix = true;\n this.next();\n node.argument = this.parseMaybeUnary(null, true);\n this.checkExpressionErrors(refDestructuringErrors, true);\n if (update) { this.checkLVal(node.argument); }\n else if (this.strict && node.operator === \"delete\" &&\n node.argument.type === \"Identifier\")\n { this.raiseRecoverable(node.start, \"Deleting local variable in strict mode\"); }\n else { sawUnary = true; }\n expr = this.finishNode(node, update ? \"UpdateExpression\" : \"UnaryExpression\");\n } else {\n expr = this.parseExprSubscripts(refDestructuringErrors);\n if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }\n while (this.type.postfix && !this.canInsertSemicolon()) {\n var node$1 = this$1.startNodeAt(startPos, startLoc);\n node$1.operator = this$1.value;\n node$1.prefix = false;\n node$1.argument = expr;\n this$1.checkLVal(expr);\n this$1.next();\n expr = this$1.finishNode(node$1, \"UpdateExpression\");\n }\n }\n\n if (!sawUnary && this.eat(types.starstar))\n { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), \"**\", false) }\n else\n { return expr }\n};\n\n// Parse call, dot, and `[]`-subscript expressions.\n\npp$3.parseExprSubscripts = function(refDestructuringErrors) {\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseExprAtom(refDestructuringErrors);\n var skipArrowSubscripts = expr.type === \"ArrowFunctionExpression\" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== \")\";\n if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) { return expr }\n var result = this.parseSubscripts(expr, startPos, startLoc);\n if (refDestructuringErrors && result.type === \"MemberExpression\") {\n if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; }\n if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; }\n }\n return result\n};\n\npp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) {\n var this$1 = this;\n\n var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === \"Identifier\" && base.name === \"async\" &&\n this.lastTokEnd === base.end && !this.canInsertSemicolon() && this.input.slice(base.start, base.end) === \"async\";\n for (var computed = (void 0);;) {\n if ((computed = this$1.eat(types.bracketL)) || this$1.eat(types.dot)) {\n var node = this$1.startNodeAt(startPos, startLoc);\n node.object = base;\n node.property = computed ? this$1.parseExpression() : this$1.parseIdent(true);\n node.computed = !!computed;\n if (computed) { this$1.expect(types.bracketR); }\n base = this$1.finishNode(node, \"MemberExpression\");\n } else if (!noCalls && this$1.eat(types.parenL)) {\n var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this$1.yieldPos, oldAwaitPos = this$1.awaitPos;\n this$1.yieldPos = 0;\n this$1.awaitPos = 0;\n var exprList = this$1.parseExprList(types.parenR, this$1.options.ecmaVersion >= 8, false, refDestructuringErrors);\n if (maybeAsyncArrow && !this$1.canInsertSemicolon() && this$1.eat(types.arrow)) {\n this$1.checkPatternErrors(refDestructuringErrors, false);\n this$1.checkYieldAwaitInDefaultParams();\n this$1.yieldPos = oldYieldPos;\n this$1.awaitPos = oldAwaitPos;\n return this$1.parseArrowExpression(this$1.startNodeAt(startPos, startLoc), exprList, true)\n }\n this$1.checkExpressionErrors(refDestructuringErrors, true);\n this$1.yieldPos = oldYieldPos || this$1.yieldPos;\n this$1.awaitPos = oldAwaitPos || this$1.awaitPos;\n var node$1 = this$1.startNodeAt(startPos, startLoc);\n node$1.callee = base;\n node$1.arguments = exprList;\n base = this$1.finishNode(node$1, \"CallExpression\");\n } else if (this$1.type === types.backQuote) {\n var node$2 = this$1.startNodeAt(startPos, startLoc);\n node$2.tag = base;\n node$2.quasi = this$1.parseTemplate({isTagged: true});\n base = this$1.finishNode(node$2, \"TaggedTemplateExpression\");\n } else {\n return base\n }\n }\n};\n\n// Parse an atomic expression — either a single token that is an\n// expression, an expression started by a keyword like `function` or\n// `new`, or an expression wrapped in punctuation like `()`, `[]`,\n// or `{}`.\n\npp$3.parseExprAtom = function(refDestructuringErrors) {\n var node, canBeArrow = this.potentialArrowAt === this.start;\n switch (this.type) {\n case types._super:\n if (!this.inFunction)\n { this.raise(this.start, \"'super' outside of function or class\"); }\n node = this.startNode();\n this.next();\n // The `super` keyword can appear at below:\n // SuperProperty:\n // super [ Expression ]\n // super . IdentifierName\n // SuperCall:\n // super Arguments\n if (this.type !== types.dot && this.type !== types.bracketL && this.type !== types.parenL)\n { this.unexpected(); }\n return this.finishNode(node, \"Super\")\n\n case types._this:\n node = this.startNode();\n this.next();\n return this.finishNode(node, \"ThisExpression\")\n\n case types.name:\n var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc;\n var id = this.parseIdent(this.type !== types.name);\n if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === \"async\" && !this.canInsertSemicolon() && this.eat(types._function))\n { return this.parseFunction(this.startNodeAt(startPos, startLoc), false, false, true) }\n if (canBeArrow && !this.canInsertSemicolon()) {\n if (this.eat(types.arrow))\n { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) }\n if (this.options.ecmaVersion >= 8 && id.name === \"async\" && this.type === types.name && !containsEsc) {\n id = this.parseIdent();\n if (this.canInsertSemicolon() || !this.eat(types.arrow))\n { this.unexpected(); }\n return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true)\n }\n }\n return id\n\n case types.regexp:\n var value = this.value;\n node = this.parseLiteral(value.value);\n node.regex = {pattern: value.pattern, flags: value.flags};\n return node\n\n case types.num: case types.string:\n return this.parseLiteral(this.value)\n\n case types._null: case types._true: case types._false:\n node = this.startNode();\n node.value = this.type === types._null ? null : this.type === types._true;\n node.raw = this.type.keyword;\n this.next();\n return this.finishNode(node, \"Literal\")\n\n case types.parenL:\n var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow);\n if (refDestructuringErrors) {\n if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr))\n { refDestructuringErrors.parenthesizedAssign = start; }\n if (refDestructuringErrors.parenthesizedBind < 0)\n { refDestructuringErrors.parenthesizedBind = start; }\n }\n return expr\n\n case types.bracketL:\n node = this.startNode();\n this.next();\n node.elements = this.parseExprList(types.bracketR, true, true, refDestructuringErrors);\n return this.finishNode(node, \"ArrayExpression\")\n\n case types.braceL:\n return this.parseObj(false, refDestructuringErrors)\n\n case types._function:\n node = this.startNode();\n this.next();\n return this.parseFunction(node, false)\n\n case types._class:\n return this.parseClass(this.startNode(), false)\n\n case types._new:\n return this.parseNew()\n\n case types.backQuote:\n return this.parseTemplate()\n\n default:\n this.unexpected();\n }\n};\n\npp$3.parseLiteral = function(value) {\n var node = this.startNode();\n node.value = value;\n node.raw = this.input.slice(this.start, this.end);\n this.next();\n return this.finishNode(node, \"Literal\")\n};\n\npp$3.parseParenExpression = function() {\n this.expect(types.parenL);\n var val = this.parseExpression();\n this.expect(types.parenR);\n return val\n};\n\npp$3.parseParenAndDistinguishExpression = function(canBeArrow) {\n var this$1 = this;\n\n var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8;\n if (this.options.ecmaVersion >= 6) {\n this.next();\n\n var innerStartPos = this.start, innerStartLoc = this.startLoc;\n var exprList = [], first = true, lastIsComma = false;\n var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart;\n this.yieldPos = 0;\n this.awaitPos = 0;\n while (this.type !== types.parenR) {\n first ? first = false : this$1.expect(types.comma);\n if (allowTrailingComma && this$1.afterTrailingComma(types.parenR, true)) {\n lastIsComma = true;\n break\n } else if (this$1.type === types.ellipsis) {\n spreadStart = this$1.start;\n exprList.push(this$1.parseParenItem(this$1.parseRestBinding()));\n if (this$1.type === types.comma) { this$1.raise(this$1.start, \"Comma is not permitted after the rest element\"); }\n break\n } else {\n exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem));\n }\n }\n var innerEndPos = this.start, innerEndLoc = this.startLoc;\n this.expect(types.parenR);\n\n if (canBeArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) {\n this.checkPatternErrors(refDestructuringErrors, false);\n this.checkYieldAwaitInDefaultParams();\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n return this.parseParenArrowList(startPos, startLoc, exprList)\n }\n\n if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); }\n if (spreadStart) { this.unexpected(spreadStart); }\n this.checkExpressionErrors(refDestructuringErrors, true);\n this.yieldPos = oldYieldPos || this.yieldPos;\n this.awaitPos = oldAwaitPos || this.awaitPos;\n\n if (exprList.length > 1) {\n val = this.startNodeAt(innerStartPos, innerStartLoc);\n val.expressions = exprList;\n this.finishNodeAt(val, \"SequenceExpression\", innerEndPos, innerEndLoc);\n } else {\n val = exprList[0];\n }\n } else {\n val = this.parseParenExpression();\n }\n\n if (this.options.preserveParens) {\n var par = this.startNodeAt(startPos, startLoc);\n par.expression = val;\n return this.finishNode(par, \"ParenthesizedExpression\")\n } else {\n return val\n }\n};\n\npp$3.parseParenItem = function(item) {\n return item\n};\n\npp$3.parseParenArrowList = function(startPos, startLoc, exprList) {\n return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList)\n};\n\n// New's precedence is slightly tricky. It must allow its argument to\n// be a `[]` or dot subscript expression, but not a call — at least,\n// not without wrapping it in parentheses. Thus, it uses the noCalls\n// argument to parseSubscripts to prevent it from consuming the\n// argument list.\n\nvar empty$1 = [];\n\npp$3.parseNew = function() {\n var node = this.startNode();\n var meta = this.parseIdent(true);\n if (this.options.ecmaVersion >= 6 && this.eat(types.dot)) {\n node.meta = meta;\n var containsEsc = this.containsEsc;\n node.property = this.parseIdent(true);\n if (node.property.name !== \"target\" || containsEsc)\n { this.raiseRecoverable(node.property.start, \"The only valid meta property for new is new.target\"); }\n if (!this.inFunction)\n { this.raiseRecoverable(node.start, \"new.target can only be used in functions\"); }\n return this.finishNode(node, \"MetaProperty\")\n }\n var startPos = this.start, startLoc = this.startLoc;\n node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true);\n if (this.eat(types.parenL)) { node.arguments = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false); }\n else { node.arguments = empty$1; }\n return this.finishNode(node, \"NewExpression\")\n};\n\n// Parse template expression.\n\npp$3.parseTemplateElement = function(ref) {\n var isTagged = ref.isTagged;\n\n var elem = this.startNode();\n if (this.type === types.invalidTemplate) {\n if (!isTagged) {\n this.raiseRecoverable(this.start, \"Bad escape sequence in untagged template literal\");\n }\n elem.value = {\n raw: this.value,\n cooked: null\n };\n } else {\n elem.value = {\n raw: this.input.slice(this.start, this.end).replace(/\\r\\n?/g, \"\\n\"),\n cooked: this.value\n };\n }\n this.next();\n elem.tail = this.type === types.backQuote;\n return this.finishNode(elem, \"TemplateElement\")\n};\n\npp$3.parseTemplate = function(ref) {\n var this$1 = this;\n if ( ref === void 0 ) ref = {};\n var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false;\n\n var node = this.startNode();\n this.next();\n node.expressions = [];\n var curElt = this.parseTemplateElement({isTagged: isTagged});\n node.quasis = [curElt];\n while (!curElt.tail) {\n if (this$1.type === types.eof) { this$1.raise(this$1.pos, \"Unterminated template literal\"); }\n this$1.expect(types.dollarBraceL);\n node.expressions.push(this$1.parseExpression());\n this$1.expect(types.braceR);\n node.quasis.push(curElt = this$1.parseTemplateElement({isTagged: isTagged}));\n }\n this.next();\n return this.finishNode(node, \"TemplateLiteral\")\n};\n\npp$3.isAsyncProp = function(prop) {\n return !prop.computed && prop.key.type === \"Identifier\" && prop.key.name === \"async\" &&\n (this.type === types.name || this.type === types.num || this.type === types.string || this.type === types.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types.star)) &&\n !lineBreak.test(this.input.slice(this.lastTokEnd, this.start))\n};\n\n// Parse an object literal or binding pattern.\n\npp$3.parseObj = function(isPattern, refDestructuringErrors) {\n var this$1 = this;\n\n var node = this.startNode(), first = true, propHash = {};\n node.properties = [];\n this.next();\n while (!this.eat(types.braceR)) {\n if (!first) {\n this$1.expect(types.comma);\n if (this$1.afterTrailingComma(types.braceR)) { break }\n } else { first = false; }\n\n var prop = this$1.parseProperty(isPattern, refDestructuringErrors);\n if (!isPattern) { this$1.checkPropClash(prop, propHash, refDestructuringErrors); }\n node.properties.push(prop);\n }\n return this.finishNode(node, isPattern ? \"ObjectPattern\" : \"ObjectExpression\")\n};\n\npp$3.parseProperty = function(isPattern, refDestructuringErrors) {\n var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc;\n if (this.options.ecmaVersion >= 9 && this.eat(types.ellipsis)) {\n if (isPattern) {\n prop.argument = this.parseIdent(false);\n if (this.type === types.comma) {\n this.raise(this.start, \"Comma is not permitted after the rest element\");\n }\n return this.finishNode(prop, \"RestElement\")\n }\n // To disallow parenthesized identifier via `this.toAssignable()`.\n if (this.type === types.parenL && refDestructuringErrors) {\n if (refDestructuringErrors.parenthesizedAssign < 0) {\n refDestructuringErrors.parenthesizedAssign = this.start;\n }\n if (refDestructuringErrors.parenthesizedBind < 0) {\n refDestructuringErrors.parenthesizedBind = this.start;\n }\n }\n // Parse argument.\n prop.argument = this.parseMaybeAssign(false, refDestructuringErrors);\n // To disallow trailing comma via `this.toAssignable()`.\n if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) {\n refDestructuringErrors.trailingComma = this.start;\n }\n // Finish\n return this.finishNode(prop, \"SpreadElement\")\n }\n if (this.options.ecmaVersion >= 6) {\n prop.method = false;\n prop.shorthand = false;\n if (isPattern || refDestructuringErrors) {\n startPos = this.start;\n startLoc = this.startLoc;\n }\n if (!isPattern)\n { isGenerator = this.eat(types.star); }\n }\n var containsEsc = this.containsEsc;\n this.parsePropertyName(prop);\n if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) {\n isAsync = true;\n isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);\n this.parsePropertyName(prop, refDestructuringErrors);\n } else {\n isAsync = false;\n }\n this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc);\n return this.finishNode(prop, \"Property\")\n};\n\npp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) {\n if ((isGenerator || isAsync) && this.type === types.colon)\n { this.unexpected(); }\n\n if (this.eat(types.colon)) {\n prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors);\n prop.kind = \"init\";\n } else if (this.options.ecmaVersion >= 6 && this.type === types.parenL) {\n if (isPattern) { this.unexpected(); }\n prop.kind = \"init\";\n prop.method = true;\n prop.value = this.parseMethod(isGenerator, isAsync);\n } else if (!isPattern && !containsEsc &&\n this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === \"Identifier\" &&\n (prop.key.name === \"get\" || prop.key.name === \"set\") &&\n (this.type !== types.comma && this.type !== types.braceR)) {\n if (isGenerator || isAsync) { this.unexpected(); }\n prop.kind = prop.key.name;\n this.parsePropertyName(prop);\n prop.value = this.parseMethod(false);\n var paramCount = prop.kind === \"get\" ? 0 : 1;\n if (prop.value.params.length !== paramCount) {\n var start = prop.value.start;\n if (prop.kind === \"get\")\n { this.raiseRecoverable(start, \"getter should have no params\"); }\n else\n { this.raiseRecoverable(start, \"setter should have exactly one param\"); }\n } else {\n if (prop.kind === \"set\" && prop.value.params[0].type === \"RestElement\")\n { this.raiseRecoverable(prop.value.params[0].start, \"Setter cannot use rest params\"); }\n }\n } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === \"Identifier\") {\n this.checkUnreserved(prop.key);\n prop.kind = \"init\";\n if (isPattern) {\n prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);\n } else if (this.type === types.eq && refDestructuringErrors) {\n if (refDestructuringErrors.shorthandAssign < 0)\n { refDestructuringErrors.shorthandAssign = this.start; }\n prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);\n } else {\n prop.value = prop.key;\n }\n prop.shorthand = true;\n } else { this.unexpected(); }\n};\n\npp$3.parsePropertyName = function(prop) {\n if (this.options.ecmaVersion >= 6) {\n if (this.eat(types.bracketL)) {\n prop.computed = true;\n prop.key = this.parseMaybeAssign();\n this.expect(types.bracketR);\n return prop.key\n } else {\n prop.computed = false;\n }\n }\n return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(true)\n};\n\n// Initialize empty function node.\n\npp$3.initFunction = function(node) {\n node.id = null;\n if (this.options.ecmaVersion >= 6) {\n node.generator = false;\n node.expression = false;\n }\n if (this.options.ecmaVersion >= 8)\n { node.async = false; }\n};\n\n// Parse object or class method.\n\npp$3.parseMethod = function(isGenerator, isAsync) {\n var node = this.startNode(), oldInGen = this.inGenerator, oldInAsync = this.inAsync,\n oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction;\n\n this.initFunction(node);\n if (this.options.ecmaVersion >= 6)\n { node.generator = isGenerator; }\n if (this.options.ecmaVersion >= 8)\n { node.async = !!isAsync; }\n\n this.inGenerator = node.generator;\n this.inAsync = node.async;\n this.yieldPos = 0;\n this.awaitPos = 0;\n this.inFunction = true;\n this.enterFunctionScope();\n\n this.expect(types.parenL);\n node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);\n this.checkYieldAwaitInDefaultParams();\n this.parseFunctionBody(node, false);\n\n this.inGenerator = oldInGen;\n this.inAsync = oldInAsync;\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n this.inFunction = oldInFunc;\n return this.finishNode(node, \"FunctionExpression\")\n};\n\n// Parse arrow function expression with given parameters.\n\npp$3.parseArrowExpression = function(node, params, isAsync) {\n var oldInGen = this.inGenerator, oldInAsync = this.inAsync,\n oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction;\n\n this.enterFunctionScope();\n this.initFunction(node);\n if (this.options.ecmaVersion >= 8)\n { node.async = !!isAsync; }\n\n this.inGenerator = false;\n this.inAsync = node.async;\n this.yieldPos = 0;\n this.awaitPos = 0;\n this.inFunction = true;\n\n node.params = this.toAssignableList(params, true);\n this.parseFunctionBody(node, true);\n\n this.inGenerator = oldInGen;\n this.inAsync = oldInAsync;\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n this.inFunction = oldInFunc;\n return this.finishNode(node, \"ArrowFunctionExpression\")\n};\n\n// Parse function body and check parameters.\n\npp$3.parseFunctionBody = function(node, isArrowFunction) {\n var isExpression = isArrowFunction && this.type !== types.braceL;\n var oldStrict = this.strict, useStrict = false;\n\n if (isExpression) {\n node.body = this.parseMaybeAssign();\n node.expression = true;\n this.checkParams(node, false);\n } else {\n var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params);\n if (!oldStrict || nonSimple) {\n useStrict = this.strictDirective(this.end);\n // If this is a strict mode function, verify that argument names\n // are not repeated, and it does not try to bind the words `eval`\n // or `arguments`.\n if (useStrict && nonSimple)\n { this.raiseRecoverable(node.start, \"Illegal 'use strict' directive in function with non-simple parameter list\"); }\n }\n // Start a new scope with regard to labels and the `inFunction`\n // flag (restore them to their old value afterwards).\n var oldLabels = this.labels;\n this.labels = [];\n if (useStrict) { this.strict = true; }\n\n // Add the params to varDeclaredNames to ensure that an error is thrown\n // if a let/const declaration in the function clashes with one of the params.\n this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && this.isSimpleParamList(node.params));\n node.body = this.parseBlock(false);\n node.expression = false;\n this.adaptDirectivePrologue(node.body.body);\n this.labels = oldLabels;\n }\n this.exitFunctionScope();\n\n if (this.strict && node.id) {\n // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval'\n this.checkLVal(node.id, \"none\");\n }\n this.strict = oldStrict;\n};\n\npp$3.isSimpleParamList = function(params) {\n for (var i = 0, list = params; i < list.length; i += 1)\n {\n var param = list[i];\n\n if (param.type !== \"Identifier\") { return false\n } }\n return true\n};\n\n// Checks function params for various disallowed patterns such as using \"eval\"\n// or \"arguments\" and duplicate parameters.\n\npp$3.checkParams = function(node, allowDuplicates) {\n var this$1 = this;\n\n var nameHash = {};\n for (var i = 0, list = node.params; i < list.length; i += 1)\n {\n var param = list[i];\n\n this$1.checkLVal(param, \"var\", allowDuplicates ? null : nameHash);\n }\n};\n\n// Parses a comma-separated list of expressions, and returns them as\n// an array. `close` is the token type that ends the list, and\n// `allowEmpty` can be turned on to allow subsequent commas with\n// nothing in between them to be parsed as `null` (which is needed\n// for array literals).\n\npp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) {\n var this$1 = this;\n\n var elts = [], first = true;\n while (!this.eat(close)) {\n if (!first) {\n this$1.expect(types.comma);\n if (allowTrailingComma && this$1.afterTrailingComma(close)) { break }\n } else { first = false; }\n\n var elt = (void 0);\n if (allowEmpty && this$1.type === types.comma)\n { elt = null; }\n else if (this$1.type === types.ellipsis) {\n elt = this$1.parseSpread(refDestructuringErrors);\n if (refDestructuringErrors && this$1.type === types.comma && refDestructuringErrors.trailingComma < 0)\n { refDestructuringErrors.trailingComma = this$1.start; }\n } else {\n elt = this$1.parseMaybeAssign(false, refDestructuringErrors);\n }\n elts.push(elt);\n }\n return elts\n};\n\npp$3.checkUnreserved = function(ref) {\n var start = ref.start;\n var end = ref.end;\n var name = ref.name;\n\n if (this.inGenerator && name === \"yield\")\n { this.raiseRecoverable(start, \"Can not use 'yield' as identifier inside a generator\"); }\n if (this.inAsync && name === \"await\")\n { this.raiseRecoverable(start, \"Can not use 'await' as identifier inside an async function\"); }\n if (this.isKeyword(name))\n { this.raise(start, (\"Unexpected keyword '\" + name + \"'\")); }\n if (this.options.ecmaVersion < 6 &&\n this.input.slice(start, end).indexOf(\"\\\\\") !== -1) { return }\n var re = this.strict ? this.reservedWordsStrict : this.reservedWords;\n if (re.test(name)) {\n if (!this.inAsync && name === \"await\")\n { this.raiseRecoverable(start, \"Can not use keyword 'await' outside an async function\"); }\n this.raiseRecoverable(start, (\"The keyword '\" + name + \"' is reserved\"));\n }\n};\n\n// Parse the next token as an identifier. If `liberal` is true (used\n// when parsing properties), it will also convert keywords into\n// identifiers.\n\npp$3.parseIdent = function(liberal, isBinding) {\n var node = this.startNode();\n if (liberal && this.options.allowReserved === \"never\") { liberal = false; }\n if (this.type === types.name) {\n node.name = this.value;\n } else if (this.type.keyword) {\n node.name = this.type.keyword;\n\n // To fix https://github.com/acornjs/acorn/issues/575\n // `class` and `function` keywords push new context into this.context.\n // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name.\n // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword\n if ((node.name === \"class\" || node.name === \"function\") &&\n (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) {\n this.context.pop();\n }\n } else {\n this.unexpected();\n }\n this.next();\n this.finishNode(node, \"Identifier\");\n if (!liberal) { this.checkUnreserved(node); }\n return node\n};\n\n// Parses yield expression inside generator.\n\npp$3.parseYield = function() {\n if (!this.yieldPos) { this.yieldPos = this.start; }\n\n var node = this.startNode();\n this.next();\n if (this.type === types.semi || this.canInsertSemicolon() || (this.type !== types.star && !this.type.startsExpr)) {\n node.delegate = false;\n node.argument = null;\n } else {\n node.delegate = this.eat(types.star);\n node.argument = this.parseMaybeAssign();\n }\n return this.finishNode(node, \"YieldExpression\")\n};\n\npp$3.parseAwait = function() {\n if (!this.awaitPos) { this.awaitPos = this.start; }\n\n var node = this.startNode();\n this.next();\n node.argument = this.parseMaybeUnary(null, true);\n return this.finishNode(node, \"AwaitExpression\")\n};\n\nvar pp$4 = Parser.prototype;\n\n// This function is used to raise exceptions on parse errors. It\n// takes an offset integer (into the current `input`) to indicate\n// the location of the error, attaches the position to the end\n// of the error message, and then raises a `SyntaxError` with that\n// message.\n\npp$4.raise = function(pos, message) {\n var loc = getLineInfo(this.input, pos);\n message += \" (\" + loc.line + \":\" + loc.column + \")\";\n var err = new SyntaxError(message);\n err.pos = pos; err.loc = loc; err.raisedAt = this.pos;\n throw err\n};\n\npp$4.raiseRecoverable = pp$4.raise;\n\npp$4.curPosition = function() {\n if (this.options.locations) {\n return new Position(this.curLine, this.pos - this.lineStart)\n }\n};\n\nvar pp$5 = Parser.prototype;\n\n// Object.assign polyfill\nvar assign = Object.assign || function(target) {\n var sources = [], len = arguments.length - 1;\n while ( len-- > 0 ) sources[ len ] = arguments[ len + 1 ];\n\n for (var i = 0, list = sources; i < list.length; i += 1) {\n var source = list[i];\n\n for (var key in source) {\n if (has(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target\n};\n\n// The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names.\n\npp$5.enterFunctionScope = function() {\n // var: a hash of var-declared names in the current lexical scope\n // lexical: a hash of lexically-declared names in the current lexical scope\n // childVar: a hash of var-declared names in all child lexical scopes of the current lexical scope (within the current function scope)\n // parentLexical: a hash of lexically-declared names in all parent lexical scopes of the current lexical scope (within the current function scope)\n this.scopeStack.push({var: {}, lexical: {}, childVar: {}, parentLexical: {}});\n};\n\npp$5.exitFunctionScope = function() {\n this.scopeStack.pop();\n};\n\npp$5.enterLexicalScope = function() {\n var parentScope = this.scopeStack[this.scopeStack.length - 1];\n var childScope = {var: {}, lexical: {}, childVar: {}, parentLexical: {}};\n\n this.scopeStack.push(childScope);\n assign(childScope.parentLexical, parentScope.lexical, parentScope.parentLexical);\n};\n\npp$5.exitLexicalScope = function() {\n var childScope = this.scopeStack.pop();\n var parentScope = this.scopeStack[this.scopeStack.length - 1];\n\n assign(parentScope.childVar, childScope.var, childScope.childVar);\n};\n\n/**\n * A name can be declared with `var` if there are no variables with the same name declared with `let`/`const`\n * in the current lexical scope or any of the parent lexical scopes in this function.\n */\npp$5.canDeclareVarName = function(name) {\n var currentScope = this.scopeStack[this.scopeStack.length - 1];\n\n return !has(currentScope.lexical, name) && !has(currentScope.parentLexical, name)\n};\n\n/**\n * A name can be declared with `let`/`const` if there are no variables with the same name declared with `let`/`const`\n * in the current scope, and there are no variables with the same name declared with `var` in the current scope or in\n * any child lexical scopes in this function.\n */\npp$5.canDeclareLexicalName = function(name) {\n var currentScope = this.scopeStack[this.scopeStack.length - 1];\n\n return !has(currentScope.lexical, name) && !has(currentScope.var, name) && !has(currentScope.childVar, name)\n};\n\npp$5.declareVarName = function(name) {\n this.scopeStack[this.scopeStack.length - 1].var[name] = true;\n};\n\npp$5.declareLexicalName = function(name) {\n this.scopeStack[this.scopeStack.length - 1].lexical[name] = true;\n};\n\nvar Node = function Node(parser, pos, loc) {\n this.type = \"\";\n this.start = pos;\n this.end = 0;\n if (parser.options.locations)\n { this.loc = new SourceLocation(parser, loc); }\n if (parser.options.directSourceFile)\n { this.sourceFile = parser.options.directSourceFile; }\n if (parser.options.ranges)\n { this.range = [pos, 0]; }\n};\n\n// Start an AST node, attaching a start offset.\n\nvar pp$6 = Parser.prototype;\n\npp$6.startNode = function() {\n return new Node(this, this.start, this.startLoc)\n};\n\npp$6.startNodeAt = function(pos, loc) {\n return new Node(this, pos, loc)\n};\n\n// Finish an AST node, adding `type` and `end` properties.\n\nfunction finishNodeAt(node, type, pos, loc) {\n node.type = type;\n node.end = pos;\n if (this.options.locations)\n { node.loc.end = loc; }\n if (this.options.ranges)\n { node.range[1] = pos; }\n return node\n}\n\npp$6.finishNode = function(node, type) {\n return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc)\n};\n\n// Finish node at given position\n\npp$6.finishNodeAt = function(node, type, pos, loc) {\n return finishNodeAt.call(this, node, type, pos, loc)\n};\n\n// The algorithm used to determine whether a regexp can appear at a\n// given point in the program is loosely based on sweet.js' approach.\n// See https://github.com/mozilla/sweet.js/wiki/design\n\nvar TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) {\n this.token = token;\n this.isExpr = !!isExpr;\n this.preserveSpace = !!preserveSpace;\n this.override = override;\n this.generator = !!generator;\n};\n\nvar types$1 = {\n b_stat: new TokContext(\"{\", false),\n b_expr: new TokContext(\"{\", true),\n b_tmpl: new TokContext(\"${\", false),\n p_stat: new TokContext(\"(\", false),\n p_expr: new TokContext(\"(\", true),\n q_tmpl: new TokContext(\"`\", true, true, function (p) { return p.tryReadTemplateToken(); }),\n f_stat: new TokContext(\"function\", false),\n f_expr: new TokContext(\"function\", true),\n f_expr_gen: new TokContext(\"function\", true, false, null, true),\n f_gen: new TokContext(\"function\", false, false, null, true)\n};\n\nvar pp$7 = Parser.prototype;\n\npp$7.initialContext = function() {\n return [types$1.b_stat]\n};\n\npp$7.braceIsBlock = function(prevType) {\n var parent = this.curContext();\n if (parent === types$1.f_expr || parent === types$1.f_stat)\n { return true }\n if (prevType === types.colon && (parent === types$1.b_stat || parent === types$1.b_expr))\n { return !parent.isExpr }\n\n // The check for `tt.name && exprAllowed` detects whether we are\n // after a `yield` or `of` construct. See the `updateContext` for\n // `tt.name`.\n if (prevType === types._return || prevType === types.name && this.exprAllowed)\n { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) }\n if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType === types.arrow)\n { return true }\n if (prevType === types.braceL)\n { return parent === types$1.b_stat }\n if (prevType === types._var || prevType === types.name)\n { return false }\n return !this.exprAllowed\n};\n\npp$7.inGeneratorContext = function() {\n var this$1 = this;\n\n for (var i = this.context.length - 1; i >= 1; i--) {\n var context = this$1.context[i];\n if (context.token === \"function\")\n { return context.generator }\n }\n return false\n};\n\npp$7.updateContext = function(prevType) {\n var update, type = this.type;\n if (type.keyword && prevType === types.dot)\n { this.exprAllowed = false; }\n else if (update = type.updateContext)\n { update.call(this, prevType); }\n else\n { this.exprAllowed = type.beforeExpr; }\n};\n\n// Token-specific context update code\n\ntypes.parenR.updateContext = types.braceR.updateContext = function() {\n if (this.context.length === 1) {\n this.exprAllowed = true;\n return\n }\n var out = this.context.pop();\n if (out === types$1.b_stat && this.curContext().token === \"function\") {\n out = this.context.pop();\n }\n this.exprAllowed = !out.isExpr;\n};\n\ntypes.braceL.updateContext = function(prevType) {\n this.context.push(this.braceIsBlock(prevType) ? types$1.b_stat : types$1.b_expr);\n this.exprAllowed = true;\n};\n\ntypes.dollarBraceL.updateContext = function() {\n this.context.push(types$1.b_tmpl);\n this.exprAllowed = true;\n};\n\ntypes.parenL.updateContext = function(prevType) {\n var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while;\n this.context.push(statementParens ? types$1.p_stat : types$1.p_expr);\n this.exprAllowed = true;\n};\n\ntypes.incDec.updateContext = function() {\n // tokExprAllowed stays unchanged\n};\n\ntypes._function.updateContext = types._class.updateContext = function(prevType) {\n if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else &&\n !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat))\n { this.context.push(types$1.f_expr); }\n else\n { this.context.push(types$1.f_stat); }\n this.exprAllowed = false;\n};\n\ntypes.backQuote.updateContext = function() {\n if (this.curContext() === types$1.q_tmpl)\n { this.context.pop(); }\n else\n { this.context.push(types$1.q_tmpl); }\n this.exprAllowed = false;\n};\n\ntypes.star.updateContext = function(prevType) {\n if (prevType === types._function) {\n var index = this.context.length - 1;\n if (this.context[index] === types$1.f_expr)\n { this.context[index] = types$1.f_expr_gen; }\n else\n { this.context[index] = types$1.f_gen; }\n }\n this.exprAllowed = true;\n};\n\ntypes.name.updateContext = function(prevType) {\n var allowed = false;\n if (this.options.ecmaVersion >= 6 && prevType !== types.dot) {\n if (this.value === \"of\" && !this.exprAllowed ||\n this.value === \"yield\" && this.inGeneratorContext())\n { allowed = true; }\n }\n this.exprAllowed = allowed;\n};\n\nvar data = {\n \"$LONE\": [\n \"ASCII\",\n \"ASCII_Hex_Digit\",\n \"AHex\",\n \"Alphabetic\",\n \"Alpha\",\n \"Any\",\n \"Assigned\",\n \"Bidi_Control\",\n \"Bidi_C\",\n \"Bidi_Mirrored\",\n \"Bidi_M\",\n \"Case_Ignorable\",\n \"CI\",\n \"Cased\",\n \"Changes_When_Casefolded\",\n \"CWCF\",\n \"Changes_When_Casemapped\",\n \"CWCM\",\n \"Changes_When_Lowercased\",\n \"CWL\",\n \"Changes_When_NFKC_Casefolded\",\n \"CWKCF\",\n \"Changes_When_Titlecased\",\n \"CWT\",\n \"Changes_When_Uppercased\",\n \"CWU\",\n \"Dash\",\n \"Default_Ignorable_Code_Point\",\n \"DI\",\n \"Deprecated\",\n \"Dep\",\n \"Diacritic\",\n \"Dia\",\n \"Emoji\",\n \"Emoji_Component\",\n \"Emoji_Modifier\",\n \"Emoji_Modifier_Base\",\n \"Emoji_Presentation\",\n \"Extender\",\n \"Ext\",\n \"Grapheme_Base\",\n \"Gr_Base\",\n \"Grapheme_Extend\",\n \"Gr_Ext\",\n \"Hex_Digit\",\n \"Hex\",\n \"IDS_Binary_Operator\",\n \"IDSB\",\n \"IDS_Trinary_Operator\",\n \"IDST\",\n \"ID_Continue\",\n \"IDC\",\n \"ID_Start\",\n \"IDS\",\n \"Ideographic\",\n \"Ideo\",\n \"Join_Control\",\n \"Join_C\",\n \"Logical_Order_Exception\",\n \"LOE\",\n \"Lowercase\",\n \"Lower\",\n \"Math\",\n \"Noncharacter_Code_Point\",\n \"NChar\",\n \"Pattern_Syntax\",\n \"Pat_Syn\",\n \"Pattern_White_Space\",\n \"Pat_WS\",\n \"Quotation_Mark\",\n \"QMark\",\n \"Radical\",\n \"Regional_Indicator\",\n \"RI\",\n \"Sentence_Terminal\",\n \"STerm\",\n \"Soft_Dotted\",\n \"SD\",\n \"Terminal_Punctuation\",\n \"Term\",\n \"Unified_Ideograph\",\n \"UIdeo\",\n \"Uppercase\",\n \"Upper\",\n \"Variation_Selector\",\n \"VS\",\n \"White_Space\",\n \"space\",\n \"XID_Continue\",\n \"XIDC\",\n \"XID_Start\",\n \"XIDS\"\n ],\n \"General_Category\": [\n \"Cased_Letter\",\n \"LC\",\n \"Close_Punctuation\",\n \"Pe\",\n \"Connector_Punctuation\",\n \"Pc\",\n \"Control\",\n \"Cc\",\n \"cntrl\",\n \"Currency_Symbol\",\n \"Sc\",\n \"Dash_Punctuation\",\n \"Pd\",\n \"Decimal_Number\",\n \"Nd\",\n \"digit\",\n \"Enclosing_Mark\",\n \"Me\",\n \"Final_Punctuation\",\n \"Pf\",\n \"Format\",\n \"Cf\",\n \"Initial_Punctuation\",\n \"Pi\",\n \"Letter\",\n \"L\",\n \"Letter_Number\",\n \"Nl\",\n \"Line_Separator\",\n \"Zl\",\n \"Lowercase_Letter\",\n \"Ll\",\n \"Mark\",\n \"M\",\n \"Combining_Mark\",\n \"Math_Symbol\",\n \"Sm\",\n \"Modifier_Letter\",\n \"Lm\",\n \"Modifier_Symbol\",\n \"Sk\",\n \"Nonspacing_Mark\",\n \"Mn\",\n \"Number\",\n \"N\",\n \"Open_Punctuation\",\n \"Ps\",\n \"Other\",\n \"C\",\n \"Other_Letter\",\n \"Lo\",\n \"Other_Number\",\n \"No\",\n \"Other_Punctuation\",\n \"Po\",\n \"Other_Symbol\",\n \"So\",\n \"Paragraph_Separator\",\n \"Zp\",\n \"Private_Use\",\n \"Co\",\n \"Punctuation\",\n \"P\",\n \"punct\",\n \"Separator\",\n \"Z\",\n \"Space_Separator\",\n \"Zs\",\n \"Spacing_Mark\",\n \"Mc\",\n \"Surrogate\",\n \"Cs\",\n \"Symbol\",\n \"S\",\n \"Titlecase_Letter\",\n \"Lt\",\n \"Unassigned\",\n \"Cn\",\n \"Uppercase_Letter\",\n \"Lu\"\n ],\n \"Script\": [\n \"Adlam\",\n \"Adlm\",\n \"Ahom\",\n \"Anatolian_Hieroglyphs\",\n \"Hluw\",\n \"Arabic\",\n \"Arab\",\n \"Armenian\",\n \"Armn\",\n \"Avestan\",\n \"Avst\",\n \"Balinese\",\n \"Bali\",\n \"Bamum\",\n \"Bamu\",\n \"Bassa_Vah\",\n \"Bass\",\n \"Batak\",\n \"Batk\",\n \"Bengali\",\n \"Beng\",\n \"Bhaiksuki\",\n \"Bhks\",\n \"Bopomofo\",\n \"Bopo\",\n \"Brahmi\",\n \"Brah\",\n \"Braille\",\n \"Brai\",\n \"Buginese\",\n \"Bugi\",\n \"Buhid\",\n \"Buhd\",\n \"Canadian_Aboriginal\",\n \"Cans\",\n \"Carian\",\n \"Cari\",\n \"Caucasian_Albanian\",\n \"Aghb\",\n \"Chakma\",\n \"Cakm\",\n \"Cham\",\n \"Cherokee\",\n \"Cher\",\n \"Common\",\n \"Zyyy\",\n \"Coptic\",\n \"Copt\",\n \"Qaac\",\n \"Cuneiform\",\n \"Xsux\",\n \"Cypriot\",\n \"Cprt\",\n \"Cyrillic\",\n \"Cyrl\",\n \"Deseret\",\n \"Dsrt\",\n \"Devanagari\",\n \"Deva\",\n \"Duployan\",\n \"Dupl\",\n \"Egyptian_Hieroglyphs\",\n \"Egyp\",\n \"Elbasan\",\n \"Elba\",\n \"Ethiopic\",\n \"Ethi\",\n \"Georgian\",\n \"Geor\",\n \"Glagolitic\",\n \"Glag\",\n \"Gothic\",\n \"Goth\",\n \"Grantha\",\n \"Gran\",\n \"Greek\",\n \"Grek\",\n \"Gujarati\",\n \"Gujr\",\n \"Gurmukhi\",\n \"Guru\",\n \"Han\",\n \"Hani\",\n \"Hangul\",\n \"Hang\",\n \"Hanunoo\",\n \"Hano\",\n \"Hatran\",\n \"Hatr\",\n \"Hebrew\",\n \"Hebr\",\n \"Hiragana\",\n \"Hira\",\n \"Imperial_Aramaic\",\n \"Armi\",\n \"Inherited\",\n \"Zinh\",\n \"Qaai\",\n \"Inscriptional_Pahlavi\",\n \"Phli\",\n \"Inscriptional_Parthian\",\n \"Prti\",\n \"Javanese\",\n \"Java\",\n \"Kaithi\",\n \"Kthi\",\n \"Kannada\",\n \"Knda\",\n \"Katakana\",\n \"Kana\",\n \"Kayah_Li\",\n \"Kali\",\n \"Kharoshthi\",\n \"Khar\",\n \"Khmer\",\n \"Khmr\",\n \"Khojki\",\n \"Khoj\",\n \"Khudawadi\",\n \"Sind\",\n \"Lao\",\n \"Laoo\",\n \"Latin\",\n \"Latn\",\n \"Lepcha\",\n \"Lepc\",\n \"Limbu\",\n \"Limb\",\n \"Linear_A\",\n \"Lina\",\n \"Linear_B\",\n \"Linb\",\n \"Lisu\",\n \"Lycian\",\n \"Lyci\",\n \"Lydian\",\n \"Lydi\",\n \"Mahajani\",\n \"Mahj\",\n \"Malayalam\",\n \"Mlym\",\n \"Mandaic\",\n \"Mand\",\n \"Manichaean\",\n \"Mani\",\n \"Marchen\",\n \"Marc\",\n \"Masaram_Gondi\",\n \"Gonm\",\n \"Meetei_Mayek\",\n \"Mtei\",\n \"Mende_Kikakui\",\n \"Mend\",\n \"Meroitic_Cursive\",\n \"Merc\",\n \"Meroitic_Hieroglyphs\",\n \"Mero\",\n \"Miao\",\n \"Plrd\",\n \"Modi\",\n \"Mongolian\",\n \"Mong\",\n \"Mro\",\n \"Mroo\",\n \"Multani\",\n \"Mult\",\n \"Myanmar\",\n \"Mymr\",\n \"Nabataean\",\n \"Nbat\",\n \"New_Tai_Lue\",\n \"Talu\",\n \"Newa\",\n \"Nko\",\n \"Nkoo\",\n \"Nushu\",\n \"Nshu\",\n \"Ogham\",\n \"Ogam\",\n \"Ol_Chiki\",\n \"Olck\",\n \"Old_Hungarian\",\n \"Hung\",\n \"Old_Italic\",\n \"Ital\",\n \"Old_North_Arabian\",\n \"Narb\",\n \"Old_Permic\",\n \"Perm\",\n \"Old_Persian\",\n \"Xpeo\",\n \"Old_South_Arabian\",\n \"Sarb\",\n \"Old_Turkic\",\n \"Orkh\",\n \"Oriya\",\n \"Orya\",\n \"Osage\",\n \"Osge\",\n \"Osmanya\",\n \"Osma\",\n \"Pahawh_Hmong\",\n \"Hmng\",\n \"Palmyrene\",\n \"Palm\",\n \"Pau_Cin_Hau\",\n \"Pauc\",\n \"Phags_Pa\",\n \"Phag\",\n \"Phoenician\",\n \"Phnx\",\n \"Psalter_Pahlavi\",\n \"Phlp\",\n \"Rejang\",\n \"Rjng\",\n \"Runic\",\n \"Runr\",\n \"Samaritan\",\n \"Samr\",\n \"Saurashtra\",\n \"Saur\",\n \"Sharada\",\n \"Shrd\",\n \"Shavian\",\n \"Shaw\",\n \"Siddham\",\n \"Sidd\",\n \"SignWriting\",\n \"Sgnw\",\n \"Sinhala\",\n \"Sinh\",\n \"Sora_Sompeng\",\n \"Sora\",\n \"Soyombo\",\n \"Soyo\",\n \"Sundanese\",\n \"Sund\",\n \"Syloti_Nagri\",\n \"Sylo\",\n \"Syriac\",\n \"Syrc\",\n \"Tagalog\",\n \"Tglg\",\n \"Tagbanwa\",\n \"Tagb\",\n \"Tai_Le\",\n \"Tale\",\n \"Tai_Tham\",\n \"Lana\",\n \"Tai_Viet\",\n \"Tavt\",\n \"Takri\",\n \"Takr\",\n \"Tamil\",\n \"Taml\",\n \"Tangut\",\n \"Tang\",\n \"Telugu\",\n \"Telu\",\n \"Thaana\",\n \"Thaa\",\n \"Thai\",\n \"Tibetan\",\n \"Tibt\",\n \"Tifinagh\",\n \"Tfng\",\n \"Tirhuta\",\n \"Tirh\",\n \"Ugaritic\",\n \"Ugar\",\n \"Vai\",\n \"Vaii\",\n \"Warang_Citi\",\n \"Wara\",\n \"Yi\",\n \"Yiii\",\n \"Zanabazar_Square\",\n \"Zanb\"\n ]\n};\nArray.prototype.push.apply(data.$LONE, data.General_Category);\ndata.gc = data.General_Category;\ndata.sc = data.Script_Extensions = data.scx = data.Script;\n\nvar pp$9 = Parser.prototype;\n\nvar RegExpValidationState = function RegExpValidationState(parser) {\n this.parser = parser;\n this.validFlags = \"gim\" + (parser.options.ecmaVersion >= 6 ? \"uy\" : \"\") + (parser.options.ecmaVersion >= 9 ? \"s\" : \"\");\n this.source = \"\";\n this.flags = \"\";\n this.start = 0;\n this.switchU = false;\n this.switchN = false;\n this.pos = 0;\n this.lastIntValue = 0;\n this.lastStringValue = \"\";\n this.lastAssertionIsQuantifiable = false;\n this.numCapturingParens = 0;\n this.maxBackReference = 0;\n this.groupNames = [];\n this.backReferenceNames = [];\n};\n\nRegExpValidationState.prototype.reset = function reset (start, pattern, flags) {\n var unicode = flags.indexOf(\"u\") !== -1;\n this.start = start | 0;\n this.source = pattern + \"\";\n this.flags = flags;\n this.switchU = unicode && this.parser.options.ecmaVersion >= 6;\n this.switchN = unicode && this.parser.options.ecmaVersion >= 9;\n};\n\nRegExpValidationState.prototype.raise = function raise (message) {\n this.parser.raiseRecoverable(this.start, (\"Invalid regular expression: /\" + (this.source) + \"/: \" + message));\n};\n\n// If u flag is given, this returns the code point at the index (it combines a surrogate pair).\n// Otherwise, this returns the code unit of the index (can be a part of a surrogate pair).\nRegExpValidationState.prototype.at = function at (i) {\n var s = this.source;\n var l = s.length;\n if (i >= l) {\n return -1\n }\n var c = s.charCodeAt(i);\n if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {\n return c\n }\n return (c << 10) + s.charCodeAt(i + 1) - 0x35FDC00\n};\n\nRegExpValidationState.prototype.nextIndex = function nextIndex (i) {\n var s = this.source;\n var l = s.length;\n if (i >= l) {\n return l\n }\n var c = s.charCodeAt(i);\n if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {\n return i + 1\n }\n return i + 2\n};\n\nRegExpValidationState.prototype.current = function current () {\n return this.at(this.pos)\n};\n\nRegExpValidationState.prototype.lookahead = function lookahead () {\n return this.at(this.nextIndex(this.pos))\n};\n\nRegExpValidationState.prototype.advance = function advance () {\n this.pos = this.nextIndex(this.pos);\n};\n\nRegExpValidationState.prototype.eat = function eat (ch) {\n if (this.current() === ch) {\n this.advance();\n return true\n }\n return false\n};\n\nfunction codePointToString$1(ch) {\n if (ch <= 0xFFFF) { return String.fromCharCode(ch) }\n ch -= 0x10000;\n return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00)\n}\n\n/**\n * Validate the flags part of a given RegExpLiteral.\n *\n * @param {RegExpValidationState} state The state to validate RegExp.\n * @returns {void}\n */\npp$9.validateRegExpFlags = function(state) {\n var this$1 = this;\n\n var validFlags = state.validFlags;\n var flags = state.flags;\n\n for (var i = 0; i < flags.length; i++) {\n var flag = flags.charAt(i);\n if (validFlags.indexOf(flag) === -1) {\n this$1.raise(state.start, \"Invalid regular expression flag\");\n }\n if (flags.indexOf(flag, i + 1) > -1) {\n this$1.raise(state.start, \"Duplicate regular expression flag\");\n }\n }\n};\n\n/**\n * Validate the pattern part of a given RegExpLiteral.\n *\n * @param {RegExpValidationState} state The state to validate RegExp.\n * @returns {void}\n */\npp$9.validateRegExpPattern = function(state) {\n this.regexp_pattern(state);\n\n // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of\n // parsing contains a |GroupName|, reparse with the goal symbol\n // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError*\n // exception if _P_ did not conform to the grammar, if any elements of _P_\n // were not matched by the parse, or if any Early Error conditions exist.\n if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) {\n state.switchN = true;\n this.regexp_pattern(state);\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern\npp$9.regexp_pattern = function(state) {\n state.pos = 0;\n state.lastIntValue = 0;\n state.lastStringValue = \"\";\n state.lastAssertionIsQuantifiable = false;\n state.numCapturingParens = 0;\n state.maxBackReference = 0;\n state.groupNames.length = 0;\n state.backReferenceNames.length = 0;\n\n this.regexp_disjunction(state);\n\n if (state.pos !== state.source.length) {\n // Make the same messages as V8.\n if (state.eat(0x29 /* ) */)) {\n state.raise(\"Unmatched ')'\");\n }\n if (state.eat(0x5D /* [ */) || state.eat(0x7D /* } */)) {\n state.raise(\"Lone quantifier brackets\");\n }\n }\n if (state.maxBackReference > state.numCapturingParens) {\n state.raise(\"Invalid escape\");\n }\n for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) {\n var name = list[i];\n\n if (state.groupNames.indexOf(name) === -1) {\n state.raise(\"Invalid named capture referenced\");\n }\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction\npp$9.regexp_disjunction = function(state) {\n var this$1 = this;\n\n this.regexp_alternative(state);\n while (state.eat(0x7C /* | */)) {\n this$1.regexp_alternative(state);\n }\n\n // Make the same message as V8.\n if (this.regexp_eatQuantifier(state, true)) {\n state.raise(\"Nothing to repeat\");\n }\n if (state.eat(0x7B /* { */)) {\n state.raise(\"Lone quantifier brackets\");\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative\npp$9.regexp_alternative = function(state) {\n while (state.pos < state.source.length && this.regexp_eatTerm(state))\n { }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term\npp$9.regexp_eatTerm = function(state) {\n if (this.regexp_eatAssertion(state)) {\n // Handle `QuantifiableAssertion Quantifier` alternative.\n // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion\n // is a QuantifiableAssertion.\n if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) {\n // Make the same message as V8.\n if (state.switchU) {\n state.raise(\"Invalid quantifier\");\n }\n }\n return true\n }\n\n if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) {\n this.regexp_eatQuantifier(state);\n return true\n }\n\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion\npp$9.regexp_eatAssertion = function(state) {\n var start = state.pos;\n state.lastAssertionIsQuantifiable = false;\n\n // ^, $\n if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) {\n return true\n }\n\n // \\b \\B\n if (state.eat(0x5C /* \\ */)) {\n if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) {\n return true\n }\n state.pos = start;\n }\n\n // Lookahead / Lookbehind\n if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) {\n var lookbehind = false;\n if (this.options.ecmaVersion >= 9) {\n lookbehind = state.eat(0x3C /* < */);\n }\n if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) {\n this.regexp_disjunction(state);\n if (!state.eat(0x29 /* ) */)) {\n state.raise(\"Unterminated group\");\n }\n state.lastAssertionIsQuantifiable = !lookbehind;\n return true\n }\n }\n\n state.pos = start;\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier\npp$9.regexp_eatQuantifier = function(state, noError) {\n if ( noError === void 0 ) noError = false;\n\n if (this.regexp_eatQuantifierPrefix(state, noError)) {\n state.eat(0x3F /* ? */);\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix\npp$9.regexp_eatQuantifierPrefix = function(state, noError) {\n return (\n state.eat(0x2A /* * */) ||\n state.eat(0x2B /* + */) ||\n state.eat(0x3F /* ? */) ||\n this.regexp_eatBracedQuantifier(state, noError)\n )\n};\npp$9.regexp_eatBracedQuantifier = function(state, noError) {\n var start = state.pos;\n if (state.eat(0x7B /* { */)) {\n var min = 0, max = -1;\n if (this.regexp_eatDecimalDigits(state)) {\n min = state.lastIntValue;\n if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) {\n max = state.lastIntValue;\n }\n if (state.eat(0x7D /* } */)) {\n // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term\n if (max !== -1 && max < min && !noError) {\n state.raise(\"numbers out of order in {} quantifier\");\n }\n return true\n }\n }\n if (state.switchU && !noError) {\n state.raise(\"Incomplete quantifier\");\n }\n state.pos = start;\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Atom\npp$9.regexp_eatAtom = function(state) {\n return (\n this.regexp_eatPatternCharacters(state) ||\n state.eat(0x2E /* . */) ||\n this.regexp_eatReverseSolidusAtomEscape(state) ||\n this.regexp_eatCharacterClass(state) ||\n this.regexp_eatUncapturingGroup(state) ||\n this.regexp_eatCapturingGroup(state)\n )\n};\npp$9.regexp_eatReverseSolidusAtomEscape = function(state) {\n var start = state.pos;\n if (state.eat(0x5C /* \\ */)) {\n if (this.regexp_eatAtomEscape(state)) {\n return true\n }\n state.pos = start;\n }\n return false\n};\npp$9.regexp_eatUncapturingGroup = function(state) {\n var start = state.pos;\n if (state.eat(0x28 /* ( */)) {\n if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) {\n this.regexp_disjunction(state);\n if (state.eat(0x29 /* ) */)) {\n return true\n }\n state.raise(\"Unterminated group\");\n }\n state.pos = start;\n }\n return false\n};\npp$9.regexp_eatCapturingGroup = function(state) {\n if (state.eat(0x28 /* ( */)) {\n if (this.options.ecmaVersion >= 9) {\n this.regexp_groupSpecifier(state);\n } else if (state.current() === 0x3F /* ? */) {\n state.raise(\"Invalid group\");\n }\n this.regexp_disjunction(state);\n if (state.eat(0x29 /* ) */)) {\n state.numCapturingParens += 1;\n return true\n }\n state.raise(\"Unterminated group\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom\npp$9.regexp_eatExtendedAtom = function(state) {\n return (\n state.eat(0x2E /* . */) ||\n this.regexp_eatReverseSolidusAtomEscape(state) ||\n this.regexp_eatCharacterClass(state) ||\n this.regexp_eatUncapturingGroup(state) ||\n this.regexp_eatCapturingGroup(state) ||\n this.regexp_eatInvalidBracedQuantifier(state) ||\n this.regexp_eatExtendedPatternCharacter(state)\n )\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier\npp$9.regexp_eatInvalidBracedQuantifier = function(state) {\n if (this.regexp_eatBracedQuantifier(state, true)) {\n state.raise(\"Nothing to repeat\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter\npp$9.regexp_eatSyntaxCharacter = function(state) {\n var ch = state.current();\n if (isSyntaxCharacter(ch)) {\n state.lastIntValue = ch;\n state.advance();\n return true\n }\n return false\n};\nfunction isSyntaxCharacter(ch) {\n return (\n ch === 0x24 /* $ */ ||\n ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ ||\n ch === 0x2E /* . */ ||\n ch === 0x3F /* ? */ ||\n ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ ||\n ch >= 0x7B /* { */ && ch <= 0x7D /* } */\n )\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter\n// But eat eager.\npp$9.regexp_eatPatternCharacters = function(state) {\n var start = state.pos;\n var ch = 0;\n while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) {\n state.advance();\n }\n return state.pos !== start\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter\npp$9.regexp_eatExtendedPatternCharacter = function(state) {\n var ch = state.current();\n if (\n ch !== -1 &&\n ch !== 0x24 /* $ */ &&\n !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) &&\n ch !== 0x2E /* . */ &&\n ch !== 0x3F /* ? */ &&\n ch !== 0x5B /* [ */ &&\n ch !== 0x5E /* ^ */ &&\n ch !== 0x7C /* | */\n ) {\n state.advance();\n return true\n }\n return false\n};\n\n// GroupSpecifier[U] ::\n// [empty]\n// `?` GroupName[?U]\npp$9.regexp_groupSpecifier = function(state) {\n if (state.eat(0x3F /* ? */)) {\n if (this.regexp_eatGroupName(state)) {\n if (state.groupNames.indexOf(state.lastStringValue) !== -1) {\n state.raise(\"Duplicate capture group name\");\n }\n state.groupNames.push(state.lastStringValue);\n return\n }\n state.raise(\"Invalid group\");\n }\n};\n\n// GroupName[U] ::\n// `<` RegExpIdentifierName[?U] `>`\n// Note: this updates `state.lastStringValue` property with the eaten name.\npp$9.regexp_eatGroupName = function(state) {\n state.lastStringValue = \"\";\n if (state.eat(0x3C /* < */)) {\n if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) {\n return true\n }\n state.raise(\"Invalid capture group name\");\n }\n return false\n};\n\n// RegExpIdentifierName[U] ::\n// RegExpIdentifierStart[?U]\n// RegExpIdentifierName[?U] RegExpIdentifierPart[?U]\n// Note: this updates `state.lastStringValue` property with the eaten name.\npp$9.regexp_eatRegExpIdentifierName = function(state) {\n state.lastStringValue = \"\";\n if (this.regexp_eatRegExpIdentifierStart(state)) {\n state.lastStringValue += codePointToString$1(state.lastIntValue);\n while (this.regexp_eatRegExpIdentifierPart(state)) {\n state.lastStringValue += codePointToString$1(state.lastIntValue);\n }\n return true\n }\n return false\n};\n\n// RegExpIdentifierStart[U] ::\n// UnicodeIDStart\n// `$`\n// `_`\n// `\\` RegExpUnicodeEscapeSequence[?U]\npp$9.regexp_eatRegExpIdentifierStart = function(state) {\n var start = state.pos;\n var ch = state.current();\n state.advance();\n\n if (ch === 0x5C /* \\ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) {\n ch = state.lastIntValue;\n }\n if (isRegExpIdentifierStart(ch)) {\n state.lastIntValue = ch;\n return true\n }\n\n state.pos = start;\n return false\n};\nfunction isRegExpIdentifierStart(ch) {\n return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */\n}\n\n// RegExpIdentifierPart[U] ::\n// UnicodeIDContinue\n// `$`\n// `_`\n// `\\` RegExpUnicodeEscapeSequence[?U]\n// \n// \npp$9.regexp_eatRegExpIdentifierPart = function(state) {\n var start = state.pos;\n var ch = state.current();\n state.advance();\n\n if (ch === 0x5C /* \\ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) {\n ch = state.lastIntValue;\n }\n if (isRegExpIdentifierPart(ch)) {\n state.lastIntValue = ch;\n return true\n }\n\n state.pos = start;\n return false\n};\nfunction isRegExpIdentifierPart(ch) {\n return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* */ || ch === 0x200D /* */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape\npp$9.regexp_eatAtomEscape = function(state) {\n if (\n this.regexp_eatBackReference(state) ||\n this.regexp_eatCharacterClassEscape(state) ||\n this.regexp_eatCharacterEscape(state) ||\n (state.switchN && this.regexp_eatKGroupName(state))\n ) {\n return true\n }\n if (state.switchU) {\n // Make the same message as V8.\n if (state.current() === 0x63 /* c */) {\n state.raise(\"Invalid unicode escape\");\n }\n state.raise(\"Invalid escape\");\n }\n return false\n};\npp$9.regexp_eatBackReference = function(state) {\n var start = state.pos;\n if (this.regexp_eatDecimalEscape(state)) {\n var n = state.lastIntValue;\n if (state.switchU) {\n // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape\n if (n > state.maxBackReference) {\n state.maxBackReference = n;\n }\n return true\n }\n if (n <= state.numCapturingParens) {\n return true\n }\n state.pos = start;\n }\n return false\n};\npp$9.regexp_eatKGroupName = function(state) {\n if (state.eat(0x6B /* k */)) {\n if (this.regexp_eatGroupName(state)) {\n state.backReferenceNames.push(state.lastStringValue);\n return true\n }\n state.raise(\"Invalid named reference\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape\npp$9.regexp_eatCharacterEscape = function(state) {\n return (\n this.regexp_eatControlEscape(state) ||\n this.regexp_eatCControlLetter(state) ||\n this.regexp_eatZero(state) ||\n this.regexp_eatHexEscapeSequence(state) ||\n this.regexp_eatRegExpUnicodeEscapeSequence(state) ||\n (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) ||\n this.regexp_eatIdentityEscape(state)\n )\n};\npp$9.regexp_eatCControlLetter = function(state) {\n var start = state.pos;\n if (state.eat(0x63 /* c */)) {\n if (this.regexp_eatControlLetter(state)) {\n return true\n }\n state.pos = start;\n }\n return false\n};\npp$9.regexp_eatZero = function(state) {\n if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) {\n state.lastIntValue = 0;\n state.advance();\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape\npp$9.regexp_eatControlEscape = function(state) {\n var ch = state.current();\n if (ch === 0x74 /* t */) {\n state.lastIntValue = 0x09; /* \\t */\n state.advance();\n return true\n }\n if (ch === 0x6E /* n */) {\n state.lastIntValue = 0x0A; /* \\n */\n state.advance();\n return true\n }\n if (ch === 0x76 /* v */) {\n state.lastIntValue = 0x0B; /* \\v */\n state.advance();\n return true\n }\n if (ch === 0x66 /* f */) {\n state.lastIntValue = 0x0C; /* \\f */\n state.advance();\n return true\n }\n if (ch === 0x72 /* r */) {\n state.lastIntValue = 0x0D; /* \\r */\n state.advance();\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter\npp$9.regexp_eatControlLetter = function(state) {\n var ch = state.current();\n if (isControlLetter(ch)) {\n state.lastIntValue = ch % 0x20;\n state.advance();\n return true\n }\n return false\n};\nfunction isControlLetter(ch) {\n return (\n (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) ||\n (ch >= 0x61 /* a */ && ch <= 0x7A /* z */)\n )\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence\npp$9.regexp_eatRegExpUnicodeEscapeSequence = function(state) {\n var start = state.pos;\n\n if (state.eat(0x75 /* u */)) {\n if (this.regexp_eatFixedHexDigits(state, 4)) {\n var lead = state.lastIntValue;\n if (state.switchU && lead >= 0xD800 && lead <= 0xDBFF) {\n var leadSurrogateEnd = state.pos;\n if (state.eat(0x5C /* \\ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) {\n var trail = state.lastIntValue;\n if (trail >= 0xDC00 && trail <= 0xDFFF) {\n state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;\n return true\n }\n }\n state.pos = leadSurrogateEnd;\n state.lastIntValue = lead;\n }\n return true\n }\n if (\n state.switchU &&\n state.eat(0x7B /* { */) &&\n this.regexp_eatHexDigits(state) &&\n state.eat(0x7D /* } */) &&\n isValidUnicode(state.lastIntValue)\n ) {\n return true\n }\n if (state.switchU) {\n state.raise(\"Invalid unicode escape\");\n }\n state.pos = start;\n }\n\n return false\n};\nfunction isValidUnicode(ch) {\n return ch >= 0 && ch <= 0x10FFFF\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape\npp$9.regexp_eatIdentityEscape = function(state) {\n if (state.switchU) {\n if (this.regexp_eatSyntaxCharacter(state)) {\n return true\n }\n if (state.eat(0x2F /* / */)) {\n state.lastIntValue = 0x2F; /* / */\n return true\n }\n return false\n }\n\n var ch = state.current();\n if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) {\n state.lastIntValue = ch;\n state.advance();\n return true\n }\n\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape\npp$9.regexp_eatDecimalEscape = function(state) {\n state.lastIntValue = 0;\n var ch = state.current();\n if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) {\n do {\n state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);\n state.advance();\n } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */)\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape\npp$9.regexp_eatCharacterClassEscape = function(state) {\n var ch = state.current();\n\n if (isCharacterClassEscape(ch)) {\n state.lastIntValue = -1;\n state.advance();\n return true\n }\n\n if (\n state.switchU &&\n this.options.ecmaVersion >= 9 &&\n (ch === 0x50 /* P */ || ch === 0x70 /* p */)\n ) {\n state.lastIntValue = -1;\n state.advance();\n if (\n state.eat(0x7B /* { */) &&\n this.regexp_eatUnicodePropertyValueExpression(state) &&\n state.eat(0x7D /* } */)\n ) {\n return true\n }\n state.raise(\"Invalid property name\");\n }\n\n return false\n};\nfunction isCharacterClassEscape(ch) {\n return (\n ch === 0x64 /* d */ ||\n ch === 0x44 /* D */ ||\n ch === 0x73 /* s */ ||\n ch === 0x53 /* S */ ||\n ch === 0x77 /* w */ ||\n ch === 0x57 /* W */\n )\n}\n\n// UnicodePropertyValueExpression ::\n// UnicodePropertyName `=` UnicodePropertyValue\n// LoneUnicodePropertyNameOrValue\npp$9.regexp_eatUnicodePropertyValueExpression = function(state) {\n var start = state.pos;\n\n // UnicodePropertyName `=` UnicodePropertyValue\n if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) {\n var name = state.lastStringValue;\n if (this.regexp_eatUnicodePropertyValue(state)) {\n var value = state.lastStringValue;\n this.regexp_validateUnicodePropertyNameAndValue(state, name, value);\n return true\n }\n }\n state.pos = start;\n\n // LoneUnicodePropertyNameOrValue\n if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) {\n var nameOrValue = state.lastStringValue;\n this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue);\n return true\n }\n return false\n};\npp$9.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) {\n if (!data.hasOwnProperty(name) || data[name].indexOf(value) === -1) {\n state.raise(\"Invalid property name\");\n }\n};\npp$9.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) {\n if (data.$LONE.indexOf(nameOrValue) === -1) {\n state.raise(\"Invalid property name\");\n }\n};\n\n// UnicodePropertyName ::\n// UnicodePropertyNameCharacters\npp$9.regexp_eatUnicodePropertyName = function(state) {\n var ch = 0;\n state.lastStringValue = \"\";\n while (isUnicodePropertyNameCharacter(ch = state.current())) {\n state.lastStringValue += codePointToString$1(ch);\n state.advance();\n }\n return state.lastStringValue !== \"\"\n};\nfunction isUnicodePropertyNameCharacter(ch) {\n return isControlLetter(ch) || ch === 0x5F /* _ */\n}\n\n// UnicodePropertyValue ::\n// UnicodePropertyValueCharacters\npp$9.regexp_eatUnicodePropertyValue = function(state) {\n var ch = 0;\n state.lastStringValue = \"\";\n while (isUnicodePropertyValueCharacter(ch = state.current())) {\n state.lastStringValue += codePointToString$1(ch);\n state.advance();\n }\n return state.lastStringValue !== \"\"\n};\nfunction isUnicodePropertyValueCharacter(ch) {\n return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch)\n}\n\n// LoneUnicodePropertyNameOrValue ::\n// UnicodePropertyValueCharacters\npp$9.regexp_eatLoneUnicodePropertyNameOrValue = function(state) {\n return this.regexp_eatUnicodePropertyValue(state)\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass\npp$9.regexp_eatCharacterClass = function(state) {\n if (state.eat(0x5B /* [ */)) {\n state.eat(0x5E /* ^ */);\n this.regexp_classRanges(state);\n if (state.eat(0x5D /* [ */)) {\n return true\n }\n // Unreachable since it threw \"unterminated regular expression\" error before.\n state.raise(\"Unterminated character class\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges\n// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges\n// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash\npp$9.regexp_classRanges = function(state) {\n var this$1 = this;\n\n while (this.regexp_eatClassAtom(state)) {\n var left = state.lastIntValue;\n if (state.eat(0x2D /* - */) && this$1.regexp_eatClassAtom(state)) {\n var right = state.lastIntValue;\n if (state.switchU && (left === -1 || right === -1)) {\n state.raise(\"Invalid character class\");\n }\n if (left !== -1 && right !== -1 && left > right) {\n state.raise(\"Range out of order in character class\");\n }\n }\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash\npp$9.regexp_eatClassAtom = function(state) {\n var start = state.pos;\n\n if (state.eat(0x5C /* \\ */)) {\n if (this.regexp_eatClassEscape(state)) {\n return true\n }\n if (state.switchU) {\n // Make the same message as V8.\n var ch$1 = state.current();\n if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) {\n state.raise(\"Invalid class escape\");\n }\n state.raise(\"Invalid escape\");\n }\n state.pos = start;\n }\n\n var ch = state.current();\n if (ch !== 0x5D /* [ */) {\n state.lastIntValue = ch;\n state.advance();\n return true\n }\n\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape\npp$9.regexp_eatClassEscape = function(state) {\n var start = state.pos;\n\n if (state.eat(0x62 /* b */)) {\n state.lastIntValue = 0x08; /* */\n return true\n }\n\n if (state.switchU && state.eat(0x2D /* - */)) {\n state.lastIntValue = 0x2D; /* - */\n return true\n }\n\n if (!state.switchU && state.eat(0x63 /* c */)) {\n if (this.regexp_eatClassControlLetter(state)) {\n return true\n }\n state.pos = start;\n }\n\n return (\n this.regexp_eatCharacterClassEscape(state) ||\n this.regexp_eatCharacterEscape(state)\n )\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter\npp$9.regexp_eatClassControlLetter = function(state) {\n var ch = state.current();\n if (isDecimalDigit(ch) || ch === 0x5F /* _ */) {\n state.lastIntValue = ch % 0x20;\n state.advance();\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence\npp$9.regexp_eatHexEscapeSequence = function(state) {\n var start = state.pos;\n if (state.eat(0x78 /* x */)) {\n if (this.regexp_eatFixedHexDigits(state, 2)) {\n return true\n }\n if (state.switchU) {\n state.raise(\"Invalid escape\");\n }\n state.pos = start;\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits\npp$9.regexp_eatDecimalDigits = function(state) {\n var start = state.pos;\n var ch = 0;\n state.lastIntValue = 0;\n while (isDecimalDigit(ch = state.current())) {\n state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);\n state.advance();\n }\n return state.pos !== start\n};\nfunction isDecimalDigit(ch) {\n return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits\npp$9.regexp_eatHexDigits = function(state) {\n var start = state.pos;\n var ch = 0;\n state.lastIntValue = 0;\n while (isHexDigit(ch = state.current())) {\n state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);\n state.advance();\n }\n return state.pos !== start\n};\nfunction isHexDigit(ch) {\n return (\n (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) ||\n (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) ||\n (ch >= 0x61 /* a */ && ch <= 0x66 /* f */)\n )\n}\nfunction hexToInt(ch) {\n if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) {\n return 10 + (ch - 0x41 /* A */)\n }\n if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) {\n return 10 + (ch - 0x61 /* a */)\n }\n return ch - 0x30 /* 0 */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence\n// Allows only 0-377(octal) i.e. 0-255(decimal).\npp$9.regexp_eatLegacyOctalEscapeSequence = function(state) {\n if (this.regexp_eatOctalDigit(state)) {\n var n1 = state.lastIntValue;\n if (this.regexp_eatOctalDigit(state)) {\n var n2 = state.lastIntValue;\n if (n1 <= 3 && this.regexp_eatOctalDigit(state)) {\n state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue;\n } else {\n state.lastIntValue = n1 * 8 + n2;\n }\n } else {\n state.lastIntValue = n1;\n }\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit\npp$9.regexp_eatOctalDigit = function(state) {\n var ch = state.current();\n if (isOctalDigit(ch)) {\n state.lastIntValue = ch - 0x30; /* 0 */\n state.advance();\n return true\n }\n state.lastIntValue = 0;\n return false\n};\nfunction isOctalDigit(ch) {\n return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits\n// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit\n// And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence\npp$9.regexp_eatFixedHexDigits = function(state, length) {\n var start = state.pos;\n state.lastIntValue = 0;\n for (var i = 0; i < length; ++i) {\n var ch = state.current();\n if (!isHexDigit(ch)) {\n state.pos = start;\n return false\n }\n state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);\n state.advance();\n }\n return true\n};\n\n// Object type used to represent tokens. Note that normally, tokens\n// simply exist as properties on the parser object. This is only\n// used for the onToken callback and the external tokenizer.\n\nvar Token = function Token(p) {\n this.type = p.type;\n this.value = p.value;\n this.start = p.start;\n this.end = p.end;\n if (p.options.locations)\n { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); }\n if (p.options.ranges)\n { this.range = [p.start, p.end]; }\n};\n\n// ## Tokenizer\n\nvar pp$8 = Parser.prototype;\n\n// Move to the next token\n\npp$8.next = function() {\n if (this.options.onToken)\n { this.options.onToken(new Token(this)); }\n\n this.lastTokEnd = this.end;\n this.lastTokStart = this.start;\n this.lastTokEndLoc = this.endLoc;\n this.lastTokStartLoc = this.startLoc;\n this.nextToken();\n};\n\npp$8.getToken = function() {\n this.next();\n return new Token(this)\n};\n\n// If we're in an ES6 environment, make parsers iterable\nif (typeof Symbol !== \"undefined\")\n { pp$8[Symbol.iterator] = function() {\n var this$1 = this;\n\n return {\n next: function () {\n var token = this$1.getToken();\n return {\n done: token.type === types.eof,\n value: token\n }\n }\n }\n }; }\n\n// Toggle strict mode. Re-reads the next number or string to please\n// pedantic tests (`\"use strict\"; 010;` should fail).\n\npp$8.curContext = function() {\n return this.context[this.context.length - 1]\n};\n\n// Read a single token, updating the parser object's token-related\n// properties.\n\npp$8.nextToken = function() {\n var curContext = this.curContext();\n if (!curContext || !curContext.preserveSpace) { this.skipSpace(); }\n\n this.start = this.pos;\n if (this.options.locations) { this.startLoc = this.curPosition(); }\n if (this.pos >= this.input.length) { return this.finishToken(types.eof) }\n\n if (curContext.override) { return curContext.override(this) }\n else { this.readToken(this.fullCharCodeAtPos()); }\n};\n\npp$8.readToken = function(code) {\n // Identifier or keyword. '\\uXXXX' sequences are allowed in\n // identifiers, so '\\' also dispatches to that.\n if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\\' */)\n { return this.readWord() }\n\n return this.getTokenFromCode(code)\n};\n\npp$8.fullCharCodeAtPos = function() {\n var code = this.input.charCodeAt(this.pos);\n if (code <= 0xd7ff || code >= 0xe000) { return code }\n var next = this.input.charCodeAt(this.pos + 1);\n return (code << 10) + next - 0x35fdc00\n};\n\npp$8.skipBlockComment = function() {\n var this$1 = this;\n\n var startLoc = this.options.onComment && this.curPosition();\n var start = this.pos, end = this.input.indexOf(\"*/\", this.pos += 2);\n if (end === -1) { this.raise(this.pos - 2, \"Unterminated comment\"); }\n this.pos = end + 2;\n if (this.options.locations) {\n lineBreakG.lastIndex = start;\n var match;\n while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) {\n ++this$1.curLine;\n this$1.lineStart = match.index + match[0].length;\n }\n }\n if (this.options.onComment)\n { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos,\n startLoc, this.curPosition()); }\n};\n\npp$8.skipLineComment = function(startSkip) {\n var this$1 = this;\n\n var start = this.pos;\n var startLoc = this.options.onComment && this.curPosition();\n var ch = this.input.charCodeAt(this.pos += startSkip);\n while (this.pos < this.input.length && !isNewLine(ch)) {\n ch = this$1.input.charCodeAt(++this$1.pos);\n }\n if (this.options.onComment)\n { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos,\n startLoc, this.curPosition()); }\n};\n\n// Called at the start of the parse and after every token. Skips\n// whitespace and comments, and.\n\npp$8.skipSpace = function() {\n var this$1 = this;\n\n loop: while (this.pos < this.input.length) {\n var ch = this$1.input.charCodeAt(this$1.pos);\n switch (ch) {\n case 32: case 160: // ' '\n ++this$1.pos;\n break\n case 13:\n if (this$1.input.charCodeAt(this$1.pos + 1) === 10) {\n ++this$1.pos;\n }\n case 10: case 8232: case 8233:\n ++this$1.pos;\n if (this$1.options.locations) {\n ++this$1.curLine;\n this$1.lineStart = this$1.pos;\n }\n break\n case 47: // '/'\n switch (this$1.input.charCodeAt(this$1.pos + 1)) {\n case 42: // '*'\n this$1.skipBlockComment();\n break\n case 47:\n this$1.skipLineComment(2);\n break\n default:\n break loop\n }\n break\n default:\n if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {\n ++this$1.pos;\n } else {\n break loop\n }\n }\n }\n};\n\n// Called at the end of every token. Sets `end`, `val`, and\n// maintains `context` and `exprAllowed`, and skips the space after\n// the token, so that the next one's `start` will point at the\n// right position.\n\npp$8.finishToken = function(type, val) {\n this.end = this.pos;\n if (this.options.locations) { this.endLoc = this.curPosition(); }\n var prevType = this.type;\n this.type = type;\n this.value = val;\n\n this.updateContext(prevType);\n};\n\n// ### Token reading\n\n// This is the function that is called to fetch the next token. It\n// is somewhat obscure, because it works in character codes rather\n// than characters, and because operator parsing has been inlined\n// into it.\n//\n// All in the name of speed.\n//\npp$8.readToken_dot = function() {\n var next = this.input.charCodeAt(this.pos + 1);\n if (next >= 48 && next <= 57) { return this.readNumber(true) }\n var next2 = this.input.charCodeAt(this.pos + 2);\n if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.'\n this.pos += 3;\n return this.finishToken(types.ellipsis)\n } else {\n ++this.pos;\n return this.finishToken(types.dot)\n }\n};\n\npp$8.readToken_slash = function() { // '/'\n var next = this.input.charCodeAt(this.pos + 1);\n if (this.exprAllowed) { ++this.pos; return this.readRegexp() }\n if (next === 61) { return this.finishOp(types.assign, 2) }\n return this.finishOp(types.slash, 1)\n};\n\npp$8.readToken_mult_modulo_exp = function(code) { // '%*'\n var next = this.input.charCodeAt(this.pos + 1);\n var size = 1;\n var tokentype = code === 42 ? types.star : types.modulo;\n\n // exponentiation operator ** and **=\n if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) {\n ++size;\n tokentype = types.starstar;\n next = this.input.charCodeAt(this.pos + 2);\n }\n\n if (next === 61) { return this.finishOp(types.assign, size + 1) }\n return this.finishOp(tokentype, size)\n};\n\npp$8.readToken_pipe_amp = function(code) { // '|&'\n var next = this.input.charCodeAt(this.pos + 1);\n if (next === code) { return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2) }\n if (next === 61) { return this.finishOp(types.assign, 2) }\n return this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1)\n};\n\npp$8.readToken_caret = function() { // '^'\n var next = this.input.charCodeAt(this.pos + 1);\n if (next === 61) { return this.finishOp(types.assign, 2) }\n return this.finishOp(types.bitwiseXOR, 1)\n};\n\npp$8.readToken_plus_min = function(code) { // '+-'\n var next = this.input.charCodeAt(this.pos + 1);\n if (next === code) {\n if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 &&\n (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) {\n // A `-->` line comment\n this.skipLineComment(3);\n this.skipSpace();\n return this.nextToken()\n }\n return this.finishOp(types.incDec, 2)\n }\n if (next === 61) { return this.finishOp(types.assign, 2) }\n return this.finishOp(types.plusMin, 1)\n};\n\npp$8.readToken_lt_gt = function(code) { // '<>'\n var next = this.input.charCodeAt(this.pos + 1);\n var size = 1;\n if (next === code) {\n size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;\n if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) }\n return this.finishOp(types.bitShift, size)\n }\n if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 &&\n this.input.charCodeAt(this.pos + 3) === 45) {\n // `\n\n\nNotice the loader is visible by default. This ensures that the user sees the loader immediately as the page loads, giving them a clear indication that the content is loading.\nTo save time, we’ve also already created the stylesheet for you to use.\nWe've given you the markup and styles to save you some time and make sure you're starting on a solid foundation. In the next section, you'll have an opportunity to write your own code.","title":"Create the HTML for the App Shell"},{"location":"/docs/index-claat.html#","text":"Now that we have most of the UI ready, it’s time to start hooking up the code to make everything work. Like the rest of the app shell, be conscious about what code is necessary as part of the key experience and what can be loaded later.\nYour work directory also already includes the app code (scripts/app.js), in it you’ll find:\nAn app object that contains some of the key information necessary for the app. The event listeners for all of the buttons in the header (add/refresh) and in the add city dialog (add/cancel). A method to add or update forecast cards (app.updateForecastCard). A method to get the latest weather forecast data from the Firebase Public Weather API (app.getForecast). A method to iterate the current cards and call app.getForecast to get the latest forecast data (app.updateForecasts). Some fake data (initialWeatherForecast) you can use to quickly test how things render.","title":"Check out the key JavaScript app code"},{"location":"/docs/index-claat.html#","text":"Now that you’ve got the core HTML, styles and JavaScript, it’s time to test the app.\nTo see how the fake weather data is rendered, uncomment the following line at the bottom of your index.html file:\n\nNext, uncomment the following line at the bottom of your app.js file:\n// app.updateForecastCard(initialWeatherForecast);\nReload your app. The result should be a nicely formatted (though fake, as you can tell by the date) forecast card with the spinner disabled, like this:\n[](https://weather-pwa-sample.firebaseapp.com/step-04/)\nOnce you’ve tried it and verified it works as expected, you can remove the call to app.updateForecastCard with the fake data again. We only needed it to ensure that everything worked as expected.","title":"Test it out"},{"location":"/docs/index-claat.html#start-with-a-fast-first-load","text":"Progressive Web Apps should start fast and be usable immediately. In its current state, our Weather App starts quickly, but it’s not useable. There’s no data. We could make an AJAX request to get that data, but that results in an extra request and makes the initial load longer. Instead, provide real data in the first load.","title":"Start with a fast first load"},{"location":"/docs/index-claat.html#","text":"For this code lab, we’ll simulate the server injecting the weather forecast directly into the JavaScript, but in a production app, the latest weather forecast data would be injected by the server based on the IP address geo-location of the user.\nThe code already contains the data that we’re going to inject. It’s the initialWeatherForecast that we used in the previous step.","title":"Inject the weather forecast data"},{"location":"/docs/index-claat.html#","text":"But, how do we know when to display this information, which may not be relevant on future loads when the weather app is pulled from the cache? When the user loads the app on subsequent visits, they may have changed cities, so we need to load the information for those cities, not necessarily the first city they ever looked up.\nUser preferences, like the list of cities a user has subscribed to, should be stored locally using IndexedDB or another fast storage mechanism. To simplify this code lab as much as possible, we’ve used localStorage, which is not ideal for production apps because it is a blocking, synchronous storage mechanism that is potentially very slow on some devices.\n**Extra Credit**: Replace `localStorage` implementation with [idb](https://www.npmjs.com/package/idb), check out [localForage](https://github.com/localForage/localForage) as a simple wrapper to idb.\nFirst, let’s add the code required to save user preferences. Find the following TODO comment in your code.\n// TODO add saveSelectedCities function here\nAnd add the following code below the comment.\n// Save list of cities to localStorage.\n app.saveSelectedCities = function() {\n var selectedCities = JSON.stringify(app.selectedCities);\n localStorage.selectedCities = selectedCities;\n };\nNext, let’s add the startup code to check if the user has any saved cities and render those, or use the injected data. Find the following comment:\n// TODO add startup code here\nAnd add the following code below this comment:\n/************************************************************************\n *\n * Code required to start the app\n *\n * NOTE: To simplify this codelab, we've used localStorage.\n * localStorage is a synchronous API and has serious performance\n * implications. It should not be used in production applications!\n * Instead, check out IDB (https://www.npmjs.com/package/idb) or\n * SimpleDB (https://gist.github.com/inexorabletash/c8069c042b734519680c)\n ************************************************************************/\n\n app.selectedCities = localStorage.selectedCities;\n if (app.selectedCities) {\n app.selectedCities = JSON.parse(app.selectedCities);\n app.selectedCities.forEach(function(city) {\n app.getForecast(city.key, city.label);\n });\n } else {\n /* The user is using the app for the first time, or the user has not\n * saved any cities, so show the user some fake data. A real app in this\n * scenario could guess the user's location via IP lookup and then inject\n * that data into the page.\n */\n app.updateForecastCard(initialWeatherForecast);\n app.selectedCities = [\n {key: initialWeatherForecast.key, label: initialWeatherForecast.label}\n ];\n app.saveSelectedCities();\n }\nThe startup code checks if there are any cities saved in local storage. If so, then it parses the local storage data and then displays a forecast card for each of the saved cities. Else, the startup code just uses the fake forecast data and saves that as the default city.","title":"Differentiating the first run"},{"location":"/docs/index-claat.html#","text":"Finally, you need to modify the “add city” button handler to save the selected city to local storage.\nUpdate your butAddCity click handler so that it matches the following code:\ndocument.getElementById('butAddCity').addEventListener('click', function() {\n // Add the newly selected city\n var select = document.getElementById('selectCityToAdd');\n var selected = select.options[select.selectedIndex];\n var key = selected.value;\n var label = selected.textContent;\n if (!app.selectedCities) {\n app.selectedCities = [];\n }\n app.getForecast(key, label);\n app.selectedCities.push({key: key, label: label});\n app.saveSelectedCities();\n app.toggleAddDialog(false);\n });\nThe new additions are the initialization of app.selectedCities if it doesn’t exist, and the calls to app.selectedCities.push() and app.saveSelectedCities().","title":"Save the selected cities"},{"location":"/docs/index-claat.html#","text":"When first run, your app should immediately show the user the forecast from initialWeatherForecast. Add a new city (by clicking the + icon on the upper right) and verify that two cards are shown. Refresh the browser and verify that the app loads both forecasts and shows the latest information.\n[](https://weather-pwa-sample.firebaseapp.com/step-05/)","title":"Test it out"},{"location":"/docs/index-claat.html#use-service-workers-to-pre-cache-the-app-shell","text":"Progressive Web Apps have to be fast, and installable, which means that they work online, offline, and on intermittent, slow connections. To achieve this, we need to cache our app shell using service worker, so that it’s always available quickly and reliably.\nIf you’re unfamiliar with service workers, you can get a basic understanding by reading Introduction To Service Workers about what they can do, how their lifecycle works and more. Once you’ve completed this code lab, be sure to check out the Debugging Service Workers code lab for a more in-depth look at how to work with service workers.\nFeatures provided via service workers should be considered a progressive enhancement, and added only if supported by the browser. For example, with service workers you can cache the app shell and data for your app, so that it’s available even when the network isn’t. When service workers aren’t supported, the offline code isn’t called, and the user gets a basic experience. Using feature detection to provide progressive enhancement has little overhead and it won’t break in older browsers that don’t support that feature.\n**Remember**: Service worker functionality is only available on pages that are accessed via HTTPS (http://localhost and equivalents will also work, to facilitate testing). To learn about the rationale behind this restriction check out [Prefer Secure Origins For Powerful New Features](http://www.chromium.org/Home/chromium-security/prefer-secure-origins-for-powerful-new-features) from the Chromium team.","title":"Use service workers to pre-cache the App Shell"},{"location":"/docs/index-claat.html#","text":"The first step to making the app work offline is to register a service worker, a script that allows background functionality without the need for an open web page or user interaction.\nThis takes two simple steps:\nTell the browser to register the JavaScript file as the service worker. Create a JavaScript file containing the service worker.\nFirst, we need to check if the browser supports service workers, and if it does, register the service worker. Add the following code to app.js (after the // TODO add service worker code here comment):\nif ('serviceWorker' in navigator) {\n navigator.serviceWorker\n .register('../service-worker.js')\n .then(function() { console.log('Service Worker Registered'); });\n }","title":"Register the service worker if it’s available"},{"location":"/docs/index-claat.html#","text":"When the service worker is registered, an install event is triggered the first time the user visits the page. In this event handler, we will cache all the assets that are needed for the application.\nThe code below must NOT be used in production, it covers only the most basic use cases and it's easy to get yourself into a state where your app shell will never update. Be sure to review the section below that discusses the pitfalls of this implementation and how to avoid them.\nWhen the service worker is fired, it should open the caches object and populate it with the assets necessary to load the App Shell. Create a file called service-worker.js in your application root folder (which should be your-first-pwapp-master/work directory). This file must live in the application root because the scope for service workers is defined by the directory in which the file resides. Add this code to your new service-worker.js file:\nvar cacheName = 'weatherPWA-step-6-1';\nvar filesToCache = [];\n\nself.addEventListener('install', function(e) {\n console.log('[ServiceWorker] Install');\n e.waitUntil(\n caches.open(cacheName).then(function(cache) {\n console.log('[ServiceWorker] Caching app shell');\n return cache.addAll(filesToCache);\n })\n );\n});\nFirst, we need to open the cache with caches.open() and provide a cache name. Providing a cache name allows us to version files, or separate data from the app shell so that we can easily update one but not affect the other.\nOnce the cache is open, we can then call cache.addAll(), which takes a list of URLs, then fetches them from the server and adds the response to the cache. Unfortunately, cache.addAll() is atomic, if any of the files fail, the entire cache step fails!\nAlright, let’s start getting familiar with how you can use DevTools to understand and debug service workers. Before reloading your page, open up DevTools, go the Service Worker pane on the Application panel. It should look like this.\nWhen you see a blank page like this, it means that the currently open page does not have any registered service workers.\nNow, reload your page. The Service Worker pane should now look like this.\nWhen you see information like this, it means the page has a service worker running.\nOK, now we’re are going to take a brief detour and demonstrate a gotcha that you may encounter when developing service workers. To demonstrate, let’s add an activate event listener below the install event listener in your service-worker.js file.\nself.addEventListener('activate', function(e) {\n console.log('[ServiceWorker] Activate');\n});\nThe activate event is fired when the service worker starts up.\nOpen up the DevTools Console and reload the page, switch to the Service Worker pane in the Application panel and click inspect on the activated service worker. You expect to see the [ServiceWorker] Activate message logged to the console, but it didn’t happen. Check out your Service Worker pane and you can see that the new service worker (that includes the activate event listener) appears to be in a “waiting” state.\nBasically, the old service worker continues to control the page as long as there is a tab open to the page. So, you could close and re-open the page or press the skipWaiting button, but a longer-term solution is to just enable the Update on Reload checkbox on the Service Worker pane of DevTools. When this checkbox is enabled, the service worker is forcibly updated every time that the page reloads.\nEnable the Update on Reload checkbox now and reload the page to confirm that the new service worker gets activated.\nNote: You may see an error in the Service Worker pane of the Application panel similar to the one below, it’s safe to ignore this error.\nThat’s all for now regarding inspecting and debugging service workers in DevTools. We’ll show you some more tricks later. Let’s get back to building your app.\nLet’s expand on the activate event listener to include some logic to update the cache. Update your code to match the code below.\nself.addEventListener('activate', function(e) {\n console.log('[ServiceWorker] Activate');\n e.waitUntil(\n caches.keys().then(function(keyList) {\n return Promise.all(keyList.map(function(key) {\n if (key !== cacheName) {\n console.log('[ServiceWorker] Removing old cache', key);\n return caches.delete(key);\n }\n }));\n })\n );\n return self.clients.claim();\n});\nThis code ensures that your service worker updates its cache whenever any of the app shell files change. In order for this to work, you’d need to increment the cacheName variable at the top of your service worker file.\nThe last statement fixes a corner-case which you can read about in the (optional) information box below.\nWhen the app is complete, `self.clients.claim()` fixes a corner case in which the app wasn't returning the latest data. You can reproduce the corner case by commenting out the line below and then doing the following steps: 1) load app for first time so that the initial New York City data is shown 2) press the refresh button on the app 3) go offline 4) reload the app. You expect to see the newer NYC data, but you actually see the initial data. This happens because the service worker is not yet activated. `self.clients.claim()` essentially lets you activate the service worker faster.\nFinally, let’s update the list of files required for the app shell. In the array, we need to include all of the files our app needs, including images, JavaScript, stylesheets, etc. Near the top of your service-worker.js file, replace var filesToCache = []; with the code below:\nvar filesToCache = [\n '/',\n '/index.html',\n '/scripts/app.js',\n '/styles/inline.css',\n '/images/clear.png',\n '/images/cloudy-scattered-showers.png',\n '/images/cloudy.png',\n '/images/fog.png',\n '/images/ic_add_white_24px.svg',\n '/images/ic_refresh_white_24px.svg',\n '/images/partly-cloudy.png',\n '/images/rain.png',\n '/images/scattered-showers.png',\n '/images/sleet.png',\n '/images/snow.png',\n '/images/thunderstorm.png',\n '/images/wind.png'\n];\nBe sure to include all permutations of file names, for example our app is served from `index.html`, but it may also be requested as `/` since the server sends `index.html` when a root folder is requested. You could deal with this in the `fetch` method, but it would require special casing which may become complex.\nOur app doesn’t work offline quite yet. We’ve cached the app shell components, but we still need to load them from the local cache.","title":"Cache the site assets"},{"location":"/docs/index-claat.html#","text":"Service workers provide the ability to intercept requests made from our Progressive Web App and handle them within the service worker. That means we can determine how we want to handle the request and potentially serve our own cached response.\nFor example:\nself.addEventListener('fetch', function(e) {\n // Do something interesting with the fetch here\n});\nLet’s now serve the app shell from the cache. Add the following code to the bottom of your service-worker.js file:\nself.addEventListener('fetch', function(e) {\n console.log('[ServiceWorker] Fetch', e.request.url);\n e.respondWith(\n caches.match(e.request).then(function(response) {\n return response || fetch(e.request);\n })\n );\n});\nStepping from inside, out, caches.match() evaluates the web request that triggered the fetch event, and checks to see if it’s available in the cache. It then either responds with the cached version, or uses fetch to get a copy from the network. The response is passed back to the web page with e.respondWith().\nIf you're not seeing the `[ServiceWorker]` logging in the console, be sure you've changed the `cacheName` variable and that you're inspecting the right service worker by opening the Service Worker pane in the Applications panel and clicking **inspect** on the running service worker. If that doesn't work, see the section on Tips for testing live service workers.","title":"Serve the app shell from the cache"},{"location":"/docs/index-claat.html#test-it-out","text":"Your app is now offline-capable! Let’s try it out.\nReload your page and then go to the Cache Storage pane on the Application panel of DevTools. Right click Cache Storage, pick Refresh Caches, expand the section and you should see the name of your app shell cache listed on the left-hand side. When you click on your app shell cache you can see all of the resources that it has currently cached.\nNow, let’s test out offline mode. Go back to the Service Worker pane of DevTools and enable the Offline checkbox. After enabling it, you should see a little yellow warning icon next to the Network panel tab. This indicates that you’re offline.\nReload your page and… it works! Kind of, at least. Notice how it loads the initial (fake) weather data.\nCheck out the else clause in app.getForecast() to understand why the app is able to load the fake data.\nThe next step is to modify the app and service worker logic to be able to cache weather data, and return the most recent data from the cache when the app is offline.\nTip: To start fresh and clear all saved data (localStorage, indexedDB data, cached files) and remove any service workers, use the Clear storage pane in the Application tab.\n[](https://weather-pwa-sample.firebaseapp.com/step-06/)","title":"Test it out"},{"location":"/docs/index-claat.html#","text":"As previously mentioned, this code must not be used in production because of the many unhandled edge cases.","title":"Beware of the edge cases"},{"location":"/docs/index-claat.html#","text":"For example this caching method requires you to update the cache key every time content is changed, otherwise, the cache will not be updated, and the old content will be served. So be sure to change the cache key with every change as you’re working on your project!","title":"Cache depends on updating the cache key for every change"},{"location":"/docs/index-claat.html#","text":"Another downside is that the entire cache is invalidated and needs to be re-downloaded every time a file changes. That means fixing a simple single character spelling mistake will invalidate the cache and require everything to be downloaded again. Not exactly efficient.","title":"Requires everything to be redownloaded for every change"},{"location":"/docs/index-claat.html#","text":"There’s another important caveat here. It’s crucial that the HTTPS request made during the install handler goes directly to the network and doesn’t return a response from the browser’s cache. Otherwise the browser may return the old, cached version, resulting in the service worker cache never actually updating!","title":"Browser cache may prevent the service worker cache from updating"},{"location":"/docs/index-claat.html#","text":"Our app uses a cache-first strategy, which results in a copy of any cached content being returned without consulting the network. While a cache-first strategy is easy to implement, it can cause challenges in the future. Once the copy of the host page and service worker registration is cached, it can be extremely difficult to change the configuration of the service worker (since the configuration depends on where it was defined), and you could find yourself deploying sites that are extremely difficult to update!","title":"Beware of cache-first strategies in production"},{"location":"/docs/index-claat.html#","text":"So how do we avoid these edge cases? Use a library like Workbox, which provides fine control over what gets expired, ensures requests go directly to the network and handles all of the hard work for you.","title":"How do I avoid these edge cases?"},{"location":"/docs/index-claat.html#","text":"Debugging service workers can be a challenge, and when it involves caching, things can become even more of a nightmare if the cache isn’t updated when you expect it. Between the typical service worker life cycle and bug in your code, you may become quickly frustrated. But don’t. There are some tools you can use to make your life easier.","title":"Tips for testing live service workers"},{"location":"/docs/index-claat.html#","text":"In some cases, you may find yourself loading cached data or that things aren’t updated as you expect. To clear all saved data (localStorage, indexedDB data, cached files) and remove any service workers, use the Clear storage pane in the Application tab.\nSome other tips:\nOnce a service worker has been unregistered, it may remain listed until its containing browser window is closed. If multiple windows to your app are open, the new service worker will not take effect until they’ve all been reloaded and updated to the latest service worker. Unregistering a service worker does not clear the cache, so it may be possible you’ll still get old data if the cache name hasn’t changed. If a service worker exists and a new service worker is registered, the new service worker won’t take control until the page is reloaded, unless you take immediate control.","title":"Start Fresh"},{"location":"/docs/index-claat.html#use-service-workers-to-cache-the-forecast-data","text":"Choosing the right caching strategy for your data is vital and depends on the type of data your app presents. For example, time-sensitive data like weather or stock quotes should be as fresh as possible, while avatar images or article content can be updated less frequently.\nThe cache-first-then-network strategy is ideal for our app. It gets data on screen as quickly as possible, then updates that once the network has returned the latest data. In comparison to network-first-then-cache, the user does not have to wait until the fetch times out to get the cached data.\nCache-first-then-network means we need to kick off two asynchronous requests, one to the cache and one to the network. Our network request with the app doesn’t need to change much, but we need to modify the service worker to cache the response before returning it.\nUnder normal circumstances, the cached data will be returned almost immediately providing the app with recent data it can use. Then, when the network request returns, the app will be updated using the latest data from the network.","title":"Use service workers to cache the forecast data"},{"location":"/docs/index-claat.html#","text":"We need to modify the service worker to intercept requests to the weather API and store their responses in the cache, so we can easily access them later. In the cache-then-network strategy, we expect the network response to be the ‘source of truth’, always providing us with the most recent information. If it can’t, it’s OK to fail because we’ve already retrieved the latest cached data in our app.\nIn the service worker, let’s add a dataCacheName so that we can separate our applications data from the app shell. When the app shell is updated and older caches are purged, our data will remain untouched, ready for a super fast load. Keep in mind, if your data format changes in the future, you’ll need a way to handle that and ensure the app shell and content stay in sync.\nAdd the following line to the top of your service-worker.js file:\nvar dataCacheName = 'weatherData-v1';\nNext, update the activate event handler so that it doesn’t delete the data cache when it cleans up the app shell cache.\nif (key !== cacheName && key !== dataCacheName) {\nFinally, update the fetch event handler to handle requests to the data API separately from other requests.\nself.addEventListener('fetch', function(e) {\n console.log('[Service Worker] Fetch', e.request.url);\n var dataUrl = 'https://query.yahooapis.com/v1/public/yql';\n if (e.request.url.indexOf(dataUrl) > -1) {\n /*\n * When the request URL contains dataUrl, the app is asking for fresh\n * weather data. In this case, the service worker always goes to the\n * network and then caches the response. This is called the \"Cache then\n * network\" strategy:\n * https://jakearchibald.com/2014/offline-cookbook/#cache-then-network\n */\n e.respondWith(\n caches.open(dataCacheName).then(function(cache) {\n return fetch(e.request).then(function(response){\n cache.put(e.request.url, response.clone());\n return response;\n });\n })\n );\n } else {\n /*\n * The app is asking for app shell files. In this scenario the app uses the\n * \"Cache, falling back to the network\" offline strategy:\n * https://jakearchibald.com/2014/offline-cookbook/#cache-falling-back-to-network\n */\n e.respondWith(\n caches.match(e.request).then(function(response) {\n return response || fetch(e.request);\n })\n );\n }\n});\nThe code intercepts the request and checks if the URL starts with the address of the weather API. If it does we’ll use fetch to make the request. Once the response is returned, our code opens the cache, clones the response, stores it in the cache, and finally returns the response to the original requestor.\nOur app won’t work offline quite yet. We’ve implemented caching and retrieval for the app shell, but even though we’re caching the data, the app doesn’t yet check the cache to see if it has any weather data.","title":"Intercept the network request and cache the response"},{"location":"/docs/index-claat.html#","text":"As mentioned previously, the app needs to kick off two asynchronous requests, one to the cache and one to the network. The app uses the caches object available in window to access the cache and retrieve the latest data. This is an excellent example of progressive enhancement as the caches object may not be available in all browsers, and if it’s not the network request should still work.\nTo do this, we need to:\nCheck if the caches object is available in the global window object. Request data from the cache.\nIf the server request is still outstanding, update the app with the cached data.\nRequest data from the server.\nSave the data for quick access later. Update the app with the fresh data from the server.","title":"Making the requests"},{"location":"/docs/index-claat.html#","text":"Next, we need to check if the caches object exists and request the latest data from it. Find the TODO add cache logic here comment in app.getForecast(), and then add the code below under the comment.\nif ('caches' in window) {\n /*\n * Check if the service worker has already cached this city's weather\n * data. If the service worker has the data, then display the cached\n * data while the app fetches the latest data.\n */\n caches.match(url).then(function(response) {\n if (response) {\n response.json().then(function updateFromCache(json) {\n var results = json.query.results;\n results.key = key;\n results.label = label;\n results.created = json.query.created;\n app.updateForecastCard(results);\n });\n }\n });\n }\nOur weather app now makes two asynchronous requests for data, one from the cache and one via an XHR. If there’s data in the cache, it’ll be returned and rendered extremely quickly (tens of milliseconds) and update the card only if the XHR is still outstanding. Then, when the XHR responds, the card will be updated with the freshest data direct from the weather API.\nNotice how the cache request and the XHR request both end with a call to update the forecast card. How does the app know whether it’s displaying the latest data? This is handled in the following code from app.updateForecastCard:\nvar cardLastUpdatedElem = card.querySelector('.card-last-updated');\n var cardLastUpdated = cardLastUpdatedElem.textContent;\n if (cardLastUpdated) {\n cardLastUpdated = new Date(cardLastUpdated);\n // Bail if the card has more recent data then the data\n if (dataLastUpdated.getTime() < cardLastUpdated.getTime()) {\n return;\n }\n }\nEvery time that a card is updated, the app stores the timestamp of the data on a hidden attribute on the card. The app just bails if the timestamp that already exists on the card is newer than the data that was passed to the function.","title":"Get data from the cache"},{"location":"/docs/index-claat.html#","text":"The app should be completely offline-functional now. Save a couple of cities and press the refresh button on the app to get fresh weather data, and then go offline and reload the page.\nThen go to the Cache Storage pane on the Application panel of DevTools. Expand the section and you should see the name of your app shell and data cache listed on the left-hand side. Opening the data cache should should the data stored for each city.\n[](https://weather-pwa-sample.firebaseapp.com/step-07/)","title":"Test it out"},{"location":"/docs/index-claat.html#support-native-integration","text":"Nobody likes to have to type in long URLs on a mobile keyboard if they don’t need to. With the Add To home screen feature, your users can choose to add a shortcut link to their device just as they would install a native app from a store, but with a lot less friction.","title":"Support native integration"},{"location":"/docs/index-claat.html#","text":"Web app install banners give you the ability to let your users quickly and seamlessly add your web app to their home screen, making it easy to launch and return to your app. Adding app install banners is easy, and Chrome handles most of the heavy lifting for you. We simply need to include a web app manifest file with details about the app.\nChrome then uses a set of criteria including the use of a service worker, SSL status and visit frequency heuristics to determine when to show the banner. In addition a user can manually add it via the “Add to Home Screen” menu button in Chrome.","title":"Web App Install Banners and Add to Homescreen for Chrome on Android"},{"location":"/docs/index-claat.html#","text":"The web app manifest is a simple JSON file that gives you, the developer, the ability to control how your app appears to the user in the areas that they would expect to see apps (for example the mobile home screen), direct what the user can launch and more importantly how they can launch it.\nUsing the web app manifest, your web app can:\nHave a rich presence on the user’s Android home screen Be launched in full-screen mode on Android with no URL bar Control the screen orientation for optimal viewing Define a “splash screen” launch experience and theme color for the site Track whether you’re launched from the home screen or URL bar\nCreate a file named manifest.json in your work folder and copy/paste the following contents:\n{\n \"name\": \"Weather\",\n \"short_name\": \"Weather\",\n \"icons\": [{\n \"src\": \"images/icons/icon-128x128.png\",\n \"sizes\": \"128x128\",\n \"type\": \"image/png\"\n }, {\n \"src\": \"images/icons/icon-144x144.png\",\n \"sizes\": \"144x144\",\n \"type\": \"image/png\"\n }, {\n \"src\": \"images/icons/icon-152x152.png\",\n \"sizes\": \"152x152\",\n \"type\": \"image/png\"\n }, {\n \"src\": \"images/icons/icon-192x192.png\",\n \"sizes\": \"192x192\",\n \"type\": \"image/png\"\n }, {\n \"src\": \"images/icons/icon-256x256.png\",\n \"sizes\": \"256x256\",\n \"type\": \"image/png\"\n }],\n \"start_url\": \"/index.html\",\n \"display\": \"standalone\",\n \"background_color\": \"#3E4EB8\",\n \"theme_color\": \"#2F3BA2\"\n}\nThe manifest supports an array of icons, intended for different screen sizes. At the time of this writing, Chrome and Opera Mobile, the only browsers that support web app manifests, won’t use anything smaller than 192px.\nAn easy way to track how the app is launched is to add a query string to the start_url parameter and then use an analytics suite to track the query string. If you use this method, remember to update the list of files cached by the App Shell to ensure that the file with the query string is cached.","title":"Declare an app manifest with a manifest.json file"},{"location":"/docs/index-claat.html#","text":"Now add the following line to the bottom of the element in your index.html file:\n","title":"Tell the browser about your manifest file"},{"location":"/docs/index-claat.html#","text":"Place the manifest link on all your site’s pages, so it will be retrieved by Chrome right when the user first visits, no matter what page they land on. The short_name is preferred on Chrome and will be used if present over the name field. Define icon sets for different density screens. Chrome will attempt to use the icon closest to 48dp, for example, 96px on a 2x device or 144px for a 3x device. Remember to include an icon with a size that is sensible for a splash screen and don’t forget to set the background_color.\nFurther Reading:\nUsing app install banners","title":"Best Practices"},{"location":"/docs/index-claat.html#","text":"In your index.html, add the following to the bottom of the element:\n\n \n \n \n ","title":"Add to Homescreen elements for Safari on iOS"},{"location":"/docs/index-claat.html#","text":"In your index.html, add the following to the bottom of the element:\n\n ","title":"Tile Icon for Windows"},{"location":"/docs/index-claat.html#","text":"In this section we’ll show you a couple of ways to test your web app manifest.\nThe first way is DevTools. Open up the Manifest pane on the Application panel. If you’ve added the manifest information correctly, you’ll be able to see it parsed and displayed in a human-friendly format on this pane.\nYou can also test the add to homescreen feature from this pane. Click on the Add to homescreen button. You should see a “add this site to your shelf” message below your URL bar, like in the screenshot below.\nThis is the desktop equivalent of mobile’s add to homescreen feature. If you can successfully trigger this prompt on desktop, then you can be assured that mobile users can add your app to their devices.\nThe second way to test is via Web Server for Chrome. With this approach, you expose your local development server (on your desktop or laptop) to other computers, and then you just access your progressive web app from a real mobile device.\nOpening up a port for remote access is handy for testing this step but may be blocked by your computer's firewall rules or network administrator. Opening ports for remote access is generally not a good thing to leave running on your computer. So, for security reasons, when you've completed testing this step, disable the `Accessible on local network` option and restart your web server.\nOn Web Server for Chrome configuration dialog, select the Accessible on local network option:\nToggle the Web Server to STOPPED and back to STARTED. You’ll see a new URL which can be used to access your app remotely.\nNow, access your site from a mobile device, using the new URL.\nYou will see service worker errors in the console when testing this way because the service worker is not being served over HTTPS.\nUsing Chrome from an Android device, try adding the app to the homescreen and verifying that the launch screen appears properly and the right icons are used.\nOn Safari and Internet Explorer, you can also manually add the app to your homescreen.\n[](https://weather-pwa-sample.firebaseapp.com/step-08/)","title":"Test it out"},{"location":"/docs/index-claat.html#deploy-to-a-secure-host-and-celebrate","text":"The final step is to deploy our weather app to a server that supports HTTPS. If you don’t already have one, the absolute easiest (and free) approach is to use the static content hosting from Firebase. It’s super easy to use, serves content over HTTPS and is backed by a global CDN.","title":"Deploy to a secure host and celebrate"},{"location":"/docs/index-claat.html#","text":"There’s one more thing that you should consider, minifying the key styles and inlining them directly into index.html. Page Speed Insights recommends serving the above the fold content in the first 15k bytes of the request.\nSee how small you can get the initial request with everything inlined.\nFurther Reading: PageSpeed Insight Rules\nThis step requires you to have [Node & NPM](https://docs.npmjs.com/getting-started/installing-node) installed on your system. If it's not, you can use any other hosting provider that supports HTTP**S**. We've used Firebase because it automatically redirects users from HTTP to HTTP**S**. If you use a different provider, be sure they're always redirects to HTTP**S**.","title":"Extra credit: minify and inline CSS"},{"location":"/docs/index-claat.html#","text":"If you’re new to Firebase, you’ll need to create your account and install some tools first.\nCreate a Firebase account at https://firebase.google.com/console/ Install the Firebase tools via npm: npm install -g firebase-tools\nOnce your account has been created and you’ve signed in, you’re ready to deploy!\nCreate a new app at https://firebase.google.com/console/ If you haven’t recently signed in to the Firebase tools, update your credentials: firebase login Initialize your app, and provide the directory (likely work) where your completed app lives: firebase init Finally, deploy the app to Firebase: firebase deploy Celebrate. You’re done! Your app will be deployed to the domain: https://YOUR-FIREBASE-APP.firebaseapp.com\nFurther reading: Firebase Hosting Guide","title":"Deploy to Firebase"},{"location":"/docs/index-claat.html#","text":"Try adding the app to your home screen then disconnect the network and verify the app works offline as expected.\n[](https://weather-pwa-sample.firebaseapp.com/final/)","title":"Test it out"},{"location":"/docs/tools/index.html","text":"","title":"Software and Tools"},{"location":"/docs/tools/index.html#software-and-tools","text":"","title":"Software and Tools"},{"location":"/docs/publication/index.html","text":"","title":"Publications"},{"location":"/docs/publication/index.html#publications","text":"","title":"Publications"}]} \ No newline at end of file diff --git a/style.60bcb90f.map b/style.60bcb90f.map deleted file mode 100644 index 514840d2..00000000 --- a/style.60bcb90f.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":[],"names":[],"mappings":"","file":"style.60bcb90f.map","sourceRoot":"../product-page-src"} \ No newline at end of file diff --git a/style.60bcb90f.css b/style.7c46d1e4.css similarity index 100% rename from style.60bcb90f.css rename to style.7c46d1e4.css