summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Haoyi <haoyi@dropbox.com>2015-03-28 22:21:24 +0800
committerLi Haoyi <haoyi@dropbox.com>2015-03-28 22:21:24 +0800
commit2e37c7f9837a6209781dafc1d21c735180c4e036 (patch)
tree0ce783adeba288b1e19c19d963c726fdc992b9c6
parentd62292f003ba32197249b09031556c84488f6707 (diff)
downloadhands-on-scala-js-2e37c7f9837a6209781dafc1d21c735180c4e036.tar.gz
hands-on-scala-js-2e37c7f9837a6209781dafc1d21c735180c4e036.tar.bz2
hands-on-scala-js-2e37c7f9837a6209781dafc1d21c735180c4e036.zip
.
-rw-r--r--index.html1042
-rw-r--r--scripts.js701
-rw-r--r--styles.css64
3 files changed, 1252 insertions, 555 deletions
diff --git a/index.html b/index.html
index 4d0fce3..c263af8 100644
--- a/index.html
+++ b/index.html
@@ -1,13 +1,63 @@
-<html><head><link href="META-INF/resources/webjars/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet" /><link href="styles.css" rel="stylesheet" /><script src="scripts.js"></script><script>
- ['DOMContentLoaded', 'load'].forEach(function(ev){
- addEventListener(ev, function(){
- Array.prototype.forEach.call(
- document.querySelectorAll('code.scalatex-highlight-js'),
- hljs.highlightBlock
- );
- })
- })
- </script><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><link rel="shortcut icon" type="image/png" href="favicon.png" /><title>Hands-on Scala.js</title><script>
+<html><head><link href="META-INF/resources/webjars/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet" /><link href="styles.css" rel="stylesheet" /><style>
+.scalatex-site-Styles-headerLink{
+ color: #777;
+ opacity: 0.05;
+ text-decoration: none;
+}
+
+
+.scalatex-site-Styles-hoverContainer:hover .scalatex-site-Styles-headerLink{
+ color: #777;
+ opacity: 0.5;
+ text-decoration: none;
+}
+.scalatex-site-Styles-hoverContainer:hover .scalatex-site-Styles-headerLink:hover{
+ opacity: 1.0;
+}
+.scalatex-site-Styles-hoverContainer:hover .scalatex-site-Styles-headerLink:active{
+ opacity: 0.75;
+}
+
+.scalatex-site-Styles-content{
+ color: #777;
+ line-height: 1.6em;
+ margin: 0 auto;
+ margin-left: auto;
+ margin-right: auto;
+ max-width: 800;
+ padding: 0 1em;
+ padding-bottom: 50px;
+}
+.scalatex-site-Styles-content *{
+ position: relative;
+}
+.scalatex-site-Styles-content p{
+ text-align: justify;
+}
+.scalatex-site-Styles-content a:link{
+ color: #37a;
+ text-decoration: none;
+}
+.scalatex-site-Styles-content a:visited{
+ color: #949;
+ text-decoration: none;
+}
+.scalatex-site-Styles-content a:hover{
+ text-decoration: underline;
+}
+.scalatex-site-Styles-content a:active{
+ color: #000;
+ text-decoration: underline;
+}
+.scalatex-site-Styles-content code{
+ color: #000;
+}
+
+/*Workaround for bug in highlight.js IDEA theme*/
+span.hljs-tag, span.hljs-symbol{
+ background: none;
+}
+ </style><script src="scripts.js"></script><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><link rel="shortcut icon" type="image/png" href="favicon.png" /><title>Hands-on Scala.js</title><script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
@@ -15,11 +65,11 @@
ga('create', 'UA-27464920-4', 'auto');
ga('send', 'pageview');
- </script></head><body onload="scrollmenu.Controller().main({&quot;value&quot;:&quot;root&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Hands-on Scala.js&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Intro to Scala.js&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;About Javascript&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Javascript-the-language&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Javascript-the-platform&quot;,&quot;children&quot;:[]}]},{&quot;value&quot;:&quot;About Scala.js&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;The Language&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Sharing Code&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Client-Server Integration&quot;,&quot;children&quot;:[]}]}]},{&quot;value&quot;:&quot;Hands On&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Getting Started&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Opening up the Project&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;The Application Code&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;The Project Code&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;project/build.sbt&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;build.sbt&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;src/main/resources/index-dev.html&quot;,&quot;children&quot;:[]}]},{&quot;value&quot;:&quot;Publishing&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Optimization&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Blob Size&quot;,&quot;children&quot;:[]}]},{&quot;value&quot;:&quot;Recap&quot;,&quot;children&quot;:[]}]},{&quot;value&quot;:&quot;Making a Canvas App&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Making a Sketchpad using Mouse Input&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Making a Clock using setInterval&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Tying it together: Flappy Box&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Setting Up the Canvas&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Defining our State&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Game Logic&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;A Working Product&quot;,&quot;children&quot;:[]}]},{&quot;value&quot;:&quot;Canvas Recap&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Development Speed&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Full Scala&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Seamless Javascript Interop&quot;,&quot;children&quot;:[]}]}]},{&quot;value&quot;:&quot;Interactive Web Pages&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Hello World: HTML&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Scalatags&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;User Input&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Re-rendering&quot;,&quot;children&quot;:[]}]},{&quot;value&quot;:&quot;Using Web Services&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Raw Javascript&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;dom.extensions&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Parsing the Data&quot;,&quot;children&quot;:[]}]},{&quot;value&quot;:&quot;Tying it together: Weather Search&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Interactive Web Pages Recap&quot;,&quot;children&quot;:[]}]},{&quot;value&quot;:&quot;The Command Line&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Commands&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;The compile Command&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;The package Command&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;The fastOptJS Command&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;The fullOptJS Command&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;The run Command&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;The test Command&quot;,&quot;children&quot;:[]}]},{&quot;value&quot;:&quot;Headless Runtimes&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Stages&quot;,&quot;children&quot;:[]}]},{&quot;value&quot;:&quot;Cross Publishing Libraries&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;A Simple Cross-Built Library&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Build Configuration&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Source Files&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Running the Module&quot;,&quot;children&quot;:[]}]},{&quot;value&quot;:&quot;Further Work&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Other Testing Libraries&quot;,&quot;children&quot;:[]}]},{&quot;value&quot;:&quot;Integrating Client-Server&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;A Client-Server Setup&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Client-Server Reflections&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Shared Templating&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Shared Code&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Boilerplate-free Serialization&quot;,&quot;children&quot;:[]}]},{&quot;value&quot;:&quot;What's Left?&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Autowire&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Setting up Autowire&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Why Autowire?&quot;,&quot;children&quot;:[]}]}]}]},{&quot;value&quot;:&quot;In Depth&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Advanced Techniques&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Functional-Reactive UIs&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Why FRP&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;FRP with Scala.Rx&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;More Rx&quot;,&quot;children&quot;:[]}]},{&quot;value&quot;:&quot;Asynchronous Workflows&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Futures &amp; Promises&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Direct Use of XMLHttpRequest&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Using dom.extensions.Ajax&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Future Combinators&quot;,&quot;children&quot;:[]}]},{&quot;value&quot;:&quot;Scala-Async&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Traditional Asynchrony&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Using Scala-Async&quot;,&quot;children&quot;:[]}]}]}]},{&quot;value&quot;:&quot;Deviations from Scala-JVM&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Language Differences&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Primitive data types&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Floats can behave as Doubles by default&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;toString of Float, Double and Unit&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Runtime type tests are based on values&quot;,&quot;children&quot;:[]}]},{&quot;value&quot;:&quot;Undefined behaviors&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Reflection&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Regular expressions&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Symbols&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Enumerations&quot;,&quot;children&quot;:[]}]},{&quot;value&quot;:&quot;Library Differences&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Standard Library&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Macros v.s. Reflection&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Pure-Scala v.s. Java Libraries&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Javascript APIs v.s. JVM APIs&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Scala/Browser tooling v.s. Java tooling&quot;,&quot;children&quot;:[]}]}]},{&quot;value&quot;:&quot;The Compilation Pipeline&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Whole Program Optimizaton&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;How Compilation Works&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Compilation&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Fast Optimization&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Full Optimization&quot;,&quot;children&quot;:[]}]}]},{&quot;value&quot;:&quot;Scala.js' Design Space&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Why No Reflection?&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Dead Code Elimination&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Whither Reflection?&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Macros&quot;,&quot;children&quot;:[]}]},{&quot;value&quot;:&quot;Why does error behavior differ?&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Divide-by-zero: a case study&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;The Performance/Correctness Tradeoff&quot;,&quot;children&quot;:[]}]},{&quot;value&quot;:&quot;Small Executables&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Raw Verbosity&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Browsers Performance&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Deployment Size&quot;,&quot;children&quot;:[]}]}]},{&quot;value&quot;:&quot;Java APIs&quot;,&quot;children&quot;:[{&quot;value&quot;:&quot;Available Java APIs&quot;,&quot;children&quot;:[]},{&quot;value&quot;:&quot;Porting Java APIs&quot;,&quot;children&quot;:[]}]}]}]})"><div id="layout"><a href="#menu" id="menuLink" class="menu-link"><span></span></a><div id="menu"></div></div><div id="main"><div id="main-box" class="scalatex-content" style="max-width: 840px;lineheight: 1.6em;">
-<div class="header scalatex-header scalatex-hover-container" id="Hands-onScala.js" style="display: block;"><h1>Hands-on Scala.js<a class="scalatex-header-link" href="#Hands-onScala.js" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a></h1><br /><h2>Writing client-side web applications in Scala</h2></div><div class="content">
+ </script></head><body><body><div>
+<div style="margin: 0px;color: #333;text-align: center;padding: 2.5em 2em 0;border-bottom: 1px solid #eee;display: block;" id="Hands-onScala.js" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><h1 style="margin: 0.2em 0;font-size: 3em;font-weight: 300;">Hands-on Scala.js<a class=" scalatex-site-Styles-headerLink" href="#Hands-onScala.js" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a></h1><br /><h2 style="font-weight: 300;color: #ccc;padding: 0px;margin-top: 0px;">Writing client-side web applications in Scala</h2></div><div class=" scalatex-site-Styles-content">
<div class="pure-g">
<div class="pure-u-1 pure-u-md-13-24">
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">var x = 0.0
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">var x = 0.0
type Graph = (String, Double =&gt; Double)
val graphs = Seq[Graph](
(&quot;red&quot;, sin),
@@ -34,7 +84,7 @@ dom.setInterval(() =&gt; {
brush.fillStyle = color
brush.fillRect(x, y + offset, 3, 3)
}
-}, 20)</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/Splash.scala#L24-L40" target="_blank"><i class="fa fa-link "></i></a></pre>
+}, 20)</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/Splash.scala#L24-L40" target="_blank"><i class="fa fa-link "></i></a></pre>
</div>
<div class="pure-u-1 pure-u-md-11-24">
<canvas id="example0" style="display: block;overflow: scroll;"></canvas><script>Splash().main(document.getElementById('example0'))</script>
@@ -67,14 +117,14 @@ is a set of detailed expositions on various parts of the Scala.js platform. Noth
<p>
Feel free to jump ahead to either of them if you have some prior exposure to Scala.js. If not, it is best to start with the introduction...
</p></div>
-<div class="header scalatex-header scalatex-hover-container" id="IntrotoScala.js" style="display: block;"><h1>Intro to Scala.js<a class="scalatex-header-link" href="#IntrotoScala.js" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a></h1><br /><h2></h2></div><div class="content">
+<div style="margin: 0px;color: #333;text-align: center;padding: 2.5em 2em 0;border-bottom: 1px solid #eee;display: block;" id="IntrotoScala.js" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><h1 style="margin: 0.2em 0;font-size: 3em;font-weight: 300;">Intro to Scala.js<a class=" scalatex-site-Styles-headerLink" href="#IntrotoScala.js" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a></h1><br /></div><div class=" scalatex-site-Styles-content">
<p>
Scala.js compiles Scala code to equivalent, executable Javascript. Here's the compilation of a trivial hello-world example:
</p>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-1-2">
- <pre><code class="scala scalatex-highlight-js">object Main extends js.JSApp{
+ <pre><code class="scala scalatex-site-Styles-highlightMe">object Main extends js.JSApp{
def main() = {
var x = 0
while(x &lt; 10) x += 3
@@ -84,7 +134,7 @@ is a set of detailed expositions on various parts of the Scala.js platform. Noth
}
</code></pre></div>
<div class="pure-u-1 pure-u-md-1-2">
- <pre><code class="javascript scalatex-highlight-js">ScalaJS.c.LMain$.prototype.main__V = (function() {
+ <pre><code class="javascript scalatex-site-Styles-highlightMe">ScalaJS.c.LMain$.prototype.main__V = (function() {
var x = 0;
while ((x &lt; 10)) {
x = ((x + 3) | 0)
@@ -95,7 +145,7 @@ is a set of detailed expositions on various parts of the Scala.js platform. Noth
});
</code></pre></div></div>
<p>
- As you can see, both of the above programs do identical things: they'll count the variable <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">x</code> from <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">0</code>, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">3</code>, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">9</code>, and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">12</code> before finally printing it out. It's just that the first is written in Scala and the second is in Javascript.
+ As you can see, both of the above programs do identical things: they'll count the variable <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">x</code> from <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">0</code>, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">3</code>, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">9</code>, and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">12</code> before finally printing it out. It's just that the first is written in Scala and the second is in Javascript.
</p>
<p>
Traditionally, Scala has been a language which runs on the JVM. This eliminates it from consideration in many cases, e.g. when you need to build interactive web apps, the browser-client only runs Javascript. Even if your back-end is all written in Scala, you need to fall back to Javascript to run your client-side code, at a great loss in terms of toolability and maintainability. Scala.js lets you to develop web applications with the safety and toolability that comes with a statically typed language:
@@ -116,11 +166,11 @@ is a set of detailed expositions on various parts of the Scala.js platform. Noth
<p>
I won't spend time on a detailed discussion on why Scala is good or why Javascript is bad; people's opinions on both sides can be found on the internet. The assumption is, going in, that you either already know and like Scala, or you are familiar with Javascript and are willing to try something new.
</p>
-<div class="header scalatex-header scalatex-hover-container" id="AboutJavascript" style="display: block;"><h1 id="AboutJavascript">About Javascript<a class="scalatex-header-link" href="#AboutJavascript" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a></h1><br /></div>
+<div style="margin: 0px;color: #333;text-align: center;padding: 2.5em 2em 0;border-bottom: 1px solid #eee;display: block;" id="AboutJavascript" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><h1 style="margin: 0.2em 0;font-size: 3em;font-weight: 300;" id="AboutJavascript">About Javascript<a class=" scalatex-site-Styles-headerLink" href="#AboutJavascript" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a></h1><br /></div>
<p>
Javascript is the language supported by web browsers, and is the only language available if you wish to write interactive web applications. As more and more activity moves online, the importance of web apps will only increase over time. Adobe Flash, Java Applets and Silverlight (which have historically allowed browser-client development in other languages) are all but dead: historically they have been the source of security vulnerabilities, none of them are available on the mobile browsers of Android or iOS or Windows8+. That leaves Javascript.
</p>
- <h1 id="Javascript-the-language" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Javascript-the-language" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Javascript-the-language</h1>
+ <h1 id="Javascript-the-language" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Javascript-the-language" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Javascript-the-language</h1>
<p>
Javascript is an OK language to do small-scale development: an animation here, an on-click transition there. There are a number of warts in the language, e.g. its verbosity, and a large amount of surprising behavior, but while your code-base doesn't extend past a few hundred lines of code, you often will not mind or care.
</p>
@@ -141,7 +191,7 @@ is a set of detailed expositions on various parts of the Scala.js platform. Noth
<p>
Even if you manage to do so, what constitutes a pitfall and what constitutes a clever-language-feature changes yearly, making it difficult to maintain cohesiveness over time. This is compounded by the fact that refactoring is difficult, and so removing &quot;unwanted&quot; patterns from a large code-base a difficult (often multi-year) process.
</p>
- <h1 id="Javascript-the-platform" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Javascript-the-platform" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Javascript-the-platform</h1>
+ <h1 id="Javascript-the-platform" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Javascript-the-platform" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Javascript-the-platform</h1>
<p>
However, even though Javascript-the-language is pretty bad, Javascript-the-platform has some very nice properties that make it a good target for application developers:
</p>
@@ -170,19 +220,19 @@ is a set of detailed expositions on various parts of the Scala.js platform. Noth
<p>
Despite the problems with Javascript (and other tools like HTML an CSS, which have their own problems) the Web platform got a lot of things right, and the Desktop and Mobile platforms have a lot of catching up to do. If only we could improve upon the parts that aren't so great. This is where Scala.js comes in.
</p>
-<div class="header scalatex-header scalatex-hover-container" id="AboutScala.js" style="display: block;"><h1 id="AboutScala.js">About Scala.js<a class="scalatex-header-link" href="#AboutScala.js" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a></h1><br /></div>
+<div style="margin: 0px;color: #333;text-align: center;padding: 2.5em 2em 0;border-bottom: 1px solid #eee;display: block;" id="AboutScala.js" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><h1 style="margin: 0.2em 0;font-size: 3em;font-weight: 300;" id="AboutScala.js">About Scala.js<a class=" scalatex-site-Styles-headerLink" href="#AboutScala.js" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a></h1><br /></div>
<p>
With Scala.js, you can cross compile your Scala code to a Javascript executable that can run on all major web browsers. You get all the benefits of the web platform in terms of deployability, security, and hyperlinking, with none of the problems of writing your software in Javascript. Scala.js provides a <a href="#TheLanguage">better language</a> to do your work in, but also provides some other goodies that have in-so-far never been seen in mainstream web development: <a href="#SharingCode">shared-code</a> and <a href="#Client-ServerIntegration">client-server integration</a>.
</p>
- <h1 id="TheLanguage" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#TheLanguage" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>The Language</h1>
+ <h1 id="TheLanguage" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#TheLanguage" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>The Language</h1>
<p>
At a first approximation, Scala.js provides you a sane language to do development in the web browser. This saves you from an endless stream of Javascript warts like this one:
</p>
- <pre><code class="javascript scalatex-highlight-js">javascript&gt; [&quot;10&quot;, &quot;10&quot;, &quot;10&quot;, &quot;10&quot;].map(parseInt)
+ <pre><code class="javascript scalatex-site-Styles-highlightMe">javascript&gt; [&quot;10&quot;, &quot;10&quot;, &quot;10&quot;, &quot;10&quot;].map(parseInt)
[10, NaN, 2, 3] // WTF
</code></pre>
- <pre><code class="scala scalatex-highlight-js">scala&gt; List(&quot;10&quot;, &quot;10&quot;, &quot;10&quot;, &quot;10&quot;).map(parseInt)
+ <pre><code class="scala scalatex-site-Styles-highlightMe">scala&gt; List(&quot;10&quot;, &quot;10&quot;, &quot;10&quot;, &quot;10&quot;).map(parseInt)
List(10, 10, 10, 10) // Yay!
</code></pre>
@@ -195,7 +245,7 @@ List(10, 10, 10, 10) // Yay!
<p>
At this point, all of Google, Facebook, and Microsoft have all announced work on a typed variant of Javascript. These are not academic exercises: <a href="https://www.dartlang.org/">Dart</a>/<a href="https://docs.google.com/document/d/11YUzC-1d0V1-Q3V0fQ7KSit97HnZoKVygDxpWzEYW0U/edit">AtScript</a>/<a href="https://lobste.rs/s/fp9ibi/flow_facebook_s_new_javascript_type_checker">Flow</a>/<a href="http://www.typescriptlang.org/">Typescript</a> are all problems that solve a real need, that these large companies have all faced once they've grown beyond a certain size. Clearly, Javascript isn't cutting it anymore, and the convenience and &quot;native-ness&quot; of the language is more than made up for in the constant barrage of self-inflicted problems. Scala.js takes this idea and runs with it!
</p>
- <h1 id="SharingCode" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#SharingCode" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Sharing Code</h1>
+ <h1 id="SharingCode" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#SharingCode" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Sharing Code</h1>
<p>
Shared code is one of the holy-grails of web development. Traditionally the client-side code and server-side code has been written in separate languages: PHP or Perl or Python or Ruby or Java on the server, with only Javascript on the client. This means that algorithms were often implemented twice, constants copied-&amp;-pasted, or awkward Ajax calls are made in an attempt to centralize the logic in one place (the server). With the advent of Node.js in the last few years, you can finally re-use the same code on the server as you can on the client, but with the cost of having all the previously client-only <a href="#Javascript-the-language">problems with Javascript</a> now inflicted upon your server code base. Node.js expanded your range-of-options for writing shared client/server logic from &quot;Write everything twice&quot; to &quot;Write everything twice, or write everything in Javascript&quot;. More options is always good, but it's not clear which of the two choices is more painful!
</p>
@@ -228,7 +278,7 @@ List(10, 10, 10, 10) // Yay!
<p>
Shared code has long been the holy-grail of web development. Even now, people speak of shared code as if it were a myth. With Scala.js, shared code is the simple, boring reality. And all this while, just as importantly, you don't need to re-write your large enterprise back-end systems in a language that doesn't scale well beyond 100s of lines of code.
</p>
- <h1 id="Client-ServerIntegration" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Client-ServerIntegration" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Client-Server Integration</h1>
+ <h1 id="Client-ServerIntegration" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Client-ServerIntegration" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Client-Server Integration</h1>
<p>
There is an endless supply of new platforms which have promised to change-the-way-we-do-web-development-forever. From old-timers like <a href="http://www.impredicative.com/ur/">Ur-Web</a>, to <a href="http://www.gwtproject.org/">GWT</a>, to Asana's <a href="https://asana.com/luna">LunaScript</a>, to more recently things like <a href="https://www.meteor.com/">Meteor.js</a>.</p>
<p>
@@ -249,13 +299,13 @@ List(10, 10, 10, 10) // Yay!
Scala.js provides all these things, and much more. If you're interested enough to want to make use of Scala.js, read on!</p>
</div>
-<div class="header scalatex-header scalatex-hover-container" id="HandsOn" style="display: block;"><h1>Hands On<a class="scalatex-header-link" href="#HandsOn" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a></h1><br /><h2>Writing your first Scala.js programs</h2></div><div class="content">
+<div style="margin: 0px;color: #333;text-align: center;padding: 2.5em 2em 0;border-bottom: 1px solid #eee;display: block;" id="HandsOn" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><h1 style="margin: 0.2em 0;font-size: 3em;font-weight: 300;">Hands On<a class=" scalatex-site-Styles-headerLink" href="#HandsOn" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a></h1><br /><h2 style="font-weight: 300;color: #ccc;padding: 0px;margin-top: 0px;">Writing your first Scala.js programs</h2></div><div class=" scalatex-site-Styles-content">
<p>
This half of the book
is a set of tutorials that walks you through getting started with Scala.js. You'll build a range of small projects, from <a href="#MakingaCanvasApp">Making a Canvas App</a> to <a href="#InteractiveWebPages">Interactive Web Pages</a> to <a href="#IntegratingClient-Server">Integrating Client-Server</a>, and in the process will get a good overview of both Scala.js's use cases as well as the development experience
</p>
- <div class="header scalatex-header scalatex-hover-container" id="GettingStarted" style="display: block;"><h1 id="GettingStarted">Getting Started<a class="scalatex-header-link" href="#GettingStarted" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a></h1><br /></div>
+ <div style="margin: 0px;color: #333;text-align: center;padding: 2.5em 2em 0;border-bottom: 1px solid #eee;display: block;" id="GettingStarted" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><h1 style="margin: 0.2em 0;font-size: 3em;font-weight: 300;" id="GettingStarted">Getting Started<a class=" scalatex-site-Styles-headerLink" href="#GettingStarted" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a></h1><br /></div>
<p>
@@ -279,7 +329,7 @@ is a set of tutorials that walks you through getting started with Scala.js. You'
<p>
The quickest way to get started with Scala.js is to <code>git clone</code> <a href="https://github.com/lihaoyi/workbench-example-app">workbench-example-app</a>, go into the repository root, and run <code>sbt ~fastOptJS</code>
</p>
-<pre><code class="bash scalatex-highlight-js">git clone https://github.com/lihaoyi/workbench-example-app
+<pre><code class="bash scalatex-site-Styles-highlightMe">git clone https://github.com/lihaoyi/workbench-example-app
cd workbench-example-app
sbt ~fastOptJS
</code></pre>
@@ -324,7 +374,7 @@ sbt ~fastOptJS
<p>
Congratulations, you just built and ran your first Scala.js application! If something here does not happen as expected, it means that one of the steps did not complete successfully. Make sure you can get this working before you proceed onward.
</p>
-<h1 id="OpeninguptheProject" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#OpeninguptheProject" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Opening up the Project</h1>
+<h1 id="OpeninguptheProject" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#OpeninguptheProject" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Opening up the Project</h1>
<p>
The next thing to do once you have the project built and running in your browser is to load it into your editor. Both IntelliJ and Eclipse should let you import the Scala.js project without any hassle. Opening it and navigating to <code>ScalaJSExample.scala</code> would look like this:
@@ -334,7 +384,7 @@ sbt ~fastOptJS
<p>
Let's try changing one line to change the background fill from black to white:
</p>
- <pre><code class="diff scalatex-highlight-js">- ctx.fillStyle = &quot;black&quot;
+ <pre><code class="diff scalatex-site-Styles-highlightMe">- ctx.fillStyle = &quot;black&quot;
+ ctx.fillStyle = &quot;white&quot;
</code></pre>
<p>
@@ -348,14 +398,14 @@ sbt ~fastOptJS
<img src="images/Hello World Console.png" style="max-width: 100%;" />
<p>
- Apart from the SBT log output (which is handled by Workbench) any <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">println</code>s in your Scala.js code will also end up in the browser console (the <code>main</code> you see in the console is printed inside the Scala.js application, see if you can find it!) and so will the stack traces for any thrown exceptions.
+ Apart from the SBT log output (which is handled by Workbench) any <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">println</code>s in your Scala.js code will also end up in the browser console (the <code>main</code> you see in the console is printed inside the Scala.js application, see if you can find it!) and so will the stack traces for any thrown exceptions.
</p>
-<h1 id="TheApplicationCode" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#TheApplicationCode" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>The Application Code</h1>
+<h1 id="TheApplicationCode" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#TheApplicationCode" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>The Application Code</h1>
<p>
We've downloaded, compiled, ran, and made changes to our first Scala.js application. Let's now take a closer look at the code that we just ran:</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">package example
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">package example
import scala.scalajs.js.annotation.JSExport
import org.scalajs.dom
import org.scalajs.dom.html
@@ -398,46 +448,46 @@ object ScalaJSExample {
dom.setInterval(() =&gt; run, 50)
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/workbench-example-app/blob/master/src/main/scala/example/ScalaJSExample.scala#L0-L44" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/workbench-example-app/blob/master/src/main/scala/example/ScalaJSExample.scala#L0-L44" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- It's a good chunk of code, though not a huge amount. To someone who didn't know about Scala.js, they would just think it's normal Scala, albeit with this unusual <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">dom</code> library and a few weird annotations. Let's pick it apart starting from the top:
+ It's a good chunk of code, though not a huge amount. To someone who didn't know about Scala.js, they would just think it's normal Scala, albeit with this unusual <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">dom</code> library and a few weird annotations. Let's pick it apart starting from the top:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">case class Point(x: Int, y: Int){
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">case class Point(x: Int, y: Int){
def +(p: Point) = Point(x + p.x, y + p.y)
def /(d: Int) = Point(x / d, y / d)
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/workbench-example-app/blob/master/src/main/scala/example/ScalaJSExample.scala#L6-L11" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/workbench-example-app/blob/master/src/main/scala/example/ScalaJSExample.scala#L6-L11" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- Here we are defining a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Point</code> case class which represents a X/Y position, with some basic operators defined on it. This is done mostly for convenience later on, when we want to manipulate these two-dimensional points. Scala.js is Scala, and supports the entirety of the Scala language. <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Point</code> here behaves identically as it would if you had run Scala on the JVM.
+ Here we are defining a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Point</code> case class which represents a X/Y position, with some basic operators defined on it. This is done mostly for convenience later on, when we want to manipulate these two-dimensional points. Scala.js is Scala, and supports the entirety of the Scala language. <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Point</code> here behaves identically as it would if you had run Scala on the JVM.
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">@JSExport
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">@JSExport
object ScalaJSExample {
@JSExport
- def main(canvas: html.Canvas): Unit = {</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/workbench-example-app/blob/master/src/main/scala/example/ScalaJSExample.scala#L11-L15" target="_blank"><i class="fa fa-link "></i></a></pre>
+ def main(canvas: html.Canvas): Unit = {</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/workbench-example-app/blob/master/src/main/scala/example/ScalaJSExample.scala#L11-L15" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- This <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">@JSExport</code> annotation is used to tell Scala.js that you want this method to be visible and callable from Javascript. By default, Scala.js does <a href="#FastOptimization">dead code elimination</a> and removes any methods or classes which are not used. This is done to keep the compiled executables a reasonable size, since most projects use only a small fraction of e.g. the standard library. <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">@JSExport</code> is used to tell Scala.js that the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">ScalaJSExample</code> object and its <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">def main</code> method are entry points to the program. Even if they aren't called anywhere internally, they are called externally by Javascript that the Scala.js compiler is not aware of, and should not be removed. In this case, we are going to call this method from Javascript to start the Scala.js program.
+ This <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">@JSExport</code> annotation is used to tell Scala.js that you want this method to be visible and callable from Javascript. By default, Scala.js does <a href="#FastOptimization">dead code elimination</a> and removes any methods or classes which are not used. This is done to keep the compiled executables a reasonable size, since most projects use only a small fraction of e.g. the standard library. <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">@JSExport</code> is used to tell Scala.js that the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">ScalaJSExample</code> object and its <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">def main</code> method are entry points to the program. Even if they aren't called anywhere internally, they are called externally by Javascript that the Scala.js compiler is not aware of, and should not be removed. In this case, we are going to call this method from Javascript to start the Scala.js program.
</p>
<p>
- Apart from this annotation, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">ScalaJSExample</code> is just a normal Scala <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">object</code>, and behaves like one in every way. Note that the main-method in this case takes a <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement">html.Canvas</a>: your exported methods can have any signature, with arbitrary arity or types for parameters or the return value. This is in contrast to the main method on the JVM which always takes an <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Array[String]</code> and returns <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Unit</code>. In fact, there's nothing special about this method at all! It's like any other exported method, we just happen to attribute it the &quot;main&quot; entry point. It is entirely possible to define multiple exported classes and methods, and build a &quot;library&quot; using Scala.js of methods that are intended for external Javascript to use.
+ Apart from this annotation, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">ScalaJSExample</code> is just a normal Scala <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">object</code>, and behaves like one in every way. Note that the main-method in this case takes a <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement">html.Canvas</a>: your exported methods can have any signature, with arbitrary arity or types for parameters or the return value. This is in contrast to the main method on the JVM which always takes an <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Array[String]</code> and returns <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Unit</code>. In fact, there's nothing special about this method at all! It's like any other exported method, we just happen to attribute it the &quot;main&quot; entry point. It is entirely possible to define multiple exported classes and methods, and build a &quot;library&quot; using Scala.js of methods that are intended for external Javascript to use.
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">val ctx = canvas.getContext(&quot;2d&quot;)
- .asInstanceOf[dom.CanvasRenderingContext2D]</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/workbench-example-app/blob/master/src/main/scala/example/ScalaJSExample.scala#L15-L18" target="_blank"><i class="fa fa-link "></i></a></pre>
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">val ctx = canvas.getContext(&quot;2d&quot;)
+ .asInstanceOf[dom.CanvasRenderingContext2D]</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/workbench-example-app/blob/master/src/main/scala/example/ScalaJSExample.scala#L15-L18" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- Here we are retrieving a handle to the canvas we will draw on using <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">document.getElementById</code>, and from it we can get a <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D">CanvasRenderingContext2D</a> which we actually use to draw on it.
+ Here we are retrieving a handle to the canvas we will draw on using <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">document.getElementById</code>, and from it we can get a <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D">CanvasRenderingContext2D</a> which we actually use to draw on it.
</p>
<p>
- We need to perform the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">asInstanceOf</code> call because depending on what you pass to <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">getElementById</code> and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">getContext</code>, you could be returned elements and contexts of different types. Hence we need to tell the compiler explicitly that we're expecting a <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement">html.Canvas</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D">CanvasRenderingContext2D</a> back from these methods for the strings we passed in.
+ We need to perform the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">asInstanceOf</code> call because depending on what you pass to <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">getElementById</code> and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">getContext</code>, you could be returned elements and contexts of different types. Hence we need to tell the compiler explicitly that we're expecting a <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement">html.Canvas</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D">CanvasRenderingContext2D</a> back from these methods for the strings we passed in.
</p>
<p>
- Note how the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement">html.Canvas</a> comes from the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">html</code> namespace, while the <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D">CanvasRenderingContext2D</a> comes from the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">dom</code> namespace. Traditionally, these types are imported via their qualified names: e.g. <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">html.Canvas</code> rather than just <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Canvas</code>.
+ Note how the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement">html.Canvas</a> comes from the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">html</code> namespace, while the <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D">CanvasRenderingContext2D</a> comes from the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">dom</code> namespace. Traditionally, these types are imported via their qualified names: e.g. <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">html.Canvas</code> rather than just <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Canvas</code>.
</p>
<p>
- In general, <a href="http://scala-js.github.io/scala-js-dom/">scala-js-dom</a> provides <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">org.scalajs.dom.html</code> to access the HTML element types of the browser, an <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">org.scalajs.dom</code> to access other things. There are a number of other namespaces (<code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">dom.svg</code>, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">dom.idb</code>, etc.) accessible inside <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">org.scalajs.dom</code>: read the <a href="http://scala-js.github.io/scala-js-dom/">scala-js-dom docs</a> to learn more.
+ In general, <a href="http://scala-js.github.io/scala-js-dom/">scala-js-dom</a> provides <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">org.scalajs.dom.html</code> to access the HTML element types of the browser, an <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">org.scalajs.dom</code> to access other things. There are a number of other namespaces (<code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">dom.svg</code>, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">dom.idb</code>, etc.) accessible inside <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">org.scalajs.dom</code>: read the <a href="http://scala-js.github.io/scala-js-dom/">scala-js-dom docs</a> to learn more.
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">def run = for (i &lt;- 0 until 10){
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">def run = for (i &lt;- 0 until 10){
if (count % 3000 == 0) clear()
count += 1
p = (p + corners(Random.nextInt(3))) / 2
@@ -449,7 +499,7 @@ object ScalaJSExample {
ctx.fillStyle = s&quot;rgb($g, $r, $b)&quot;
ctx.fillRect(p.x, p.y, 1, 1)
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/workbench-example-app/blob/master/src/main/scala/example/ScalaJSExample.scala#L27-L41" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/workbench-example-app/blob/master/src/main/scala/example/ScalaJSExample.scala#L27-L41" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
This is the part of the Scala.js program which does the real work. It runs 10 iterations of a <a href="http://en.wikipedia.org/wiki/Sierpinski_triangle#Chaos_game">small algorithm</a> that generates a Sierpinski Triangle point-by-point. The steps, as described by the linked article, are roughly:
@@ -458,7 +508,7 @@ object ScalaJSExample {
<li>
Pick a random corner of the large-triangle</li>
<li>
- Move your current-position <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">p</code> halfway between its current location and that corner</li>
+ Move your current-position <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">p</code> halfway between its current location and that corner</li>
<li>
Draw a dot</li>
<li>
@@ -467,20 +517,20 @@ object ScalaJSExample {
<p>
In this example, the triangle is hard-coded to be 255 pixels high by 255 pixels wide, and some math is done to pick a color for each dot which will give the triangle a pretty gradient.
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">dom.setInterval(() =&gt; run, 50)</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/workbench-example-app/blob/master/src/main/scala/example/ScalaJSExample.scala#L41-L42" target="_blank"><i class="fa fa-link "></i></a></pre>
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">dom.setInterval(() =&gt; run, 50)</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/workbench-example-app/blob/master/src/main/scala/example/ScalaJSExample.scala#L41-L42" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- Now this is the call that actually does the useful work. All this method does is call <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">dom.setInterval</code>, which tells the browser to run the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">run</code> method every 50 milliseconds. As mentioned earlier, the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">dom.*</code> methods are simply facades to their native Javascript equivalents, and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">dom.setInterval</code> is <a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers.setInterval">no different</a>. Note how you can pass a Scala lambda to <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">setInterval</code> to have it called by the browser, where in Javascript you'd need to pass a Javascript <code class="javascript scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">function(){...</code>}
+ Now this is the call that actually does the useful work. All this method does is call <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">dom.setInterval</code>, which tells the browser to run the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">run</code> method every 50 milliseconds. As mentioned earlier, the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">dom.*</code> methods are simply facades to their native Javascript equivalents, and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">dom.setInterval</code> is <a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers.setInterval">no different</a>. Note how you can pass a Scala lambda to <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">setInterval</code> to have it called by the browser, where in Javascript you'd need to pass a Javascript <code class="javascript scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">function(){...</code>}
</p>
-<h1 id="TheProjectCode" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#TheProjectCode" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>The Project Code</h1>
+<h1 id="TheProjectCode" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#TheProjectCode" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>The Project Code</h1>
<p>
We've already taken a look at the application code for a simple, self-contained Scala.js application, but this application is not <i>entirely</i> self contained. It's wrapped in a small SBT project that sets up the necessary dependencies and infrastructure for this application to work.
</p>
- <h2 id="project/build.sbt" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#project/build.sbt" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>project/build.sbt</h2>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">addSbtPlugin(&quot;org.scala-js&quot; % &quot;sbt-scalajs&quot; % &quot;0.6.0&quot;)
+ <h2 id="project/build.sbt" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#project/build.sbt" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>project/build.sbt</h2>
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">addSbtPlugin(&quot;org.scala-js&quot; % &quot;sbt-scalajs&quot; % &quot;0.6.0&quot;)
-addSbtPlugin(&quot;com.lihaoyi&quot; % &quot;workbench&quot; % &quot;0.2.3&quot;)</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/workbench-example-app/blob/master/project/build.sbt#L0-L3" target="_blank"><i class="fa fa-link "></i></a></pre>
+addSbtPlugin(&quot;com.lihaoyi&quot; % &quot;workbench&quot; % &quot;0.2.3&quot;)</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/workbench-example-app/blob/master/project/build.sbt#L0-L3" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
This is the list of SBT plugins used by this small example application. There are two of them: the Scala.js plugin (which contains the Scala.js compiler and other things, e.g. tasks such as <code>fastOptJS</code>) and the <a href="https://github.com/lihaoyi/workbench">Workbench</a> plugin, which is used to provide the auto-reload-on-change behavior and the forwarding of SBT logspam to the browser console.
@@ -489,8 +539,8 @@ addSbtPlugin(&quot;com.lihaoyi&quot; % &quot;workbench&quot; % &quot;0.2.3&quot;
Of the two, only the Scala.js plugin is really necessary. The Workbench plugin is a convenience that makes development easier. Without it you'd need to keep a terminal open to view the SBT logspam, and manually refresh the page when compilation finished. Not the end of the world.
</p>
- <h2 id="build.sbt" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#build.sbt" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>build.sbt</h2>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">import com.lihaoyi.workbench.Plugin._
+ <h2 id="build.sbt" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#build.sbt" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>build.sbt</h2>
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">import com.lihaoyi.workbench.Plugin._
enablePlugins(ScalaJSPlugin)
@@ -508,19 +558,19 @@ libraryDependencies ++= Seq(
bootSnippet := &quot;example.ScalaJSExample().main(document.getElementById('canvas'));&quot;
-updateBrowsers &lt;&lt;= updateBrowsers.triggeredBy(fastOptJS in Compile)</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/workbench-example-app/blob/master/build.sbt#L0-L19" target="_blank"><i class="fa fa-link "></i></a></pre>
+updateBrowsers &lt;&lt;= updateBrowsers.triggeredBy(fastOptJS in Compile)</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/workbench-example-app/blob/master/build.sbt#L0-L20" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- The <code>build.sbt</code> project file for this application is similarly unremarkable: It includes the settings for the two SBT plugins we saw earlier, as well as boilerplate <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">name</code>/<code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">version</code>/<code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">scalaVersion</code> values common to all projects.
+ The <code>build.sbt</code> project file for this application is similarly unremarkable: It includes the settings for the two SBT plugins we saw earlier, as well as boilerplate <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">name</code>/<code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">version</code>/<code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">scalaVersion</code> values common to all projects.
</p>
<p>
- Of interest is the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">libraryDependencies</code>. In Scala-JVM, this key is used to declare dependencies on libraries from Maven Central, so you can use them in your Scala-JVM projects. In Scala.js, the same key is used to declare dependencies on libraries so you can use them in your Scala.js projects! Re-usable libraries can be built and published with Scala.js just as you do on Scala-JVM, and here we make use of one which provides the typed facades with which we used to access the DOM in the application code.
+ Of interest is the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">libraryDependencies</code>. In Scala-JVM, this key is used to declare dependencies on libraries from Maven Central, so you can use them in your Scala-JVM projects. In Scala.js, the same key is used to declare dependencies on libraries so you can use them in your Scala.js projects! Re-usable libraries can be built and published with Scala.js just as you do on Scala-JVM, and here we make use of one which provides the typed facades with which we used to access the DOM in the application code.
</p>
<p>
- Lastly, we have two Workbench related settings: <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">bootSnippet</code> basically tells Workbench how to restart your application when a new compilation run finishes, and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">updateBrowsers</code> actually tells it to perform this application-restarting.
+ Lastly, we have two Workbench related settings: <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">bootSnippet</code> basically tells Workbench how to restart your application when a new compilation run finishes, and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">updateBrowsers</code> actually tells it to perform this application-restarting.
</p>
- <h2 id="src/main/resources/index-dev.html" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#src/main/resources/index-dev.html" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>src/main/resources/index-dev.html</h2>
- <pre class="scalatex-hover-container"><code class=" scalatex-highlight-js hljs">&lt;!DOCTYPE html&gt;
+ <h2 id="src/main/resources/index-dev.html" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#src/main/resources/index-dev.html" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>src/main/resources/index-dev.html</h2>
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="html scalatex-site-Styles-highlightMe">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Example Scala.js application&lt;/title&gt;
@@ -538,26 +588,26 @@ updateBrowsers &lt;&lt;= updateBrowsers.triggeredBy(fastOptJS in Compile)</code>
example.ScalaJSExample().main(document.getElementById('canvas'));
&lt;/script&gt;
&lt;/body&gt;
-&lt;/html&gt;</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/workbench-example-app/blob/master/src/main/resources/index-dev.html#L0-L19" target="_blank"><i class="fa fa-link "></i></a></pre>
+&lt;/html&gt;</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/workbench-example-app/blob/master/src/main/resources/index-dev.html#L0-L19" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- This is the HTML page which our toy app lives in, and the same page that we have so far been using to view the app in the browser. To anyone who has used HTML, most of it is probably familiar. Things of note are the <code class="html scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&lt;script&gt;</code> tags: <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&quot;../example-fastopt.js&quot;</code> Is the executable blob spat out by the compiler, which we need to include in the HTML page for anything to happen. This is where the results of your compiled Scala code appear. <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&quot;workbench.js&quot;</code> is the client for the Workbench plugin that connects to SBT, reloads the browser and forwards logspam to the browser console.
+ This is the HTML page which our toy app lives in, and the same page that we have so far been using to view the app in the browser. To anyone who has used HTML, most of it is probably familiar. Things of note are the <code class="xml scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&lt;script&gt;</code> tags: <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&quot;../example-fastopt.js&quot;</code> Is the executable blob spat out by the compiler, which we need to include in the HTML page for anything to happen. This is where the results of your compiled Scala code appear. <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&quot;workbench.js&quot;</code> is the client for the Workbench plugin that connects to SBT, reloads the browser and forwards logspam to the browser console.
</p>
<p>
- The <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">example.ScalaJSExample().main()</code> call is what kicks off the Scala.js application and starts its execution. Scala.js follows Scala semantics in that <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">object</code>s are evaluated lazily, with no top-level code allowed. This is in contrast to Javascript, where you can include top-level statements and object-literals in your code which execute immediately. In Scala.js, nothing happens when <code>../example-fastopt.js</code> is imported! We have to call the main-method first. In this case, we're passing the canvas object (attained using <code class="javascript scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">getElementById</code>) to it so it knows where to do its thing.
+ The <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">example.ScalaJSExample().main()</code> call is what kicks off the Scala.js application and starts its execution. Scala.js follows Scala semantics in that <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">object</code>s are evaluated lazily, with no top-level code allowed. This is in contrast to Javascript, where you can include top-level statements and object-literals in your code which execute immediately. In Scala.js, nothing happens when <code>../example-fastopt.js</code> is imported! We have to call the main-method first. In this case, we're passing the canvas object (attained using <code class="javascript scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">getElementById</code>) to it so it knows where to do its thing.
</p>
<p>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">document.getElementById</code> is the exact same API that's used in normal Javascript, as documented <a href="https://developer.mozilla.org/en-US/docs/Web/API/document.getElementById">here</a>. In fact, the entire <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">org.scalajs.dom</code> namespace (imported at the top of the file) comprises statically typed facades for the javascript APIs provided by the browser.
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">document.getElementById</code> is the exact same API that's used in normal Javascript, as documented <a href="https://developer.mozilla.org/en-US/docs/Web/API/document.getElementById">here</a>. In fact, the entire <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">org.scalajs.dom</code> namespace (imported at the top of the file) comprises statically typed facades for the javascript APIs provided by the browser.
<p>
- Lastly, only <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">@JSExport</code>ed objects and methods can be called from Javascript. Also, although this example only exports the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">main</code> method which is called once, there is nothing stopping you from exporting any number of objects and methods and calling them whenever you need to. In this way, you can easily make a Scala.js &quot;library&quot; which is available to external Javascript as an API.
+ Lastly, only <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">@JSExport</code>ed objects and methods can be called from Javascript. Also, although this example only exports the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">main</code> method which is called once, there is nothing stopping you from exporting any number of objects and methods and calling them whenever you need to. In this way, you can easily make a Scala.js &quot;library&quot; which is available to external Javascript as an API.
</p></p>
-<h1 id="Publishing" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Publishing" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Publishing</h1>
+<h1 id="Publishing" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Publishing" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Publishing</h1>
<p>
The last thing that we'll do with our toy application is to publish it. If you look in the <code>target/scala-2.11</code> folder, you'll see the output of everything we've done so far:
</p>
- <pre><code class="bash scalatex-highlight-js">target/scala-2.11
+ <pre><code class="bash scalatex-site-Styles-highlightMe">target/scala-2.11
├── classes
│   ├── JS_DEPENDENCIES
│   ├── example
@@ -581,13 +631,13 @@ updateBrowsers &lt;&lt;= updateBrowsers.triggeredBy(fastOptJS in Compile)</code>
<p>
These two files can be extracted and published as-is: you can put them on <a href="https://pages.github.com/">Github-Pages</a>, <a href="http://docs.aws.amazon.com/gettingstarted/latest/swh/website-hosting-intro.html">Amazon Web Services</a>, or a hundred other places. However, one thing of note is the fact that the generated Javascript file is quite large:
</p>
- <pre><code class="bash scalatex-highlight-js">haoyi-mbp:temp haoyi$ du -h target/scala-2.11/example-fastopt.js
+ <pre><code class="bash scalatex-site-Styles-highlightMe">haoyi-mbp:temp haoyi$ du -h target/scala-2.11/example-fastopt.js
656K target/scala-2.11/example-fastopt.js
</code></pre>
<p>
656 Kilobytes for a hello world app! That is clearly too large. If you examine the contents of the file, you'll see that your code has been translated into something like this:
</p>
- <pre><code class="javascript scalatex-highlight-js">var v1 = i;
+ <pre><code class="javascript scalatex-site-Styles-highlightMe">var v1 = i;
if (((count$1.elem$1 % 3000) === 0)) {
ScalaJS.m.Lexample_ScalaJSExample$().example$ScalaJSExample$$clear$1__Lorg_scalajs_dom_CanvasRenderingContext2D__V(ctx$1)
};
@@ -600,19 +650,19 @@ var r = ((ScalaJS.as.Lexample_Point(p$1.elem$1).x$1 * height) | 0);
var g = ((((255 - ScalaJS.as.Lexample_Point(p$1.elem$1).x$1) | 0) * height) | 0);
</code></pre>
<p>
- As you can see, this code is still very verbose, with lots of unnecessarily long identifiers such as <code class="javascript scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Lexample_ScalaJSExample$</code> in it. This is because we've only performed the <a href="#FastOptimization">Fast Optimization</a> on this file, to try and keep the time taken to edit -&gt; compile while developing reasonably short.
+ As you can see, this code is still very verbose, with lots of unnecessarily long identifiers such as <code class="javascript scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Lexample_ScalaJSExample$</code> in it. This is because we've only performed the <a href="#FastOptimization">Fast Optimization</a> on this file, to try and keep the time taken to edit -&gt; compile while developing reasonably short.
</p>
- <h2 id="Optimization" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Optimization" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Optimization</h2>
+ <h2 id="Optimization" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Optimization" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Optimization</h2>
<p>
If we're planning on publishing the app for real, we can run the <a href="#FullOptimization">Full Optimization</a>. This takes several seconds longer than the <a href="#FastOptimization">Fast Optimization</a>, but results in a significantly smaller and leaner output file <code>example-opt.js</code>.
</p>
- <pre><code class="bash scalatex-highlight-js">haoyi-mbp:temp haoyi$ du -h target/scala-2.11/example-opt.js
+ <pre><code class="bash scalatex-site-Styles-highlightMe">haoyi-mbp:temp haoyi$ du -h target/scala-2.11/example-opt.js
104K target/scala-2.11/example-opt.js
</code></pre>
<p>
104 Kilobytes! Better. Not great, though! In general, Scala.js does not produce tiny executables, although the output size of the compiled executables is dropping all the time. If you look inside that file, you'll see all of the long identifiers have been replaced by short ones by the <a href="https://developers.google.com/closure/compiler/">Google Closure Compiler</a>.
</p>
- <pre><code class="javascript scalatex-highlight-js"> y=fb(gb((new F).Ya([&quot;rgb(&quot;,&quot;, &quot;,&quot;, &quot;,&quot;)&quot;])),(new F).Ya([(255-c.l.Db|0)*y|0,c.l.Db*y|0,c.l.Eb]));a.fillStyle=y;a.fillRect(c.l.Db,c.l.Eb,1,1);w=1+w|0}}}(a,b,c,e),50)}Xa.prototype.main=function(a){Ya(a)};Xa.prototype.a=new x({$g:0},!1,&quot;example.ScalaJSExample$&quot;,B,{$g:1,b:1});var hb=void 0;function bb(){hb||(hb=(new Xa).c());return hb}ba.example=ba.example||{};ba.example.ScalaJSExample=bb;function Da(){this.Pb=null}Da.prototype=new A;
+ <pre><code class="javascript scalatex-site-Styles-highlightMe"> y=fb(gb((new F).Ya([&quot;rgb(&quot;,&quot;, &quot;,&quot;, &quot;,&quot;)&quot;])),(new F).Ya([(255-c.l.Db|0)*y|0,c.l.Db*y|0,c.l.Eb]));a.fillStyle=y;a.fillRect(c.l.Db,c.l.Eb,1,1);w=1+w|0}}}(a,b,c,e),50)}Xa.prototype.main=function(a){Ya(a)};Xa.prototype.a=new x({$g:0},!1,&quot;example.ScalaJSExample$&quot;,B,{$g:1,b:1});var hb=void 0;function bb(){hb||(hb=(new Xa).c());return hb}ba.example=ba.example||{};ba.example.ScalaJSExample=bb;function Da(){this.Pb=null}Da.prototype=new A;
</code></pre>
<p>
@@ -621,7 +671,7 @@ var g = ((((255 - ScalaJS.as.Lexample_Point(p$1.elem$1).x$1) | 0) * height) | 0)
<p>
This means you can develop and debug using <code>fastOptJS</code>, and only spend the extra time (and increased debugging-difficulty) on the <code>fullOptJS</code> version just as you're going to publish it, with the assurance that although the code is much more compact, its behavior will not change.
</p>
- <h2 id="BlobSize" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#BlobSize" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Blob Size</h2>
+ <h2 id="BlobSize" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#BlobSize" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Blob Size</h2>
<p>
Even the fully-optimized version of our toy Scala.js app are pretty large. There are some factors that mitigate the large size of these executables:
</p>
@@ -644,7 +694,7 @@ var g = ((((255 - ScalaJS.as.Lexample_Point(p$1.elem$1).x$1) | 0) * height) | 0)
<p>
More advanced users would want to integrate them into their build process or serve them from a web server, all of which is entirely possible. You just need to run the Scala.js compiler and place the output <code>.js</code> file somewhere your web server can pick it up, e.g. in some static-resource folder. We cover an example setup of this with a Scala webserver in our chapter <a href="#IntegratingClient-Server">Integrating Client-Server</a>.
</p>
-<h1 id="Recap" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Recap" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Recap</h1>
+<h1 id="Recap" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Recap" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Recap</h1>
<p>
If you've made it this far, you've downloaded, made modifications to, and published a toy Scala.js application. At the same time, we've gone over many of the key concepts in the Scala.js development process:
@@ -683,7 +733,7 @@ var g = ((((255 - ScalaJS.as.Lexample_Point(p$1.elem$1).x$1) | 0) * height) | 0)
When you're done poking around our toy web application, read on to the next chapter, where we will explore making something more meaty using the Scala.js toolchain!</p>
- <div class="header scalatex-header scalatex-hover-container" id="MakingaCanvasApp" style="display: block;"><h1 id="MakingaCanvasApp">Making a Canvas App<a class="scalatex-header-link" href="#MakingaCanvasApp" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a></h1><br /></div>
+ <div style="margin: 0px;color: #333;text-align: center;padding: 2.5em 2em 0;border-bottom: 1px solid #eee;display: block;" id="MakingaCanvasApp" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><h1 style="margin: 0.2em 0;font-size: 3em;font-weight: 300;" id="MakingaCanvasApp">Making a Canvas App<a class=" scalatex-site-Styles-headerLink" href="#MakingaCanvasApp" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a></h1><br /></div>
<p>
By this point, you've already cloned and got your hands dirty fiddling around with the toy <a href="https://github.com/lihaoyi/workbench-example-app">workbench-example-app</a>. You have your editor set up, SBT installed, and have published the example application in a way you can host online for other people to see. Maybe you've even made some changes to the application to see what happens. Hopefully you're curious, and want to learn more.
@@ -702,12 +752,12 @@ var g = ((((255 - ScalaJS.as.Lexample_Point(p$1.elem$1).x$1) | 0) * height) | 0)
<p>
In general, while the previous chapter was mostly set-up and exploring the Scala.js project, this chapter will walk you through actually writing a non-trivial, self-contained Scala.js application. Throughout this chapter, we will only be making modifications to <code>ScalaJSExample.scala</code>; the rest of the project will remain unchanged.
</p>
-<h1 id="MakingaSketchpadusingMouseInput" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#MakingaSketchpadusingMouseInput" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Making a Sketchpad using Mouse Input</h1>
+<h1 id="MakingaSketchpadusingMouseInput" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#MakingaSketchpadusingMouseInput" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Making a Sketchpad using Mouse Input</h1>
<p>
- To begin with, lets remove all the existing stuff in our <code>.scala</code> file and leave only the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">object</code> and the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">main</code> method. Let's start off with some necessary boilerplate:
+ To begin with, lets remove all the existing stuff in our <code>.scala</code> file and leave only the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">object</code> and the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">main</code> method. Let's start off with some necessary boilerplate:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">/*setup*/
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">/*setup*/
val renderer = canvas.getContext(&quot;2d&quot;)
.asInstanceOf[dom.CanvasRenderingContext2D]
@@ -715,7 +765,7 @@ canvas.width = canvas.parentElement.clientWidth
canvas.height = canvas.parentElement.clientHeight
renderer.fillStyle = &quot;#f8f8f8&quot;
-renderer.fillRect(0, 0, canvas.width, canvas.height)</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/canvasapp/ScratchPad.scala#L12-L22" target="_blank"><i class="fa fa-link "></i></a></pre>
+renderer.fillRect(0, 0, canvas.width, canvas.height)</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/canvasapp/ScratchPad.scala#L12-L22" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
As described earlier, this code uses the <a href="https://developer.mozilla.org/en-US/docs/Web/API/document.getElementById">document.getElementById</a> function to fish out the <code>canvas</code> element that we interested in from the DOM. It then gets a rendering context from that <code>canvas</code>, and sets the height and width of the canvas to completely fill its containing element. Lastly, it fills out the canvas light-gray, so that we can see it on the page.
@@ -725,7 +775,7 @@ renderer.fillRect(0, 0, canvas.width, canvas.height)</code><a class="scalatex-he
</p>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-13-24">
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">/*code*/
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">/*code*/
renderer.fillStyle = &quot;black&quot;
var down = false
canvas.onmousedown =
@@ -743,7 +793,7 @@ canvas.onmousemove = {
e.clientY - rect.top,
10, 10
)
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/canvasapp/ScratchPad.scala#L22-L41" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/canvasapp/ScratchPad.scala#L22-L41" target="_blank"><i class="fa fa-link "></i></a></pre>
</div>
<div class="pure-u-1 pure-u-md-11-24">
<canvas id="example1" style="display: block;overflow: scroll;"></canvas><script>canvasapp.ScratchPad().main(document.getElementById('example1'))</script>
@@ -752,14 +802,14 @@ canvas.onmousemove = {
This code sets up the <a href="https://developer.mozilla.org/en-US/docs/Web/Events/mousedown">mousedown</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/Events/mouseup">mouseup</a> events to keep track of whether or not the mouse has currently been clicked. It then draws black squares any time you move the mouse while the button is down. This lets you basically click-and-drag to draw pictures on the canvas. Try it out!
</p>
<p>
- In general, you have access to all the DOM APIs through the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">dom</code> package as well as through Javascript objects such as the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement">html.Canvas</a>. Setting the <code>onmouseXXX</code> callbacks is just one way of interacting with the DOM. With Scala.js, you also get a very handy autocomplete in the editor, which you can use to browse the various other APIs that are available for use:
+ In general, you have access to all the DOM APIs through the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">dom</code> package as well as through Javascript objects such as the <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement">html.Canvas</a>. Setting the <code>onmouseXXX</code> callbacks is just one way of interacting with the DOM. With Scala.js, you also get a very handy autocomplete in the editor, which you can use to browse the various other APIs that are available for use:
</p>
<img src="images/Dropdown.png" style="max-width: 100%;" />
<p>
Apart from mouse events, keyboard events, scroll events, input events, etc. are all usable from Scala.js as you'd expect. If you have problems getting this to work, feel free to click on the link <i class="fa fa-link "></i> icon below the code snippet to see what the full code for the example looks like
</p>
-<h1 id="MakingaClockusingsetInterval" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#MakingaClockusingsetInterval" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Making a Clock using setInterval</h1>
+<h1 id="MakingaClockusingsetInterval" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#MakingaClockusingsetInterval" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Making a Clock using setInterval</h1>
<p>
You've already seen this in the previous example, but <a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers.setInterval">WindowTimers.setInterval</a> can be used to schedule recurring, periodic events in your program. Common use cases include running the <a href="http://gameprogrammingpatterns.com/game-loop.html">event loop for a game</a>, making smooth animations, and other tasks of that sort which require some work to happen over a period of time.
@@ -767,7 +817,7 @@ canvas.onmousemove = {
<p>
Again, we need roughly the same boilerplate as just now to set up the canvas:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">/*setup*/
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">/*setup*/
val renderer = canvas.getContext(&quot;2d&quot;)
.asInstanceOf[dom.CanvasRenderingContext2D]
@@ -784,17 +834,17 @@ renderer.fillStyle = gradient
//renderer.fillStyle = &quot;black&quot;
renderer.textAlign = &quot;center&quot;
-renderer.textBaseline = &quot;middle&quot;</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/canvasapp/Clock.scala#L11-L30" target="_blank"><i class="fa fa-link "></i></a></pre>
+renderer.textBaseline = &quot;middle&quot;</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/canvasapp/Clock.scala#L11-L30" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- The only thing unusual here is that I'm going to create a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">linearGradient</code> in order to make the stopwatch look pretty. This is by no means necessary, and you could simply make the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">fillStyle</code> <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&quot;black&quot;</code> if you want to keep things simple.
+ The only thing unusual here is that I'm going to create a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">linearGradient</code> in order to make the stopwatch look pretty. This is by no means necessary, and you could simply make the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">fillStyle</code> <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&quot;black&quot;</code> if you want to keep things simple.
</p>
<p>
Once that's done, it's only a few lines of code to set up a nice, live clock:
</p>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-13-24">
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">/*code*/
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">/*code*/
def render() = {
val date = new js.Date()
renderer.clearRect(
@@ -812,15 +862,15 @@ def render() = {
canvas.height / 2
)
}
-dom.setInterval(render _, 1000)</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/canvasapp/Clock.scala#L30-L49" target="_blank"><i class="fa fa-link "></i></a></pre>
+dom.setInterval(render _, 1000)</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/canvasapp/Clock.scala#L30-L49" target="_blank"><i class="fa fa-link "></i></a></pre>
</div>
<div class="pure-u-1 pure-u-md-11-24">
<canvas id="example2" style="display: block;overflow: scroll;"></canvas><script>canvasapp.Clock().main(document.getElementById('example2'))</script>
</div></div>
<p>
- As you can see, we're using more <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D">Canvas APIs</a>, in this case dealing with rendering text on the canvas. Another thing we're using is the Javascript <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date">Date</a> class, in Scala.js under the full name <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">scala.scalajs.js.Date</code>, here imported as <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">js.Date</code>. Again, click on the link <i class="fa fa-link "></i> icon to view the full-code if you're having trouble here.
+ As you can see, we're using more <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D">Canvas APIs</a>, in this case dealing with rendering text on the canvas. Another thing we're using is the Javascript <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date">Date</a> class, in Scala.js under the full name <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">scala.scalajs.js.Date</code>, here imported as <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">js.Date</code>. Again, click on the link <i class="fa fa-link "></i> icon to view the full-code if you're having trouble here.
</p>
-<h1 id="Tyingittogether:FlappyBox" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Tyingittogether:FlappyBox" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Tying it together: Flappy Box</h1>
+<h1 id="Tyingittogether:FlappyBox" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Tyingittogether:FlappyBox" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Tying it together: Flappy Box</h1>
<p>
You've just seen two examples of how to use Scala.js, together with the Javascript DOM APIs, to make simple applications. However, we've only used the &quot;Scala&quot; in Scala.js in the most rudimentary fashion: setting a few primitives here and there, defining some methods, mainly just gluing together a few Javascript APIs
@@ -843,8 +893,8 @@ dom.setInterval(render _, 1000)</code><a class="scalatex-header-link" style="pos
<p>
It's a relatively simple game, but there should be enough &quot;business logic&quot; in here that we won't be simply gluing together APIs. Let's start!
</p>
- <h2 id="SettingUptheCanvas" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#SettingUptheCanvas" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Setting Up the Canvas</h2>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">/*setup*/
+ <h2 id="SettingUptheCanvas" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#SettingUptheCanvas" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Setting Up the Canvas</h2>
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">/*setup*/
val renderer = canvas.getContext(&quot;2d&quot;)
.asInstanceOf[dom.CanvasRenderingContext2D]
@@ -853,16 +903,16 @@ canvas.height = 400
renderer.font = &quot;50px sans-serif&quot;
renderer.textAlign = &quot;center&quot;
-renderer.textBaseline = &quot;middle&quot;</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/canvasapp/FlappyLine.scala#L12-L23" target="_blank"><i class="fa fa-link "></i></a></pre>
+renderer.textBaseline = &quot;middle&quot;</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/canvasapp/FlappyLine.scala#L12-L23" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- This section of the code is peripherally necessary, but not core to the implementation or logic of Flappy Box. We see the same <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">canvas</code>/<code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">renderer</code> logic we've seen in all our examples, along with some logic to make the canvas a reasonable size, and some configuration of how we will render text to the canvas.
+ This section of the code is peripherally necessary, but not core to the implementation or logic of Flappy Box. We see the same <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">canvas</code>/<code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">renderer</code> logic we've seen in all our examples, along with some logic to make the canvas a reasonable size, and some configuration of how we will render text to the canvas.
</p>
<p>
In general, code like this will usually end up being necessary in a Scala.js program: the Javascript APIs that the browser provides to do things often ends up being somewhat roundabout and verbose. It's somewhat annoying to have to do for a small program such as this one, but in a larger application, the cost is both spread out over thousands of lines of code and also typically hidden away in helper functions, so the verbosity and non-idiomatic-scala-ness doesn't bother you much.
</p>
- <h2 id="DefiningourState" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#DefiningourState" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Defining our State</h2>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">/*variables*/
+ <h2 id="DefiningourState" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#DefiningourState" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Defining our State</h2>
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">/*variables*/
val obstacleGap = 200 // Gap between the approaching obstacles
val holeSize = 50 // Size of the hole in each obstacle you must go through
val gravity = 0.1 // Y acceleration of the player
@@ -878,7 +928,7 @@ var frame = -50
// List of each obstacle, storing only the Y position of the hole.
// The X position of the obstacle is calculated by its position in the
// queue and in the current frame.
-val obstacles = collection.mutable.Queue.empty[Int]</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/canvasapp/FlappyLine.scala#L23-L42" target="_blank"><i class="fa fa-link "></i></a></pre>
+val obstacles = collection.mutable.Queue.empty[Int]</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/canvasapp/FlappyLine.scala#L23-L42" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
This is where we start defining things that are relevant to Flappy Box. There are roughly two groups of values here: immutable constants in the top group, and mutable variables in the bottom. The rough meaning of each variable is documented in the comments, and we'll see exactly how we use them later.
@@ -886,8 +936,8 @@ val obstacles = collection.mutable.Queue.empty[Int]</code><a class="scalatex-hea
<p>
One notable thing is that we're using a <a href="http://docs.scala-lang.org/overviews/collections/concrete-mutable-collection-classes.html">collection.mutable.Queue</a> to store the list of obstacles. This is defined in the Scala standard library; in general, all the collections in the Scala standard library can be used without issue in Scala.js.
</p>
- <h2 id="GameLogic" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#GameLogic" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Game Logic</h2>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">def runLive() = {
+ <h2 id="GameLogic" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#GameLogic" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Game Logic</h2>
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">def runLive() = {
frame += 2
// Create new obstacles, or kill old ones as necessary
@@ -929,10 +979,10 @@ val obstacles = collection.mutable.Queue.empty[Int]</code><a class="scalatex-hea
if (playerY &lt; 0 || playerY &gt; canvas.height){
dead = 50
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/canvasapp/FlappyLine.scala#L42-L86" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/canvasapp/FlappyLine.scala#L42-L86" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- The <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">runLive</code> function is the meat of Flappy Box. In it, we
+ The <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">runLive</code> function is the meat of Flappy Box. In it, we
</p>
<ul>
<li>
@@ -949,7 +999,7 @@ val obstacles = collection.mutable.Queue.empty[Int]</code><a class="scalatex-hea
<p>
This function basically contains all the game logic, from motion, to collision-detection, to rendering, so it's pretty large. Not that large though! And entirely understandable, even if it takes a few moments to read through.
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">def runDead() = {
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">def runDead() = {
playerY = canvas.height / 2
playerV = 0
frame = -50
@@ -957,13 +1007,13 @@ val obstacles = collection.mutable.Queue.empty[Int]</code><a class="scalatex-hea
dead -= 1
renderer.fillStyle = &quot;darkred&quot;
renderer.fillText(&quot;Game Over&quot;, canvas.width / 2, canvas.height / 2)
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/canvasapp/FlappyLine.scala#L86-L96" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/canvasapp/FlappyLine.scala#L86-L96" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- This is the function that handles what happens when you're dead. Essentially, we reset all the mutable variables to their initial state, and just count down the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">dead</code> counter until it reaches zero and we're considered alive again.
+ This is the function that handles what happens when you're dead. Essentially, we reset all the mutable variables to their initial state, and just count down the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">dead</code> counter until it reaches zero and we're considered alive again.
</p>
- <h2 id="AWorkingProduct" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#AWorkingProduct" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>A Working Product</h2>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">def run() = {
+ <h2 id="AWorkingProduct" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#AWorkingProduct" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>A Working Product</h2>
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">def run() = {
renderer.clearRect(0, 0, canvas.width, canvas.height)
if (dead &gt; 0) runDead()
else runLive()
@@ -973,10 +1023,10 @@ dom.setInterval(run _, 20)
canvas.onclick = (e: dom.MouseEvent) =&gt; {
playerV -= 5
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/canvasapp/FlappyLine.scala#L96-L107" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/canvasapp/FlappyLine.scala#L96-L107" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- And finally, this is the code that kicks everything off: we define the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">run</code> function to swap between <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">runLive</code> and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">runDead</code>, register an <a href="https://developer.mozilla.org/en-US/docs/Web/Events/onclick">onclick</a> handler to make the player jump by tweaking his velocity, and we call <a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers.setInterval">WindowTimers.setInterval</a> to run the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">run</code> function every 20 milliseconds.
+ And finally, this is the code that kicks everything off: we define the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">run</code> function to swap between <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">runLive</code> and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">runDead</code>, register an <a href="https://developer.mozilla.org/en-US/docs/Web/Events/onclick">onclick</a> handler to make the player jump by tweaking his velocity, and we call <a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers.setInterval">WindowTimers.setInterval</a> to run the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">run</code> function every 20 milliseconds.
</p>
<p>
At almost 100 lines of code, this is quite a meaty example! Nonetheless, when all is said and done, you will find that the example actually works! Try it out!
@@ -984,41 +1034,41 @@ canvas.onclick = (e: dom.MouseEvent) =&gt; {
<div>
<canvas id="example3" style="display: block;overflow: scroll;"></canvas><script>canvasapp.FlappyLine().main(document.getElementById('example3'))</script>
</div>
-<h1 id="CanvasRecap" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#CanvasRecap" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Canvas Recap</h1>
+<h1 id="CanvasRecap" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#CanvasRecap" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Canvas Recap</h1>
<p>
We've now gone through the workings of building a handful of toy applications using Scala.js. What have we learnt in the process?
</p>
- <h2 id="DevelopmentSpeed" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#DevelopmentSpeed" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Development Speed</h2>
+ <h2 id="DevelopmentSpeed" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#DevelopmentSpeed" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Development Speed</h2>
<p>
We've by now written a good chunk of Scala.js code, and perhaps debugged some mysterious errors, and tried some new things. One thing you've probably noticed is the efficiency of the process: you make a change in your editor, the browser reloads itself, and life goes on. There is a compile cycle, but after a few runs the compiler warms up and the compilation cycle drops to less than a second.</p>
<p>
Apart from the compilation/reload speed, you've probably noticed the benefit of tooling around Scala.js. Unlike Javascript editors, your existing Scala IDEs like <a href="http://blog.jetbrains.com/scala/">IntelliJ</a> or <a href="http://scala-ide.org/">Eclipse</a> can give very useful help when you're working with Scala.js. Autocomplete, error-highlighting, jump-to-definition, and a myriad other modern conveniences that are missing when working in dynamically-typed languages are present when working in Scala.js. This makes the code much less mysterious: you're no longer trying to guess what methods a value has, or what a method returns: it's all laid out in front of you in plain sight.
</p>
- <h2 id="FullScala" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#FullScala" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Full Scala</h2>
+ <h2 id="FullScala" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#FullScala" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Full Scala</h2>
<p>
All of the examples so far have been very self-contained: they do not touch the HTML DOM, they do not make Ajax calls, or try to access web services. They don't push the limits of the browser's API.
</p>
<p>
Nevertheless, these examples have exercised a good amount of the Scala language. List comprehensions, collections, the math library, and more. In general, most of the Scala standard library works under Scala.js, as well as a large number of third-party libraries. Unlike many other compile-to-Javascript languages out there, this isn't a language-that-looks-like-Scala: it is Scala through and through, with a tiny number of semantic differences.
</p>
- <h2 id="SeamlessJavascriptInterop" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#SeamlessJavascriptInterop" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Seamless Javascript Interop</h2>
+ <h2 id="SeamlessJavascriptInterop" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#SeamlessJavascriptInterop" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Seamless Javascript Interop</h2>
<p>
Even if we take some time to read through the code we've written, it is not immediately obvious which bits of code are Scala and which bits are Javascript! It all kind of meshes together, for example if we take the Flappy Box source code:
</p>
<ul>
<li>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">obstacles</code> is a Scala <a href="http://docs.scala-lang.org/overviews/collections/concrete-mutable-collection-classes.html">mutable.Queue</a>, as we defined it earlier, and all the methods on it are Scala method calls</li>
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">obstacles</code> is a Scala <a href="http://docs.scala-lang.org/overviews/collections/concrete-mutable-collection-classes.html">mutable.Queue</a>, as we defined it earlier, and all the methods on it are Scala method calls</li>
<li>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">renderer</code> is a Javascript <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D">CanvasRenderingContext2D</a>, and all the methods on it are Javascript method calls directly on the Javascript object</li>
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">renderer</code> is a Javascript <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D">CanvasRenderingContext2D</a>, and all the methods on it are Javascript method calls directly on the Javascript object</li>
<li>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">frame</code> is a Scala <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Int</code>, and obeys Scala semantics, though it is implemented as a Javascript <code class="javascript scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Number</code> under the hood.</li>
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">frame</code> is a Scala <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Int</code>, and obeys Scala semantics, though it is implemented as a Javascript <code class="javascript scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Number</code> under the hood.</li>
<li>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">playerY</code> and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">playerV</code> are Scala <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Double</code>s, implemented directly as Javascript <code class="javascript scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Number</code>s
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">playerY</code> and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">playerV</code> are Scala <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Double</code>s, implemented directly as Javascript <code class="javascript scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Number</code>s
</li></ul>
<p>
This reveals something pretty interesting about Scala.js: even though Scala at-first-glance is a very different language from Javascript, the interoperation with Javascript is so seamless that you can't even tell from the code which values/methods are defined in Scala and which values/methods come from Javascript!</p>
<p>
- These two classes of values/methods are treated very differently by the compiler when it comes to emitting the executable Javascript blob, but the compiler does not need extra syntax telling it which things belong to Scala and which to Javascript: the types are sufficient. <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">renderer</code>, for example is of type <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D">CanvasRenderingContext2D</a> which is a subtype of <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">scalajs.js.Object</code>, indicating to the compiler that it needs special treatment. Primitives like <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Double</code>s and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Int</code>s have similar treatment
+ These two classes of values/methods are treated very differently by the compiler when it comes to emitting the executable Javascript blob, but the compiler does not need extra syntax telling it which things belong to Scala and which to Javascript: the types are sufficient. <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">renderer</code>, for example is of type <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D">CanvasRenderingContext2D</a> which is a subtype of <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">scalajs.js.Object</code>, indicating to the compiler that it needs special treatment. Primitives like <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Double</code>s and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Int</code>s have similar treatment
</p>
<p>
Overall, this seamless mix of Scala and Javascript values/methods/functions is a common theme in Scala.js applications, so you should expect to see more of it in later chapters of the book.
@@ -1042,7 +1092,7 @@ canvas.onclick = (e: dom.MouseEvent) =&gt; {
By this point you've some experience building stand-alone, single-canvas Scala.js applications, which has hopefully given you a feel for how Scala.js works. The problem is that few web applications satisfy the criteria of being stand-alone single-page canvas applications! Most web applications need to deal with the DOM of the HTML page, need to fetch data from web services, and generally need to do a lot of other messy things. We'll go into that in the next chapter</p>
- <div class="header scalatex-header scalatex-hover-container" id="InteractiveWebPages" style="display: block;"><h1 id="InteractiveWebPages">Interactive Web Pages<a class="scalatex-header-link" href="#InteractiveWebPages" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a></h1><br /></div>
+ <div style="margin: 0px;color: #333;text-align: center;padding: 2.5em 2em 0;border-bottom: 1px solid #eee;display: block;" id="InteractiveWebPages" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><h1 style="margin: 0.2em 0;font-size: 3em;font-weight: 300;" id="InteractiveWebPages">Interactive Web Pages<a class=" scalatex-site-Styles-headerLink" href="#InteractiveWebPages" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a></h1><br /></div>
<p>
@@ -1053,14 +1103,14 @@ canvas.onclick = (e: dom.MouseEvent) =&gt; {
</p>
-<h1 id="HelloWorld:HTML" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#HelloWorld:HTML" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Hello World: HTML</h1>
+<h1 id="HelloWorld:HTML" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#HelloWorld:HTML" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Hello World: HTML</h1>
<p>
- The most basic way of building interactive web pages using Scala.js is to use the Javascript APIs to blat HTML strings directly into some container <code class="html scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&lt;div&gt;</code> or <code class="html scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&lt;body&gt;</code>. This approach works, as the following code snippet demonstrates:
+ The most basic way of building interactive web pages using Scala.js is to use the Javascript APIs to blat HTML strings directly into some container <code class="xml scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&lt;div&gt;</code> or <code class="xml scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&lt;body&gt;</code>. This approach works, as the following code snippet demonstrates:
</p>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-13-24">
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">package webpage
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">package webpage
import org.scalajs.dom
import dom.html
import scalajs.js.annotation.JSExport
@@ -1079,38 +1129,38 @@ object HelloWorld0 extends{
&lt;/div&gt;
&quot;&quot;&quot;
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/HelloWorld0.scala#L0-L20" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/HelloWorld0.scala#L0-L20" target="_blank"><i class="fa fa-link "></i></a></pre>
</div>
<div class="pure-u-1 pure-u-md-11-24">
<div id="example4" style="display: block;overflow: scroll;"></div><script>webpage.HelloWorld0().main(document.getElementById('example4'))</script>
</div></div>
<p>
- Remember that we're now requiring a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">html.Div</code> instead of a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">html.Canvas</code> to be passed in when the Javascript calls <code class="javascript scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">webpage.HelloWorld0().main(...)</code>. If you're coming to this point from the previous chapter, you'll need to update the on-page Javascript's <code class="javascript scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">document.getElementById</code> to pick a <code class="html scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&lt;div&gt;</code> rather than the <code class="html scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&lt;canvas&gt;</code> we were using in the previous chapter.
+ Remember that we're now requiring a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">html.Div</code> instead of a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">html.Canvas</code> to be passed in when the Javascript calls <code class="javascript scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">webpage.HelloWorld0().main(...)</code>. If you're coming to this point from the previous chapter, you'll need to update the on-page Javascript's <code class="javascript scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">document.getElementById</code> to pick a <code class="xml scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&lt;div&gt;</code> rather than the <code class="xml scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&lt;canvas&gt;</code> we were using in the previous chapter.
</p>
<p>
This approach works, as the above example shows, but has a couple of disadvantages:
</p>
<ul>
<li>
- It is untyped: it is easy to accidentally mistype something, and result in malformed HTML. A typo such as <code class="html scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&lt;dvi&gt;</code> would go un-noticed at build-time. Depending on where the typo happens, it could go un-noticed until the application is deployed, causing subtle bugs that only get resolved much later.</li>
+ It is untyped: it is easy to accidentally mistype something, and result in malformed HTML. A typo such as <code class="xml scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&lt;dvi&gt;</code> would go un-noticed at build-time. Depending on where the typo happens, it could go un-noticed until the application is deployed, causing subtle bugs that only get resolved much later.</li>
<li>
- It is insecure: <a href="http://en.wikipedia.org/wiki/Cross-site_scripting">Cross-site Scripting</a> is a real thing, and it is easy to forget to escape the values you are putting into your HTML strings. Above they're constants like <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&quot;dog&quot;</code>, but if they're user-defined, you may not notice there is a problem until something like <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&quot;&lt;script&gt;...&lt;/script&gt;&quot;</code> sneaks through and your users' accounts &amp; data is compromised.
+ It is insecure: <a href="http://en.wikipedia.org/wiki/Cross-site_scripting">Cross-site Scripting</a> is a real thing, and it is easy to forget to escape the values you are putting into your HTML strings. Above they're constants like <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&quot;dog&quot;</code>, but if they're user-defined, you may not notice there is a problem until something like <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&quot;&lt;script&gt;...&lt;/script&gt;&quot;</code> sneaks through and your users' accounts &amp; data is compromised.
</li></ul>
<p>
There are more, but we won't go deep into the intricacies of these problems. Suffice to say it makes mistakes easy to make and hard to catch, and we have something better...
</p>
-<h1 id="Scalatags" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Scalatags" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Scalatags</h1>
+<h1 id="Scalatags" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Scalatags" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Scalatags</h1>
<p>
<a href="https://github.com/lihaoyi/scalatags">Scalatags</a> is a cross-platform Scala.js/Scala-JVM library that is designed to generate HTML. To use Scalatags, you need to add it as a dependency to your Scala.js SBT project, in the <code>build.sbt</code> file:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">libraryDependencies += &quot;com.lihaoyi&quot; %%% &quot;scalatags&quot; % &quot;0.4.6&quot;</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/build.sbt#L16-L17" target="_blank"><i class="fa fa-link "></i></a></pre>
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">libraryDependencies += &quot;com.lihaoyi&quot; %%% &quot;scalatags&quot; % &quot;0.4.6&quot;</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/build.sbt#L16-L17" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
With that, the above snippet of code re-written using Scalatags looks as follows:
</p>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-13-24">
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">package webpage
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">package webpage
import org.scalajs.dom
import dom.html
import scalajs.js.annotation.JSExport
@@ -1131,21 +1181,21 @@ object HelloWorld1 extends{
).render
)
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/HelloWorld1.scala#L0-L22" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/HelloWorld1.scala#L0-L22" target="_blank"><i class="fa fa-link "></i></a></pre>
</div>
<div class="pure-u-1 pure-u-md-11-24">
<div id="example5" style="display: block;overflow: scroll;"></div><script>webpage.HelloWorld1().main(document.getElementById('example5'))</script>
</div></div>
<p>
- Scalatags has some nice advantages over plain HTML: it's type-safe, so typos like <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">dvi</code> get caught at compile-time. It's also secure, such that you don't need to worry about script-tags in strings or similar. The <a href="https://github.com/lihaoyi/scalatags#scalatags">Scalatags Readme</a> elaborates on these points and other advantages. As you can see, it takes just 1 import at the top of the file to bring it in scope, and then you can use all of Scalatags' functionality.
+ Scalatags has some nice advantages over plain HTML: it's type-safe, so typos like <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">dvi</code> get caught at compile-time. It's also secure, such that you don't need to worry about script-tags in strings or similar. The <a href="https://github.com/lihaoyi/scalatags#scalatags">Scalatags Readme</a> elaborates on these points and other advantages. As you can see, it takes just 1 import at the top of the file to bring it in scope, and then you can use all of Scalatags' functionality.
</p>
<p>
The Scalatags github page has <a href="https://github.com/lihaoyi/scalatags#hello-world">comprehensive documentation</a> on how to express all manner of HTML fragments using Scalatags, so anyone who's familiar with how HTML works can quickly get up to speed. Instead of a detailed listing, we'll walk through some interactive examples to show Scalatags in action!
</p>
- <h2 id="UserInput" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#UserInput" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>User Input</h2>
+ <h2 id="UserInput" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#UserInput" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>User Input</h2>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-13-24">
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">val box = input(
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">val box = input(
`type`:=&quot;text&quot;,
placeholder:=&quot;Type here!&quot;
).render
@@ -1167,51 +1217,51 @@ target.appendChild(
div(box),
div(output)
).render
-)</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Inputs.scala#L11-L34" target="_blank"><i class="fa fa-link "></i></a></pre>
+)</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Inputs.scala#L11-L34" target="_blank"><i class="fa fa-link "></i></a></pre>
</div>
<div class="pure-u-1 pure-u-md-11-24">
<div style="height: 150px;display: block;overflow: scroll;" id="example6"></div><script>webpage.Inputs().main(document.getElementById('example6'))</script>
</div></div>
<p>
- In Scalatags, you build up fragments of type <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Frag</code> using functions like <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">div</code>, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">h1</code>, etc., and call <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">.render</code> on it to turn it into a real <a href="https://developer.mozilla.org/en-US/docs/Web/API/Element">Element</a>. Different fragments render to different things: e.g. <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">input.render</code> gives you a <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement">html.Input</a>, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">span.render</code> gives you a <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLSpanElement">html.Span</a>. You can then access the properties of these elements: adding callbacks, checking their value, anything you want.
+ In Scalatags, you build up fragments of type <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Frag</code> using functions like <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">div</code>, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">h1</code>, etc., and call <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">.render</code> on it to turn it into a real <a href="https://developer.mozilla.org/en-US/docs/Web/API/Element">Element</a>. Different fragments render to different things: e.g. <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">input.render</code> gives you a <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement">html.Input</a>, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">span.render</code> gives you a <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLSpanElement">html.Span</a>. You can then access the properties of these elements: adding callbacks, checking their value, anything you want.
</p>
<p>
- In this example, we render and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">input</code> element and a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">span</code>, wire up the input to set the value of the span whenever you press a key in the input, and then stuff both of them into a larger HTML fragment that forms the contents of our <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">target</code> element.
+ In this example, we render and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">input</code> element and a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">span</code>, wire up the input to set the value of the span whenever you press a key in the input, and then stuff both of them into a larger HTML fragment that forms the contents of our <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">target</code> element.
</p>
- <h2 id="Re-rendering" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Re-rendering" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Re-rendering</h2>
+ <h2 id="Re-rendering" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Re-rendering" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Re-rendering</h2>
<p>
Let's look at a slightly longer example. While above we spliced small snippets of text into the DOM, here we are going to re-render entire sections of HTML! The goal of this little exercise is to make a filtering search-box: starting from a default list of items, narrow it down as the user enters text into the box.
</p>
<p>
To begin with, let's define our list of items: Fruits!
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">val listings = Seq(
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">val listings = Seq(
&quot;Apple&quot;, &quot;Apricot&quot;, &quot;Banana&quot;, &quot;Cherry&quot;,
&quot;Mango&quot;, &quot;Mangosteen&quot;, &quot;Mandarin&quot;,
&quot;Grape&quot;, &quot;Grapefruit&quot;, &quot;Guava&quot;
-)</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Search0.scala#L11-L17" target="_blank"><i class="fa fa-link "></i></a></pre>
+)</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Search0.scala#L11-L17" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- Next, let's think about how we want to render these fruits. One natural way would be as a list, which in HTML is represented by a <code class="html scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&lt;ul&gt;</code> with <code class="html scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&lt;li&gt;</code>s inside of it if we wanted the list to be unordered. We'll make it a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">def</code>, because we know up-front we're going to need to re-render this listing as the search query changes. Lastly, we know we want 1 list item for each fruit, but only if the fruit starts with the search query.
+ Next, let's think about how we want to render these fruits. One natural way would be as a list, which in HTML is represented by a <code class="xml scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&lt;ul&gt;</code> with <code class="xml scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&lt;li&gt;</code>s inside of it if we wanted the list to be unordered. We'll make it a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">def</code>, because we know up-front we're going to need to re-render this listing as the search query changes. Lastly, we know we want 1 list item for each fruit, but only if the fruit starts with the search query.
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">def renderListings = ul(
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">def renderListings = ul(
for {
fruit &lt;- listings
if fruit.toLowerCase.startsWith(
box.value.toLowerCase
)
} yield li(fruit)
-).render</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Search0.scala#L17-L26" target="_blank"><i class="fa fa-link "></i></a></pre>
+).render</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Search0.scala#L17-L26" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- Using a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">for</code>-loop with a filter inside the Scalatags fragment is just normal Scala, since you can nest arbitrary Scala expressions inside a Scalatags snippet. In this case, we're converting both the fruit and the search query to lower case so we can compare them case-insensitively.
+ Using a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">for</code>-loop with a filter inside the Scalatags fragment is just normal Scala, since you can nest arbitrary Scala expressions inside a Scalatags snippet. In this case, we're converting both the fruit and the search query to lower case so we can compare them case-insensitively.
</p>
<p>
Lastly, we just need to define the input box and output-container (as we did earlier), set the <a href="https://developer.mozilla.org/en-US/docs/Web/Events/onkeyup">onkeyup</a> event handler, and place it in a larger fragment, and then into our target:
</p>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-13-24">
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">val output = div(renderListings).render
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">val output = div(renderListings).render
box.onkeyup = (e: dom.Event) =&gt; {
output.innerHTML = &quot;&quot;
@@ -1228,17 +1278,17 @@ target.appendChild(
div(box),
output
).render
-)</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Search0.scala#L31-L49" target="_blank"><i class="fa fa-link "></i></a></pre>
+)</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Search0.scala#L31-L49" target="_blank"><i class="fa fa-link "></i></a></pre>
</div>
<div class="pure-u-1 pure-u-md-11-24">
<div id="example7" style="display: block;overflow: scroll;"></div><script>webpage.Search0().main(document.getElementById('example7'))</script>
</div></div>
<p>
- And there you have it! A working search box. This is a relatively self-contained example: all the items its searching are available locally, no Ajax calls, and there's no fancy handling of the searched items. If we want to, for example, highlight the matched section of each fruit's name, we can modify the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">def renderListings</code> call to do so:
+ And there you have it! A working search box. This is a relatively self-contained example: all the items its searching are available locally, no Ajax calls, and there's no fancy handling of the searched items. If we want to, for example, highlight the matched section of each fruit's name, we can modify the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">def renderListings</code> call to do so:
</p>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-13-24">
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">def renderListings = ul(
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">def renderListings = ul(
for {
fruit &lt;- listings
if fruit.toLowerCase.startsWith(
@@ -1256,13 +1306,13 @@ target.appendChild(
last
)
}
-).render</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Search1.scala#L16-L37" target="_blank"><i class="fa fa-link "></i></a></pre>
+).render</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Search1.scala#L16-L37" target="_blank"><i class="fa fa-link "></i></a></pre>
</div>
<div class="pure-u-1 pure-u-md-11-24">
<div id="example8" style="display: block;overflow: scroll;"></div><script>webpage.Search1().main(document.getElementById('example8'))</script>
</div></div>
<p>
- Here, instead of sticking the name of the matched fruits directly into the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">li</code>, we instead first split off the part which matches the query, and then highlght the first section yellow. Easy!
+ Here, instead of sticking the name of the matched fruits directly into the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">li</code>, we instead first split off the part which matches the query, and then highlght the first section yellow. Easy!
</p>
<hr />
@@ -1275,20 +1325,20 @@ target.appendChild(
<li>
It's composable! You can easily define fragments and assign them to variables, to be used later. You can break apart large Scalatags fragments the same way you break apart normal code, avoiding the huge monolithic HTML templates that are common in other templating systems.</li>
<li>
- It's Scala! You have the full power of the Scala language to write your fragments. No need to learn special syntax/cases for conditionals or repetitions: you can use plain-old-Scala <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">if</code>-<code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">else</code>s, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">for</code>-loops, etc.
+ It's Scala! You have the full power of the Scala language to write your fragments. No need to learn special syntax/cases for conditionals or repetitions: you can use plain-old-Scala <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">if</code>-<code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">else</code>s, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">for</code>-loops, etc.
</li></ul>
<p>
Now that you've gotten a quick overview of the kinds of things you can do with Scalatags, let's move on to the next section of our hands-on tutorial...
</p>
-<h1 id="UsingWebServices" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#UsingWebServices" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Using Web Services</h1>
+<h1 id="UsingWebServices" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#UsingWebServices" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Using Web Services</h1>
<p>
One half of the web application faces forwards towards the user, managing and rendering HTML or Canvas for the user to view and interact with. Another half faces backwards, talking to various web-services or databases which turn the application from a standalone-widget into part of a greater whole. We've already seen how to make the front half, let's now talk about working with the back half.
</p>
- <h2 id="RawJavascript" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#RawJavascript" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Raw Javascript</h2>
+ <h2 id="RawJavascript" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#RawJavascript" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Raw Javascript</h2>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-13-24">
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">val xhr = new dom.XMLHttpRequest()
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">val xhr = new dom.XMLHttpRequest()
xhr.open(&quot;GET&quot;,
&quot;http://api.openweathermap.org/&quot; +
&quot;data/2.5/weather?q=Singapore&quot;
@@ -1300,19 +1350,19 @@ xhr.onload = (e: dom.Event) =&gt; {
)
}
}
-xhr.send()</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Weather0.scala#L12-L25" target="_blank"><i class="fa fa-link "></i></a></pre>
+xhr.send()</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Weather0.scala#L12-L25" target="_blank"><i class="fa fa-link "></i></a></pre>
</div>
<div class="pure-u-1 pure-u-md-11-24">
<div style="height: 400px;display: block;overflow: scroll;" id="example9"></div><script>webpage.Weather0().main(document.getElementById('example9'))</script></div></div>
<p>
- The above snippet of code uses the raw Javascript Ajax API in order to make a request to <a href="http://openweathermap.org/">openweathermap.org</a>, to get the weather data for the city of Singapore as a JSON blob. The part of the API that we'll be using is documented <a href="http://openweathermap.org/current">here</a>, and if you're interested you can read all about the various options that they provide. For now, we're unceremoniously dumping it in a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">pre</code> so you can see the raw response data.
+ The above snippet of code uses the raw Javascript Ajax API in order to make a request to <a href="http://openweathermap.org/">openweathermap.org</a>, to get the weather data for the city of Singapore as a JSON blob. The part of the API that we'll be using is documented <a href="http://openweathermap.org/current">here</a>, and if you're interested you can read all about the various options that they provide. For now, we're unceremoniously dumping it in a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">pre</code> so you can see the raw response data.
</p>
<p>
As you can see, using the raw Javascript API to make the Ajax call looks almost identical to actually doing this in Javascript, shown below:
</p>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-13-24">
- <pre class="scalatex-hover-container"><code class="javascript scalatex-highlight-js hljs">var xhr = new XMLHttpRequest()
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="javascript scalatex-site-Styles-highlightMe">var xhr = new XMLHttpRequest()
xhr.open(&quot;GET&quot;,
&quot;http://api.openweathermap.org/data/&quot; +
@@ -1326,7 +1376,7 @@ xhr.onload = function (e) {
target.appendChild(pre);
}
};
-xhr.send();</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/resources/webpage/weather.js#L1-L16" target="_blank"><i class="fa fa-link "></i></a></pre>
+xhr.send();</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/resources/webpage/weather.js#L1-L16" target="_blank"><i class="fa fa-link "></i></a></pre>
</div>
<div class="pure-u-1 pure-u-md-11-24">
<div id="example10" style="display: block;overflow: scroll;"></div><script>WeatherJs(document.getElementById('example10'))</script>
@@ -1336,23 +1386,23 @@ xhr.send();</code><a class="scalatex-header-link" style="position: absolute;righ
</p>
<ul>
<li>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">val</code>s for immutable data v.s. mutable <code class="javascript scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">var</code>s.</li>
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">val</code>s for immutable data v.s. mutable <code class="javascript scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">var</code>s.</li>
<li>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">=&gt;</code> v.s. <code class="javascript scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">function</code> to define the callback.</li>
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">=&gt;</code> v.s. <code class="javascript scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">function</code> to define the callback.</li>
<li>
- Scalatags' <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">pre</code> v.s. <code class="javascript scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">document.createElement(&quot;pre&quot;)</code>
+ Scalatags' <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">pre</code> v.s. <code class="javascript scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">document.createElement(&quot;pre&quot;)</code>
</li></ul>
<p>
Overall, they're pretty close, which is a common theme in Scala.js: using Javascript APIs in Scala.js is often as seamless and easy as using them in Javascript itself, and it often looks almost identical.
</p>
- <h2 id="dom.extensions" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#dom.extensions" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>dom.extensions</h2>
+ <h2 id="dom.extensions" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#dom.extensions" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>dom.extensions</h2>
<p>
Although the Javascript XMLHttpRequest API is workable, it's kind of awkward and clunky compared to what you're used to in Scala. We create a half-baked object, set some magic properties, and call a magic function, which all has to be done in the correct order or it won't work.
</p>
<p>
With Scala.js, we provide a simpler API that is more clearly functional. First, you need to import some things into scope:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">import dom.html
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">import dom.html
@JSExport
object Weather1 extends{
@JSExport
@@ -1362,17 +1412,17 @@ object Weather1 extends{
.concurrent
.JSExecutionContext
.Implicits
- .runNow</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Weather1.scala#L7-L19" target="_blank"><i class="fa fa-link "></i></a></pre>
+ .runNow</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Weather1.scala#L7-L19" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- The first import brings in Scala adapters to several DOM APIs, which allow you to use them more idiomatically from Scala. The second brings in an implicit <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">scala.concurrent.ExecutionContext</code> that we'll need to run our asynchronous operations.
+ The first import brings in Scala adapters to several DOM APIs, which allow you to use them more idiomatically from Scala. The second brings in an implicit <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">scala.concurrent.ExecutionContext</code> that we'll need to run our asynchronous operations.
</p>
<p>
Then we need the code itself:
</p>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-13-24">
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">val url =
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">val url =
&quot;http://api.openweathermap.org/&quot; +
&quot;data/2.5/weather?q=Singapore&quot;
@@ -1380,15 +1430,15 @@ Ajax.get(url).onSuccess{ case xhr =&gt;
target.appendChild(
pre(xhr.responseText).render
)
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Weather1.scala#L19-L28" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Weather1.scala#L19-L28" target="_blank"><i class="fa fa-link "></i></a></pre>
</div>
<div class="pure-u-1 pure-u-md-11-24">
<div style="height: 400px;overflow: scroll;display: block;overflow: scroll;" id="example11"></div><script>webpage.Weather1().main(document.getElementById('example11'))</script>
</div></div>
<p>
- A single call to <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Ajax.get(...)</code>, with the URL, and we receive a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">scala.concurrent.Future</code> that we can use to get access to the result when ready. Here we're just using it's <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">onSuccess</code>, but we could use it in a for-comprehension, with <a href="https://github.com/scala/async">Scala Async</a>, or however else we can use normal <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Future</code>s
+ A single call to <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Ajax.get(...)</code>, with the URL, and we receive a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">scala.concurrent.Future</code> that we can use to get access to the result when ready. Here we're just using it's <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">onSuccess</code>, but we could use it in a for-comprehension, with <a href="https://github.com/scala/async">Scala Async</a>, or however else we can use normal <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Future</code>s
</p>
- <h2 id="ParsingtheData" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#ParsingtheData" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Parsing the Data</h2>
+ <h2 id="ParsingtheData" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#ParsingtheData" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Parsing the Data</h2>
<p>
We've taken the data-dump from OpenWeatherMap in three different ways, but there's still something missing: we need to actually parse the JSON data to make use of it! Most people don't use their JSON data as strings but as structured documents, querying and extracting only the bits we need.
</p>
@@ -1397,7 +1447,7 @@ Ajax.get(url).onSuccess{ case xhr =&gt;
</p>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-13-24">
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">Ajax.get(url).onSuccess{ case xhr =&gt;
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">Ajax.get(url).onSuccess{ case xhr =&gt;
target.appendChild(
pre(
js.JSON.stringify(
@@ -1406,20 +1456,20 @@ Ajax.get(url).onSuccess{ case xhr =&gt;
)
).render
)
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Weather2.scala#L24-L34" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Weather2.scala#L24-L34" target="_blank"><i class="fa fa-link "></i></a></pre>
</div>
<div class="pure-u-1 pure-u-md-11-24">
<div style="height: 400px;display: block;overflow: scroll;" id="example12"></div><script>webpage.Weather2().main(document.getElementById('example12'))</script>
</div></div>
<p>
- We do this by taking <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">xhr.responseText</code> and putting it through both <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">JSON.parse</code> and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">JSON.stringify</code>, passing in a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">space</code> argument to tell <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">JSON.stringify</code> to spread it out nicely.
+ We do this by taking <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">xhr.responseText</code> and putting it through both <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">JSON.parse</code> and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">JSON.stringify</code>, passing in a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">space</code> argument to tell <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">JSON.stringify</code> to spread it out nicely.
</p>
<p>
- Now that we've pretty-printed it, we can immediately see what data it contains and which part of the data we want. Let's change the previous example's <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">onSuccess</code> call to extract the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">weather</code>, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">temp</code> and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">humidity</code> and put them in a nice, human-friendly format for us to enjoy:
+ Now that we've pretty-printed it, we can immediately see what data it contains and which part of the data we want. Let's change the previous example's <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">onSuccess</code> call to extract the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">weather</code>, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">temp</code> and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">humidity</code> and put them in a nice, human-friendly format for us to enjoy:
</p>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-13-24">
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">Ajax.get(url).onSuccess{ case xhr =&gt;
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">Ajax.get(url).onSuccess{ case xhr =&gt;
if (xhr.status == 200) {
val json = js.JSON.parse(
xhr.responseText
@@ -1448,22 +1498,22 @@ Ajax.get(url).onSuccess{ case xhr =&gt;
).render
)
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Weather3.scala#L24-L54" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/Weather3.scala#L24-L54" target="_blank"><i class="fa fa-link "></i></a></pre>
</div>
<div class="pure-u-1 pure-u-md-11-24">
<div style="height: 400px;overflow: scroll;display: block;overflow: scroll;" id="example13"></div><script>webpage.Weather3().main(document.getElementById('example13'))</script>
</div></div>
<p>
- First we parse the incoming response, extract a bunch of values from it, and then stick it in a Scalatags fragment for us to see. Note how we can use the names of the attributes e.g. <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">json.name</code> even though <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">name</code> is a dynamic property which you can't be sure exists: this is because <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">json</code> is of type <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">js.Dynamic</code>, which allows us to refer to arbitrary parameters and methods on the underlying object without type-checking.
+ First we parse the incoming response, extract a bunch of values from it, and then stick it in a Scalatags fragment for us to see. Note how we can use the names of the attributes e.g. <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">json.name</code> even though <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">name</code> is a dynamic property which you can't be sure exists: this is because <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">json</code> is of type <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">js.Dynamic</code>, which allows us to refer to arbitrary parameters and methods on the underlying object without type-checking.
</p>
<p>
- Calls on <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">js.Dynamic</code> resolve directly to javascript property/method references, and will fail at run-time with an exception if used wrongly. This is also why we need to call <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">.toString</code> or <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">.asInstanceOf</code>on the values before use: without these casts, the compiler can't be sure what kind of value is underneath the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">js.Dynamic</code> type, and so we have to provide it the guarantee that it is what it needs.
+ Calls on <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">js.Dynamic</code> resolve directly to javascript property/method references, and will fail at run-time with an exception if used wrongly. This is also why we need to call <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">.toString</code> or <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">.asInstanceOf</code>on the values before use: without these casts, the compiler can't be sure what kind of value is underneath the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">js.Dynamic</code> type, and so we have to provide it the guarantee that it is what it needs.
</p>
-<h1 id="Tyingittogether:WeatherSearch" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Tyingittogether:WeatherSearch" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Tying it together: Weather Search</h1>
+<h1 id="Tyingittogether:WeatherSearch" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Tyingittogether:WeatherSearch" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Tying it together: Weather Search</h1>
<p>
At this point we've made a small app that allows us to search from a pre-populated list of words, as well as a small app that lets us query a remote web-service to find the weather in Singapore. The natural thing to do is to put these things together to make a app that will let us search from a list of countries and query the weather in any country we desire. Let's start!
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">lazy val box = input(
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">lazy val box = input(
`type`:=&quot;text&quot;,
placeholder:=&quot;Type here!&quot;
).render
@@ -1488,12 +1538,12 @@ target.appendChild(
p(box),
hr, output, hr
).render
-)</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/WeatherSearch.scala#L15-L42" target="_blank"><i class="fa fa-link "></i></a></pre>
+)</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/WeatherSearch.scala#L15-L42" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- This sets up the basics: an input box, an output div, and sets an <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">onkeyup</code> that fetches the weather data each time you hit a key. It then renders all these components and sticks them into the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">target</code> div. This is basically the same stuff we saw in the early examples, with minor tweaks e.g. adding a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">maxHeight</code> and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">overflowY:=&quot;scroll&quot;</code> to the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">output</code> box in case the output is too large. Whenever we enter something in the box, we call the function <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">fetchWeather</code>, which is defined as:
+ This sets up the basics: an input box, an output div, and sets an <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">onkeyup</code> that fetches the weather data each time you hit a key. It then renders all these components and sticks them into the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">target</code> div. This is basically the same stuff we saw in the early examples, with minor tweaks e.g. adding a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">maxHeight</code> and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">overflowY:=&quot;scroll&quot;</code> to the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">output</code> box in case the output is too large. Whenever we enter something in the box, we call the function <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">fetchWeather</code>, which is defined as:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">def fetchWeather(query: String) = {
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">def fetchWeather(query: String) = {
val searchUrl =
&quot;http://api.openweathermap.org/data/&quot; +
&quot;2.5/find?type=like&amp;mode=json&amp;q=&quot; +
@@ -1509,15 +1559,15 @@ target.appendChild(
case _ =&gt;
output.innerHTML = &quot;No Results&quot;
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/WeatherSearch.scala#L42-L60" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/WeatherSearch.scala#L42-L60" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- This is where the actual data fetching happens. It's relatively straightforward: we make an <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Ajax.get</code> request, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">JSON.parse</code> the response, and feed it into the callback function. We're using a slightly different API from earlier: we now have the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&quot;type=like&quot;</code> flag, which is documented in the <a href="http://openweathermap.org/current#other">OpenWeatherMap API docs</a> to return multiple results for each city whose name matches your query.
+ This is where the actual data fetching happens. It's relatively straightforward: we make an <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Ajax.get</code> request, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">JSON.parse</code> the response, and feed it into the callback function. We're using a slightly different API from earlier: we now have the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&quot;type=like&quot;</code> flag, which is documented in the <a href="http://openweathermap.org/current#other">OpenWeatherMap API docs</a> to return multiple results for each city whose name matches your query.
</p>
<p>
- Notably, before we re-render the results, we check whether the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">query</code> that was passed in is the same value that's in the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">box</code>. This is to prevent a particularly slow ajax call from finishing out-of-order, potentially stomping over the results of more recent searches. We also check whether the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">.list: js.Dynamic</code> property we want is an instance of <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">js.Array</code>: if it isn't, it means we don't have any results to show, and we can skip the whole render-output step.
+ Notably, before we re-render the results, we check whether the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">query</code> that was passed in is the same value that's in the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">box</code>. This is to prevent a particularly slow ajax call from finishing out-of-order, potentially stomping over the results of more recent searches. We also check whether the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">.list: js.Dynamic</code> property we want is an instance of <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">js.Array</code>: if it isn't, it means we don't have any results to show, and we can skip the whole render-output step.
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">def showResults(jsonlist: js.Array[js.Dynamic], query: String) = {
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">def showResults(jsonlist: js.Array[js.Dynamic], query: String) = {
for (json &lt;- jsonlist) {
val name = json.name.toString
val country = json.sys.country.toString
@@ -1543,17 +1593,17 @@ target.appendChild(
)
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/WeatherSearch.scala#L60-L89" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/webpage/WeatherSearch.scala#L60-L89" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- Here is the meat and potatoes of this program: every time it gets called with an array of weather-data, we iterate over the cities in that array. It then does a similar sort of data-extraction that we did earlier, putting the results into the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">output</code> div we defined above, including highlighting.
+ Here is the meat and potatoes of this program: every time it gets called with an array of weather-data, we iterate over the cities in that array. It then does a similar sort of data-extraction that we did earlier, putting the results into the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">output</code> div we defined above, including highlighting.
</p>
<div id="example14" style="display: block;overflow: scroll;"></div><script>webpage.WeatherSearch().main(document.getElementById('example14'))</script>
<p>
And that's the working example! Try searching for cities like &quot;Singapore&quot; or &quot;New York&quot; or &quot;San Francisco&quot; and watch as the search narrows as you enter more characters into the text box. Note that the OpenWeatherMap API limits ambiguous searches to about a dozen results, so if a city doesn't turn up in a partial-search, try entering more characters to narrow it down.
</p>
-<h1 id="InteractiveWebPagesRecap" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#InteractiveWebPagesRecap" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Interactive Web Pages Recap</h1>
+<h1 id="InteractiveWebPagesRecap" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#InteractiveWebPagesRecap" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Interactive Web Pages Recap</h1>
<p>
In this chapter, we've explored the basics of how you can use Scala.js to build interactive web pages. The two main contributions are using Scalatags to render HTML in a concise, safe way, and making Ajax calls to external web services. We combined these two capabilities in a small weather-search app that let a user interactively search for the weather in different cities around the world.</p>
<p>
@@ -1563,15 +1613,15 @@ target.appendChild(
<li>
Using Scalatags to render HTML fragments, and managing them at runtime with callbacks and getting/setting properties, is really quite nice</li>
<li>
- Using <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">new dom.XMLHttpRequest</code> to make web requests feels just like the Javascript code to do so</li>
+ Using <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">new dom.XMLHttpRequest</code> to make web requests feels just like the Javascript code to do so</li>
<li>
- Using <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Ajax.get(...)</code> and working with the resultant : <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Future</code> feels a lot cleaner than directly using the Javascript API
+ Using <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Ajax.get(...)</code> and working with the resultant : <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Future</code> feels a lot cleaner than directly using the Javascript API
</li></ul>
<p>
You're at this point reasonably pro</p>
- <div class="header scalatex-header scalatex-hover-container" id="TheCommandLine" style="display: block;"><h1 id="TheCommandLine">The Command Line<a class="scalatex-header-link" href="#TheCommandLine" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a></h1><br /></div>
+ <div style="margin: 0px;color: #333;text-align: center;padding: 2.5em 2em 0;border-bottom: 1px solid #eee;display: block;" id="TheCommandLine" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><h1 style="margin: 0.2em 0;font-size: 3em;font-weight: 300;" id="TheCommandLine">The Command Line<a class=" scalatex-site-Styles-headerLink" href="#TheCommandLine" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a></h1><br /></div>
<p>
@@ -1603,22 +1653,22 @@ target.appendChild(
<p>
Now, let's open up your SBT console in your Scala.js app
</p>
-<pre><code class="bash scalatex-highlight-js">&gt;
+<pre><code class="bash scalatex-site-Styles-highlightMe">&gt;
</code></pre>
<p>
And let's get started!
</p>
-<h1 id="Commands" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Commands" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Commands</h1>
+<h1 id="Commands" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Commands" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Commands</h1>
<p>
The most fundamental thing you can do in the Scala.js CLI is to compile your code. Let's go through the various mechanisms of &quot;compiling&quot; things:
</p>
- <h2 id="ThecompileCommand" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#ThecompileCommand" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>The compile Command</h2>
- <pre><code class="bash scalatex-highlight-js">&gt; compile
+ <h2 id="ThecompileCommand" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#ThecompileCommand" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>The compile Command</h2>
+ <pre><code class="bash scalatex-site-Styles-highlightMe">&gt; compile
</code></pre>
<p>
Just as you can <code>compile</code> Scala-JVM projects, you can also <code>compile</code> Scala.js projects. Like compiling Scala-JVM projects, this leaves a bunch of <code>.class</code> files in your <code>target</code> directory. Unlike Scala-JVM projects, this also leaves a bunch of <code>.sjsir</code> files, which correspond to your Scala.js output files:
</p>
- <pre><code class="bash scalatex-highlight-js">classes
+ <pre><code class="bash scalatex-site-Styles-highlightMe">classes
└── example
├── Point$.class
├── Point$.sjsir
@@ -1633,12 +1683,12 @@ target.appendChild(
<p>
However, unlike on Scala-JVM, you cannot directly run the <code>.sjsir</code> files spat out by the Scala.js compiler. These files are an Intermediate Representation, which needs to go through the next step in the compilation pipeline before being turned into Javascript.
</p>
- <h2 id="ThepackageCommand" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#ThepackageCommand" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>The package Command</h2>
- <pre><code class="bash scalatex-highlight-js">&gt; package</code></pre>
+ <h2 id="ThepackageCommand" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#ThepackageCommand" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>The package Command</h2>
+ <pre><code class="bash scalatex-site-Styles-highlightMe">&gt; package</code></pre>
<p>
Also like on Scala-JVM, Scala.js also supports the <code>package</code> command. This command generates a <code>.jar</code> like it does in Scala-JVM, except this version appends this weird <code>_sjs0.6</code> suffix.
</p>
- <pre><code class="bash scalatex-highlight-js">target/scala-2.11/
+ <pre><code class="bash scalatex-site-Styles-highlightMe">target/scala-2.11/
└── example_sjs0.6_2.11-0.1-SNAPSHOT.jar
</code></pre>
<p>
@@ -1647,27 +1697,27 @@ target.appendChild(
<p>
Again, unlike Scala-JVM, these <code>.jar</code> files are not directly executable: the <code>.sjsir</code> files need further processing to turn into runnable Javascript. Instead, their sole purpose is to hold bundles of <code>.sjsir</code> files to be published and depended-upon: they can be <code>publishLocal</code>ed to be used by other projects on your computer, or <code>publishSigned</code>ed to <a href="http://search.maven.org/">Maven Central</a>, just like any Scala-JVM project.
</p>
- <h2 id="ThefastOptJSCommand" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#ThefastOptJSCommand" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>The fastOptJS Command</h2>
- <pre><code class="bash scalatex-highlight-js">&gt; fastOptJS</code></pre>
+ <h2 id="ThefastOptJSCommand" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#ThefastOptJSCommand" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>The fastOptJS Command</h2>
+ <pre><code class="bash scalatex-site-Styles-highlightMe">&gt; fastOptJS</code></pre>
<p>
- <code>fastOptJS</code> is a command we've used in earlier chapters. It basically runs the <a href="#FastOptimization">Fast Optimization</a> stage of the compilation pipeline. This results in a moderately-sized executable, which you can then load in the browser with a <code class="html scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&lt;script&gt;</code> tag and run.
+ <code>fastOptJS</code> is a command we've used in earlier chapters. It basically runs the <a href="#FastOptimization">Fast Optimization</a> stage of the compilation pipeline. This results in a moderately-sized executable, which you can then load in the browser with a <code class="xml scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&lt;script&gt;</code> tag and run.
</p>
<p>
This is the first phase which actually results in an executable blob of Javascript. I won't go into much detail about this command: you've used it before, and more details about the particular kind of optimization and how it fits into the large process is available in the chapter on The Compilation Pipeline. Nonetheless, it's fast, produces not-too-huge output code, and is what you typically use for iterative development in the browser.
</p>
- <h2 id="ThefullOptJSCommand" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#ThefullOptJSCommand" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>The fullOptJS Command</h2>
- <pre><code class="bash scalatex-highlight-js">&gt; fullOptJS</code></pre>
+ <h2 id="ThefullOptJSCommand" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#ThefullOptJSCommand" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>The fullOptJS Command</h2>
+ <pre><code class="bash scalatex-site-Styles-highlightMe">&gt; fullOptJS</code></pre>
<p>
- <code>fullOptJS</code> is another command that we've seen before: it performs an aggressive, somewhat slower <a href="#FullOptimization">Full Optimization</a> pass on the generated Javascript. This results in a much smaller executable Javascript blob, which you can also load via a <code class="html scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&lt;script&gt;</code> tag and run.</p>
+ <code>fullOptJS</code> is another command that we've seen before: it performs an aggressive, somewhat slower <a href="#FullOptimization">Full Optimization</a> pass on the generated Javascript. This results in a much smaller executable Javascript blob, which you can also load via a <code class="xml scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&lt;script&gt;</code> tag and run.</p>
<p>
Again, I won't go into much details, as exactly what this optimization does is described in the chapter on the Compilation Pipeline. This command is somewhat too-slow to be running during iterative development, and is instead typically used just before deployment to minimize the size of the file your users have to download.
</p>
- <h2 id="TherunCommand" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#TherunCommand" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>The run Command</h2>
- <pre><code class="bash scalatex-highlight-js">&gt; run</code></pre>
+ <h2 id="TherunCommand" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#TherunCommand" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>The run Command</h2>
+ <pre><code class="bash scalatex-site-Styles-highlightMe">&gt; run</code></pre>
<p>
- Here's something you haven't seen before: the <code>run</code> command gives you the ability to run a Scala.js program from the command line. This prints its output to standard output (i.e. the terminal). Like Scala-JVM, you need a <code>main</code> method to run to kick off your program. Unlike Scala-JVM, the main method is marked on an <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">object</code> which <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">extends scala.scalajs.js.JSApp</code>, e.g.
+ Here's something you haven't seen before: the <code>run</code> command gives you the ability to run a Scala.js program from the command line. This prints its output to standard output (i.e. the terminal). Like Scala-JVM, you need a <code>main</code> method to run to kick off your program. Unlike Scala-JVM, the main method is marked on an <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">object</code> which <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">extends scala.scalajs.js.JSApp</code>, e.g.
</p>
- <pre><code class="scala scalatex-highlight-js">// src/main/scala/RunMe.scala
+ <pre><code class="scala scalatex-site-Styles-highlightMe">// src/main/scala/RunMe.scala
object RunMe extends scala.scalajs.js.JSApp{
def main(): Unit = {
println(&quot;Hello World!&quot;)
@@ -1678,22 +1728,22 @@ object RunMe extends scala.scalajs.js.JSApp{
<p>
Running <code>sbt run</code> with the above Scala.js code will print out
</p>
- <pre><code class="bash scalatex-highlight-js">Hello World!
+ <pre><code class="bash scalatex-site-Styles-highlightMe">Hello World!
In Scala.js, (1.0).toString is 1!
</code></pre>
<p>
- This exhibits the weirdness of <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Double.toString</code> in Scala.js, which is one of the few ways in which <a href="#DeviationsfromScala-JVM">Scala.js deviates from Scala-JVM</a>. This also shows us we're really running on Scala.js: on Scala-JVM, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">(1.0).toString</code> returns <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&quot;1.0&quot;</code> rather than <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&quot;1&quot;</code>!
+ This exhibits the weirdness of <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Double.toString</code> in Scala.js, which is one of the few ways in which <a href="#DeviationsfromScala-JVM">Scala.js deviates from Scala-JVM</a>. This also shows us we're really running on Scala.js: on Scala-JVM, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">(1.0).toString</code> returns <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&quot;1.0&quot;</code> rather than <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&quot;1&quot;</code>!
</p>
<p>
One thing you may be wondering is: when you run a Scala.js program in the terminal, how does it execute the output Javascript? What about the DOM? and Ajax calls? Can it access the filesystem? The answer to all these questions is &quot;it depends&quot;: it turns out there are multiple ways you can run Scala.js from the command-line, dictated by the <i>stage</i> and the <i>environment</i>.
</p>
<p>
- By default, runs are done in the <code>PreLinkStage</code>, which uses the Rhino environment. With the sbt setting <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">jsDependencies += RuntimeDOM</code>, the Scala.js runner will automatically set up <b>env.js</b> in Rhino so that you have access to an emulation of the DOM API.
+ By default, runs are done in the <code>PreLinkStage</code>, which uses the Rhino environment. With the sbt setting <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">jsDependencies += RuntimeDOM</code>, the Scala.js runner will automatically set up <b>env.js</b> in Rhino so that you have access to an emulation of the DOM API.
</p>
<p>
You can enable a different stage, <code>FastOptStage</code> or <code>FullOptStage</code>, with the following sbt command:
</p>
- <pre><code class="bash scalatex-highlight-js">&gt; set scalaJSStage in Global := FastOptStage
+ <pre><code class="bash scalatex-site-Styles-highlightMe">&gt; set scalaJSStage in Global := FastOptStage
</code></pre>
<p>
In <code>FastOptStage</code> and <code>FullOptStage</code>, the environment can be one of <b>Node.js</b> or <b>PhantomJS</b>. These JavaScript VMs must be installed separately.
@@ -1702,13 +1752,13 @@ In Scala.js, (1.0).toString is 1!
<li>
By default, Node.js is used.</li>
<li>
- With the sbt setting <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">jsDependencies += RuntimeDOM</code>, PhantomJS is used instead, so that a headless DOM is available.
+ With the sbt setting <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">jsDependencies += RuntimeDOM</code>, PhantomJS is used instead, so that a headless DOM is available.
</li></ul>
<p>
Typically, the best way to get started is using Rhino, since it's setup-free, and setting up Node.js or PhantomJS later as necessary. The next two sections elaborate on the differences between these ways of running your code. Check out the later sections on <a href="#HeadlessRuntimes">Headless Runtimes</a> and <a href="#Stages">Stages</a> to learn more about the other settings and why you would want to use them.
</p>
- <h2 id="ThetestCommand" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#ThetestCommand" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>The test Command</h2>
- <pre><code class="bash scalatex-highlight-js">&gt; test
+ <h2 id="ThetestCommand" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#ThetestCommand" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>The test Command</h2>
+ <pre><code class="bash scalatex-site-Styles-highlightMe">&gt; test
</code></pre>
<p>
The <code>sbt test</code> command behaves very similarly to <code>sbt run</code>. It also runs on Rhino, Node.js or PhantomJS, dependending of the stage and the dependency on the DOM.</p>
@@ -1717,18 +1767,18 @@ In Scala.js, (1.0).toString is 1!
<p>
We won't spend much time talking about <code>sbt test</code> here. Not because it's not important: it most certainly is! Rather, we will be spending a good amount of time setting up tests in <a href="#CrossPublishingLibraries">the next chapter</a>, so feel free to jump ahead if you want to see an example usage of <code>sbt test</code>.
</p>
-<h1 id="HeadlessRuntimes" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#HeadlessRuntimes" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Headless Runtimes</h1>
+<h1 id="HeadlessRuntimes" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#HeadlessRuntimes" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Headless Runtimes</h1>
<ul>
<li>
<a href="https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino">Rhino</a> is the default way of running Scala.js applications. The upside of using Rhino is that it is pure-Java, and doesn't need any additional binaries or installation. The downside of using Rhino is that it is slow: maybe a hundred times slower than the alternatives, making it not suitable for running long-running, compute-intensive programs.</li>
<li>
<a href="http://nodejs.org/">Node.js</a>, a relatively new Javascript runtime based on Google's V8 Javascript engine, Node.js lets you run your Scala.js application from the command line much faster than in Rhino, with performance that matches that of modern browsers. However, you need to separately <a href="http://nodejs.org/download/">install Node.js</a> in order to use it. Node.js does not have DOM or browser-related functionality. You need to set the stage with <code>set scalaJSStage in Global := FastOptStage</code> to run using Node.js.</li>
<li>
- <a href="http://phantomjs.org/">PhantomJS</a> is a headless Webkit browser. This means that unlike Node.js, PhantomJS provides you with a full DOM and all its APIs to use in your tests, if you wish to e.g. test interactions with the HTML of the web page. On the other hand, it is somewhat slower than Node.js, though still much faster than Rhino. Like Node.js, it needs to be installed separately. You need to set the stage with <code>set scalaJSStage in Global := FastOptStage</code>, as well as setting the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">jsDependencies += RuntimeDOM</code> flag in your SBT configuration, to use PhantomJS.</li></ul>
+ <a href="http://phantomjs.org/">PhantomJS</a> is a headless Webkit browser. This means that unlike Node.js, PhantomJS provides you with a full DOM and all its APIs to use in your tests, if you wish to e.g. test interactions with the HTML of the web page. On the other hand, it is somewhat slower than Node.js, though still much faster than Rhino. Like Node.js, it needs to be installed separately. You need to set the stage with <code>set scalaJSStage in Global := FastOptStage</code>, as well as setting the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">jsDependencies += RuntimeDOM</code> flag in your SBT configuration, to use PhantomJS.</li></ul>
<p>
These are your three options to run your Scala.js code via the command-line. Generally, it's easiest to get started with Rhino since it's the default and requires no setup, though you will quickly find it worthwhile to setup Node.js or PhantomJS to speed up your runs and tests.
</p>
-<h1 id="Stages" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Stages" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Stages</h1>
+<h1 id="Stages" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Stages" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Stages</h1>
<p>
Let us recap the three different stages of execution, and what they mean.
</p>
@@ -1745,7 +1795,7 @@ In Scala.js, (1.0).toString is 1!
<p>
Hopefully by this point you more-or-less know your way around the Scala.js command-line tools. As mentioned earlier, command line tools make it much easier to run a bunch of Scala.js code, e.g. unit tests, without having to muck around with HTML pages or refreshing the browser. That will come in handy soon, as we're next going to learn to publish a standalone, distributable Scala.js module. And what's a module without tests...</p>
- <div class="header scalatex-header scalatex-hover-container" id="CrossPublishingLibraries" style="display: block;"><h1 id="CrossPublishingLibraries">Cross Publishing Libraries<a class="scalatex-header-link" href="#CrossPublishingLibraries" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a></h1><br /></div>
+ <div style="margin: 0px;color: #333;text-align: center;padding: 2.5em 2em 0;border-bottom: 1px solid #eee;display: block;" id="CrossPublishingLibraries" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><h1 style="margin: 0.2em 0;font-size: 3em;font-weight: 300;" id="CrossPublishingLibraries">Cross Publishing Libraries<a class=" scalatex-site-Styles-headerLink" href="#CrossPublishingLibraries" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a></h1><br /></div>
<p>
We've spent several chapters exploring the experience of making web apps using Scala.js, but any large application (web or not!) likely relies on a host of libraries in order to implement large chunks of its functionality. Ideally these libraries would be re-usable, and can be shared among different projects, teams or even companies.
@@ -1754,12 +1804,12 @@ In Scala.js, (1.0).toString is 1!
Not all code is developed in the browser. Maybe you want to run simple snippets of Scala.js which don't interact with the browser at all, and having to keep a browser open is an overkill. Maybe you want to write unit tests for your browser-destined code, so you can verify that it works without firing up Chrome. Maybe it's not a simple script but a re-distributable library, and you want to run the same command-line unit tests on both Scala.js and Scala-JVM to verify that the behavior is identical. This chapter will go through all these cases.
</p>
-<h1 id="ASimpleCross-BuiltLibrary" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#ASimpleCross-BuiltLibrary" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>A Simple Cross-Built Library</h1>
+<h1 id="ASimpleCross-BuiltLibrary" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#ASimpleCross-BuiltLibrary" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>A Simple Cross-Built Library</h1>
<p>
As always, we will start with an example: in this case a toy library whose sole purpose in life is to take a series of timestamps (milliseconds UTC) and format them into a single, newline-delimited string. This is what the project layout looks like:
</p>
- <pre><code class="bash scalatex-highlight-js">$ tree
+ <pre><code class="bash scalatex-site-Styles-highlightMe">$ tree
.
├── build.sbt
├── project/build.sbt
@@ -1771,17 +1821,17 @@ In Scala.js, (1.0).toString is 1!
<p>
As you can see, we have three main places where code lives: <code>js/</code> is where Scala-JS specific code lives, <code>jvm/</code> for Scala-JVM specific code, and <code>shared/</code> for code that is common between both platforms. Depending on your project, you may have more or less code in the <code>shared/</code> folder: a mostly-the-same cross-compiled module may have most or all its code in <code>shared/</code> while a <a href="#IntegratingClient-Server">client-server web application</a> would have lots of client/server js/jvm-specific code.
</p>
- <h2 id="BuildConfiguration" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#BuildConfiguration" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Build Configuration</h2>
+ <h2 id="BuildConfiguration" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#BuildConfiguration" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Build Configuration</h2>
<p>
From the bash shell in the project root. Let's take a look at the various files that make up this project. First, the <code>build.sbt</code> files:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">/*project/build.sbt*/
-addSbtPlugin(&quot;org.scala-js&quot; % &quot;sbt-scalajs&quot; % &quot;0.6.0&quot;)</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/simple/project/build.sbt#L0-L2" target="_blank"><i class="fa fa-link "></i></a></pre>
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">/*project/build.sbt*/
+addSbtPlugin(&quot;org.scala-js&quot; % &quot;sbt-scalajs&quot; % &quot;0.6.0&quot;)</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/simple/project/build.sbt#L0-L2" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
The <code>project/build.sbt</code> file is uneventful: it simply includes the Scala.js SBT plugin. However, the <code>build.sbt</code> file is a bit more interesting:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">
val library = crossProject.settings(
libraryDependencies += &quot;com.lihaoyi&quot; %%% &quot;utest&quot; % &quot;0.3.0&quot;,
testFrameworks += new TestFramework(&quot;utest.runner.Framework&quot;)
@@ -1793,33 +1843,33 @@ val library = crossProject.settings(
lazy val js = library.js
-lazy val jvm = library.jvm</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/simple/build.sbt#L0-L13" target="_blank"><i class="fa fa-link "></i></a></pre>
+lazy val jvm = library.jvm</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/simple/build.sbt#L0-L13" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- Unlike the equivalent <code>build.sbt</code> files you saw in earlier chapters, this does not simply enable the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">ScalaJSPlugin</code> to the root project. Rather, it uses the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">crossProject</code> function provided by the Scala.js plugin to set up two projects: one in the <code>app/js/</code> folder and one in the <code>jvm/</code> folder. We also have places to put settings related to either the JS side, the JVM side, or both. In this case, we add a dependency on <a href="https://github.com/lihaoyi/utest">uTest</a>, which we will use as the test framework for our library. Note how we use triple <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">%%%</code> to indicate that we're using the platform-specific version of uTest, such that the Scala.js or Scala-JVM version will be properly pulled in when compiling for each platform.
+ Unlike the equivalent <code>build.sbt</code> files you saw in earlier chapters, this does not simply enable the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">ScalaJSPlugin</code> to the root project. Rather, it uses the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">crossProject</code> function provided by the Scala.js plugin to set up two projects: one in the <code>app/js/</code> folder and one in the <code>jvm/</code> folder. We also have places to put settings related to either the JS side, the JVM side, or both. In this case, we add a dependency on <a href="https://github.com/lihaoyi/utest">uTest</a>, which we will use as the test framework for our library. Note how we use triple <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">%%%</code> to indicate that we're using the platform-specific version of uTest, such that the Scala.js or Scala-JVM version will be properly pulled in when compiling for each platform.
</p>
- <h2 id="SourceFiles" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#SourceFiles" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Source Files</h2>
+ <h2 id="SourceFiles" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#SourceFiles" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Source Files</h2>
<p>
Now, let's look at the contents of the <code>.scala</code> files that make up the meat of this project:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">// library/shared/src/main/scala/simple/Simple.scala
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">// library/shared/src/main/scala/simple/Simple.scala
package simple
object Simple{
def formatTimes(timestamps: Seq[Long]): Seq[String] = {
timestamps.map(Platform.format).map(_.dropRight(5))
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/simple/library/shared/src/main/scala/simple/Simple.scala#L0-L7" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/simple/library/shared/src/main/scala/simple/Simple.scala#L0-L7" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- In <code>Simple.scala</code> we have the shared, cross-platform API of our library: a single <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">object</code> with a single method <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">def</code> which does what we want, which can then be used in either Scala.js or Scala-JVM. In general, you can put as much shared logic here as you want: classes, objects, methods, anything that can run on both Javascript and on the JVM. We're chopping off the last 5 characters (the milliseconds) to keep the formatted dates slightly less verbose.
+ In <code>Simple.scala</code> we have the shared, cross-platform API of our library: a single <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">object</code> with a single method <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">def</code> which does what we want, which can then be used in either Scala.js or Scala-JVM. In general, you can put as much shared logic here as you want: classes, objects, methods, anything that can run on both Javascript and on the JVM. We're chopping off the last 5 characters (the milliseconds) to keep the formatted dates slightly less verbose.
</p>
<p>
- However, when it comes to actually formatting the date, we have a problem: Javascript and Java provide different utilities for formatting dates! They both let you format them, but they provide different APIs. Thus, to do the formatting of each individual date, we call out to the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Platform.format</code> function, which is implemented twice: once in <code>js/</code> and once in <code>jvm/</code>:
+ However, when it comes to actually formatting the date, we have a problem: Javascript and Java provide different utilities for formatting dates! They both let you format them, but they provide different APIs. Thus, to do the formatting of each individual date, we call out to the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Platform.format</code> function, which is implemented twice: once in <code>js/</code> and once in <code>jvm/</code>:
</p>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-1-2">
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">// library/js/src/main/scala/simple/Platform.scala
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">// library/js/src/main/scala/simple/Platform.scala
package simple
import scalajs.js
@@ -1827,10 +1877,10 @@ object Platform{
def format(ts: Long) = {
new js.Date(ts).toISOString()
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/simple/library/js/src/main/scala/simple/Platform.scala#L0-L9" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/simple/library/js/src/main/scala/simple/Platform.scala#L0-L9" target="_blank"><i class="fa fa-link "></i></a></pre>
</div>
<div class="pure-u-1 pure-u-md-1-2">
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">// library/jvm/src/main/scala/simple/Platform.scala
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">// library/jvm/src/main/scala/simple/Platform.scala
package simple
import java.text.SimpleDateFormat
import java.util.TimeZone
@@ -1843,16 +1893,16 @@ object Platform{
fmt.setTimeZone(TimeZone.getTimeZone(&quot;UTC&quot;))
fmt.format(new java.util.Date(ts))
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/simple/library/jvm/src/main/scala/simple/Platform.scala#L0-L14" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/simple/library/jvm/src/main/scala/simple/Platform.scala#L0-L14" target="_blank"><i class="fa fa-link "></i></a></pre>
</div></div>
<p>
- In the <code>js/</code> version, we are using the Javascript <code class="javascript scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Date</code> object to take the millis and do what we want. In the <code>jvm/</code> version, we instead use <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">java.text.SimpleDateFormat</code> with a custom formatter (The syntax is defined <a href="http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html">here</a>).
+ In the <code>js/</code> version, we are using the Javascript <code class="javascript scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Date</code> object to take the millis and do what we want. In the <code>jvm/</code> version, we instead use <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">java.text.SimpleDateFormat</code> with a custom formatter (The syntax is defined <a href="http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html">here</a>).
</p>
<p>
Again, you can put as much platform-specific logic in these files as you want, to account for differences in the available APIs. Maybe you want to use <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse">Json.parse</a> for parsing JSON blobs in <code>js/</code>, but <a href="http://jackson.codehaus.org/">Jackson</a> or <a href="https://code.google.com/p/google-gson/">GSON</a> for parsing them in <code>jvm/</code>.
</p>
- <h2 id="RunningtheModule" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#RunningtheModule" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Running the Module</h2>
- <pre><code class="bash scalatex-highlight-js">&gt; ;libraryJS/test ;libraryJVM/test
+ <h2 id="RunningtheModule" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#RunningtheModule" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Running the Module</h2>
+ <pre><code class="bash scalatex-site-Styles-highlightMe">&gt; ;libraryJS/test ;libraryJVM/test
[info] Compiling 1 Scala source to library/js/target/scala-2.10/test-classes...
[info] ---------------------------Results---------------------------
[info] simple.SimpleTest Success
@@ -1900,7 +1950,7 @@ object Platform{
<p>
Apart from running each sub-project manually as we did above, you can also simply hit <code>test</code> and SBT will run tests for both
</p>
-<h1 id="FurtherWork" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#FurtherWork" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Further Work</h1>
+<h1 id="FurtherWork" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#FurtherWork" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Further Work</h1>
<p>
You've by this point set up a basic cross-building Scala.js/Scala-JVM project! If you wish, you can do more things with this project you've set up:
</p>
@@ -1910,12 +1960,12 @@ object Platform{
<li>
Publish it! Both <code>sbt publishLocal</code> and <code>sbt publishSigned</code> work on this module, for publishing either locally, Maven Central via Sonatype, or Bintray. Running the command bare should be sufficient to publish both the <code>js</code> or <code>jvm</code> projects, or you can also specify which one e.g. <code>jvm/publishLocal</code> to publish only one subproject.</li>
<li>
- Cross-cross build it! You can use <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">crossScalaVersions</code> in your <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">crossProject</code> to build a library that works across all of {Scala.js, Scala-JVM} X {2.10, 2.11}. Many existing libraries, such as <a href="https://github.com/lihaoyi/scalatags">Scalatags</a> or <a href="https://github.com/lihaoyi/utest">uTest</a> are published like that.
+ Cross-cross build it! You can use <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">crossScalaVersions</code> in your <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">crossProject</code> to build a library that works across all of {Scala.js, Scala-JVM} X {2.10, 2.11}. Many existing libraries, such as <a href="https://github.com/lihaoyi/scalatags">Scalatags</a> or <a href="https://github.com/lihaoyi/utest">uTest</a> are published like that.
</li></ul>
<p>
Now that you've gotten your code cross-compiling to Scala.js/Scala-JVM, the sky's the limit in what you can do. In general, although a large amount of your Scala-JVM code <i>does</i> deal with files or networks or other Scala-JVM-speciic functionality, in most applications there is a large library of helpers which don't. These could easily be packaged up into a cross-platform library and shared with your front-end Scala.js (or even pure-Javascript!) code.
</p>
-<h1 id="OtherTestingLibraries" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#OtherTestingLibraries" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Other Testing Libraries</h1>
+<h1 id="OtherTestingLibraries" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#OtherTestingLibraries" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Other Testing Libraries</h1>
<p>
You can also try using a different testing library. While uTest was the first Scala.js testing library, it is definitely not the last! Here are a few alternatives worth trying:
</p>
@@ -1936,7 +1986,7 @@ object Platform{
Note that you cannot use <a href="http://www.scalatest.org/">Scalatest</a> or <a href="http://etorreborre.github.io/specs2">Specs2</a> in Scala.js. Despite the popularity of those libraries, they depend on too many Java-specific details of Scala-JVM to be easily ported to Scala.js. Thus you'll have to use one of the (relatively new) libraries which supports Scala.js, such as uTest or those above.</p>
- <div class="header scalatex-header scalatex-hover-container" id="IntegratingClient-Server" style="display: block;"><h1 id="IntegratingClient-Server">Integrating Client-Server<a class="scalatex-header-link" href="#IntegratingClient-Server" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a></h1><br /></div>
+ <div style="margin: 0px;color: #333;text-align: center;padding: 2.5em 2em 0;border-bottom: 1px solid #eee;display: block;" id="IntegratingClient-Server" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><h1 style="margin: 0.2em 0;font-size: 3em;font-weight: 300;" id="IntegratingClient-Server">Integrating Client-Server<a class=" scalatex-site-Styles-headerLink" href="#IntegratingClient-Server" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a></h1><br /></div>
@@ -1956,11 +2006,11 @@ object Platform{
</p>
-<h1 id="AClient-ServerSetup" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#AClient-ServerSetup" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>A Client-Server Setup</h1>
+<h1 id="AClient-ServerSetup" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#AClient-ServerSetup" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>A Client-Server Setup</h1>
<p>
Getting started with client-server integration, let's go with the simplest configuration possible: a Spray server and a Scala.js client. Most of the other web-frameworks (<a href="https://www.playframework.com/">Play</a>, <a href="http://www.scalatra.org/">Scalatra</a>, etc.) will have more complex configurations, but the basic mechanism of wiring up Scala.js to your web framework will be the same. Just like our project in <a href="#CrossPublishingLibraries">Cross Publishing Libraries</a>, our project will look like this:
</p>
- <pre><code class="bash scalatex-highlight-js">$ tree
+ <pre><code class="bash scalatex-site-Styles-highlightMe">$ tree
.
├── build.sbt
├── project/build.sbt
@@ -1974,7 +2024,7 @@ object Platform{
<p>
First, let's do the wiring in <code>build.sbt</code>:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">import NativePackagerKeys._
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">import NativePackagerKeys._
val app = crossProject.settings(
unmanagedSourceDirectories in Compile +=
@@ -1999,10 +2049,10 @@ val app = crossProject.settings(
lazy val appJS = app.js
lazy val appJVM = app.jvm.settings(
(resources in Compile) += (fastOptJS in (appJS, Compile)).value.data
-)</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/build.sbt#L0-L26" target="_blank"><i class="fa fa-link "></i></a></pre>
+)</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/build.sbt#L0-L27" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- Again, we are using <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">crossProject</code> to define our <code>js/</code> and <code>jvm/</code> sub-projects. Both projects share a number of settings: the settings to add <a href="https://github.com/lihaoyi/scalatags">Scalatags</a> and <a href="https://github.com/lihaoyi/upickle">uPickle</a> to the build. Note that those two dependencies use the triple <code>%%%</code> instead of the double <code>%%</code> to declare: this means that for each dependency, we will pull in the Scala-JVM or Scala.js version depending on whether it's being used in a Scala.js project. Note also the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">packageArchetype.java_application</code> setting, which isn't strictly necessary depending on what you want to do with the application, but this example needs it as part of the deployment to Heroku.
+ Again, we are using <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">crossProject</code> to define our <code>js/</code> and <code>jvm/</code> sub-projects. Both projects share a number of settings: the settings to add <a href="https://github.com/lihaoyi/scalatags">Scalatags</a> and <a href="https://github.com/lihaoyi/upickle">uPickle</a> to the build. Note that those two dependencies use the triple <code>%%%</code> instead of the double <code>%%</code> to declare: this means that for each dependency, we will pull in the Scala-JVM or Scala.js version depending on whether it's being used in a Scala.js project. Note also the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">packageArchetype.java_application</code> setting, which isn't strictly necessary depending on what you want to do with the application, but this example needs it as part of the deployment to Heroku.
</p>
<p>
The <code>js/</code> sub-project is uneventful, with a dependency on the by-now-familiar <code>scalajs-dom</code> library. The <code>jvm/</code> project, on the other hand, is interesting: it contains the dependencies required for us to set up out Spray server, and one additional thing: we add the output of <code>fastOptJS</code> from the client to the <code>resources</code> on the server. This will allow the <code>server</code> to serve the compiled-javascript from our <code>client</code> project from its resources.
@@ -2011,7 +2061,7 @@ lazy val appJVM = app.jvm.settings(
Next, let's kick off the Spray server in our Scala-JVM main method:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">package simple
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">package simple
import akka.actor.ActorSystem
import spray.http.{HttpEntity, MediaTypes}
@@ -2056,15 +2106,15 @@ object Server extends SimpleRoutingApp{
if f.getName.startsWith(last)
} yield FileData(f.getName, f.length())
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/app/jvm/src/main/scala/simple/Server.scala#L0-L46" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/app/jvm/src/main/scala/simple/Server.scala#L0-L46" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
This is a not-very-interesting <a href="http://spray.io/documentation/1.2.2/spray-routing/">spray-routing</a> application: we set up a server on <code>localhost:8080</code>, have the root URL serve the main page on GET, and have other GET URLs serve resources. This includes the <code>js-fastopt.js</code> file that is now in our resources because of our <code>build.sbt</code> config earlier! We also add a POST route to allow the client ask the server to list files various directories.
</p>
<p>
- The HTML template <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Page.skeleton</code> is not shown above; I put it in a separate file for neatness:
+ The HTML template <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Page.skeleton</code> is not shown above; I put it in a separate file for neatness:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">package simple
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">package simple
import scalatags.Text.all._
object Page{
@@ -2084,14 +2134,14 @@ object Page{
div(id:=&quot;contents&quot;)
)
)
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/app/jvm/src/main/scala/simple/Page.scala#L0-L21" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/app/jvm/src/main/scala/simple/Page.scala#L0-L21" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
This is a typical <a href="https://github.com/lihaoyi/scalatags">Scalatags</a> HTML snippet. Note that since we're serving it directly from the server in Scala code, we do not need to leave a <code>.html</code> file somewhere on the filesystem! We can declare all HTML, including the skeleton of the page, in Scalatags. Otherwise it's the same as what we saw in earlier chapters: A simple HTML page which includes a script tag to run our Scala.js application.</p>
<p>
- Lastly, we'll set up the Scala.js main method, which we are calling in the <code class="html scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&lt;script&gt;</code> tag above to kick off the client-side application.
+ Lastly, we'll set up the Scala.js main method, which we are calling in the <code class="xml scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&lt;script&gt;</code> tag above to kick off the client-side application.
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">package simple
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">package simple
import scalatags.JsDom.all._
import scalajs.concurrent.JSExecutionContext.Implicits.runNow
@@ -2127,18 +2177,18 @@ object Client extends{
).render
)
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/app/js/src/main/scala/simple/Client.scala#L0-L37" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/app/js/src/main/scala/simple/Client.scala#L0-L37" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
Again this is a simple Scala.js application, not unlike what we saw in earlier chapters. However, there is one difference: earlier, we made our Ajax calls to <code>api.openweathermap.org/...</code>. Here, we're making it to <code>/ajax</code>: the same server the page is served from!
</p>
<p>
- You may have noticed in both client and server, we have made reference to a mysterious <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">FileData</code> type which holds the name and size of each file. <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">FileData</code> is defined in the <code>shared/</code> folder, so it can be accessed from both Scala-JVM and Scala.js:
+ You may have noticed in both client and server, we have made reference to a mysterious <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">FileData</code> type which holds the name and size of each file. <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">FileData</code> is defined in the <code>shared/</code> folder, so it can be accessed from both Scala-JVM and Scala.js:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">package simple
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">package simple
-case class FileData(name: String, size: Long)</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/app/shared/src/main/scala/simple/FileData.scala#L0-L3" target="_blank"><i class="fa fa-link "></i></a></pre>
+case class FileData(name: String, size: Long)</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/app/shared/src/main/scala/simple/FileData.scala#L0-L3" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
Now, if we go to the browser at <code>localhost:8080</code>, we should see our web-page!
@@ -2154,105 +2204,105 @@ case class FileData(name: String, size: Long)</code><a class="scalatex-header-li
<p>
This is a real, live example running on a <a href="https://hands-on-scala-js.herokuapp.com/">Heroku server</a>. Feel free to poke around and explore the filesystem on the server, just to convince yourself that this actually works and is not just a mock up.
</p>
-<h1 id="Client-ServerReflections" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Client-ServerReflections" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Client-Server Reflections</h1>
+<h1 id="Client-ServerReflections" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Client-ServerReflections" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Client-Server Reflections</h1>
<p>
By now you've already set up your first client-server application. However, it might not be immediately clear what we've done and why it's interesting! Here are some points to consider.
</p>
- <h2 id="SharedTemplating" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#SharedTemplating" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Shared Templating</h2>
+ <h2 id="SharedTemplating" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#SharedTemplating" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Shared Templating</h2>
<p>
In both the client code and the server code, we made use of the same Scalatags HTML generation library. This is pretty neat: transferring rendering logic between client and server no longer means an annoying/messy rewrite! You can simply C&amp;P the Scalatags snippet over. That means it's easy if you want to e.g. shift the logic from one side to the other in order to optimize for performance or time-to-load or other things.</p>
<p>
- One thing to take note of is that we're actually using subtly <i>different</i> implementations of Scalatags on both sides: on the server, we're importing from <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">scalatags.Text</code>, while on the client we're using <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">scalatags.JsDom</code>. The <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Text</code> backend renders directly to Strings, and is available on both Scala-JVM and Scala.js. The <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">JsDom</code> backend, on the other hand, renders to <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement">html.Element</a>-s which only exist on Scala.js. Thus while on the client you can do things like attach event listeners to the rendered <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement">html.Element</a> objects, or checking their runtime <code>.value</code>, on the server you can't. And that's exactly what you want!
+ One thing to take note of is that we're actually using subtly <i>different</i> implementations of Scalatags on both sides: on the server, we're importing from <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">scalatags.Text</code>, while on the client we're using <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">scalatags.JsDom</code>. The <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Text</code> backend renders directly to Strings, and is available on both Scala-JVM and Scala.js. The <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">JsDom</code> backend, on the other hand, renders to <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement">html.Element</a>-s which only exist on Scala.js. Thus while on the client you can do things like attach event listeners to the rendered <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement">html.Element</a> objects, or checking their runtime <code>.value</code>, on the server you can't. And that's exactly what you want!
</p>
- <h2 id="SharedCode" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#SharedCode" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Shared Code</h2>
+ <h2 id="SharedCode" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#SharedCode" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Shared Code</h2>
<p>
- One thing that we skimmed over is the fact that we could easily define our <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">case class FileData(name: String, size: Long)</code> in the <code>shared/</code> folder, and have it instantly and consistently available on both client and server. This perhaps does not seem so amazing: we've already done many similar things earlier when we were building Cross-platform Modules. Nevertheless, in the context of web development, it is a relatively novel idea to be able to ad-hoc share bits of code between client and server.</p>
+ One thing that we skimmed over is the fact that we could easily define our <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">case class FileData(name: String, size: Long)</code> in the <code>shared/</code> folder, and have it instantly and consistently available on both client and server. This perhaps does not seem so amazing: we've already done many similar things earlier when we were building Cross-platform Modules. Nevertheless, in the context of web development, it is a relatively novel idea to be able to ad-hoc share bits of code between client and server.</p>
<p>
Sharing code is not limited to class definitions: <i>anything</i> can be shared. Objects, classes, interfaces/traits, functions and algorithms, constants: all of these are things that you will likely want to share at some point or another. Traditionally, people have simply re-implemented the same code twice in two languages, or have resorted to awkward Ajax calls to push the logic to the server. With Scala.js, you no longer need to do so: you can easily, create ad-hoc bits of code which are available on both platforms.
</p>
- <h2 id="Boilerplate-freeSerialization" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Boilerplate-freeSerialization" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Boilerplate-free Serialization</h2>
+ <h2 id="Boilerplate-freeSerialization" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Boilerplate-freeSerialization" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Boilerplate-free Serialization</h2>
<p>
The Ajax/RPC layer is one of the more fragile parts of web applications. Often, you have your various Ajax endpoints written once on the server, have a set of routes written to connect those Ajax endpoints to URLs, and client code (traditionally Javascript) made calls to those URLs with &quot;raw&quot; data: basically whatever you wanted, packed in an ad-hoc mix of CSV and JSON and raw-strings.
</p>
<p>
- This has always been annoying boilerplate, and Scala.js removes it. With <a href="https://github.com/lihaoyi/upickle">uPickle</a>, you can simply call <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">upickle.write(...)</code> and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">upickle.read[T](...)</code> to convert your collections, primitives or case-classes to and from JSON. This means you do not need to constantly re-invent different ways of making Ajax calls: you can just fling the data right across the network from client to server and back again.
+ This has always been annoying boilerplate, and Scala.js removes it. With <a href="https://github.com/lihaoyi/upickle">uPickle</a>, you can simply call <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">upickle.write(...)</code> and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">upickle.read[T](...)</code> to convert your collections, primitives or case-classes to and from JSON. This means you do not need to constantly re-invent different ways of making Ajax calls: you can just fling the data right across the network from client to server and back again.
</p>
-<h1 id="What'sLeft?" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#What'sLeft?" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>What's Left?</h1>
+<h1 id="What'sLeft?" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#What'sLeft?" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>What's Left?</h1>
<p>
We've built a small client-server web application with a Scala.js web-client that makes Ajax calls to a Scala-JVM web-server running on Spray. We performed these Ajax calls using uPickle to serialize the data back and forth, so serializing the arguments and return-value was boilerplate-free and correct.
</p>
<p>
However, there is still some amount of duplication in the code. In particular, the definition of the endpoint name &quot;list&quot; is duplicated 4 times:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">path(&quot;ajax&quot; / &quot;list&quot;){</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/app/jvm/src/main/scala/simple/Server.scala#L25-L26" target="_blank"><i class="fa fa-link "></i></a></pre>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">upickle.write(list(e))</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/app/jvm/src/main/scala/simple/Server.scala#L28-L29" target="_blank"><i class="fa fa-link "></i></a></pre>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">def list(path: String) = {</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/app/jvm/src/main/scala/simple/Server.scala#L35-L36" target="_blank"><i class="fa fa-link "></i></a></pre>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">def update() = Ajax.post(&quot;/ajax/list&quot;, inputBox.value).foreach{ xhr =&gt;</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/app/js/src/main/scala/simple/Client.scala#L15-L16" target="_blank"><i class="fa fa-link "></i></a></pre>
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">path(&quot;ajax&quot; / &quot;list&quot;){</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/app/jvm/src/main/scala/simple/Server.scala#L25-L26" target="_blank"><i class="fa fa-link "></i></a></pre>
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">upickle.write(list(e))</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/app/jvm/src/main/scala/simple/Server.scala#L28-L29" target="_blank"><i class="fa fa-link "></i></a></pre>
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">def list(path: String) = {</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/app/jvm/src/main/scala/simple/Server.scala#L35-L36" target="_blank"><i class="fa fa-link "></i></a></pre>
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">def update() = Ajax.post(&quot;/ajax/list&quot;, inputBox.value).foreach{ xhr =&gt;</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/app/js/src/main/scala/simple/Client.scala#L15-L16" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- Three times on the server and once on the client! What's worse, two of the appearances of <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&quot;list&quot;</code> are in string literals, which are not checked by the compiler to match up with themselves or the name of the method <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">list</code>. Apart from this, there is one other piece of duplication that is unchecked: the type being returned from <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">list</code> (<code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Seq[FileData]</code>) is being repeated on the client in <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">upickle.read[Seq[FileData]]</code> in order to de-serialize the serialized data. This leaves three opportunities for error wide-open:
+ Three times on the server and once on the client! What's worse, two of the appearances of <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&quot;list&quot;</code> are in string literals, which are not checked by the compiler to match up with themselves or the name of the method <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">list</code>. Apart from this, there is one other piece of duplication that is unchecked: the type being returned from <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">list</code> (<code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Seq[FileData]</code>) is being repeated on the client in <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">upickle.read[Seq[FileData]]</code> in order to de-serialize the serialized data. This leaves three opportunities for error wide-open:
</p>
<ul>
<li>
- You could change the string literals <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&quot;list&quot;</code> and forget to change the method-name <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">list</code>, thus confusing future maintainers of the code.</li>
+ You could change the string literals <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&quot;list&quot;</code> and forget to change the method-name <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">list</code>, thus confusing future maintainers of the code.</li>
<li>
- You could change one of literal <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&quot;list&quot;</code>s but forget to change the other, thus causing an error at run-time (e.g. a 404 NOT FOUND response)</li>
+ You could change one of literal <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&quot;list&quot;</code>s but forget to change the other, thus causing an error at run-time (e.g. a 404 NOT FOUND response)</li>
<li>
- You could update the return type of the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">list</code> method and forget to update the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">upickle.read</code> deserialization call on the client, resulting in a deserialization failure at runtime.
+ You could update the return type of the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">list</code> method and forget to update the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">upickle.read</code> deserialization call on the client, resulting in a deserialization failure at runtime.
</li></ul>
<p></p>
<p>
Neither of these scenarios is great! Although we've already made great progress in making our client-server application type-safe (via Scala.js on the client) and DRY (via shared code in <code>shared/</code>) we still have this tiny bit of annoying, un-checked duplication and danger lurking in the code-base. The basic problem is that what is normally called the &quot;routing layer&quot; in the web application is still unsafe, and so these silly errors can go un-caught and blow up on unsuspecting developers at run-time. Let's see how we can fix it.
</p>
-<h1 id="Autowire" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Autowire" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Autowire</h1>
+<h1 id="Autowire" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Autowire" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Autowire</h1>
<p>
<a href="https://github.com/lihaoyi/autowire">Autowire</a> is a library that turns your request routing layer from a fragile, hand-crafted mess into a solid, type-checked, boilerplate-free experience. Autowire basically turns what was previously a stringly-typed, hand-crafted Ajax call and route:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">def update() = Ajax.post(&quot;/ajax/list&quot;, inputBox.value).foreach{ xhr =&gt;</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/app/js/src/main/scala/simple/Client.scala#L15-L16" target="_blank"><i class="fa fa-link "></i></a></pre>
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">def update() = Ajax.post(&quot;/ajax/list&quot;, inputBox.value).foreach{ xhr =&gt;</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver/app/js/src/main/scala/simple/Client.scala#L15-L16" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
Into a safe, type-checked function call:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">def update() = Ajaxer[Api].list(inputBox.value).call().foreach{ data =&gt;</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver2/app/js/src/main/scala/simple/Client.scala#L26-L27" target="_blank"><i class="fa fa-link "></i></a></pre>
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">def update() = Ajaxer[Api].list(inputBox.value).call().foreach{ data =&gt;</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver2/app/js/src/main/scala/simple/Client.scala#L26-L27" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
Let's see how we can do that.
</p>
- <h2 id="SettingupAutowire" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#SettingupAutowire" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Setting up Autowire</h2>
+ <h2 id="SettingupAutowire" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#SettingupAutowire" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Setting up Autowire</h2>
<p>
To begin with, Autowire requires you to provide three things:
</p>
<ul>
<li>
- An <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">autowire.Server</code> on the Server, set up to feed the incoming request into Autowire's routing logic</li>
+ An <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">autowire.Server</code> on the Server, set up to feed the incoming request into Autowire's routing logic</li>
<li>
- An <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">autowire.Client</code> on the Client, set up to take a serialized request and send it across the network to the server.</li>
+ An <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">autowire.Client</code> on the Client, set up to take a serialized request and send it across the network to the server.</li>
<li>
- An interface (A Scala <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">trait</code>) which defines the interface between these two
+ An interface (A Scala <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">trait</code>) which defines the interface between these two
</li></ul>
<p>
Let's start with our client-server interface definition
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">package simple
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">package simple
case class FileData(name: String, size: Long)
trait Api{
def list(path: String): Seq[FileData]
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver2/app/shared/src/main/scala/simple/Shared.scala#L0-L7" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver2/app/shared/src/main/scala/simple/Shared.scala#L0-L7" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- Here, you can see that in addition to sharing the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">FileData</code> class, we are also creating an <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Api</code> trait which contains the signature of our <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">list</code> method. The exact name of the trait doesn't matter. We need it to be in <code>shared/</code> so that the code in both client and server can reference it.
+ Here, you can see that in addition to sharing the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">FileData</code> class, we are also creating an <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Api</code> trait which contains the signature of our <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">list</code> method. The exact name of the trait doesn't matter. We need it to be in <code>shared/</code> so that the code in both client and server can reference it.
</p>
<p>
Next, let's look at modifying our server code to make use of Autowire:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">package simple
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">package simple
import akka.actor.ActorSystem
import spray.http.{HttpEntity, MediaTypes}
@@ -2305,12 +2355,12 @@ object Server extends SimpleRoutingApp with Api{
if f.getName.startsWith(last)
} yield FileData(f.getName, f.length())
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver2/app/jvm/src/main/scala/simple/Server.scala#L0-L54" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver2/app/jvm/src/main/scala/simple/Server.scala#L0-L54" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- Now, instead of hard-coding the route <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&quot;ajax&quot; / &quot;list&quot;</code>, we now take in any route matching <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&quot;ajax&quot; / Segments</code>, feeding the resultant path segments into the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Router</code> object:
+ Now, instead of hard-coding the route <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&quot;ajax&quot; / &quot;list&quot;</code>, we now take in any route matching <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&quot;ajax&quot; / Segments</code>, feeding the resultant path segments into the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Router</code> object:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">path(&quot;ajax&quot; / Segments){ s =&gt;
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">path(&quot;ajax&quot; / Segments){ s =&gt;
extract(_.request.entity.asString) { e =&gt;
complete {
Router.route[Api](Server)(
@@ -2321,22 +2371,22 @@ object Server extends SimpleRoutingApp with Api{
)
}
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver2/app/jvm/src/main/scala/simple/Server.scala#L28-L40" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver2/app/jvm/src/main/scala/simple/Server.scala#L28-L40" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- The <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Router</code> object in turn simply defines how you intend the objects to be serialized and deserialized:
+ The <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Router</code> object in turn simply defines how you intend the objects to be serialized and deserialized:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">object Router extends autowire.Server[String, upickle.Reader, upickle.Writer]{
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">object Router extends autowire.Server[String, upickle.Reader, upickle.Writer]{
def read[Result: upickle.Reader](p: String) = upickle.read[Result](p)
def write[Result: upickle.Writer](r: Result) = upickle.write(r)
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver2/app/jvm/src/main/scala/simple/Server.scala#L7-L12" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver2/app/jvm/src/main/scala/simple/Server.scala#L7-L12" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- In this case using uPickle. Note how the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">route</code> call explicitly states the type (here <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Api</code>) that it is to generate routes against; this ensures that only methods which you explicitly put in your public interface <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Api</code> are publically reachable.
+ In this case using uPickle. Note how the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">route</code> call explicitly states the type (here <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Api</code>) that it is to generate routes against; this ensures that only methods which you explicitly put in your public interface <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Api</code> are publically reachable.
</p>
<p>
Next, let's look at the modified client code:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">package simple
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">package simple
import scalatags.JsDom.all._
import org.scalajs.dom
import dom.html
@@ -2382,12 +2432,12 @@ object Client extends{
).render
)
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver2/app/js/src/main/scala/simple/Client.scala#L0-L47" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver2/app/js/src/main/scala/simple/Client.scala#L0-L47" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- There are two main modifications here: the existence of the new <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Ajaxer</code> object, and the modification to the Ajax call-site. Let's first look at <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Ajaxer</code>:
+ There are two main modifications here: the existence of the new <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Ajaxer</code> object, and the modification to the Ajax call-site. Let's first look at <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Ajaxer</code>:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">object Ajaxer extends autowire.Client[String, upickle.Reader, upickle.Writer]{
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">object Ajaxer extends autowire.Client[String, upickle.Reader, upickle.Writer]{
override def doCall(req: Request) = {
dom.ext.Ajax.post(
url = &quot;/ajax/&quot; + req.path.mkString(&quot;/&quot;),
@@ -2397,24 +2447,24 @@ object Client extends{
def read[Result: upickle.Reader](p: String) = upickle.read[Result](p)
def write[Result: upickle.Writer](r: Result) = upickle.write(r)
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver2/app/js/src/main/scala/simple/Client.scala#L8-L20" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver2/app/js/src/main/scala/simple/Client.scala#L8-L20" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- Like the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Router</code> object, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Ajaxer</code> also defines how you perform the serialization and deserialization of data-structures, again using uPickle. Unlike the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Router</code> object, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Ajaxer</code> also defines how the out-going Ajax call gets sent over the network. Here we're doing it using the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Ajax.post</code> method.
+ Like the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Router</code> object, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Ajaxer</code> also defines how you perform the serialization and deserialization of data-structures, again using uPickle. Unlike the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Router</code> object, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Ajaxer</code> also defines how the out-going Ajax call gets sent over the network. Here we're doing it using the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Ajax.post</code> method.
</p>
<p>
Lastly, let's look at the modified callsite for the ajax call itself:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">def update() = Ajaxer[Api].list(inputBox.value).call().foreach{ data =&gt;</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver2/app/js/src/main/scala/simple/Client.scala#L26-L27" target="_blank"><i class="fa fa-link "></i></a></pre>
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">def update() = Ajaxer[Api].list(inputBox.value).call().foreach{ data =&gt;</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/crossBuilds/clientserver2/app/js/src/main/scala/simple/Client.scala#L26-L27" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
There are a few things of note here:
</p>
<ul>
<li>
- The previous call to <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Ajax.post</code> with the path as a string has been replaced by calling <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Ajaxer[Api].list(...).call()</code>, since the logic of actually performing the POST is specified once-and-only-once in the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Ajaxer</code> object.</li>
+ The previous call to <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Ajax.post</code> with the path as a string has been replaced by calling <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Ajaxer[Api].list(...).call()</code>, since the logic of actually performing the POST is specified once-and-only-once in the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Ajaxer</code> object.</li>
<li>
- While <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Ajax.post</code> returned a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Future[dom.XMLHttpRequest]</code> and left us to call <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">upickle.read</code> and deserialize the data ourselves, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Ajaxer[Api].list(...).call()</code> now returns a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Future[Seq[FileData]]</code>! Thus we don't need to worry about making a mistake in the deserialization logic when we write it by hand.
+ While <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Ajax.post</code> returned a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Future[dom.XMLHttpRequest]</code> and left us to call <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">upickle.read</code> and deserialize the data ourselves, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Ajaxer[Api].list(...).call()</code> now returns a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Future[Seq[FileData]]</code>! Thus we don't need to worry about making a mistake in the deserialization logic when we write it by hand.
</li></ul>
<p>
Other than that, nothing much has changed. If you've done this correctly, the web application will look and behave exactly as it did earlier!
@@ -2430,16 +2480,16 @@ object Client extends{
<p>
So why did we do this in the first place?
</p>
- <h2 id="WhyAutowire?" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#WhyAutowire?" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Why Autowire?</h2>
+ <h2 id="WhyAutowire?" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#WhyAutowire?" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Why Autowire?</h2>
<p>
- Overall, this set up requires some boilerplate to define the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Ajaxer</code> and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Router</code> objects, as well as the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Api</code> trait. However, these can be defined just once and used over and over; while it might be wasteful/unnecessary for making a single Ajax call, the cost is much less amortized over a number of Ajax calls. In a non-trivial web application with dozens of routes being called all over the place, spending a dozen lines setting up things up-front isn't a huge cost.
+ Overall, this set up requires some boilerplate to define the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Ajaxer</code> and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Router</code> objects, as well as the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Api</code> trait. However, these can be defined just once and used over and over; while it might be wasteful/unnecessary for making a single Ajax call, the cost is much less amortized over a number of Ajax calls. In a non-trivial web application with dozens of routes being called all over the place, spending a dozen lines setting up things up-front isn't a huge cost.
</p>
<p>
What have we gotten in exchange? It turns out that by using Autowire, we have eliminated the three failure modes described earlier, that could:
</p>
<ul>
<li>
- It is impossible for the route and the endpoint method-name to diverge accidentally: if the endpoint is called <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">list</code>, the requests will go through the <code>/list</code> URL. No room for discussion, or to make a mistake</li>
+ It is impossible for the route and the endpoint method-name to diverge accidentally: if the endpoint is called <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">list</code>, the requests will go through the <code>/list</code> URL. No room for discussion, or to make a mistake</li>
<li>
You cannot accidentally rename the route on the server without changing the client, or vice versa. Attempts to do so will cause a compilation error, and even your IDE should highlight it as red. Try it out!
</li>
@@ -2465,13 +2515,13 @@ object Client extends{
<li>
What if you wanted to use another server rather than Spray? How about trying to set up a Play or Scalatra server to serve our Scala.js application code?</li></ul>
</div>
-<div class="header scalatex-header scalatex-hover-container" id="InDepth" style="display: block;"><h1>In Depth<a class="scalatex-header-link" href="#InDepth" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a></h1><br /><h2>Exploring Scala.js</h2></div><div class="content">
+<div style="margin: 0px;color: #333;text-align: center;padding: 2.5em 2em 0;border-bottom: 1px solid #eee;display: block;" id="InDepth" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><h1 style="margin: 0.2em 0;font-size: 3em;font-weight: 300;">In Depth<a class=" scalatex-site-Styles-headerLink" href="#InDepth" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a></h1><br /><h2 style="font-weight: 300;color: #ccc;padding: 0px;margin-top: 0px;">Exploring Scala.js</h2></div><div class=" scalatex-site-Styles-content">
<p>
This half of the book
is a set of detailed expositions on various parts of the Scala.js platform. Nothing in here is necessary for you to make your first demos, but as you dig deeper into the platform, you will likely need or want to care about these things so you can properly understand what's going on &quot;under the hood&quot;
</p>
- <div class="header scalatex-header scalatex-hover-container" id="AdvancedTechniques" style="display: block;"><h1 id="AdvancedTechniques">Advanced Techniques<a class="scalatex-header-link" href="#AdvancedTechniques" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a></h1><br /></div>
+ <div style="margin: 0px;color: #333;text-align: center;padding: 2.5em 2em 0;border-bottom: 1px solid #eee;display: block;" id="AdvancedTechniques" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><h1 style="margin: 0.2em 0;font-size: 3em;font-weight: 300;" id="AdvancedTechniques">Advanced Techniques<a class=" scalatex-site-Styles-headerLink" href="#AdvancedTechniques" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a></h1><br /></div>
<p>
<a href="#GettingStarted">Getting Started</a> walks you through how to set up some basic Scala.js applications, but that only scratches the surface of the things you can do with Scala.js. Apart from being able to use the same techniques you're used to in Scala-JVM in the browser, Scala.js opens up a whole range of possibilities and novel techniques that are not found in typical Scala-JVM applications.
@@ -2492,7 +2542,7 @@ is a set of detailed expositions on various parts of the Scala.js platform. Noth
</p>
-<h1 id="Functional-ReactiveUIs" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Functional-ReactiveUIs" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Functional-Reactive UIs</h1>
+<h1 id="Functional-ReactiveUIs" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Functional-ReactiveUIs" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Functional-Reactive UIs</h1>
<p>
<a href="http://en.wikipedia.org/wiki/Functional_reactive_programming">Functional-reactive Programming</a> (FRP) is a field with encompasses several things:
</p>
@@ -2502,7 +2552,7 @@ is a set of detailed expositions on various parts of the Scala.js platform. Noth
<li>
<b>Continuous</b>: Handling of first-class signals, like in <link>Elmhttp://elm-lang.org/learn/What-is-FRP.elm</link>
</li></ul>
- <h2 id="WhyFRP" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#WhyFRP" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Why FRP</h2>
+ <h2 id="WhyFRP" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#WhyFRP" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Why FRP</h2>
<p>
The value proposition of FRP is that in a &quot;traditional&quot; program, when an event occurs, events and changes propagate throughout the program in an ad-hoc manner. An event-listener may trigger additional events, call some callbacks, or set some mutable variables that subsequent code will read and react to.
</p>
@@ -2513,13 +2563,13 @@ is a set of detailed expositions on various parts of the Scala.js platform. Noth
Furthermore, because the propagation is ad-hoc, there is no way for the code to help ensure that you are propagating changes in a &quot;valid&quot; manner: it is thus easy for programmer errors to result in changes or events being incorrectly propagated. This most often results in data falling out of sync: a UI widget may forget to update when an action is taken, resulting in an inconsistent state being shown to the user, ultimately resulting in confused users.
</p>
<p>
- FRP basically structures these event- or change-propagations as first-class values within the program, either as an <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">EventSource[T]</code> type that represents a discrete source of individual <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">T</code> events, or as a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Signal[T]</code> type which represents a continuous time-varying value <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">T</code>. This comes at some cost within the program: you now have to program using these <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">EventSource</code>s or <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Signal</code>s, rather than just ad-hoc running callbacks or listening-to/triggering events all over the place. In exchange, you get more powerful tools to work with these values, making it easy for the library to e.g. ensure that changes always propagate correctly throughout your program, and that all values are always kept in sync.
+ FRP basically structures these event- or change-propagations as first-class values within the program, either as an <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">EventSource[T]</code> type that represents a discrete source of individual <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">T</code> events, or as a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Signal[T]</code> type which represents a continuous time-varying value <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">T</code>. This comes at some cost within the program: you now have to program using these <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">EventSource</code>s or <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Signal</code>s, rather than just ad-hoc running callbacks or listening-to/triggering events all over the place. In exchange, you get more powerful tools to work with these values, making it easy for the library to e.g. ensure that changes always propagate correctly throughout your program, and that all values are always kept in sync.
</p>
- <h2 id="FRPwithScala.Rx" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#FRPwithScala.Rx" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>FRP with Scala.Rx</h2>
+ <h2 id="FRPwithScala.Rx" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#FRPwithScala.Rx" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>FRP with Scala.Rx</h2>
<p>
<a href="https://github.com/lihaoyi/scala.rx">Scala.Rx</a> is a change-propagation library that implements the <b>Continuous</b> style of FRP. To begin with, we need to include it in our <code>build.sbt</code> dependencies:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">libraryDependencies += &quot;com.lihaoyi&quot; %%% &quot;scalarx&quot; % &quot;0.2.8&quot;</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/build.sbt#L18-L19" target="_blank"><i class="fa fa-link "></i></a></pre>
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">libraryDependencies += &quot;com.lihaoyi&quot; %%% &quot;scalarx&quot; % &quot;0.2.8&quot;</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/build.sbt#L18-L19" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
Scala.Rx provides you with smart variables that automatically track dependencies with each other, such that if one smart variable changes, the rest re-compute immediately and automatically. The main primitives in Scala.Rx are:
@@ -2533,27 +2583,27 @@ is a set of detailed expositions on various parts of the Scala.js platform. Noth
<b>Obs</b>s: Observers on either an <b>Rx</b> or a <b>Var</b>, which performs some action when it changes
</li></ul>
<p>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Var</code>s and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Rx</code>s roughly correspond to the idea of a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Signal</code> described earlier. The documentation for Scala.Rx goes into this in much more detail, so if you're curious you should read it. This section will jump straight into how to use Scala.Rx with Scala.js.
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Var</code>s and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Rx</code>s roughly correspond to the idea of a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Signal</code> described earlier. The documentation for Scala.Rx goes into this in much more detail, so if you're curious you should read it. This section will jump straight into how to use Scala.Rx with Scala.js.
</p>
<p>
To begin with, let's set up our imports:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">package advanced
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">package advanced
import org.scalajs.dom
import scalajs.js
import scalajs.js.annotation.JSExport
import rx._
import scalatags.JsDom.all._
-import dom.html</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/BasicRx.scala#L0-L8" target="_blank"><i class="fa fa-link "></i></a></pre>
+import dom.html</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/BasicRx.scala#L0-L8" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- Here we are seeing the same <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">dom</code> and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">scalatags</code>, imports we saw in the hands-on tutorial, as well a new <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">import rx._</code> which bring all the Scala.Rx names into the local namespace.
+ Here we are seeing the same <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">dom</code> and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">scalatags</code>, imports we saw in the hands-on tutorial, as well a new <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">import rx._</code> which bring all the Scala.Rx names into the local namespace.
</p>
<p>
Scala.Rx does not &quot;natively&quot; bind to Scalatags, but integrating them yourself is simple enough that it's not worth putting into a separate library. He's a simple integration:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">implicit def rxFrag[T &lt;% Frag](r: Rx[T]): Frag = {
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">implicit def rxFrag[T &lt;% Frag](r: Rx[T]): Frag = {
def rSafe: dom.Node = span(r()).render
var last = rSafe
Obs(r, skipInitial = true){
@@ -2563,17 +2613,17 @@ import dom.html</code><a class="scalatex-header-link" style="position: absolute;
last = newLast
}
last
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/BasicRx.scala#L68-L79" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/BasicRx.scala#L68-L79" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- Scalatags requires that anything you want to embed in a Scalatags fragment be implicitly convertible to <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Frag</code>; here we are providing one for any Scala.Rx <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Rx[T]</code>s, as long as the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">T</code> provided is itself convertible to a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Frag</code>. We call <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">r().render</code> to extract the &quot;current&quot; value of the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Rx</code>, and then set up an <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Obs</code> that watches the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Rx</code>, replacing the previous value with the current one every time its value changes.
+ Scalatags requires that anything you want to embed in a Scalatags fragment be implicitly convertible to <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Frag</code>; here we are providing one for any Scala.Rx <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Rx[T]</code>s, as long as the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">T</code> provided is itself convertible to a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Frag</code>. We call <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">r().render</code> to extract the &quot;current&quot; value of the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Rx</code>, and then set up an <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Obs</code> that watches the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Rx</code>, replacing the previous value with the current one every time its value changes.
</p>
<p>
- Now that the set-up is out of the way, let's consider a simple HTML widget that lets you enter text in a <code class="html scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">&lt;textarea&gt;</code>, and keeps track of the number of words, characters, and counts how long each word is.
+ Now that the set-up is out of the way, let's consider a simple HTML widget that lets you enter text in a <code class="xml scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">&lt;textarea&gt;</code>, and keeps track of the number of words, characters, and counts how long each word is.
</p>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-13-24">
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">val txt = Var(&quot;&quot;)
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">val txt = Var(&quot;&quot;)
val numChars = Rx{txt().length}
val numWords = Rx{
txt().split(' ')
@@ -2599,31 +2649,31 @@ container.appendChild(
li(&quot;Word Length: &quot;, avgWordLength)
)
).render
-)</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/BasicRx.scala#L12-L39" target="_blank"><i class="fa fa-link "></i></a></pre>
+)</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/BasicRx.scala#L12-L39" target="_blank"><i class="fa fa-link "></i></a></pre>
</div>
<div class="pure-u-1 pure-u-md-11-24">
<div id="example15" style="display: block;overflow: scroll;"></div><script>advanced.BasicRx().main(document.getElementById('example15'))</script>
</div></div>
<p>
- This snippet sets up a basic data-flow graph. We have our <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">txt</code> <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Var</code>, and a bunch of <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Rx</code>s (<code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">numChars</code>, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">numWords</code>, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">avgWordLength</code>) that are computed based on <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">txt</code>.
+ This snippet sets up a basic data-flow graph. We have our <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">txt</code> <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Var</code>, and a bunch of <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Rx</code>s (<code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">numChars</code>, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">numWords</code>, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">avgWordLength</code>) that are computed based on <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">txt</code>.
</p>
<p>
- Next, we construct our Scalatags fragment: a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">textarea</code> tag with a listener that updates <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">txt</code>, and a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">div</code> containing the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">textarea</code> and a list containing the bound values of our <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Rx</code>s.
+ Next, we construct our Scalatags fragment: a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">textarea</code> tag with a listener that updates <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">txt</code>, and a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">div</code> containing the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">textarea</code> and a list containing the bound values of our <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Rx</code>s.
</p>
<p>
That's all we need to end up with a live-updating widget, which re-renders the necessary bits of the page when the contents of the text box changes! Note how the code basically flows top-to-bottom, like a batch-rendering program, but at the end of it we get a live widget. The code is much simpler than a similar widget built up using jQuery or Backbone.
</p>
<p>
- Furthermore, there is no chance for the parts of the DOM which are &quot;live&quot; to fall out of sync. There is no visible logic that handles the individual re-calulations and re-renders: that is all done by Scala.Rx and by our <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">rxFrag</code> implicit. Because we do not need to write code for each site to keep each individual <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Rx</code> and each DOM fragment in sync, that means there is no chance of the developer screwing it up and resulting in an out-of-sync page.
+ Furthermore, there is no chance for the parts of the DOM which are &quot;live&quot; to fall out of sync. There is no visible logic that handles the individual re-calulations and re-renders: that is all done by Scala.Rx and by our <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">rxFrag</code> implicit. Because we do not need to write code for each site to keep each individual <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Rx</code> and each DOM fragment in sync, that means there is no chance of the developer screwing it up and resulting in an out-of-sync page.
</p>
- <h2 id="MoreRx" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#MoreRx" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>More Rx</h2>
+ <h2 id="MoreRx" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#MoreRx" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>More Rx</h2>
<p>
That was a pretty simple example to get you started with a simple Scala.Rx application. Let's look at a more meaty example to see how we can use Scala.Rx to help structure our interactive web application:
</p>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-13-24">
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">val fruits = Seq(
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">val fruits = Seq(
&quot;Apple&quot;, &quot;Apricot&quot;, &quot;Banana&quot;, &quot;Cherry&quot;,
&quot;Mango&quot;, &quot;Mangosteen&quot;, &quot;Mandarin&quot;,
&quot;Grape&quot;, &quot;Grapefruit&quot;, &quot;Guava&quot;
@@ -2647,13 +2697,13 @@ container.appendChild(
txtInput,
ul(fragments)
).render
-)</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/BasicRx.scala#L42-L67" target="_blank"><i class="fa fa-link "></i></a></pre>
+)</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/BasicRx.scala#L42-L67" target="_blank"><i class="fa fa-link "></i></a></pre>
</div>
<div class="pure-u-1 pure-u-md-11-24">
<div id="example16" style="display: block;overflow: scroll;"></div><script>advanced.BasicRx().main2(document.getElementById('example16'))</script>
</div></div>
<p>
- This is a basic re-implementation of the autocomplete widget we created in the chapter <a href="#InteractiveWebPages">Interactive Web Pages</a>, except done using Scala.Rx. Note that unlike the original implementation, we don't need to manage the clearing of the output area via <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">innerHTML = &quot;&quot;</code> and the re-rendering via <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">appendChild(...)</code>. All this is handled by the same <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">rxFrag</code> code we wrote earlier.
+ This is a basic re-implementation of the autocomplete widget we created in the chapter <a href="#InteractiveWebPages">Interactive Web Pages</a>, except done using Scala.Rx. Note that unlike the original implementation, we don't need to manage the clearing of the output area via <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">innerHTML = &quot;&quot;</code> and the re-rendering via <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">appendChild(...)</code>. All this is handled by the same <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">rxFrag</code> code we wrote earlier.
</p>
<p>
Furthermore, this implementation is more efficient than the original: In the original, everything is always re-rendered every time, which can be a problem if the number of things being rendered is large. In this implementation, only when a fruit appears-in/disappears-from the list does re-rendering happen, and only for that particular fruit. For the bulk of the fruits which did not experience any change in appearance, the DOM is left entirely untouched.
@@ -2666,7 +2716,7 @@ container.appendChild(
<p>
Hopefully this has given you a sense of how you can use Scala.Rx to help build complex, interactive web applications. The implementation is tricky, but the basic value proposition is clear: you get to write your code top-to-bottom, like the most old-fashioned static pages, and have it transformed by Scala.Rx into an interactive, always-consistent web app. By abstracting away the whole event-propagation, manual-updating process inside the library, we have ensured that there is no place where the developer can screw it up, and the application's UI will forever be in sync with its data.
</p>
-<h1 id="AsynchronousWorkflows" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#AsynchronousWorkflows" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Asynchronous Workflows</h1>
+<h1 id="AsynchronousWorkflows" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#AsynchronousWorkflows" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Asynchronous Workflows</h1>
<p>
In a traditional setting, Scala applications tend to have a mix of concurrency models: some spawn multiple threads and use thread-blocking operations or libraries, others do things with Actors or Futures, trying hard to stay non-blocking throughout, while most are a mix of these two paradigms.
</p>
@@ -2676,7 +2726,7 @@ container.appendChild(
<p>
However, Scala.js has much more powerful tools to work with than your typical Javascript libraries. The Scala standard library comes with a rich API for <a href="#Futures&amp;Promises">Futures &amp; Promises</a>, which are thankfully 100% asynchronous. Though this design was chosen for performance on the JVM, it perfectly fits our 100% asynchronous Javascript APIs. We have tools like <a href="#Scala-Async">Scala-Async</a>, which works perfectly with Scala.js, and lets you create asynchronous computations in a much less confusing manner.
</p>
- <h2 id="Futures&amp;Promises" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Futures&amp;Promises" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Futures &amp; Promises</h2>
+ <h2 id="Futures&amp;Promises" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Futures&amp;Promises" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Futures &amp; Promises</h2>
<p>
A Future represents an in-progress computation that may or may not have completed. It may encapsulate a web request, or an RPC, or a task happening on another thread. They are not a novel concept, and Scala provides a good in-built implementation of Futures that works well with Scala.js.
</p>
@@ -2697,7 +2747,7 @@ container.appendChild(
<p>
To begin with, let's write the scaffolding code, that will display the input box, deal with the listeners, and all that:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">val myInput = input(value:=&quot;London,Singapore,Berlin,New York&quot;).render
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">val myInput = input(value:=&quot;London,Singapore,Berlin,New York&quot;).render
val output = div.render
myInput.onkeyup = (e: dom.KeyboardEvent) =&gt; {
if (e.keyCode == KeyCode.enter){
@@ -2710,21 +2760,21 @@ container.appendChild(
myInput,
output
).render
-)</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Futures.scala#L16-L30" target="_blank"><i class="fa fa-link "></i></a></pre>
+)</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Futures.scala#L16-L30" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- So far so good. The only thing that's missing here is the mysterious <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">handle</code> function, which is given the list of names and the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">output</code> div, and must handle the Ajax requests, aggregating the results, and displaying them in <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">output</code>. Let's also define a small number of helper functions that we'll use later:
+ So far so good. The only thing that's missing here is the mysterious <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">handle</code> function, which is given the list of names and the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">output</code> div, and must handle the Ajax requests, aggregating the results, and displaying them in <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">output</code>. Let's also define a small number of helper functions that we'll use later:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">def urlFor(name: String) = {
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">def urlFor(name: String) = {
&quot;http://api.openweathermap.org/data/&quot; +
&quot;2.5/find?mode=json&amp;q=&quot; +
name
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Futures.scala#L31-L36" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Futures.scala#L31-L36" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">urlFor</code> encapsulates the messy URL-construction logic that we need to make the Ajax call to the right place.
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">urlFor</code> encapsulates the messy URL-construction logic that we need to make the Ajax call to the right place.
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">def parseTemp(text: String) = {
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">def parseTemp(text: String) = {
val data = js.JSON.parse(text)
val kelvins = data.list
.pop()
@@ -2732,12 +2782,12 @@ container.appendChild(
.temp
.asInstanceOf[Double]
kelvins - 272.15
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Futures.scala#L36-L45" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Futures.scala#L36-L45" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">parseTemp</code> encapsulates the messy result-extraction logic that we need to get the data we want (current temperature, in celsius) out of the structured JSON return blob.
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">parseTemp</code> encapsulates the messy result-extraction logic that we need to get the data we want (current temperature, in celsius) out of the structured JSON return blob.
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">def formatResults(output: html.Element, results: Seq[(String, Double)]) = {
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">def formatResults(output: html.Element, results: Seq[(String, Double)]) = {
output.innerHTML = &quot;&quot;
output.appendChild(ul(
for((name, temp) &lt;- results) yield li(
@@ -2745,19 +2795,19 @@ container.appendChild(
)
).render)
}
-@JSExport</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Futures.scala#L45-L54" target="_blank"><i class="fa fa-link "></i></a></pre>
+@JSExport</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Futures.scala#L45-L54" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">formatResults</code> encapsulates the conversion of the final <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">(name, celsius)</code> data back into readable HTML.
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">formatResults</code> encapsulates the conversion of the final <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">(name, celsius)</code> data back into readable HTML.
</p>
<p>
- Overall, these helper functions do nothing special, btu we're defining them first to avoid having to copy-&amp;-paste code throughout the subsequent examples. Now that we've defined all the relevant scaffolding, let's walk through a few ways that we can implement the all-important <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">handle</code> method.
+ Overall, these helper functions do nothing special, btu we're defining them first to avoid having to copy-&amp;-paste code throughout the subsequent examples. Now that we've defined all the relevant scaffolding, let's walk through a few ways that we can implement the all-important <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">handle</code> method.
</p>
- <h3 id="DirectUseofXMLHttpRequest" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#DirectUseofXMLHttpRequest" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Direct Use of XMLHttpRequest</h3>
+ <h3 id="DirectUseofXMLHttpRequest" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#DirectUseofXMLHttpRequest" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Direct Use of XMLHttpRequest</h3>
<div style="height: 200px;display: block;overflow: scroll;" id="example17"></div><script>advanced.Futures().main0(document.getElementById('example17'))</script>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">def handle0(names: Seq[String], output: html.Div) = {
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">def handle0(names: Seq[String], output: html.Div) = {
val results = mutable.Buffer.empty[(String, Double)]
for(name &lt;- names){
val xhr = new XMLHttpRequest
@@ -2771,19 +2821,19 @@ container.appendChild(
}
xhr.send()
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Futures.scala#L55-L70" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Futures.scala#L55-L70" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- This is a simple solution that directly uses the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">XMLHttpRequest</code> class that is available in Javascript in order to perform the Ajax call. Every Ajax call that returns, we aggregate in a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">results</code> buffer, and when the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">results</code> buffer is full we then append the formatted results to the output div.</p>
+ This is a simple solution that directly uses the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">XMLHttpRequest</code> class that is available in Javascript in order to perform the Ajax call. Every Ajax call that returns, we aggregate in a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">results</code> buffer, and when the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">results</code> buffer is full we then append the formatted results to the output div.</p>
<p>
- This is relatively straightforward, though maybe knottier than people would be used to. For example, we have to &quot;construct&quot; the Ajax call via calling mutating methods and setting properties on the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">XMLHttpRequest</code> object, where it's easy to make a mistake. Furthermore, we need to manually aggregate the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">results</code> and keep track ourselves whether or not the calls have all completed, which again is messy and error-prone.
+ This is relatively straightforward, though maybe knottier than people would be used to. For example, we have to &quot;construct&quot; the Ajax call via calling mutating methods and setting properties on the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">XMLHttpRequest</code> object, where it's easy to make a mistake. Furthermore, we need to manually aggregate the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">results</code> and keep track ourselves whether or not the calls have all completed, which again is messy and error-prone.
</p>
<p>
- This solution is basically equivalent to the initial code given in the <a href="#RawJavascript">Raw Javascript</a> section of <a href="#InteractiveWebPages">Interactive Web Pages</a>, with the additional code necessary for aggregation. As described in <a href="#dom.extensions">dom.extensions</a>, we can make use of the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Ajax</code> object to make it slightly tidier.
+ This solution is basically equivalent to the initial code given in the <a href="#RawJavascript">Raw Javascript</a> section of <a href="#InteractiveWebPages">Interactive Web Pages</a>, with the additional code necessary for aggregation. As described in <a href="#dom.extensions">dom.extensions</a>, we can make use of the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Ajax</code> object to make it slightly tidier.
</p>
- <h3 id="Usingdom.extensions.Ajax" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Usingdom.extensions.Ajax" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Using dom.extensions.Ajax</h3>
+ <h3 id="Usingdom.extensions.Ajax" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Usingdom.extensions.Ajax" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Using dom.extensions.Ajax</h3>
<div style="height: 200px;display: block;overflow: scroll;" id="example18"></div><script>advanced.Futures().main1(document.getElementById('example18'))</script>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">def handle1(names: Seq[String], output: html.Div) = {
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">def handle1(names: Seq[String], output: html.Div) = {
val results = mutable.Buffer.empty[(String, Double)]
for{
name &lt;- names
@@ -2795,16 +2845,16 @@ container.appendChild(
formatResults(output, results)
}
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Futures.scala#L74-L87" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Futures.scala#L74-L87" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- This solution uses the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">dom.extensions.Ajax</code> object, as described in <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">dom.extensions</code>. This basically wraps the messy <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">XMLHttpRequest</code> interface in a single function that returns a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">scala.concurrent.Future</code>, which you can then map/foreach over to perform the action when the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Future</code> is complete.</p>
+ This solution uses the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">dom.extensions.Ajax</code> object, as described in <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">dom.extensions</code>. This basically wraps the messy <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">XMLHttpRequest</code> interface in a single function that returns a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">scala.concurrent.Future</code>, which you can then map/foreach over to perform the action when the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Future</code> is complete.</p>
<p>
- However, we still have the messiness inherent in the result aggregation: we don't actually want to perform our action (writing to the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">output</code> div) when one <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Future</code> is complete, but only when <i>all</i> the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Future</code>s are complete. Thus we still need to do some amount of manual book-keeping in the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">results</code> buffer.
+ However, we still have the messiness inherent in the result aggregation: we don't actually want to perform our action (writing to the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">output</code> div) when one <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Future</code> is complete, but only when <i>all</i> the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Future</code>s are complete. Thus we still need to do some amount of manual book-keeping in the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">results</code> buffer.
</p>
- <h3 id="FutureCombinators" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#FutureCombinators" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Future Combinators</h3>
+ <h3 id="FutureCombinators" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#FutureCombinators" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Future Combinators</h3>
<div style="height: 200px;display: block;overflow: scroll;" id="example19"></div><script>advanced.Futures().main2(document.getElementById('example19'))</script>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">def handle2(names: Seq[String], output: html.Div) = {
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">def handle2(names: Seq[String], output: html.Div) = {
val futures = for(name &lt;- names) yield{
Ajax.get(urlFor(name)).map( xhr =&gt;
(name, parseTemp(xhr.responseText))
@@ -2814,12 +2864,12 @@ container.appendChild(
for(results &lt;- Future.sequence(futures)){
formatResults(output, results)
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Futures.scala#L91-L103" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Futures.scala#L91-L103" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- Since we're using Scala's <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Future</code>s, we aren't limited to just map/foreach-ing over them. <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">scala.concurrent.Future</code> provides a <a href="http://www.scala-lang.org/files/archive/nightly/docs/library/scala/concurrent/Future.html">rich api</a> that can be used to deal with common tasks like working with lists of futures in parallel, or aggregating the result of futures together.</p>
+ Since we're using Scala's <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Future</code>s, we aren't limited to just map/foreach-ing over them. <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">scala.concurrent.Future</code> provides a <a href="http://www.scala-lang.org/files/archive/nightly/docs/library/scala/concurrent/Future.html">rich api</a> that can be used to deal with common tasks like working with lists of futures in parallel, or aggregating the result of futures together.</p>
<p>
- Here, instead of manually counting until all the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Future</code>s are complete, we instead create the Futures which will contain what we want (name and temperature) and store them in a list. Then we can use the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Future.sequence</code> function to invert the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Seq[Future[T]]</code> into a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Future[Seq[T]]</code>, a single Future that will provide all the results in a single list when every Future is complete. We can then simply foreach- over the single Future to get the data we need to feed to <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">formatResults</code>/<code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">appendChild</code>.
+ Here, instead of manually counting until all the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Future</code>s are complete, we instead create the Futures which will contain what we want (name and temperature) and store them in a list. Then we can use the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Future.sequence</code> function to invert the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Seq[Future[T]]</code> into a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Future[Seq[T]]</code>, a single Future that will provide all the results in a single list when every Future is complete. We can then simply foreach- over the single Future to get the data we need to feed to <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">formatResults</code>/<code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">appendChild</code>.
</p>
<p>
This approach is significantly neater than the previous two examples: we no longer have any mutation going on, and the logic is expressed in a very high-level, simple manner. &quot;Make a bunch of Futures, join them, use the result&quot; is much less error-prone than the imperative result-aggregation-and-counting logic used in the previous examples.
@@ -2827,9 +2877,9 @@ container.appendChild(
<hr />
<p>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">scala.concurrent.Future</code> isn't limited to just calling <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">.sequence</code> on lists. It provides the ability to <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">.zip</code> two Futures of different types together to get their result, or <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">.recover</code> in the case where Futures fail. Although these tools were originally built for Scala-JVM, all of them work unchanged on Scala.js, and serve their purpose well in simplifying messy asynchronous computations.
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">scala.concurrent.Future</code> isn't limited to just calling <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">.sequence</code> on lists. It provides the ability to <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">.zip</code> two Futures of different types together to get their result, or <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">.recover</code> in the case where Futures fail. Although these tools were originally built for Scala-JVM, all of them work unchanged on Scala.js, and serve their purpose well in simplifying messy asynchronous computations.
</p>
- <h2 id="Scala-Async" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Scala-Async" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Scala-Async</h2>
+ <h2 id="Scala-Async" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Scala-Async" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Scala-Async</h2>
<p>
Let's look at how to use Scala-Async. To motivate us, let's consider a simple paint-like canvas application similar to the one we built in the section <a href="#MakingaSketchpadusingMouseInput">Making a Sketchpad using Mouse Input</a>. This application will have a few properties:
</p>
@@ -2846,7 +2896,7 @@ container.appendChild(
<p>
This is a toy example, but is enough to bring out the difficulty of doing things the &quot;traditional&quot; way, and why using Scala-Async with Scala.js is superior. To begin with, let's set the stage:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">val renderer = canvas.getContext(&quot;2d&quot;)
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">val renderer = canvas.getContext(&quot;2d&quot;)
.asInstanceOf[dom.CanvasRenderingContext2D]
canvas.style.backgroundColor = &quot;#f8f8f8&quot;
@@ -2856,18 +2906,18 @@ canvas.width = canvas.parentElement.clientWidth
renderer.lineWidth = 5
renderer.strokeStyle = &quot;red&quot;
renderer.fillStyle = &quot;cyan&quot;
-renderer</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Async.scala#L12-L23" target="_blank"><i class="fa fa-link "></i></a></pre>
+renderer</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Async.scala#L12-L23" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
To initialize the canvas with the part of the code which will remain the same, so we can look more closely at the code which differs.
</p>
- <h3 id="TraditionalAsynchrony" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#TraditionalAsynchrony" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Traditional Asynchrony</h3>
+ <h3 id="TraditionalAsynchrony" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#TraditionalAsynchrony" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Traditional Asynchrony</h3>
<p>
- Let's look at a traditional implementation, using Scala.js but no special features. We'll just use the Javascript <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">canvas.onmouveXXX</code> operations directly.
+ Let's look at a traditional implementation, using Scala.js but no special features. We'll just use the Javascript <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">canvas.onmouveXXX</code> operations directly.
</p>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-13-24">
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">// traditional
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">// traditional
def rect = canvas.getBoundingClientRect()
var dragState = 0
@@ -2899,7 +2949,7 @@ canvas.onmousedown ={(e: dom.MouseEvent) =&gt;
e.clientY - rect.top
)
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Async.scala#L67-L100" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Async.scala#L67-L100" target="_blank"><i class="fa fa-link "></i></a></pre>
</div>
<div class="pure-u-1 pure-u-md-11-24">
<canvas id="example20" style="display: block;overflow: scroll;"></canvas><script>advanced.Async().main0(document.getElementById('example20'))</script></div></div>
@@ -2908,31 +2958,31 @@ canvas.onmousedown ={(e: dom.MouseEvent) =&gt;
</p>
<ul>
<li>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">canvas.onmousemove</code></li>
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">canvas.onmousemove</code></li>
<li>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">canvas.onmousedown</code></li>
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">canvas.onmousedown</code></li>
<li>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">canvas.onmouseup</code>
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">canvas.onmouseup</code>
</li></ul>
<p>
And each listener is in charge of deciding what to do when it is it's turn to fire.
</p>
<p>
- This code is pretty tricky and hard to follow. It's not immediately clear what it is doing. One thing you may notice is the presence of this <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">dragState</code> variable, which seems to add a lot to the confusion with branches all over the place. At first you may think you can simplify the code to do without it, but attempts to do so will reveal why it is necessary.
+ This code is pretty tricky and hard to follow. It's not immediately clear what it is doing. One thing you may notice is the presence of this <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">dragState</code> variable, which seems to add a lot to the confusion with branches all over the place. At first you may think you can simplify the code to do without it, but attempts to do so will reveal why it is necessary.
</p>
<p>
- This variable is necessary because each mouse event could mean different things at different times. For example, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">canvas.onmousemove</code> should do nothing it occurs between an <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">canvas.onmousedown</code> and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">canvas.onmouseup</code>. <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">canvas.onmouseup</code> itself has two tasks: it either ends the dragging phase (which necessitates the fill-current-shape call) or it serves to clear the canvas if happening after a drag. And <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">canvas.onmousedown</code> should not start a new drag if the previous drawing hasn't been cleared from the canvas.
+ This variable is necessary because each mouse event could mean different things at different times. For example, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">canvas.onmousemove</code> should do nothing it occurs between an <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">canvas.onmousedown</code> and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">canvas.onmouseup</code>. <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">canvas.onmouseup</code> itself has two tasks: it either ends the dragging phase (which necessitates the fill-current-shape call) or it serves to clear the canvas if happening after a drag. And <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">canvas.onmousedown</code> should not start a new drag if the previous drawing hasn't been cleared from the canvas.
</p>
<p>
This is a pretty simple workflow for the user, and yet the code is already tricky enough it's not obvious that it's correct at first glance. More complex tools will have correspondingly more complex workflows, and it is easy to see how just another 1 or 2 more states can get out of hand.
</p>
- <h3 id="UsingScala-Async" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#UsingScala-Async" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Using Scala-Async</h3>
+ <h3 id="UsingScala-Async" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#UsingScala-Async" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Using Scala-Async</h3>
<p>
Now we've seen what a &quot;traditional&quot; approach looks like, let's look at how we would do this using Scala-Async.
</p>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-13-24">
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">// async
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">// async
def rect = canvas.getBoundingClientRect()
type ME = dom.MouseEvent
@@ -2967,20 +3017,20 @@ async{
await(mouseup())
renderer.clearRect(0, 0, 1000, 1000)
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Async.scala#L27-L63" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Async.scala#L27-L63" target="_blank"><i class="fa fa-link "></i></a></pre>
</div>
<div class="pure-u-1 pure-u-md-11-24">
<canvas id="example21" style="display: block;overflow: scroll;"></canvas><script>advanced.Async().main(document.getElementById('example21'))</script>
</div></div>
<p>
- We have an <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">async</code> block, which contains a while loop. Each round around the loop, we wait for the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">mousedown</code> channel to start the path, waiting for either <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">mousemove</code> or <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">mouseup</code> (which continues the path or ends it respectively), fill the shape, and then wait for another <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">mousedown</code> before clearing the canvas and going again.
+ We have an <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">async</code> block, which contains a while loop. Each round around the loop, we wait for the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">mousedown</code> channel to start the path, waiting for either <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">mousemove</code> or <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">mouseup</code> (which continues the path or ends it respectively), fill the shape, and then wait for another <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">mousedown</code> before clearing the canvas and going again.
</p>
<p>
Hopefully you'd agree that this code is much simpler to read and understand than the previous version. In particular, the control-flow of the code goes from top to bottom in a &quot;natural&quot; fashion, rather than jumping around ad-hoc like in the previous callback-based design.</p>
<p>
- You may be wondering what these <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Channel</code> things are, and where they are coming from. Although these are not provided by Scala, they are pretty straightforward to define ourselves:
+ You may be wondering what these <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Channel</code> things are, and where they are coming from. Although these are not provided by Scala, they are pretty straightforward to define ourselves:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">class Channel[T](init: (T =&gt; Unit) =&gt; Unit){
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">class Channel[T](init: (T =&gt; Unit) =&gt; Unit){
init(update)
private[this] var value: Promise[T] = null
def apply(): Future[T] = {
@@ -2998,46 +3048,46 @@ async{
} p.trySuccess(t)
p.future
}
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Async.scala#L103-L122" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/lihaoyi/hands-on-scala-js/blob/master/examples/demos/src/main/scala/advanced/Async.scala#L103-L122" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
- The point of <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Channel</code> is to allow us to turn event-callbacks (like those provided by the DOM's <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">onmouseXXX</code> properties) into some kind of event-stream, that we can listen to asynchronously (via <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">apply</code> that returns a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Future</code>) or merge via <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">|</code>. This is a minimal implementation for what we need now, but it would be easy to provide more functionality (filter, map, etc.) as necessary.
+ The point of <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Channel</code> is to allow us to turn event-callbacks (like those provided by the DOM's <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">onmouseXXX</code> properties) into some kind of event-stream, that we can listen to asynchronously (via <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">apply</code> that returns a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Future</code>) or merge via <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">|</code>. This is a minimal implementation for what we need now, but it would be easy to provide more functionality (filter, map, etc.) as necessary.
</p>
<hr />
<p>
- Scala-Async is a Macro; that means that it is both more flexible and more limited than normal Scala, e.g. you cannot put the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">await</code> call inside a lambda or higher-order-function like <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">.map</code>. Like Futures, it doesn't provide any fundamentally new capabilities, but is a tool that can be used to simplify otherwise messy asynchronous workflows.</p>
+ Scala-Async is a Macro; that means that it is both more flexible and more limited than normal Scala, e.g. you cannot put the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">await</code> call inside a lambda or higher-order-function like <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">.map</code>. Like Futures, it doesn't provide any fundamentally new capabilities, but is a tool that can be used to simplify otherwise messy asynchronous workflows.</p>
- <div class="header scalatex-header scalatex-hover-container" id="DeviationsfromScala-JVM" style="display: block;"><h1 id="DeviationsfromScala-JVM">Deviations from Scala-JVM<a class="scalatex-header-link" href="#DeviationsfromScala-JVM" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a></h1><br /></div>
+ <div style="margin: 0px;color: #333;text-align: center;padding: 2.5em 2em 0;border-bottom: 1px solid #eee;display: block;" id="DeviationsfromScala-JVM" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><h1 style="margin: 0.2em 0;font-size: 3em;font-weight: 300;" id="DeviationsfromScala-JVM">Deviations from Scala-JVM<a class=" scalatex-site-Styles-headerLink" href="#DeviationsfromScala-JVM" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a></h1><br /></div>
<p>
Although Scala.js tries very hard to maintain compatibility with Scala-JVM, there are some parts where the two platforms differs. This can be roughly grouped into two things: differences in the libraries available, and differences in the language itself. This chapter will cover both of these facets.
</p>
-<h1 id="LanguageDifferences" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#LanguageDifferences" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Language Differences</h1>
+<h1 id="LanguageDifferences" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#LanguageDifferences" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Language Differences</h1>
- <h2 id="Primitivedatatypes" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Primitivedatatypes" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Primitive data types</h2>
+ <h2 id="Primitivedatatypes" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Primitivedatatypes" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Primitive data types</h2>
<p>
All primitive data types work exactly as on the JVM, with the three following
exceptions.
</p>
- <h3 id="FloatscanbehaveasDoublesbydefault" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#FloatscanbehaveasDoublesbydefault" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Floats can behave as Doubles by default</h3>
+ <h3 id="FloatscanbehaveasDoublesbydefault" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#FloatscanbehaveasDoublesbydefault" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Floats can behave as Doubles by default</h3>
<p>
Scala.js underspecifies the behavior of <code>Float</code>s by default. Any <code>Float</code> value can be stored as a <code>Double</code> instead, and any operation on <code>Float</code>s can be computed with double precision. The choice of whether or not to behave as such, when and where, is left to the
implementation.</p>
<p>
If exact single precision operations are important to your application, you can enable strict-floats semantics in Scala.js, with the following sbt setting:</p>
- <pre><code class="scala scalatex-highlight-js">scalaJSSemantics ~= { _.withStrictFloats(true) }</code></pre>
+ <pre><code class="scala scalatex-site-Styles-highlightMe">scalaJSSemantics ~= { _.withStrictFloats(true) }</code></pre>
<p>
Note that this can have a major impact on performance of your application on JS interpreters that do not support <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround">the Math.fround function</a>.
</p>
- <h3 id="toStringofFloat,DoubleandUnit" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#toStringofFloat,DoubleandUnit" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>toString of Float, Double and Unit</h3>
+ <h3 id="toStringofFloat,DoubleandUnit" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#toStringofFloat,DoubleandUnit" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>toString of Float, Double and Unit</h3>
<p>
<code>x.toString()</code> returns slightly different results for floating point numbers and <code>()</code> (<code>Unit</code>).
</p>
<div class="pure-g">
<div class="pure-u-1 pure-u-md-1-2">
- <pre><code class="scala scalatex-highlight-js">// Scala-JVM
+ <pre><code class="scala scalatex-site-Styles-highlightMe">// Scala-JVM
&gt; println(())
()
&gt; println(1.0)
@@ -3046,7 +3096,7 @@ async{
1.4
</code></pre></div>
<div class="pure-u-1 pure-u-md-1-2">
- <pre><code class="scala scalatex-highlight-js">// Scala.js
+ <pre><code class="scala scalatex-site-Styles-highlightMe">// Scala.js
&gt; println(())
undefined
&gt; println(1.0)
@@ -3059,7 +3109,7 @@ undefined
<p>
To get sensible and portable string representation of floating point numbers, use <code>String.format()</code> or related methods.
</p>
- <h3 id="Runtimetypetestsarebasedonvalues" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Runtimetypetestsarebasedonvalues" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Runtime type tests are based on values</h3>
+ <h3 id="Runtimetypetestsarebasedonvalues" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Runtimetypetestsarebasedonvalues" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Runtime type tests are based on values</h3>
<p>
Instance tests (and consequently pattern matching) on any of <code>Byte</code>, <code>Short</code>, <code>Int</code>, <code>Float</code>, <code>Double</code> are based on the value and not the type they were created with. The following are examples:</p>
<ul>
@@ -3081,15 +3131,15 @@ undefined
<code>NaN</code>, <code>Infinity</code>, <code>-Infinity</code> and <code>-0.0</code> match <code>Float</code>, <code>Double</code></li></ul>
<p>
As a consequence, the following apparent subtyping relationships hold:</p>
- <pre><code class="scala scalatex-highlight-js">Byte &lt;:&lt; Short &lt;:&lt; Int &lt;:&lt; Double
+ <pre><code class="scala scalatex-site-Styles-highlightMe">Byte &lt;:&lt; Short &lt;:&lt; Int &lt;:&lt; Double
&lt;:&lt; Float &lt;:&lt;</code></pre>
<p>
if strict-floats are enabled, or</p>
- <pre><code class="scala scalatex-highlight-js">Byte &lt;:&lt; Short &lt;:&lt; Int &lt;:&lt; Float =:= Double</code></pre>
+ <pre><code class="scala scalatex-site-Styles-highlightMe">Byte &lt;:&lt; Short &lt;:&lt; Int &lt;:&lt; Float =:= Double</code></pre>
<p>
otherwise.
</p>
- <h2 id="Undefinedbehaviors" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Undefinedbehaviors" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Undefined behaviors</h2>
+ <h2 id="Undefinedbehaviors" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Undefinedbehaviors" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Undefined behaviors</h2>
<p>
The JVM is a very well specified environment, which even specifies how some bugs are reported as exceptions. Some examples are:</p>
<ul>
@@ -3124,18 +3174,18 @@ undefined
<code>UndefinedBehaviorError</code>s are <i>fatal</i> in the sense that they are not matched by <code>case NonFatal(e)</code> handlers. This makes sure that they always crash your program as early as possible, so that you can detect and fix the bug. It is <i>never</i> OK to catch an <code>UndefinedBehaviorError</code> (other than in a testing framework), since that means your program will behave differently in fullOpt stage than in fastOpt.</p>
<p>
If you need a particular kind of exception to be thrown in compliance with the JVM semantics, you can do so with an sbt setting. For example, this setting enables compliant <code>asInstanceOf</code>s:</p>
- <pre><code class="scala scalatex-highlight-js">scalaJSSemantics ~= { _.withAsInstanceOfs(
+ <pre><code class="scala scalatex-site-Styles-highlightMe">scalaJSSemantics ~= { _.withAsInstanceOfs(
org.scalajs.core.tools.sem.CheckedBehavior.Compliant) }</code></pre>
<p>
Note that this will have (potentially major) performance impacts.</p>
<p>
For a more detailed rationale, see the section <a href="#Whydoeserrorbehaviordiffer?">Why does error behavior differ?</a>.
</p>
- <h2 id="Reflection" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Reflection" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Reflection</h2>
+ <h2 id="Reflection" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Reflection" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Reflection</h2>
<p>
Java reflection and, a fortiori, Scala reflection, are not supported. There is limited support for <code>java.lang.Class</code>, e.g., <code>obj.getClass.getName</code> will work for any Scala.js object (not for objects that come from JavaScript interop). Reflection makes it difficult to perform the optimizations that Scala.js heavily relies on. For a more detailed discussion on this topic, take a look at the section <a href="#WhyNoReflection?">Why No Reflection?</a>.
</p>
- <h2 id="Regularexpressions" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Regularexpressions" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Regular expressions</h2>
+ <h2 id="Regularexpressions" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Regularexpressions" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Regular expressions</h2>
<p>
<a href="http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide:Regular_Expressions">JavaScript regular expressions</a> are slightly different from <a href="http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html">Java regular expressions</a>. The support for regular expressions in Scala.js is implemented on top of JavaScript regexes.</p>
<p>
@@ -3145,32 +3195,32 @@ undefined
<li>
<code>StringLike.split(x: Array[Char])</code>
</li></ul>
- <h2 id="Symbols" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Symbols" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Symbols</h2>
+ <h2 id="Symbols" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Symbols" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Symbols</h2>
<p>
<code>scala.Symbol</code> is supported, but is a potential source of memory leaks in applications that make heavy use of symbols. The main reason is that
JavaScript does not support weak references, causing all symbols created by Scala.js to remain in memory throughout the lifetime of the application.
</p>
- <h2 id="Enumerations" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Enumerations" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Enumerations</h2>
+ <h2 id="Enumerations" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Enumerations" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Enumerations</h2>
<p>
The methods <code>Value()</code> and <code>Value(i: Int)</code> on <code>scala.Enumeration</code> use reflection to retrieve a string representation of the member name and are therefore -- in principle -- unsupported. However, since Enumerations are an integral part of the Scala library, Scala.js adds limited support for these two methods:</p>
<p>
Calls to either of these two methods of the forms:</p>
- <pre><code class="scala scalatex-highlight-js">val &lt;ident&gt; = Value
+ <pre><code class="scala scalatex-site-Styles-highlightMe">val &lt;ident&gt; = Value
val &lt;ident&gt; = Value(&lt;num&gt;)</code></pre>
<p>
are statically rewritten to (a slightly more complicated version of):</p>
- <pre><code class="scala scalatex-highlight-js">val &lt;ident&gt; = Value(&quot;&lt;ident&gt;&quot;)
+ <pre><code class="scala scalatex-site-Styles-highlightMe">val &lt;ident&gt; = Value(&quot;&lt;ident&gt;&quot;)
val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
<p>
Note that this also includes calls like</p>
- <pre><code class="scala scalatex-highlight-js">val A, B, C, D = Value</code></pre>
+ <pre><code class="scala scalatex-site-Styles-highlightMe">val A, B, C, D = Value</code></pre>
<p>
since they are desugared into separate <code>val</code> definitions.</p>
<p>
Calls to either of these two methods which could not be rewritten, or calls to constructors of the protected &lt;code&gt;Val&lt;/code&gt; class without an explicit name as parameter, will issue a warning.</p>
<p>
Note that the name rewriting honors the <code>nextName</code> iterator. Therefore, the full rewrite is:</p>
- <pre><code class="scala scalatex-highlight-js">val &lt;ident&gt; = Value(
+ <pre><code class="scala scalatex-site-Styles-highlightMe">val &lt;ident&gt; = Value(
if (nextName != null &amp;&amp; nextName.hasNext)
nextName.next()
else
@@ -3179,7 +3229,7 @@ val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
<p>
We believe that this covers most use cases of <code>scala.Enumeration</code>. Please let us know if another (generalized) rewrite would make your life easier.
</p>
-<h1 id="LibraryDifferences" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#LibraryDifferences" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Library Differences</h1>
+<h1 id="LibraryDifferences" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#LibraryDifferences" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Library Differences</h1>
<p>
@@ -3221,7 +3271,7 @@ val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
<p>
We'll go into each section bit by bit
</p>
- <h2 id="StandardLibrary" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#StandardLibrary" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Standard Library</h2>
+ <h2 id="StandardLibrary" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#StandardLibrary" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Standard Library</h2>
<table class="pure-table pure-table-horizontal half-table"><thead><th>Can Use</th><th>Can't Use</th></thead><tbody>
<tr>
@@ -3234,11 +3284,11 @@ val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
<td>Some of java.util.*</td><td>org.omg.CORBA, sun.misc.*</td>
</tr></tbody></table>
<p>
- You can use more-or-less the whole Scala standard library in Scala.js, sans some more esoteric components like the parallel collections or the tools. Furthermore, we've ported some subset of the Java standard library that many common Scala libraries depends on, including most of <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">java.lang.*</code> and some of <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">java.util.*</code>.</p>
+ You can use more-or-less the whole Scala standard library in Scala.js, sans some more esoteric components like the parallel collections or the tools. Furthermore, we've ported some subset of the Java standard library that many common Scala libraries depends on, including most of <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">java.lang.*</code> and some of <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">java.util.*</code>.</p>
<p>
There isn't a full list of standard library library APIs which are available from Scala.js, but it should be enough to give you a rough idea of what is supported. The full list of classes that have been ported to Scala.js is available under <a href="#AvailableJavaAPIs">Available Java APIs</a>
</p>
- <h2 id="Macrosv.s.Reflection" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Macrosv.s.Reflection" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Macros v.s. Reflection</h2>
+ <h2 id="Macrosv.s.Reflection" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Macrosv.s.Reflection" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Macros v.s. Reflection</h2>
<table class="pure-table pure-table-horizontal half-table"><thead><th>Can Use</th><th>Can't Use</th></thead><tbody>
<tr>
@@ -3250,7 +3300,7 @@ val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
<p>
On the other hand, Scala.js does support Macros, and macros can in many ways substitute many of the use cases that people have traditionally used reflection for (see <a href="#Macros">here</a>). For example, instead of using a reflection-based serialization library like <a href="https://github.com/scala/pickling">scala-pickling</a>, you can use a macro-based library such as <a href="https://github.com/lihaoyi/upickle">uPickle</a>.
</p>
- <h2 id="Pure-Scalav.s.JavaLibraries" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Pure-Scalav.s.JavaLibraries" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Pure-Scala v.s. Java Libraries</h2>
+ <h2 id="Pure-Scalav.s.JavaLibraries" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Pure-Scalav.s.JavaLibraries" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Pure-Scala v.s. Java Libraries</h2>
<table class="pure-table pure-table-horizontal half-table"><thead><th>Can Use</th><th>Can't Use</th></thead><tbody>
<tr>
@@ -3260,7 +3310,7 @@ val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
<p>
You cannot use any libraries which have a Java dependency. This means libraries like <a href="http://www.scalatest.org/">ScalaTest</a> or <a href="https://github.com/scalate/scalate">Scalate</a>, which depend on a number of external Java libraries or source files, cannot be used from Scala.js. You can only use libraries which have no dependency on Java libraries or sources.
</p>
- <h2 id="JavascriptAPIsv.s.JVMAPIs" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#JavascriptAPIsv.s.JVMAPIs" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Javascript APIs v.s. JVM APIs</h2>
+ <h2 id="JavascriptAPIsv.s.JVMAPIs" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#JavascriptAPIsv.s.JVMAPIs" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Javascript APIs v.s. JVM APIs</h2>
<table class="pure-table pure-table-horizontal half-table"><thead><th>Can Use</th><th>Can't Use</th></thead><tbody>
<tr>
@@ -3272,12 +3322,12 @@ val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
<p>
Apart from depending on Java sources, the other thing that you can't use in Scala.js are JVM-specific APIs. This means that anything which goes down to the underlying operating system, filesystem, GUI or network are unavailable in Scala.js. This makes sense when you consider that these capabilities are no provided by the browser which Scala.js runs in, and it's impossible to re-implement them ourselves.</p>
<p>
- In exchange for this, Scala.js provides you access to Browser APIs that do related things. Although you can't set up a HTTP server to take in-bound requests, you can make out-bound requests using <a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a> to other servers. You can't write to the filesystem or databases directly, but you can write to the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">dom.localStorage</code> provided by the browser. You can't use Swing or AWT or WebGL but instead work with the DOM and Canvas and WebGL.</p>
+ In exchange for this, Scala.js provides you access to Browser APIs that do related things. Although you can't set up a HTTP server to take in-bound requests, you can make out-bound requests using <a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a> to other servers. You can't write to the filesystem or databases directly, but you can write to the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">dom.localStorage</code> provided by the browser. You can't use Swing or AWT or WebGL but instead work with the DOM and Canvas and WebGL.</p>
<p>
Naturally, none of these are an exact replacement, as the browser environment is fundamentally different from that of a desktop application running on the JVM. Nonetheless, there are many analogues, and if so desired you can write code to abstract away these differences and run on both Scala.js and Scala-JVM
</p>
- <h2 id="Scala/Browsertoolingv.s.Javatooling" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Scala/Browsertoolingv.s.Javatooling" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Scala/Browser tooling v.s. Java tooling</h2>
+ <h2 id="Scala/Browsertoolingv.s.Javatooling" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Scala/Browsertoolingv.s.Javatooling" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Scala/Browser tooling v.s. Java tooling</h2>
<table class="pure-table pure-table-horizontal half-table"><thead><th>Can Use</th><th>Can't Use</th></thead><tbody>
<tr>
@@ -3292,13 +3342,13 @@ val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
Lastly, you gain access to browser tools that don't work with normal Scala: you can use the Chrome or Firefox consoles to poke at your Scala.js application from the command line, or their profilers/debuggers. With source maps set up, you can even step-through debug your Scala.js application directly in Chrome.</p>
- <div class="header scalatex-header scalatex-hover-container" id="TheCompilationPipeline" style="display: block;"><h1 id="TheCompilationPipeline">The Compilation Pipeline<a class="scalatex-header-link" href="#TheCompilationPipeline" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a></h1><br /></div>
+ <div style="margin: 0px;color: #333;text-align: center;padding: 2.5em 2em 0;border-bottom: 1px solid #eee;display: block;" id="TheCompilationPipeline" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><h1 style="margin: 0.2em 0;font-size: 3em;font-weight: 300;" id="TheCompilationPipeline">The Compilation Pipeline<a class=" scalatex-site-Styles-headerLink" href="#TheCompilationPipeline" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a></h1><br /></div>
<p>
Scala.js is implemented as a compiler plugin in the Scala compiler. Despite this, the overall process looks very different from that of a normal Scala application. This is because Scala.js optimizes for the size of the compiled executable, which is something that Scala-JVM does not usually do.
</p>
-<h1 id="WholeProgramOptimizaton" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#WholeProgramOptimizaton" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Whole Program Optimizaton</h1>
+<h1 id="WholeProgramOptimizaton" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#WholeProgramOptimizaton" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Whole Program Optimizaton</h1>
<p>
At a first approximation, Scala.js achieves its tiny executables by using whole-program optimization. Scala-JVM, like Java, allows for separate compilation: this means that after compilation, you can combine your compiled code with code compiled separately, which can interact with the code you already compiled in an ad-hoc basis: code from both sides can call each others methods, instantiate each others classes, etc. without any limits.
</p>
@@ -3314,7 +3364,7 @@ val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
<p>
It's worth noting that such optimizations exist as an option on the JVM aswell: <a href="http://proguard.sourceforge.net/">Proguard</a> is a well known library for doing similar DCE/optimization for Java/Scala applications, and is extensively used in developing mobile applications which face similar &quot;minimize-code-size&quot; constraints that web-apps do. However, the bulk of Scala code which runs on the server does not use these tools.
</p>
-<h1 id="HowCompilationWorks" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#HowCompilationWorks" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>How Compilation Works</h1>
+<h1 id="HowCompilationWorks" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#HowCompilationWorks" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>How Compilation Works</h1>
<p>
The Scala.js compilation pipeline is roughly split into multiple stages:
</p>
@@ -3341,7 +3391,7 @@ val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
<p>
But produced far larger (20mb) and slower executables. This section will explore each stage and we'll learn what these stages do, starting with a small example program:
</p>
- <pre><code class="scala scalatex-highlight-js">def main() = {
+ <pre><code class="scala scalatex-site-Styles-highlightMe">def main() = {
var x = 0
while(x &lt; 999){
x = x + &quot;2&quot;.toInt
@@ -3349,7 +3399,7 @@ val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
println(x)
}
</code></pre>
- <h2 id="Compilation" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Compilation" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Compilation</h2>
+ <h2 id="Compilation" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Compilation" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Compilation</h2>
<p>
As described earlier, the Scala.js compiler is implemented as a Scala compiler plugin, and lives in the main repository in <a href="https://github.com/scala-js/scala-js/tree/master/compiler">compiler/</a>. The bulk of the plugin runs after the <code>mixin</code> phase in the <a href="http://stackoverflow.com/a/4528092/871202">Scala compilation pipeline</a>. By this point:
</p>
@@ -3359,9 +3409,9 @@ val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
<li>
Pattern-matches have been compiled to imperative code</li>
<li>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">@tailrec</code> functions have been translated to while-loops, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">lazy val</code>s have been replaced by <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">var</code>s.</li>
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">@tailrec</code> functions have been translated to while-loops, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">lazy val</code>s have been replaced by <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">var</code>s.</li>
<li>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">trait</code>s have been <a href="http://stackoverflow.com/a/2558317/871202">replaced by interfaces and classes</a>
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">trait</code>s have been <a href="http://stackoverflow.com/a/2558317/871202">replaced by interfaces and classes</a>
</li></ul>
<p>
Overall, by the time the Scala.js compiler plugin takes action, most of the high-level features of the Scala language have already been removed. Compared to a hypothetical, alternative &quot;from scratch&quot; implementation, this approach has several advantages:
@@ -3382,15 +3432,15 @@ val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
The <code>.sjsir</code> files, destined for further compilation in the Scala.js pipeline.
</li></ul>
<p>
- The ASTs defined in the <code>.sjsir</code> files is at about the same level of abstraction as the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Tree</code>s that the Scala compiler is working with at this stage. However, the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Tree</code>s within the Scala compiler contain a lot of cruft related to the compiler internals, and are also not easily serializable. This phase cleans them up into a &quot;purer&quot; format, (defined in the <a href="https://github.com/scala-js/scala-js/blob/master/ir/src/main/scala/scala/scalajs/ir/Trees.scala">ir/</a> folder) which is also serializable.
+ The ASTs defined in the <code>.sjsir</code> files is at about the same level of abstraction as the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Tree</code>s that the Scala compiler is working with at this stage. However, the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Tree</code>s within the Scala compiler contain a lot of cruft related to the compiler internals, and are also not easily serializable. This phase cleans them up into a &quot;purer&quot; format, (defined in the <a href="https://github.com/scala-js/scala-js/blob/master/ir/src/main/scala/scala/scalajs/ir/Trees.scala">ir/</a> folder) which is also serializable.
</p>
<p>
This is the only phase in the Scala.js compilation pipeline that separate compilation is possible: you can compile many different sets of Scala.js <code>.scala</code> files separately, only to combine them later. This is used e.g. for distributing Scala.js libraries as Maven Jars, which are compiled separately by library authors to be combined into a final executable later.
</p>
- <h2 id="FastOptimization" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#FastOptimization" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Fast Optimization</h2>
+ <h2 id="FastOptimization" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#FastOptimization" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Fast Optimization</h2>
<p>
Without optimizations, the actual JavaScript code emitted for the above snippet would look like this:</p>
- <pre><code class="javascript scalatex-highlight-js">ScalaJS.c.Lexample_ScalaJSExample$.prototype.main__V = (function() {
+ <pre><code class="javascript scalatex-site-Styles-highlightMe">ScalaJS.c.Lexample_ScalaJSExample$.prototype.main__V = (function() {
var x = 0;
while ((x &lt; 999)) {
x = ((x + new ScalaJS.c.sci_StringOps().init___T(
@@ -3403,17 +3453,17 @@ val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
</p>
<ul>
<li>
- Scala-style method <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">def</code>s become Javascript-style prototype-function-assignment</li>
+ Scala-style method <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">def</code>s become Javascript-style prototype-function-assignment</li>
<li>
- Scala <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">val</code>s and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">var</code>s become Javascript <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">var</code>s</li>
+ Scala <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">val</code>s and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">var</code>s become Javascript <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">var</code>s</li>
<li>
- Scala <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">while</code>s become Javascript <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">while</code>s</li>
+ Scala <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">while</code>s become Javascript <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">while</code>s</li>
<li>
- Implicits are materialized, hence all the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">StringOps</code> and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">augmentString</code> extensions are present in the output</li>
+ Implicits are materialized, hence all the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">StringOps</code> and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">augmentString</code> extensions are present in the output</li>
<li>
- Classes and methods are fully-qualified, e.g. <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">println</code> becomes <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Predef().println</code></li>
+ Classes and methods are fully-qualified, e.g. <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">println</code> becomes <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Predef().println</code></li>
<li>
- Method names are qualified by their types, e.g. <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">__O__V</code> means that <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">println</code> takes <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Object</code> and returns <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">void</code>
+ Method names are qualified by their types, e.g. <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">__O__V</code> means that <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">println</code> takes <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Object</code> and returns <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">void</code>
</li></ul>
<p>
This is an incomplete description of the translation, but it should give a good sense of how the translation from Scala to Javascript looks like. In general, the output is verbose but straightforward.
@@ -3423,7 +3473,7 @@ val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
</p>
<ul>
<li>
- <b>Dead-code elimination</b>: entry-points to the program such as <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">@JSExport</code>ed methods/classes are kept, as are any methods/classes that these reference. All others are removed. This reduces the potentially 20mb of Javascript generated by a naive compilation to a more manageable 400kb-1mb for a typical application</li>
+ <b>Dead-code elimination</b>: entry-points to the program such as <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">@JSExport</code>ed methods/classes are kept, as are any methods/classes that these reference. All others are removed. This reduces the potentially 20mb of Javascript generated by a naive compilation to a more manageable 400kb-1mb for a typical application</li>
<li>
<b>Inlining</b>: under some circumstances, the optimizer inlines the implementation of methods at call sites. For example, it does so for all &quot;small enough&quot; methods. This typically reduces the code size by a small amount, but offers a several-times speedup of the generated code by inlining away much of the overhead from the abstractions (implicit-conversions, higher-order-functions, etc.) in Scala's standard library.</li>
<li>
@@ -3433,7 +3483,7 @@ val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
<p>
Applying these optimizations on our examples results in the following JavaScript code instead, which is what you typically execute in fastOpt stage:
</p>
- <pre><code class="javascript scalatex-highlight-js">ScalaJS.c.Lexample_ScalaJSExample$.prototype.main__V = (function() {
+ <pre><code class="javascript scalatex-site-Styles-highlightMe">ScalaJS.c.Lexample_ScalaJSExample$.prototype.main__V = (function() {
var x = 0;
while ((x &lt; 999)) {
var jsx$1 = x;
@@ -3449,13 +3499,13 @@ val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
});
</code></pre>
<p>
- As a whole-program optimization, it tightly ties together the code it is compiling and does not let you e.g. inject additional classes later. This does not mean you cannot interact with external code at all: you can, but it has to go through explicitly <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">@JSExport</code>ed methods and classes via Javascript Interop, and not on ad-hoc classes/methods within the module. Thus it's entirely possible to have multiple &quot;whole-programs&quot; running in the same browser; they just will likely have duplicate copies of e.g. standard library classes inside of them, since they cannot share the code as it's not exported.
+ As a whole-program optimization, it tightly ties together the code it is compiling and does not let you e.g. inject additional classes later. This does not mean you cannot interact with external code at all: you can, but it has to go through explicitly <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">@JSExport</code>ed methods and classes via Javascript Interop, and not on ad-hoc classes/methods within the module. Thus it's entirely possible to have multiple &quot;whole-programs&quot; running in the same browser; they just will likely have duplicate copies of e.g. standard library classes inside of them, since they cannot share the code as it's not exported.
</p>
<p>
While the input for this phase is the aggregate <code>.sjsir</code> files from your project and all your dependencies, the output is executable Javascript. This phase usually runs in less than a second, outputs a Javascript blob in the 400kb-1mb range, and is suitable for repeated use during development. This corresponds to the <code>fastOptJS</code> command in SBT.
</p>
- <h2 id="FullOptimization" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#FullOptimization" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Full Optimization</h2>
- <pre><code class="javascript scalatex-highlight-js">Fd.prototype.main = function() {
+ <h2 id="FullOptimization" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#FullOptimization" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Full Optimization</h2>
+ <pre><code class="javascript scalatex-site-Styles-highlightMe">Fd.prototype.main = function() {
for(var a = 0;999 &gt; a;) {
var b = (new D).j(&quot;2&quot;);
E();
@@ -3470,7 +3520,7 @@ val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
The <a href="https://developers.google.com/closure/compiler/">Google Closure Compiler</a> (GCC) is a set of tools that work with Javascript. It has multiple <a href="https://developers.google.com/closure/compiler/docs/compilation_levels">levels of optimization</a>, doing everything from basic whitespace-removal to heavy optimization. It is an old, relatively mature project that is relied on both inside and outside Google to optimize the delivery of Javascript to the browser.
</p>
<p>
- Scala.js uses GCC in its most aggressive mode: <a href="https://developers.google.com/closure/compiler/docs/api-tutorial3">Advanced Optimization</a>. GCC spits out a compressed, minified version of the Javascript (above) that <a href="#FastOptimization">Fast Optimization</a> spits out: e.g. in the example above, all identifiers have been renamed to short strings, the <code class="javascript scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">while</code>-loop has been replaced by a <code class="javascript scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">for</code>-loop, and the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">println</code> function has been inlined.
+ Scala.js uses GCC in its most aggressive mode: <a href="https://developers.google.com/closure/compiler/docs/api-tutorial3">Advanced Optimization</a>. GCC spits out a compressed, minified version of the Javascript (above) that <a href="#FastOptimization">Fast Optimization</a> spits out: e.g. in the example above, all identifiers have been renamed to short strings, the <code class="javascript scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">while</code>-loop has been replaced by a <code class="javascript scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">for</code>-loop, and the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">println</code> function has been inlined.
</p>
<p>
As described in the linked documentation, GCC performs optimizations such as:
@@ -3500,14 +3550,14 @@ val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
<p>
This whole chapter has been focused on the <i>what</i> but not the <i>why</i>. The chapter on <a href="#Scala.js'DesignSpace">Scala.js' Design Space</a> contains a section which talks about <a href="#SmallExecutables">why we care so much about small executables</a>.</p>
- <div class="header scalatex-header scalatex-hover-container" id="Scala.js'DesignSpace" style="display: block;"><h1 id="Scala.js'DesignSpace">Scala.js' Design Space<a class="scalatex-header-link" href="#Scala.js'DesignSpace" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a></h1><br /></div>
+ <div style="margin: 0px;color: #333;text-align: center;padding: 2.5em 2em 0;border-bottom: 1px solid #eee;display: block;" id="Scala.js'DesignSpace" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><h1 style="margin: 0.2em 0;font-size: 3em;font-weight: 300;" id="Scala.js'DesignSpace">Scala.js' Design Space<a class=" scalatex-site-Styles-headerLink" href="#Scala.js'DesignSpace" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a></h1><br /></div>
<p>
Scala.js is a relatively large project, and is the result of both an enormous amount of hard work as well as a number of decisions that craft what it's like to program in Scala.js today. Many of these decisions result in marked differences from the behavior of the same code running on the JVM. This chapter explores the reasoning and rationale behind these decisions.
</p>
-<h1 id="WhyNoReflection?" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#WhyNoReflection?" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Why No Reflection?</h1>
+<h1 id="WhyNoReflection?" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#WhyNoReflection?" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Why No Reflection?</h1>
<p>
Scala.js prohibits reflection as it makes dead-code elimination difficult, and the compiler relies heavily on dead-code elimination to generate reasonably-sized executables. The chapter on <a href="#TheCompilationPipeline">The Compilation Pipeline</a> goes into more detail of why, but a rough estimate of the effect of various optimizations on a small application is:
</p>
@@ -3524,11 +3574,11 @@ val &lt;ident&gt; = Value(&lt;num&gt;, &quot;&lt;ident&gt;&quot;)</code></pre>
<p>
The default output size of 20mb makes the executables difficult to work with. Even though browsers can deal with 20mb Javascript blobs, it takes the browser several seconds to even load it, and up to a minute after that for the JIT to optimize the whole thing.
</p>
- <h2 id="DeadCodeElimination" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#DeadCodeElimination" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Dead Code Elimination</h2>
+ <h2 id="DeadCodeElimination" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#DeadCodeElimination" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Dead Code Elimination</h2>
<p>
To illustrate why reflection makes things difficult, consider a tiny application:
</p>
- <pre><code class="scala scalatex-highlight-js">@JSExport
+ <pre><code class="scala scalatex-site-Styles-highlightMe">@JSExport
object App extends js.JSApp{
@JSExport
def main() = {
@@ -3546,22 +3596,22 @@ object Dead{
</p>
<ul>
<li>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">App</code> and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">App.main</code> are exported via <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">@JSExport</code>, and thus can't be considered dead code.</li>
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">App</code> and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">App.main</code> are exported via <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">@JSExport</code>, and thus can't be considered dead code.</li>
<li>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">App.foo</code> is called from <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">App.main</code>, and so has to be kept around</li>
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">App.foo</code> is called from <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">App.main</code>, and so has to be kept around</li>
<li>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">App.bar</code> is never called from <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">App.main</code> or <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">App.foo</code>, and so can be eliminated</li>
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">App.bar</code> is never called from <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">App.main</code> or <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">App.foo</code>, and so can be eliminated</li>
<li>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Dead</code>, including <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Dead.complexFunction</code>, are not called from any live code, and can be eliminated.
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Dead</code>, including <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Dead.complexFunction</code>, are not called from any live code, and can be eliminated.
</li></ul>
<p>
- The actual process is a bit more involved than this, but this is a first-approximation of how the dead-code-elimination works: you start with a small set of live code (e.g. <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">@JSExport</code>ed things), search out to find the things which are recursively reachable from that set, and eliminate all the rest. This means that the Scala.js compiler can eliminate, e.g., parts of the Scala standard library that you are not using. The standard library is not small, and makes up the bulk of the 20mb of the uncompressed blob.
+ The actual process is a bit more involved than this, but this is a first-approximation of how the dead-code-elimination works: you start with a small set of live code (e.g. <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">@JSExport</code>ed things), search out to find the things which are recursively reachable from that set, and eliminate all the rest. This means that the Scala.js compiler can eliminate, e.g., parts of the Scala standard library that you are not using. The standard library is not small, and makes up the bulk of the 20mb of the uncompressed blob.
</p>
- <h2 id="WhitherReflection?" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#WhitherReflection?" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Whither Reflection?</h2>
+ <h2 id="WhitherReflection?" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#WhitherReflection?" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Whither Reflection?</h2>
<p>
- To imagine why reflection makes this difficult, imagine a slightly modified program which includes some reflective calls in <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">App.main</code>
+ To imagine why reflection makes this difficult, imagine a slightly modified program which includes some reflective calls in <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">App.main</code>
</p>
- <pre><code class="scala scalatex-highlight-js">@JSExport
+ <pre><code class="scala scalatex-site-Styles-highlightMe">@JSExport
object App extends js.JSApp{
@JSExport
def main() = {
@@ -3575,9 +3625,9 @@ object Dead{
}
</code></pre>
<p>
- Here, we're assuming <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">userInput()</code> is some method which returns a <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">String</code> that was input by the user or otherwise somehow decided at runtime.</p>
+ Here, we're assuming <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">userInput()</code> is some method which returns a <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">String</code> that was input by the user or otherwise somehow decided at runtime.</p>
<p>
- We can start the same process: <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">App.main</code> is live since we <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">@JSExport</code>ed it, but what objects or methods are reachable from <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">App.main</code>? The answer is: it depends on the values of <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">userInput()</code>, which we don't know. And hence we don't know which classes or methods are reachable! Depending on what <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">userInput()</code> returns, any or all methods and classes could be used by <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">App.main()</code>.</p>
+ We can start the same process: <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">App.main</code> is live since we <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">@JSExport</code>ed it, but what objects or methods are reachable from <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">App.main</code>? The answer is: it depends on the values of <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">userInput()</code>, which we don't know. And hence we don't know which classes or methods are reachable! Depending on what <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">userInput()</code> returns, any or all methods and classes could be used by <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">App.main()</code>.</p>
<p>
This leaves us a few options:
</p>
@@ -3590,7 +3640,7 @@ object Dead{
Allow the user to annotate methods/classes that should be kept, and eliminate the rest.
</li></ul>
<p>
- All three are possible options: Scala.js started off with #1. #3 is the approach used by <a href="http://proguard.sourceforge.net/manual/examples.html#annotated">Proguard</a>, which lets you annotate things e.g. <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">@KeepApplication</code> to preserve things for reflection and preventing Proguard from eliminating them as dead code.
+ All three are possible options: Scala.js started off with #1. #3 is the approach used by <a href="http://proguard.sourceforge.net/manual/examples.html#annotated">Proguard</a>, which lets you annotate things e.g. <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">@KeepApplication</code> to preserve things for reflection and preventing Proguard from eliminating them as dead code.
</p>
<p>
In the end, Scala.js chose #2. This is helped by the fact that overall, Scala code tends not to use reflection as heavily as Java, or dynamic languages which use it heavily. Scala uses techniques such as <a href="http://docs.scala-lang.org/tutorials/tour/anonymous-function-syntax.html">lambdas</a> or <a href="http://docs.scala-lang.org/tutorials/tour/implicit-parameters.html">implicits</a> to satisfy many use cases which Java has traditionally used reflection for, while friendly to the optimizer.
@@ -3598,7 +3648,7 @@ object Dead{
<p>
There are a range of use-cases for reflection where you want to inspect an object's structure or methods, where lambdas or implicits don't help. People use reflection to <a href="http://jackson.codehaus.org/DataBindingDeepDive">serialize objects</a>, or for <a href="https://access.redhat.com/documentation/en-US/Fuse_ESB_Enterprise/7.1/html/Implementing_Enterprise_Integration_Patterns/files/BasicPrinciples-BeanIntegration.html">routing messages to methods</a>. However, both these cases can be satisfied by...
</p>
- <h2 id="Macros" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Macros" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Macros</h2>
+ <h2 id="Macros" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Macros" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Macros</h2>
<p>
The Scala programming language, since the 2.10.x series, has support for <a href="http://docs.scala-lang.org/overviews/macros/overview.html">Macros</a> in the language. Although experimental, these are heavily used in many projects such as Play and Slick and Akka, and allow a developer to perform compile-time computations and generate code where-ever the macros are used.
@@ -3609,7 +3659,7 @@ object Dead{
<p>
Practically, this means that you can use macros to do things such as inspecting the methods, fields and other type-level properties of a typed value. This allows us to do things like <a href="https://github.com/lihaoyi/upickle">serialize objects with no boilerplate</a>:
</p>
- <pre><code class="scala scalatex-highlight-js">import upickle._
+ <pre><code class="scala scalatex-site-Styles-highlightMe">import upickle._
case class Thing(a: Int, b: String)
write(Thing(1, &quot;gg&quot;))
@@ -3624,44 +3674,44 @@ write(Thing(1, &quot;gg&quot;))
<p>
Using macros here also plays well with the Scala.js optimizer: the macros are fully expanded before the optimizer is run, so by the time the optimizer sees the code, there is no more magic left: it is then free to do dead-code-elimination/inlining/other-optimizations without worrying about reflection causing the code to do weird things at runtime. Thus, we've managed to substitute most of the main use-cases of reflection, and so can do without it.
</p>
-<h1 id="Whydoeserrorbehaviordiffer?" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Whydoeserrorbehaviordiffer?" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Why does error behavior differ?</h1>
+<h1 id="Whydoeserrorbehaviordiffer?" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Whydoeserrorbehaviordiffer?" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Why does error behavior differ?</h1>
<p>
Scala.js deviates from the semantics of Scala-JVM in several ways. Many of these ways revolve around the edge-conditions of a program: what happens when something goes wrong? An array index is out of bounds? An integer is divided-by-zero? These differences cause some amount of annoyance when debugging, since when you mess up an array index, you expect an exception, not silently-invalid-data!
</p>
<p>
In most of these cases, it was a trade-off between performance and correctness. These are situations where the default semantics of Scala deviate from that of Javascript, and Scala.js would have to perform extra work to emulate the desired behavior. For example, compare the division behavior of the JVM and Javascript.</p>
- <h2 id="Divide-by-zero:acasestudy" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#Divide-by-zero:acasestudy" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Divide-by-zero: a case study</h2>
- <pre><code class="scala scalatex-highlight-js">/*JVM*/
+ <h2 id="Divide-by-zero:acasestudy" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#Divide-by-zero:acasestudy" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Divide-by-zero: a case study</h2>
+ <pre><code class="scala scalatex-site-Styles-highlightMe">/*JVM*/
15 / 4 // 3</code></pre>
- <pre><code class="javascript scalatex-highlight-js">/*JS*/
+ <pre><code class="javascript scalatex-site-Styles-highlightMe">/*JS*/
15 / 4 // 3.25</code></pre>
<p>
- On the JVM, integer division is a primitive, and dividing <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">15 / 4</code> gives <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">3</code>. However, in Javascript, it gives <code class="javascript scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">3.25</code>, since all numbers of double-precision floating points.
+ On the JVM, integer division is a primitive, and dividing <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">15 / 4</code> gives <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">3</code>. However, in Javascript, it gives <code class="javascript scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">3.25</code>, since all numbers of double-precision floating points.
</p>
<p>
- Scala.js works around this in the general case by adding a <code class="javascript scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">| 0</code> to the translation, e.g.
+ Scala.js works around this in the general case by adding a <code class="javascript scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">| 0</code> to the translation, e.g.
</p>
- <pre><code class="scala scalatex-highlight-js">/*JVM*/
+ <pre><code class="scala scalatex-site-Styles-highlightMe">/*JVM*/
15 / 4 // 3</code></pre>
- <pre><code class="javascript scalatex-highlight-js">/*JS*/
+ <pre><code class="javascript scalatex-site-Styles-highlightMe">/*JS*/
(15 / 4) | 0 // 3
</code></pre>
<p>
This gives the correct result for most numbers, and is reasonably efficient (actually, it tends to be <i>more</i> efficient on modern VMs). However, what about dividing-by-zero?
</p>
- <pre><code class="scala scalatex-highlight-js">/*JVM*/
+ <pre><code class="scala scalatex-site-Styles-highlightMe">/*JVM*/
15 / 0 // ArithmeticException</code></pre>
- <pre><code class="javascript scalatex-highlight-js">/*JS*/
+ <pre><code class="javascript scalatex-site-Styles-highlightMe">/*JS*/
15 / 0 // Infinity
(15 / 0) | 0 // 0
</code></pre>
<p>
- On the JVM, the JVM is kind enough to throw an exception for you. However, in Javascript, the integer simply wraps around to <code class="javascript scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">Infinity</code>, which then gets truncated down to zero.</p>
+ On the JVM, the JVM is kind enough to throw an exception for you. However, in Javascript, the integer simply wraps around to <code class="javascript scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">Infinity</code>, which then gets truncated down to zero.</p>
<p>
So that's the current behavior of integers in Scala.js. One may ask: can we fix it? And the answer is, we can:</p>
- <pre><code class="scala scalatex-highlight-js">/*JVM*/
+ <pre><code class="scala scalatex-site-Styles-highlightMe">/*JVM*/
1 / 0 // ArithmeticException</code></pre>
- <pre><code class="javascript scalatex-highlight-js">/*JS*/
+ <pre><code class="javascript scalatex-site-Styles-highlightMe">/*JS*/
function intDivide(x, y){
var z = x / y
if (z == Infinity) throw new ArithmeticException(&quot;Divide by Zero&quot;)
@@ -3669,19 +3719,19 @@ function intDivide(x, y){
}
intDivide(1, 0) // ArithmeticException</code></pre>
<p>
- This translation fixes the problem, and enforces that the <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">ArithmeticException</code> is thrown at the correct time. However, this approach causes some overhead: what was previously two primitive operations is now a function call, a local variable assignment, and a conditional. That is a lot more expensive than two primitive operations!
+ This translation fixes the problem, and enforces that the <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">ArithmeticException</code> is thrown at the correct time. However, this approach causes some overhead: what was previously two primitive operations is now a function call, a local variable assignment, and a conditional. That is a lot more expensive than two primitive operations!
</p>
- <h2 id="ThePerformance/CorrectnessTradeoff" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#ThePerformance/CorrectnessTradeoff" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>The Performance/Correctness Tradeoff</h2>
+ <h2 id="ThePerformance/CorrectnessTradeoff" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#ThePerformance/CorrectnessTradeoff" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>The Performance/Correctness Tradeoff</h2>
<p>
In the end, a lot of the semantic differences listed here come down to the same tradeoff: we could make the code behave more-like-Scala, but at a cost of adding overhead via function calls and other checks. Furthermore, the cost is paid regardless of whether the &quot;exceptional case&quot; is triggered or not: in the example above, every division in the program pays the cost!</p>
<p>
- The decision to not support these exceptional cases comes down to a value judgement: how often do people actually depend on an exception being thrown as part of their program semantics, e.g. by catching it and performing actions? And how often are they just a way of indicating bugs? It turns out that very few <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">ArithmeticException</code>s, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">ArrayIndexOutOfBoundsException</code>s, or similar are actually a necessary part of the program! They exist during debugging, but after that, these code paths are never relied upon &quot;in production&quot;.</p>
+ The decision to not support these exceptional cases comes down to a value judgement: how often do people actually depend on an exception being thrown as part of their program semantics, e.g. by catching it and performing actions? And how often are they just a way of indicating bugs? It turns out that very few <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">ArithmeticException</code>s, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">ArrayIndexOutOfBoundsException</code>s, or similar are actually a necessary part of the program! They exist during debugging, but after that, these code paths are never relied upon &quot;in production&quot;.</p>
<p>
Thus Scala.js goes for a compromise: in the Fast Optimization mode, we run the code with all these checks in place (this is work in progress; currently only <code>asInstanceOf</code>s are thus checked), so as to catch cases where these errors occur close-to-the-source and make it easy for you to debug them. In Full Optimization mode, on the other hand, we remove these checks, assuming you've already ran through these cases and found any bugs during development.</p>
<p>
This is a common pattern in situations where there's a tradeoff between debuggability and speed. In Scala.js' case, it allows us to get good debuggability in development, as well as good performance in production. There's some loss in debuggability in development, sacrificed in exchange for greater performance.
</p>
-<h1 id="SmallExecutables" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#SmallExecutables" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Small Executables</h1>
+<h1 id="SmallExecutables" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#SmallExecutables" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Small Executables</h1>
Why do we care so much about how big our executables are in Scala.js? Why don't we care about how big they are on Scala-JVM? This is mostly due to three reasons:
<ul>
@@ -3695,17 +3745,17 @@ intDivide(1, 0) // ArithmeticException</code></pre>
<p>
These factors combined means that Scala.js has to put in extra effort to optimize the code to reduce it's size at compile-time.
</p>
- <h2 id="RawVerbosity" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#RawVerbosity" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Raw Verbosity</h2>
+ <h2 id="RawVerbosity" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#RawVerbosity" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Raw Verbosity</h2>
<p>
Scala.js compiles to Javascript source code, while Scala-JVM compiles to Java bytecode. Java bytecode is a binary format and thus somewhat optimized for size, while Javascript is textual and is designed to be easy to read and write by hand.</p>
<p>
- What does these mean, concretely? This means that a symbol marking something, e.g. the start of a function, is often a single byte in Java bytecode. Even more, it may not have any delimiter at all, instead the meaning of the binary data being inferred from its position in the file! On the other hand, in Javascript, declaring a function takes a long-and-verbose <code class="javascript scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">function</code> keyword, which together with peripheral punctuation (<code>.</code>, <code> = </code>, etc.) often adds up to tens of bytes to express a single idea.</p>
+ What does these mean, concretely? This means that a symbol marking something, e.g. the start of a function, is often a single byte in Java bytecode. Even more, it may not have any delimiter at all, instead the meaning of the binary data being inferred from its position in the file! On the other hand, in Javascript, declaring a function takes a long-and-verbose <code class="javascript scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">function</code> keyword, which together with peripheral punctuation (<code>.</code>, <code> = </code>, etc.) often adds up to tens of bytes to express a single idea.</p>
<p>
What does this mean concretely? This means that expressing the same meaning in Javascript usually takes more &quot;raw code&quot; than expressing the same meaning in Java bytecode. Even though Java bytecode is relatively verbose for a binary format, it still is significantly more concise the Javascript, and it shows: the Scala standard library weighs in at a cool 6mb on Scala-JVM, while it weighs 20mb on Scala.js.</p>
<p>
All things being equal, this would mean that Scala.js would have to work harder to keep down code-size than Scala-JVM would have to. Alas, not all other things are equal.
</p>
- <h2 id="BrowsersPerformance" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#BrowsersPerformance" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Browsers Performance</h2>
+ <h2 id="BrowsersPerformance" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#BrowsersPerformance" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Browsers Performance</h2>
<p>
Without any optimization, a naive compilation to Scala.js results in an executable (Including the standard library) weighing around 20mb. On the surface, this isn't a problem: runtimes like the JVM have no issue with loading 20mb of Java bytecode to execute; many large desktop applications weigh in the 100s of megabytes while still loading and executing fine.</p>
<p>
@@ -3713,7 +3763,7 @@ intDivide(1, 0) // ArithmeticException</code></pre>
<p>
Overall, this means that you probably do not want to work with un-optimized Scala.js executables. Even for development, the slow load times and initial sluggishness make testing the results of your hard-work in the browser a frustrating experience. But that's not all...
</p>
- <h2 id="DeploymentSize" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#DeploymentSize" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Deployment Size</h2>
+ <h2 id="DeploymentSize" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#DeploymentSize" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Deployment Size</h2>
<p>
Scala.js applications often run in the browser. Not just any browser, but the browsers of your users, who had come to your website or web-app to try and accomplish some task. This is in stark contrast the Scala-JVM applications, which most often run on servers: servers that you own and control, and can deploy code to at your leisure.
</p>
@@ -3733,15 +3783,15 @@ intDivide(1, 0) // ArithmeticException</code></pre>
Thus, while on Scala-JVM you typically have executables that (including dependencies) end up weighing 10s to 100s of megabytes, Scala.js has a much tighter budget. A hello world Scala.js application weighs in at around 100kb, and as you write more code and use more libraries (and parts of the standard library) this number rises to the 100s of kb. This isn't tiny, especially compared to the many small Javascript libraries out there, but it definitely is much smaller than what you'd be used to on the JVM.</p>
- <div class="header scalatex-header scalatex-hover-container" id="JavaAPIs" style="display: block;"><h1 id="JavaAPIs">Java APIs<a class="scalatex-header-link" href="#JavaAPIs" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a></h1><br /></div>
+ <div style="margin: 0px;color: #333;text-align: center;padding: 2.5em 2em 0;border-bottom: 1px solid #eee;display: block;" id="JavaAPIs" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><h1 style="margin: 0.2em 0;font-size: 3em;font-weight: 300;" id="JavaAPIs">Java APIs<a class=" scalatex-site-Styles-headerLink" href="#JavaAPIs" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a></h1><br /></div>
<p>
- Below is a list of classes from the Java Standard Library that are available from Scala.js. In general, much of <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">java.lang</code>, and parts of <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">java.io</code>, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">java.util</code> and <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">java.net</code> have been ported over. This means that all these classes are available for use in Scala.js applications despite being part of the Java standard library.</p>
+ Below is a list of classes from the Java Standard Library that are available from Scala.js. In general, much of <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">java.lang</code>, and parts of <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">java.io</code>, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">java.util</code> and <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">java.net</code> have been ported over. This means that all these classes are available for use in Scala.js applications despite being part of the Java standard library.</p>
<p>
- There are many reasons you may want to port a Java class to Scala.js: you want to use it directly, you may be trying to port a library which uses it. In general, we haven't been porting things &quot;for fun&quot;, and obscure classes like <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">org.omg.corba</code> will likely never be ported: we've been porting things as the need arises in order to support libraries (e.g. <a href="https://github.com/lihaoyi/scala.rx">Scala.Rx</a> that need them.
+ There are many reasons you may want to port a Java class to Scala.js: you want to use it directly, you may be trying to port a library which uses it. In general, we haven't been porting things &quot;for fun&quot;, and obscure classes like <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">org.omg.corba</code> will likely never be ported: we've been porting things as the need arises in order to support libraries (e.g. <a href="https://github.com/lihaoyi/scala.rx">Scala.Rx</a> that need them.
</p>
-<h1 id="AvailableJavaAPIs" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#AvailableJavaAPIs" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Available Java APIs</h1>
+<h1 id="AvailableJavaAPIs" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#AvailableJavaAPIs" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Available Java APIs</h1>
<ul>
@@ -4039,7 +4089,7 @@ intDivide(1, 0) // ArithmeticException</code></pre>
<li>
<a href="https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html">java.util.regex.Pattern</a>
</li></ul>
-<h1 id="PortingJavaAPIs" style="display: block;" class="scalatex-header scalatex-hover-container"><a class="scalatex-header-link" href="#PortingJavaAPIs" style="position: absolute;right: 0;"><i class="fa fa-link"></i></a>Porting Java APIs</h1>
+<h1 id="PortingJavaAPIs" style="display: block;" class=" scalatex-site-Styles-hoverContainer scalatex-site-Styles-headerTag"><a class=" scalatex-site-Styles-headerLink" href="#PortingJavaAPIs" style="position: absolute;right: 0px;"><i class="fa fa-link"></i></a>Porting Java APIs</h1>
<p>
The process for making Java library classes available in Scala.js is relatively straightforward:</p>
<ul>
@@ -4061,12 +4111,12 @@ intDivide(1, 0) // ArithmeticException</code></pre>
<li>
Network APIs</li>
<li>
- <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">sun.misc.Unsafe</code>
+ <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">sun.misc.Unsafe</code>
</li></ul>
<p>
- And other similar APIs will either need to be rewritten to not-use them. For example, <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">AtomicXXXs</code> can be written without threading/unsafe APIs because Javascript is single-threaded, making the implementation for e.g. an <code class="scala scalatex-highlight-js" style="display: inline;padding: 0;margin: 0;">AtomicBoolean</code> pretty trivial:
+ And other similar APIs will either need to be rewritten to not-use them. For example, <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">AtomicXXXs</code> can be written without threading/unsafe APIs because Javascript is single-threaded, making the implementation for e.g. an <code class="scala scalatex-site-Styles-highlightMe" style="display: inline;padding: 0px;margin: 0px;">AtomicBoolean</code> pretty trivial:
</p>
- <pre class="scalatex-hover-container"><code class="scala scalatex-highlight-js hljs">package java.util.concurrent.atomic
+ <pre class=" scalatex-site-Styles-hoverContainer"><code class="scala scalatex-site-Styles-highlightMe">package java.util.concurrent.atomic
class AtomicBoolean(private[this] var value: Boolean) extends Serializable {
def this() = this(false)
@@ -4098,10 +4148,22 @@ class AtomicBoolean(private[this] var value: Boolean) extends Serializable {
override def toString(): String =
value.toString()
-}</code><a class="scalatex-header-link" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/scala-js/scala-js/blob/master/javalib/src/main/scala/java/util/concurrent/atomic/AtomicBoolean.scala#L0-L33" target="_blank"><i class="fa fa-link "></i></a></pre>
+}</code><a class=" scalatex-site-Styles-headerLink" style="position: absolute;right: 0.5em;top: 0.5em;display: block;font-size: 24px;" href="https://github.com/scala-js/scala-js/blob/master/javalib/src/main/scala/java/util/concurrent/atomic/AtomicBoolean.scala#L0-L33" target="_blank"><i class="fa fa-link "></i></a></pre>
<p>
Others can't be ported at all (e.g. <code>java.io.File</code>) simply because the API capabilities they provide (blocking reads &amp; writes to files) do not exist in the Javascript runtime.
</p>
</div>
-</div></div></body></html> \ No newline at end of file
+</div><script>
+ scalatex.scrollspy.Controller().main(
+ [{"value":"Hands-on Scala.js","children":[]},{"value":"Intro to Scala.js","children":[{"value":"About Javascript","children":[{"value":"Javascript-the-language","children":[]},{"value":"Javascript-the-platform","children":[]}]},{"value":"About Scala.js","children":[{"value":"The Language","children":[]},{"value":"Sharing Code","children":[]},{"value":"Client-Server Integration","children":[]}]}]},{"value":"Hands On","children":[{"value":"Getting Started","children":[{"value":"Opening up the Project","children":[]},{"value":"The Application Code","children":[]},{"value":"The Project Code","children":[{"value":"project/build.sbt","children":[]},{"value":"build.sbt","children":[]},{"value":"src/main/resources/index-dev.html","children":[]}]},{"value":"Publishing","children":[{"value":"Optimization","children":[]},{"value":"Blob Size","children":[]}]},{"value":"Recap","children":[]}]},{"value":"Making a Canvas App","children":[{"value":"Making a Sketchpad using Mouse Input","children":[]},{"value":"Making a Clock using setInterval","children":[]},{"value":"Tying it together: Flappy Box","children":[{"value":"Setting Up the Canvas","children":[]},{"value":"Defining our State","children":[]},{"value":"Game Logic","children":[]},{"value":"A Working Product","children":[]}]},{"value":"Canvas Recap","children":[{"value":"Development Speed","children":[]},{"value":"Full Scala","children":[]},{"value":"Seamless Javascript Interop","children":[]}]}]},{"value":"Interactive Web Pages","children":[{"value":"Hello World: HTML","children":[]},{"value":"Scalatags","children":[{"value":"User Input","children":[]},{"value":"Re-rendering","children":[]}]},{"value":"Using Web Services","children":[{"value":"Raw Javascript","children":[]},{"value":"dom.extensions","children":[]},{"value":"Parsing the Data","children":[]}]},{"value":"Tying it together: Weather Search","children":[]},{"value":"Interactive Web Pages Recap","children":[]}]},{"value":"The Command Line","children":[{"value":"Commands","children":[{"value":"The compile Command","children":[]},{"value":"The package Command","children":[]},{"value":"The fastOptJS Command","children":[]},{"value":"The fullOptJS Command","children":[]},{"value":"The run Command","children":[]},{"value":"The test Command","children":[]}]},{"value":"Headless Runtimes","children":[]},{"value":"Stages","children":[]}]},{"value":"Cross Publishing Libraries","children":[{"value":"A Simple Cross-Built Library","children":[{"value":"Build Configuration","children":[]},{"value":"Source Files","children":[]},{"value":"Running the Module","children":[]}]},{"value":"Further Work","children":[]},{"value":"Other Testing Libraries","children":[]}]},{"value":"Integrating Client-Server","children":[{"value":"A Client-Server Setup","children":[]},{"value":"Client-Server Reflections","children":[{"value":"Shared Templating","children":[]},{"value":"Shared Code","children":[]},{"value":"Boilerplate-free Serialization","children":[]}]},{"value":"What's Left?","children":[]},{"value":"Autowire","children":[{"value":"Setting up Autowire","children":[]},{"value":"Why Autowire?","children":[]}]}]}]},{"value":"In Depth","children":[{"value":"Advanced Techniques","children":[{"value":"Functional-Reactive UIs","children":[{"value":"Why FRP","children":[]},{"value":"FRP with Scala.Rx","children":[]},{"value":"More Rx","children":[]}]},{"value":"Asynchronous Workflows","children":[{"value":"Futures & Promises","children":[{"value":"Direct Use of XMLHttpRequest","children":[]},{"value":"Using dom.extensions.Ajax","children":[]},{"value":"Future Combinators","children":[]}]},{"value":"Scala-Async","children":[{"value":"Traditional Asynchrony","children":[]},{"value":"Using Scala-Async","children":[]}]}]}]},{"value":"Deviations from Scala-JVM","children":[{"value":"Language Differences","children":[{"value":"Primitive data types","children":[{"value":"Floats can behave as Doubles by default","children":[]},{"value":"toString of Float, Double and Unit","children":[]},{"value":"Runtime type tests are based on values","children":[]}]},{"value":"Undefined behaviors","children":[]},{"value":"Reflection","children":[]},{"value":"Regular expressions","children":[]},{"value":"Symbols","children":[]},{"value":"Enumerations","children":[]}]},{"value":"Library Differences","children":[{"value":"Standard Library","children":[]},{"value":"Macros v.s. Reflection","children":[]},{"value":"Pure-Scala v.s. Java Libraries","children":[]},{"value":"Javascript APIs v.s. JVM APIs","children":[]},{"value":"Scala/Browser tooling v.s. Java tooling","children":[]}]}]},{"value":"The Compilation Pipeline","children":[{"value":"Whole Program Optimizaton","children":[]},{"value":"How Compilation Works","children":[{"value":"Compilation","children":[]},{"value":"Fast Optimization","children":[]},{"value":"Full Optimization","children":[]}]}]},{"value":"Scala.js' Design Space","children":[{"value":"Why No Reflection?","children":[{"value":"Dead Code Elimination","children":[]},{"value":"Whither Reflection?","children":[]},{"value":"Macros","children":[]}]},{"value":"Why does error behavior differ?","children":[{"value":"Divide-by-zero: a case study","children":[]},{"value":"The Performance/Correctness Tradeoff","children":[]}]},{"value":"Small Executables","children":[{"value":"Raw Verbosity","children":[]},{"value":"Browsers Performance","children":[]},{"value":"Deployment Size","children":[]}]}]},{"value":"Java APIs","children":[{"value":"Available Java APIs","children":[]},{"value":"Porting Java APIs","children":[]}]}]}]
+ )</script><script>
+ ['DOMContentLoaded', 'load'].forEach(function(ev){
+ addEventListener(ev, function(){
+ Array.prototype.forEach.call(
+ document.getElementsByClassName('scalatex-site-Styles-highlightMe'),
+ hljs.highlightBlock
+ );
+ })
+ })
+ </script></body></body></html> \ No newline at end of file
diff --git a/scripts.js b/scripts.js
index 6ed5300..9abf203 100644
--- a/scripts.js
+++ b/scripts.js
@@ -1,9 +1,706 @@
var hljs=new function(){function j(v){return v.replace(/&/gm,"&amp;").replace(/</gm,"&lt;").replace(/>/gm,"&gt;")}function t(v){return v.nodeName.toLowerCase()}function h(w,x){var v=w&&w.exec(x);return v&&v.index==0}function r(w){var v=(w.className+" "+(w.parentNode?w.parentNode.className:"")).split(/\s+/);v=v.map(function(x){return x.replace(/^lang(uage)?-/,"")});return v.filter(function(x){return i(x)||/no(-?)highlight/.test(x)})[0]}function o(x,y){var v={};for(var w in x){v[w]=x[w]}if(y){for(var w in y){v[w]=y[w]}}return v}function u(x){var v=[];(function w(y,z){for(var A=y.firstChild;A;A=A.nextSibling){if(A.nodeType==3){z+=A.nodeValue.length}else{if(A.nodeType==1){v.push({event:"start",offset:z,node:A});z=w(A,z);if(!t(A).match(/br|hr|img|input/)){v.push({event:"stop",offset:z,node:A})}}}}return z})(x,0);return v}function q(w,y,C){var x=0;var F="";var z=[];function B(){if(!w.length||!y.length){return w.length?w:y}if(w[0].offset!=y[0].offset){return(w[0].offset<y[0].offset)?w:y}return y[0].event=="start"?w:y}function A(H){function G(I){return" "+I.nodeName+'="'+j(I.value)+'"'}F+="<"+t(H)+Array.prototype.map.call(H.attributes,G).join("")+">"}function E(G){F+="</"+t(G)+">"}function v(G){(G.event=="start"?A:E)(G.node)}while(w.length||y.length){var D=B();F+=j(C.substr(x,D[0].offset-x));x=D[0].offset;if(D==w){z.reverse().forEach(E);do{v(D.splice(0,1)[0]);D=B()}while(D==w&&D.length&&D[0].offset==x);z.reverse().forEach(A)}else{if(D[0].event=="start"){z.push(D[0].node)}else{z.pop()}v(D.splice(0,1)[0])}}return F+j(C.substr(x))}function m(y){function v(z){return(z&&z.source)||z}function w(A,z){return RegExp(v(A),"m"+(y.cI?"i":"")+(z?"g":""))}function x(D,C){if(D.compiled){return}D.compiled=true;D.k=D.k||D.bK;if(D.k){var z={};var E=function(G,F){if(y.cI){F=F.toLowerCase()}F.split(" ").forEach(function(H){var I=H.split("|");z[I[0]]=[G,I[1]?Number(I[1]):1]})};if(typeof D.k=="string"){E("keyword",D.k)}else{Object.keys(D.k).forEach(function(F){E(F,D.k[F])})}D.k=z}D.lR=w(D.l||/\b[A-Za-z0-9_]+\b/,true);if(C){if(D.bK){D.b="\\b("+D.bK.split(" ").join("|")+")\\b"}if(!D.b){D.b=/\B|\b/}D.bR=w(D.b);if(!D.e&&!D.eW){D.e=/\B|\b/}if(D.e){D.eR=w(D.e)}D.tE=v(D.e)||"";if(D.eW&&C.tE){D.tE+=(D.e?"|":"")+C.tE}}if(D.i){D.iR=w(D.i)}if(D.r===undefined){D.r=1}if(!D.c){D.c=[]}var B=[];D.c.forEach(function(F){if(F.v){F.v.forEach(function(G){B.push(o(F,G))})}else{B.push(F=="self"?D:F)}});D.c=B;D.c.forEach(function(F){x(F,D)});if(D.starts){x(D.starts,C)}var A=D.c.map(function(F){return F.bK?"\\.?("+F.b+")\\.?":F.b}).concat([D.tE,D.i]).map(v).filter(Boolean);D.t=A.length?w(A.join("|"),true):{exec:function(F){return null}}}x(y)}function c(T,L,J,R){function v(V,W){for(var U=0;U<W.c.length;U++){if(h(W.c[U].bR,V)){return W.c[U]}}}function z(V,U){if(h(V.eR,U)){return V}if(V.eW){return z(V.parent,U)}}function A(U,V){return !J&&h(V.iR,U)}function E(W,U){var V=M.cI?U[0].toLowerCase():U[0];return W.k.hasOwnProperty(V)&&W.k[V]}function w(aa,Y,X,W){var U=W?"":b.classPrefix,V='<span class="'+U,Z=X?"":"</span>";V+=aa+'">';return V+Y+Z}function N(){if(!I.k){return j(C)}var U="";var X=0;I.lR.lastIndex=0;var V=I.lR.exec(C);while(V){U+=j(C.substr(X,V.index-X));var W=E(I,V);if(W){H+=W[1];U+=w(W[0],j(V[0]))}else{U+=j(V[0])}X=I.lR.lastIndex;V=I.lR.exec(C)}return U+j(C.substr(X))}function F(){if(I.sL&&!f[I.sL]){return j(C)}var U=I.sL?c(I.sL,C,true,S):e(C);if(I.r>0){H+=U.r}if(I.subLanguageMode=="continuous"){S=U.top}return w(U.language,U.value,false,true)}function Q(){return I.sL!==undefined?F():N()}function P(W,V){var U=W.cN?w(W.cN,"",true):"";if(W.rB){D+=U;C=""}else{if(W.eB){D+=j(V)+U;C=""}else{D+=U;C=V}}I=Object.create(W,{parent:{value:I}})}function G(U,Y){C+=U;if(Y===undefined){D+=Q();return 0}var W=v(Y,I);if(W){D+=Q();P(W,Y);return W.rB?0:Y.length}var X=z(I,Y);if(X){var V=I;if(!(V.rE||V.eE)){C+=Y}D+=Q();do{if(I.cN){D+="</span>"}H+=I.r;I=I.parent}while(I!=X.parent);if(V.eE){D+=j(Y)}C="";if(X.starts){P(X.starts,"")}return V.rE?0:Y.length}if(A(Y,I)){throw new Error('Illegal lexeme "'+Y+'" for mode "'+(I.cN||"<unnamed>")+'"')}C+=Y;return Y.length||1}var M=i(T);if(!M){throw new Error('Unknown language: "'+T+'"')}m(M);var I=R||M;var S;var D="";for(var K=I;K!=M;K=K.parent){if(K.cN){D=w(K.cN,"",true)+D}}var C="";var H=0;try{var B,y,x=0;while(true){I.t.lastIndex=x;B=I.t.exec(L);if(!B){break}y=G(L.substr(x,B.index-x),B[0]);x=B.index+y}G(L.substr(x));for(var K=I;K.parent;K=K.parent){if(K.cN){D+="</span>"}}return{r:H,value:D,language:T,top:I}}catch(O){if(O.message.indexOf("Illegal")!=-1){return{r:0,value:j(L)}}else{throw O}}}function e(y,x){x=x||b.languages||Object.keys(f);var v={r:0,value:j(y)};var w=v;x.forEach(function(z){if(!i(z)){return}var A=c(z,y,false);A.language=z;if(A.r>w.r){w=A}if(A.r>v.r){w=v;v=A}});if(w.language){v.second_best=w}return v}function g(v){if(b.tabReplace){v=v.replace(/^((<[^>]+>|\t)+)/gm,function(w,z,y,x){return z.replace(/\t/g,b.tabReplace)})}if(b.useBR){v=v.replace(/\n/g,"<br>")}return v}function p(A){var B=r(A);if(/no(-?)highlight/.test(B)){return}var y;if(b.useBR){y=document.createElementNS("http://www.w3.org/1999/xhtml","div");y.innerHTML=A.innerHTML.replace(/\n/g,"").replace(/<br[ \/]*>/g,"\n")}else{y=A}var z=y.textContent;var v=B?c(B,z,true):e(z);var x=u(y);if(x.length){var w=document.createElementNS("http://www.w3.org/1999/xhtml","div");w.innerHTML=v.value;v.value=q(x,u(w),z)}v.value=g(v.value);A.innerHTML=v.value;A.className+=" hljs "+(!B&&v.language||"");A.result={language:v.language,re:v.r};if(v.second_best){A.second_best={language:v.second_best.language,re:v.second_best.r}}}var b={classPrefix:"hljs-",tabReplace:null,useBR:false,languages:undefined};function s(v){b=o(b,v)}function l(){if(l.called){return}l.called=true;var v=document.querySelectorAll("pre code");Array.prototype.forEach.call(v,p)}function a(){addEventListener("DOMContentLoaded",l,false);addEventListener("load",l,false)}var f={};var n={};function d(v,x){var w=f[v]=x(this);if(w.aliases){w.aliases.forEach(function(y){n[y]=v})}}function k(){return Object.keys(f)}function i(v){return f[v]||f[n[v]]}this.highlight=c;this.highlightAuto=e;this.fixMarkup=g;this.highlightBlock=p;this.configure=s;this.initHighlighting=l;this.initHighlightingOnLoad=a;this.registerLanguage=d;this.listLanguages=k;this.getLanguage=i;this.inherit=o;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";this.BNR="\\b(0b[01]+)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\[\\s\\S]",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE]};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE]};this.PWM={b:/\b(a|an|the|are|I|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such)\b/};this.CLCM={cN:"comment",b:"//",e:"$",c:[this.PWM]};this.CBCM={cN:"comment",b:"/\\*",e:"\\*/",c:[this.PWM]};this.HCM={cN:"comment",b:"#",e:"$",c:[this.PWM]};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.CSSNM={cN:"number",b:this.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0};this.RM={cN:"regexp",b:/\//,e:/\/[gim]*/,i:/\n/,c:[this.BE,{b:/\[/,e:/\]/,r:0,c:[this.BE]}]};this.TM={cN:"title",b:this.IR,r:0};this.UTM={cN:"title",b:this.UIR,r:0}}();hljs.registerLanguage("coffeescript",function(c){var b={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",reserved:"case default function var void with const let enum export import native __hasProp __extends __slice __bind __indexOf",built_in:"npm require console print module global window document"};var a="[A-Za-z$_][0-9A-Za-z$_]*";var f=c.inherit(c.TM,{b:a});var e={cN:"subst",b:/#\{/,e:/}/,k:b};var d=[c.BNM,c.inherit(c.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'''/,e:/'''/,c:[c.BE]},{b:/'/,e:/'/,c:[c.BE]},{b:/"""/,e:/"""/,c:[c.BE,e]},{b:/"/,e:/"/,c:[c.BE,e]}]},{cN:"regexp",v:[{b:"///",e:"///",c:[e,c.HCM]},{b:"//[gim]*",r:0},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{cN:"property",b:"@"+a},{b:"`",e:"`",eB:true,eE:true,sL:"javascript"}];e.c=d;return{aliases:["coffee","cson","iced"],k:b,i:/\/\*/,c:d.concat([{cN:"comment",b:"###",e:"###"},c.HCM,{cN:"function",b:"(^\\s*|\\B)("+a+"\\s*=\\s*)?(\\(.*\\))?\\s*\\B[-=]>",e:"[-=]>",rB:true,c:[f,{cN:"params",b:"\\([^\\(]",rB:true,c:[{b:/\(/,e:/\)/,k:b,c:["self"].concat(d)}]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:true,i:/[:="\[\]]/,c:[f]},f]},{cN:"attribute",b:a+":",e:":",rB:true,eE:true,r:0}])}});hljs.registerLanguage("nginx",function(c){var b={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+c.UIR}]};var a={eW:true,l:"[a-z/_]+",k:{built_in:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[c.HCM,{cN:"string",c:[c.BE,b],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{cN:"url",b:"([a-z]+):/",e:"\\s",eW:true,eE:true,c:[b]},{cN:"regexp",c:[c.BE,b],v:[{b:"\\s\\^",e:"\\s|{|;",rE:true},{b:"~\\*?\\s+",e:"\\s|{|;",rE:true},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},b]};return{aliases:["nginxconf"],c:[c.HCM,{b:c.UIR+"\\s",e:";|{",rB:true,c:[{cN:"title",b:c.UIR,starts:a}],r:0}],i:"[^\\s\\}]"}});hljs.registerLanguage("json",function(a){var e={literal:"true false null"};var d=[a.QSM,a.CNM];var c={cN:"value",e:",",eW:true,eE:true,c:d,k:e};var b={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:true,eE:true,c:[a.BE],i:"\\n",starts:c}],i:"\\S"};var f={b:"\\[",e:"\\]",c:[a.inherit(c,{cN:null})],i:"\\S"};d.splice(d.length,0,b,f);return{c:d,k:e,i:"\\S"}});hljs.registerLanguage("http",function(a){return{i:"\\S",c:[{cN:"status",b:"^HTTP/[0-9\\.]+",e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{cN:"request",b:"^[A-Z]+ (.*?) HTTP/[0-9\\.]+$",rB:true,e:"$",c:[{cN:"string",b:" ",e:" ",eB:true,eE:true}]},{cN:"attribute",b:"^\\w",e:": ",eE:true,i:"\\n|\\s|=",starts:{cN:"string",e:"$"}},{b:"\\n\\n",starts:{sL:"",eW:true}}]}});hljs.registerLanguage("javascript",function(a){return{aliases:["js"],k:{keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document"},c:[{cN:"pi",b:/^\s*('|")use strict('|")/,r:10},a.ASM,a.QSM,a.CLCM,a.CBCM,a.CNM,{b:"("+a.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[a.CLCM,a.CBCM,a.RM,{b:/</,e:/>;/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:true,c:[a.inherit(a.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,c:[a.CLCM,a.CBCM],i:/["'\(]/}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+a.IR,r:0}]}});hljs.registerLanguage("sql",function(a){var b={cN:"comment",b:"--",e:"$"};return{cI:true,i:/[<>]/,c:[{cN:"operator",bK:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate savepoint release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup",e:/;/,eW:true,k:{keyword:"abs absolute acos action add adddate addtime aes_decrypt aes_encrypt after aggregate all allocate alter analyze and any are as asc ascii asin assertion at atan atan2 atn2 authorization authors avg backup before begin benchmark between bin binlog bit_and bit_count bit_length bit_or bit_xor both by cache call cascade cascaded case cast catalog ceil ceiling chain change changed char_length character_length charindex charset check checksum checksum_agg choose close coalesce coercibility collate collation collationproperty column columns columns_updated commit compress concat concat_ws concurrent connect connection connection_id consistent constraint constraints continue contributors conv convert convert_tz corresponding cos cot count count_big crc32 create cross cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime data database databases datalength date_add date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts datetimeoffsetfromparts day dayname dayofmonth dayofweek dayofyear deallocate declare decode default deferrable deferred degrees delayed delete des_decrypt des_encrypt des_key_file desc describe descriptor diagnostics difference disconnect distinct distinctrow div do domain double drop dumpfile each else elt enclosed encode encrypt end end-exec engine engines eomonth errors escape escaped event eventdata events except exception exec execute exists exp explain export_set extended external extract fast fetch field fields find_in_set first first_value floor flush for force foreign format found found_rows from from_base64 from_days from_unixtime full function get get_format get_lock getdate getutcdate global go goto grant grants greatest group group_concat grouping grouping_id gtid_subset gtid_subtract handler having help hex high_priority hosts hour ident_current ident_incr ident_seed identified identity if ifnull ignore iif ilike immediate in index indicator inet6_aton inet6_ntoa inet_aton inet_ntoa infile initially inner innodb input insert install instr intersect into is is_free_lock is_ipv4 is_ipv4_compat is_ipv4_mapped is_not is_not_null is_used_lock isdate isnull isolation join key kill language last last_day last_insert_id last_value lcase lead leading least leaves left len lenght level like limit lines ln load load_file local localtime localtimestamp locate lock log log10 log2 logfile logs low_priority lower lpad ltrim make_set makedate maketime master master_pos_wait match matched max md5 medium merge microsecond mid min minute mod mode module month monthname mutex name_const names national natural nchar next no no_write_to_binlog not now nullif nvarchar oct octet_length of old_password on only open optimize option optionally or ord order outer outfile output pad parse partial partition password patindex percent_rank percentile_cont percentile_disc period_add period_diff pi plugin position pow power pragma precision prepare preserve primary prior privileges procedure procedure_analyze processlist profile profiles public publishingservername purge quarter query quick quote quotename radians rand read references regexp relative relaylog release release_lock rename repair repeat replace replicate reset restore restrict return returns reverse revoke right rlike rollback rollup round row row_count rows rpad rtrim savepoint schema scroll sec_to_time second section select serializable server session session_user set sha sha1 sha2 share show sign sin size slave sleep smalldatetimefromparts snapshot some soname soundex sounds_like space sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_no_cache sql_small_result sql_variant_property sqlstate sqrt square start starting status std stddev stddev_pop stddev_samp stdev stdevp stop str str_to_date straight_join strcmp string stuff subdate substr substring subtime subtring_index sum switchoffset sysdate sysdatetime sysdatetimeoffset system_user sysutcdatetime table tables tablespace tan temporary terminated tertiary_weights then time time_format time_to_sec timediff timefromparts timestamp timestampadd timestampdiff timezone_hour timezone_minute to to_base64 to_days to_seconds todatetimeoffset trailing transaction translation trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse ucase uncompress uncompressed_length unhex unicode uninstall union unique unix_timestamp unknown unlock update upgrade upped upper usage use user user_resources using utc_date utc_time utc_timestamp uuid uuid_short validate_password_strength value values var var_pop var_samp variables variance varp version view warnings week weekday weekofyear weight_string when whenever where with work write xml xor year yearweek zon",literal:"true false null",built_in:"array bigint binary bit blob boolean char character date dec decimal float int integer interval number numeric real serial smallint varchar varying int8 serial8 text"},c:[{cN:"string",b:"'",e:"'",c:[a.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[a.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[a.BE]},a.CNM,a.CBCM,b]},a.CBCM,b]}});hljs.registerLanguage("php",function(b){var e={cN:"variable",b:"(\\$|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*"};var a={cN:"preprocessor",b:/<\?(php)?|\?>/};var c={cN:"string",c:[b.BE,a],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},b.inherit(b.ASM,{i:null}),b.inherit(b.QSM,{i:null})]};var d={v:[b.BNM,b.CNM]};return{aliases:["php3","php4","php5","php6"],cI:true,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",c:[b.CLCM,b.HCM,{cN:"comment",b:"/\\*",e:"\\*/",c:[{cN:"phpdoc",b:"\\s@[A-Za-z]+"},a]},{cN:"comment",b:"__halt_compiler.+?;",eW:true,k:"__halt_compiler",l:b.UIR},{cN:"string",b:"<<<['\"]?\\w+['\"]?$",e:"^\\w+;",c:[b.BE]},a,e,{cN:"function",bK:"function",e:/[;{]/,eE:true,i:"\\$|\\[|%",c:[b.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",e,b.CBCM,c,d]}]},{cN:"class",bK:"class interface",e:"{",eE:true,i:/[:\(\$"]/,c:[{bK:"extends implements"},b.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[b.UTM]},{bK:"use",e:";",c:[b.UTM]},{b:"=>"},c,d]}});hljs.registerLanguage("makefile",function(a){var b={cN:"variable",b:/\$\(/,e:/\)/,c:[a.BE]};return{aliases:["mk","mak"],c:[a.HCM,{b:/^\w+\s*\W*=/,rB:true,r:0,starts:{cN:"constant",e:/\s*\W*=/,eE:true,starts:{e:/$/,r:0,c:[b]}}},{cN:"title",b:/^[\w]+:\s*$/},{cN:"phony",b:/^\.PHONY:/,e:/$/,k:".PHONY",l:/[\.\w]+/},{b:/^\t+/,e:/$/,r:0,c:[a.QSM,b]}]}});hljs.registerLanguage("bash",function(b){var a={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)\}/}]};var d={cN:"string",b:/"/,e:/"/,c:[b.BE,a,{cN:"variable",b:/\$\(/,e:/\)/,c:[b.BE]}]};var c={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/-?[a-z\.]+/,k:{keyword:"if then else elif fi for break continue while in do done exit return set declare case esac export exec",literal:"true false",built_in:"printf echo read cd pwd pushd popd dirs let eval unset typeset readonly getopts source shopt caller type hash bind help sudo",operator:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"shebang",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:true,c:[b.inherit(b.TM,{b:/\w[\w\d_]*/})],r:0},b.HCM,b.NM,d,c,a]}});hljs.registerLanguage("cpp",function(a){var b={keyword:"false int float while private char catch export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const struct for static_cast|10 union namespace unsigned long throw volatile static protected bool template mutable if public friend do return goto auto void enum else break new extern using true class asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue wchar_t inline delete alignof char16_t char32_t constexpr decltype noexcept nullptr static_assert thread_local restrict _Bool complex _Complex _Imaginary",built_in:"std string cin cout cerr clog stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf"};return{aliases:["c","h","c++","h++"],k:b,i:"</",c:[a.CLCM,a.CBCM,a.QSM,{cN:"string",b:"'\\\\?.",e:"'",i:"."},{cN:"number",b:"\\b(\\d+(\\.\\d*)?|\\.\\d+)(u|U|l|L|ul|UL|f|F)"},a.CNM,{cN:"preprocessor",b:"#",e:"$",k:"if else elif endif define undef warning error line pragma",c:[{b:'include\\s*[<"]',e:'[>"]',k:"include",i:"\\n"},a.CLCM]},{cN:"stl_container",b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:b,c:["self"]},{b:a.IR+"::"}]}});hljs.registerLanguage("perl",function(c){var d="getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qqfileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmgetsub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedirioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when";var f={cN:"subst",b:"[$@]\\{",e:"\\}",k:d};var g={b:"->{",e:"}"};var a={cN:"variable",v:[{b:/\$\d/},{b:/[\$\%\@](\^\w\b|#\w+(\:\:\w+)*|{\w+}|\w+(\:\:\w*)*)/},{b:/[\$\%\@][^\s\w{]/,r:0}]};var e={cN:"comment",b:"^(__END__|__DATA__)",e:"\\n$",r:5};var h=[c.BE,f,a];var b=[a,c.HCM,e,{cN:"comment",b:"^\\=\\w",e:"\\=cut",eW:true},g,{cN:"string",c:h,v:[{b:"q[qwxr]?\\s*\\(",e:"\\)",r:5},{b:"q[qwxr]?\\s*\\[",e:"\\]",r:5},{b:"q[qwxr]?\\s*\\{",e:"\\}",r:5},{b:"q[qwxr]?\\s*\\|",e:"\\|",r:5},{b:"q[qwxr]?\\s*\\<",e:"\\>",r:5},{b:"qw\\s+q",e:"q",r:5},{b:"'",e:"'",c:[c.BE]},{b:'"',e:'"'},{b:"`",e:"`",c:[c.BE]},{b:"{\\w+}",c:[],r:0},{b:"-?\\w+\\s*\\=\\>",c:[],r:0}]},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\/\\/|"+c.RSR+"|\\b(split|return|print|reverse|grep)\\b)\\s*",k:"split return print reverse grep",r:0,c:[c.HCM,e,{cN:"regexp",b:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",r:10},{cN:"regexp",b:"(m|qr)?/",e:"/[a-z]*",c:[c.BE],r:0}]},{cN:"sub",bK:"sub",e:"(\\s*\\(.*?\\))?[;{]",r:5},{cN:"operator",b:"-\\w\\b",r:0}];f.c=b;g.c=b;return{aliases:["pl"],k:d,c:b}});hljs.registerLanguage("ini",function(a){return{cI:true,i:/\S/,c:[{cN:"comment",b:";",e:"$"},{cN:"title",b:"^\\[",e:"\\]"},{cN:"setting",b:"^[a-z0-9\\[\\]_-]+[ \\t]*=[ \\t]*",e:"$",c:[{cN:"value",eW:true,k:"on off true false yes no",c:[a.QSM,a.NM],r:0}]}]}});hljs.registerLanguage("apache",function(a){var b={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:true,c:[a.HCM,{cN:"tag",b:"</?",e:">"},{cN:"keyword",b:/\w+/,r:0,k:{common:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"sqbracket",b:"\\s\\[",e:"\\]$"},{cN:"cbracket",b:"[\\$%]\\{",e:"\\}",c:["self",b]},b,a.QSM]}}],i:/\S/}});hljs.registerLanguage("java",function(c){var b=c.UIR+"(<"+c.UIR+">)?";var a="false synchronized int abstract float private char boolean static null if const for true while long throw strictfp finally protected import native final return void enum else break transient new catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private";return{aliases:["jsp"],k:a,i:/<\//,c:[{cN:"javadoc",b:"/\\*\\*",e:"\\*/",r:0,c:[{cN:"javadoctag",b:"(^|\\s)@[A-Za-z]+"}]},c.CLCM,c.CBCM,c.ASM,c.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:true,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},c.UTM]},{bK:"new",e:/\s/,r:0},{cN:"function",b:"("+b+"\\s+)+"+c.UIR+"\\s*\\(",rB:true,e:/[{;=]/,eE:true,k:a,c:[{b:c.UIR+"\\s*\\(",rB:true,c:[c.UTM]},{cN:"params",b:/\(/,e:/\)/,k:a,c:[c.ASM,c.QSM,c.CNM,c.CBCM]},c.CLCM,c.CBCM]},c.CNM,{cN:"annotation",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("xml",function(a){var c="[A-Za-z0-9\\._:-]+";var d={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php",subLanguageMode:"continuous"};var b={eW:true,i:/</,r:0,c:[d,{cN:"attribute",b:c,r:0},{b:"=",r:0,c:[{cN:"value",v:[{b:/"/,e:/"/},{b:/'/,e:/'/},{b:/[^\s\/>]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xsl","plist"],cI:true,c:[{cN:"doctype",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"<!--",e:"-->",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{title:"style"},c:[b],starts:{e:"</style>",rE:true,sL:"css"}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{title:"script"},c:[b],starts:{e:"<\/script>",rE:true,sL:"javascript"}},{b:"<%",e:"%>",sL:"vbscript"},d,{cN:"pi",b:/<\?\w+/,e:/\?>/,r:10},{cN:"tag",b:"</?",e:"/?>",c:[{cN:"title",b:/[^ \/><\n\t]+/,r:0},b]}]}});hljs.registerLanguage("markdown",function(a){return{aliases:["md","mkdown","mkd"],c:[{cN:"header",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"blockquote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"`.+?`"},{b:"^( {4}|\t)",e:"$",r:0}]},{cN:"horizontal_rule",b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:true,c:[{cN:"link_label",b:"\\[",e:"\\]",eB:true,rE:true,r:0},{cN:"link_url",b:"\\]\\(",e:"\\)",eB:true,eE:true},{cN:"link_reference",b:"\\]\\[",e:"\\]",eB:true,eE:true}],r:10},{b:"^\\[.+\\]:",rB:true,c:[{cN:"link_reference",b:"\\[",e:"\\]:",eB:true,eE:true,starts:{cN:"link_url",e:"$"}}]}]}});hljs.registerLanguage("cs",function(c){var b="abstract as base bool break byte case catch char checked const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long new null object operator out override params private protected public readonly ref return sbyte sealed short sizeof stackalloc static string struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual volatile void while async await protected public private internal ascending descending from get group into join let orderby partial select set value var where yield";var a=c.IR+"(<"+c.IR+">)?";return{aliases:["csharp"],k:b,i:/::/,c:[{cN:"comment",b:"///",e:"$",rB:true,c:[{cN:"xmlDocTag",v:[{b:"///",r:0},{b:"<!--|-->"},{b:"</?",e:">"}]}]},c.CLCM,c.CBCM,{cN:"preprocessor",b:"#",e:"$",k:"if else elif endif define undef warning error line region endregion pragma checksum"},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},c.ASM,c.QSM,c.CNM,{bK:"class namespace interface",e:/[{;=]/,i:/[^\s:]/,c:[c.TM,c.CLCM,c.CBCM]},{bK:"new",e:/\s/,r:0},{cN:"function",b:"("+a+"\\s+)+"+c.IR+"\\s*\\(",rB:true,e:/[{;=]/,eE:true,k:b,c:[{b:c.IR+"\\s*\\(",rB:true,c:[c.TM]},{cN:"params",b:/\(/,e:/\)/,k:b,c:[c.ASM,c.QSM,c.CNM,c.CBCM]},c.CLCM,c.CBCM]}]}});hljs.registerLanguage("ruby",function(f){var j="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?";var i="and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor";var b={cN:"yardoctag",b:"@[A-Za-z]+"};var c={cN:"value",b:"#<",e:">"};var k={cN:"comment",v:[{b:"#",e:"$",c:[b]},{b:"^\\=begin",e:"^\\=end",c:[b],r:10},{b:"^__END__",e:"\\n$"}]};var d={cN:"subst",b:"#\\{",e:"}",k:i};var e={cN:"string",c:[f.BE,d],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:"%[qw]?\\(",e:"\\)"},{b:"%[qw]?\\[",e:"\\]"},{b:"%[qw]?{",e:"}"},{b:"%[qw]?<",e:">"},{b:"%[qw]?/",e:"/"},{b:"%[qw]?%",e:"%"},{b:"%[qw]?-",e:"-"},{b:"%[qw]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/}]};var a={cN:"params",b:"\\(",e:"\\)",k:i};var h=[e,c,k,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[f.inherit(f.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+f.IR+"::)?"+f.IR}]},k]},{cN:"function",bK:"def",e:" |$|;",r:0,c:[f.inherit(f.TM,{b:j}),a,k]},{cN:"constant",b:"(::)?(\\b[A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:f.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":",c:[e,{b:j}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+f.RSR+")\\s*",c:[c,k,{cN:"regexp",c:[f.BE,d],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}],r:0}];d.c=h;a.c=h;var g=[{b:/^\s*=>/,cN:"status",starts:{e:"$",c:h}},{cN:"prompt",b:/^\S[^=>\n]*>+/,starts:{e:"$",c:h}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:i,c:[k].concat(g).concat(h)}});hljs.registerLanguage("diff",function(a){return{aliases:["patch"],c:[{cN:"chunk",r:10,v:[{b:/^\@\@ +\-\d+,\d+ +\+\d+,\d+ +\@\@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"header",v:[{b:/Index: /,e:/$/},{b:/=====/,e:/=====$/},{b:/^\-\-\-/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+\+\+/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"change",b:"^\\!",e:"$"}]}});hljs.registerLanguage("objectivec",function(a){var d={keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"NSString NSData NSDictionary CGRect CGPoint UIButton UILabel UITextView UIWebView MKMapView NSView NSViewController NSWindow NSWindowController NSSet NSUUID NSIndexSet UISegmentedControl NSObject UITableViewDelegate UITableViewDataSource NSThread UIActivityIndicator UITabbar UIToolBar UIBarButtonItem UIImageView NSAutoreleasePool UITableView BOOL NSInteger CGFloat NSException NSLog NSMutableString NSMutableArray NSMutableDictionary NSURL NSIndexPath CGSize UITableViewCell UIView UIViewController UINavigationBar UINavigationController UITabBarController UIPopoverController UIPopoverControllerDelegate UIImage NSNumber UISearchBar NSFetchedResultsController NSFetchedResultsChangeType UIScrollView UIScrollViewDelegate UIEdgeInsets UIColor UIFont UIApplication NSNotFound NSNotificationCenter NSNotification UILocalNotification NSBundle NSFileManager NSTimeInterval NSDate NSCalendar NSUserDefaults UIWindow NSRange NSArray NSError NSURLRequest NSURLConnection NSURLSession NSURLSessionDataTask NSURLSessionDownloadTask NSURLSessionUploadTask NSURLResponseUIInterfaceOrientation MPMoviePlayerController dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"};var c=/[a-zA-Z@][a-zA-Z0-9_]*/;var b="@interface @class @protocol @implementation";return{aliases:["m","mm","objc","obj-c"],k:d,l:c,i:"</",c:[a.CLCM,a.CBCM,a.CNM,a.QSM,{cN:"string",v:[{b:'@"',e:'"',i:"\\n",c:[a.BE]},{b:"'",e:"[^\\\\]'",i:"[^\\\\][^']"}]},{cN:"preprocessor",b:"#",e:"$",c:[{cN:"title",v:[{b:'"',e:'"'},{b:"<",e:">"}]}]},{cN:"class",b:"("+b.split(" ").join("|")+")\\b",e:"({|$)",eE:true,k:b,l:c,c:[a.UTM]},{cN:"variable",b:"\\."+a.UIR,r:0}]}});hljs.registerLanguage("css",function(a){var b="[a-zA-Z-][a-zA-Z0-9_-]*";var c={cN:"function",b:b+"\\(",rB:true,eE:true,e:"\\("};return{cI:true,i:"[=/|']",c:[a.CBCM,{cN:"id",b:"\\#[A-Za-z0-9_-]+"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+"},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{cN:"at_rule",b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:true,eE:true,r:0,c:[c,a.ASM,a.QSM,a.CSSNM]}]},{cN:"tag",b:b,r:0},{cN:"rules",b:"{",e:"}",i:"[^\\s]",r:0,c:[a.CBCM,{cN:"rule",b:"[^\\s]",rB:true,e:";",eW:true,c:[{cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:true,i:"[^\\s]",starts:{cN:"value",eW:true,eE:true,c:[c,a.CSSNM,a.QSM,a.ASM,a.CBCM,{cN:"hexcolor",b:"#[0-9A-Fa-f]+"},{cN:"important",b:"!important"}]}}]}]}]}});hljs.registerLanguage("python",function(a){var f={cN:"prompt",b:/^(>>>|\.\.\.) /};var b={cN:"string",c:[a.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[f],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[f],r:10},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},a.ASM,a.QSM]};var d={cN:"number",r:0,v:[{b:a.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:a.CNR+"[lLjJ]?"}]};var e={cN:"params",b:/\(/,e:/\)/,c:["self",f,d,b]};var c={e:/:/,i:/[${=;\n]/,c:[a.UTM,e]};return{aliases:["py","gyp"],k:{keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},i:/(<\/|->|\?)/,c:[f,d,b,a.HCM,a.inherit(c,{cN:"function",bK:"def",r:10}),a.inherit(c,{cN:"class",bK:"class"}),{cN:"decorator",b:/@/,e:/$/},{b:/\b(print|exec)\(/}]}});
+hljs.registerLanguage("xml",function(a){var c="[A-Za-z0-9\\._:-]+";var d={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php",subLanguageMode:"continuous"};var b={eW:true,i:/</,r:0,c:[d,{cN:"attribute",b:c,r:0},{b:"=",r:0,c:[{cN:"value",v:[{b:/"/,e:/"/},{b:/'/,e:/'/},{b:/[^\s\/>]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xsl","plist"],cI:true,c:[{cN:"doctype",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"<!--",e:"-->",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{title:"style"},c:[b],starts:{e:"</style>",rE:true,sL:"css"}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{title:"script"},c:[b],starts:{e:"<\/script>",rE:true,sL:"javascript"}},{b:"<%",e:"%>",sL:"vbscript"},d,{cN:"pi",b:/<\?\w+/,e:/\?>/,r:10},{cN:"tag",b:"</?",e:"/?>",c:[{cN:"title",b:/[^ \/><\n\t]+/,r:0},b]}]}});
hljs.registerLanguage("scala",function(d){var b={cN:"annotation",b:"@[A-Za-z]+"};var c={cN:"string",b:'u?r?"""',e:'"""',r:10};var a={cN:"symbol",b:"'\\w[\\w\\d_]*(?!')"};var e={cN:"type",b:"\\b[A-Z][A-Za-z0-9_]*",r:0};var h={cN:"title",b:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,r:0};var i={cN:"class",bK:"class object trait type",e:/[:={\[(\n;]/,c:[{cN:"keyword",bK:"extends with",r:10},h]};var g={cN:"function",bK:"def val",e:/[:={\[(\n;]/,c:[h]};var f={cN:"javadoc",b:"/\\*\\*",e:"\\*/",c:[{cN:"javadoctag",b:"@[A-Za-z]+"}],r:10};return{k:{literal:"true false null",keyword:"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit"},c:[d.CLCM,d.CBCM,c,d.QSM,a,e,g,i,d.CNM,b]}});
hljs.registerLanguage("javascript",function(a){return{aliases:["js"],k:{keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document"},c:[{cN:"pi",b:/^\s*('|")use strict('|")/,r:10},a.ASM,a.QSM,a.CLCM,a.CBCM,a.CNM,{b:"("+a.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[a.CLCM,a.CBCM,a.RM,{b:/</,e:/>;/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,eE:true,c:[a.inherit(a.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,c:[a.CLCM,a.CBCM],i:/["'\(]/}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+a.IR,r:0}]}});
-hljs.registerLanguage("bash",function(b){var a={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)\}/}]};var d={cN:"string",b:/"/,e:/"/,c:[b.BE,a,{cN:"variable",b:/\$\(/,e:/\)/,c:[b.BE]}]};var c={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/-?[a-z\.]+/,k:{keyword:"if then else elif fi for break continue while in do done exit return set declare case esac export exec",literal:"true false",built_in:"printf echo read cd pwd pushd popd dirs let eval unset typeset readonly getopts source shopt caller type hash bind help sudo",operator:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"shebang",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:true,c:[b.inherit(b.TM,{b:/\w[\w\d_]*/})],r:0},b.HCM,b.NM,d,c,a]}});
hljs.registerLanguage("diff",function(a){return{aliases:["patch"],c:[{cN:"chunk",r:10,v:[{b:/^\@\@ +\-\d+,\d+ +\+\d+,\d+ +\@\@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"header",v:[{b:/Index: /,e:/$/},{b:/=====/,e:/=====$/},{b:/^\-\-\-/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+\+\+/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"change",b:"^\\!",e:"$"}]}});
-hljs.registerLanguage("xml",function(a){var c="[A-Za-z0-9\\._:-]+";var d={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php",subLanguageMode:"continuous"};var b={eW:true,i:/</,r:0,c:[d,{cN:"attribute",b:c,r:0},{b:"=",r:0,c:[{cN:"value",v:[{b:/"/,e:/"/},{b:/'/,e:/'/},{b:/[^\s\/>]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xsl","plist"],cI:true,c:[{cN:"doctype",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"<!--",e:"-->",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{title:"style"},c:[b],starts:{e:"</style>",rE:true,sL:"css"}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{title:"script"},c:[b],starts:{e:"<\/script>",rE:true,sL:"javascript"}},{b:"<%",e:"%>",sL:"vbscript"},d,{cN:"pi",b:/<\?\w+/,e:/\?>/,r:10},{cN:"tag",b:"</?",e:"/?>",c:[{cN:"title",b:/[^ \/><\n\t]+/,r:0},b]}]}});
+hljs.registerLanguage("bash",function(b){var a={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)\}/}]};var d={cN:"string",b:/"/,e:/"/,c:[b.BE,a,{cN:"variable",b:/\$\(/,e:/\)/,c:[b.BE]}]};var c={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/-?[a-z\.]+/,k:{keyword:"if then else elif fi for break continue while in do done exit return set declare case esac export exec",literal:"true false",built_in:"printf echo read cd pwd pushd popd dirs let eval unset typeset readonly getopts source shopt caller type hash bind help sudo",operator:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"shebang",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:true,c:[b.inherit(b.TM,{b:/\w[\w\d_]*/})],r:0},b.HCM,b.NM,d,c,a]}});
+(function(){'use strict';function aa(){return function(a){return a}}function ba(){return function(){}}function da(a){return function(b){this[a]=b}}function c(a){return function(){return this[a]}}function h(a){return function(){return a}}var l,ea="object"===typeof __ScalaJSEnv&&__ScalaJSEnv?__ScalaJSEnv:{},m="object"===typeof ea.global&&ea.global?ea.global:"object"===typeof global&&global&&global.Object===Object?global:this;ea.global=m;var fa="object"===typeof ea.exportsNamespace&&ea.exportsNamespace?ea.exportsNamespace:m;
+ea.exportsNamespace=fa;m.Object.freeze(ea);var ga=0;function ha(a){return function(b,d){return!(!b||!b.a||b.a.Qh!==d||b.a.Oh!==a)}}function ia(a){var b,d;for(d in a)b=d;return b}function p(a,b){return ja(a,b,0)}function ja(a,b,d){var e=new a.ek(b[d]);if(d<b.length-1){a=a.Vh;d+=1;for(var f=e.d,g=0;g<f.length;g++)f[g]=ja(a,b,d)}return e}function ka(a){return void 0===a?"undefined":a.toString()}
+function la(a){switch(typeof a){case "string":return q(ma);case "number":var b=a|0;return b===a?b<<24>>24===b&&1/b!==1/-0?q(na):b<<16>>16===b&&1/b!==1/-0?q(oa):q(pa):a!==a||qa(a)===a?q(ra):q(sa);case "boolean":return q(ta);case "undefined":return q(ua);default:if(null===a)throw(new va).b();return wa(a)?q(xa):a&&a.a?q(a.a):null}}function ya(a,b){return a&&a.a||null===a?a.K(b):"number"===typeof a?"number"===typeof b&&(a===b?0!==a||1/a===1/b:a!==a&&b!==b):a===b}
+function za(a){switch(typeof a){case "string":return Aa(Ba(),a);case "number":return Ca(Da(),a);case "boolean":return a?1231:1237;case "undefined":return 0;default:return a&&a.a||null===a?a.M():42}}function Ea(a,b,d){return"string"===typeof a?a.substring(b,d):a.Dp(b,d)}function Fa(a,b,d,e,f){a=a.d;d=d.d;if(a!==d||e<b||b+f<e)for(var g=0;g<f;g++)d[e+g]=a[b+g];else for(g=f-1;0<=g;g--)d[e+g]=a[b+g]}
+function Ga(a){if(a&&a.a){var b=a.$idHashCode$0;void 0===b&&(ga=b=ga+1|0,a.$idHashCode$0=b);return b}return null===a?0:za(a)}function Ha(a){return(a|0)===a&&1/a!==1/-0}function Ia(a){return null===a?Ja().kd:a}this.__ScalaJSExportsNamespace=fa;function Ka(a,b,d){this.ij=this.ek=void 0;this.t={};this.Vh=null;this.wl=a;this.Zj=b;this.Lh=this.Mh=void 0;this.ne=h(!1);this.name=d;this.isPrimitive=!0;this.isArrayClass=this.isInterface=!1;this.isInstance=h(!1)}
+function s(a,b,d,e,f,g,k){var n=ia(a);g=g||function(a){return!!(a&&a.a&&a.a.t[n])};k=k||function(a,b){return!!(a&&a.a&&a.a.Qh===b&&a.a.Oh.t[n])};this.ek=void 0;this.ij=f;this.t=e;this.wl=this.Vh=null;this.Zj="L"+d+";";this.Lh=this.Mh=void 0;this.ne=k;this.name=d;this.isPrimitive=!1;this.isInterface=b;this.isArrayClass=!1;this.isInstance=g}
+function La(a){function b(a){if("number"===typeof a){this.d=Array(a);for(var b=0;b<a;b++)this.d[b]=d}else this.d=a}var d=a.wl;"longZero"==d&&(d=Ja().kd);b.prototype=new t;b.prototype.a=this;var e="["+a.Zj,f=a.Oh||a,g=(a.Qh||0)+1;this.ek=b;this.ij=u;this.t={c:1};this.Vh=a;this.Oh=f;this.Qh=g;this.wl=null;this.Zj=e;this.ne=this.Lh=this.Mh=void 0;this.name=e;this.isInterface=this.isPrimitive=!1;this.isArrayClass=!0;this.isInstance=function(a){return f.ne(a,g)}}
+function q(a){if(!a.Mh){var b=new Ma;b.Ed=a;a.Mh=b}return a.Mh}function v(a){a.Lh||(a.Lh=new La(a));return a.Lh}s.prototype.getFakeInstance=function(){return this===ma?"some string":this===ta?!1:this===na||this===oa||this===pa||this===ra||this===sa?0:this===xa?Ja().kd:this===ua?void 0:{a:this}};s.prototype.getSuperclass=function(){return this.ij?q(this.ij):null};s.prototype.getComponentType=function(){return this.Vh?q(this.Vh):null};
+s.prototype.newArrayOfThisClass=function(a){for(var b=this,d=0;d<a.length;d++)b=v(b);return p(b,a)};Ka.prototype=s.prototype;La.prototype=s.prototype;var Na=new Ka(void 0,"V","void"),Pa=new Ka(!1,"Z","boolean"),Qa=new Ka(0,"C","char"),Sa=new Ka(0,"B","byte"),Ta=new Ka(0,"S","short"),Ua=new Ka(0,"I","int"),Va=new Ka("longZero","J","long"),Xa=new Ka(0,"F","float"),Ya=new Ka(0,"D","double"),Za=ha(Pa);Pa.ne=Za;var $a=ha(Qa);Qa.ne=$a;var ab=ha(Sa);Sa.ne=ab;var bb=ha(Ta);Ta.ne=bb;var cb=ha(Ua);Ua.ne=cb;
+var db=ha(Va);Va.ne=db;var eb=ha(Xa);Xa.ne=eb;var fb=ha(Ya);Ya.ne=fb;var w=m.Math.imul||function(a,b){var d=a&65535,e=b&65535;return d*e+((a>>>16&65535)*e+d*(b>>>16&65535)<<16>>>0)|0},qa=m.Math.fround||function(a){return+a};var gb=new s({uf:0},!0,"upickle.Js$Value",{uf:1});function hb(){}function t(){}t.prototype=hb.prototype;hb.prototype.b=function(){return this};hb.prototype.K=function(a){return this===a};hb.prototype.o=function(){var a=ib(la(this)),b=(+(this.M()>>>0)).toString(16);return a+"@"+b};hb.prototype.M=function(){return Ga(this)};hb.prototype.toString=function(){return this.o()};function jb(a,b){var d=a&&a.a;if(d){var e=d.Qh||0;return!(e<b)&&(e>b||!d.Oh.isPrimitive)}return!1}
+var u=new s({c:0},!1,"java.lang.Object",{c:1},void 0,function(a){return null!==a},jb);hb.prototype.a=u;function kb(){this.$j=this.pl=null}kb.prototype=new t;kb.prototype.b=function(){lb=this;var a=(new mb).h("^[a-z][\\w0-9-]*$"),b=x();this.pl=nb(a.f,b);a=(new mb).h("^[a-zA-Z_:][-a-zA-Z0-9_:.]*$");b=x();this.$j=nb(a.f,b);return this};kb.prototype.a=new s({wq:0},!1,"scalatags.Escaping$",{wq:1,c:1});var lb=void 0;function ob(){lb||(lb=(new kb).b());return lb}function qb(){this.oE=this.wk=null}
+qb.prototype=new t;qb.prototype.b=function(){rb=this;this.wk=(new sb).b();this.oE=(new tb).b();return this};qb.prototype.a=new s({Pq:0},!1,"scalatags.generic.Namespace$",{Pq:1,c:1});var rb=void 0;function ub(){rb||(rb=(new qb).b());return rb}function vb(a){var b=(new wb).$d((new z).b());a.al(b.Cb(a.Eb,"auto"))}
+function xb(a){var b=(new z).b();a.Co(A(new B,a,"start",b));b=(new z).b();a.yo(A(new B,a,"end",b));b=(new z).b();a.Ao(A(new B,a,"left",b));b=(new z).b();a.Bo(A(new B,a,"right",b));b=(new z).b();a.xo(A(new B,a,"center",b));b=(new z).b();a.zo(A(new B,a,"justify",b))}function yb(){this.W=this.yb=null}yb.prototype=new t;
+function zb(a){var b=ub().wk,d=ob();if(!Ab(Bb(d.pl,a.yb)))throw(new Cb).h(Db((new Eb).La((new C).A(["Illegal tag name: "," is not a valid XML tag name"])),(new C).A([a.yb])));a.W;return Fb(new Gb,a.yb,x(),!0,b)}function D(a){var b=ub().wk,d=ob();if(!Ab(Bb(d.pl,a.yb)))throw(new Cb).h(Db((new Eb).La((new C).A(["Illegal tag name: "," is not a valid XML tag name"])),(new C).A([a.yb])));a.W;return Fb(new Gb,a.yb,x(),!1,b)}function Hb(a){return(new E).ia(Ib(Jb(),a.yb),a.yb)}
+function F(a,b){var d=new yb;d.yb=b;if(null===a)throw G(H(),null);d.W=a;return d}function I(a){var b=ob();if(!Ab(Bb(b.$j,a.yb)))throw(new Cb).h(Db((new Eb).La((new C).A(["Illegal attribute name: "," is not a valid XML attribute name"])),(new C).A([a.yb])));return(new Lb).h(a.yb)}yb.prototype.a=new s({qr:0},!1,"scalatags.generic.Util$ExtendedString",{qr:1,c:1});function Mb(){}Mb.prototype=new t;
+function Ib(a,b){function d(a){var b=65535&(a.charCodeAt(0)|0),b=Nb(Ob(),b),b=m.String.fromCharCode(b);a=(new mb).h(a);var d=a.f.length|0;return""+b+Pb(Qb(),a.f,1,d)}var e=Rb(Ba(),b,"-",0),f=J().N.$e();f.Ta(e.d.length);f.Ka((new Sb).me(e));if((f=f.pa())&&f.a&&f.a.t.el)e=f.Jf,f=f.Cd;else throw(new K).w(f);var g=J().N;if(g===J().N)if(f===x())f=x();else{for(var g=f.u(),k=g=Tb(new Ub,d(g),x()),f=f.s();f!==x();)var n=f.u(),n=Tb(new Ub,d(n),x()),k=k.Cd=n,f=f.s();f=g}else{for(g=Vb(f,g);!f.m();)k=f.u(),g.Da(d(k)),
+f=f.s();f=g.pa()}return L(Tb(new Ub,e,f),"","","")}Mb.prototype.a=new s({tr:0},!1,"scalatags.package$",{tr:1,c:1});var Wb=void 0;function Jb(){Wb||(Wb=(new Mb).b());return Wb}function Xb(a){a=0===(1024&a.Q)?Yb(a):a.Tj;var b=M(function(a){return $b(a.Q?a.fg:ac(a),x())}),d=bc();return a.oe(b,d.N).fc("\n")}function cc(a,b){return"scalatex-scrollspy-Styles-"+a+b}function dc(){this.Wm=this.be=this.si=null;this.Bk=!1;this.pe=this.ch=this.Wi=this.Vn=this.Bj=null}dc.prototype=new t;
+function ec(a){fc(a.si);gc(a.Bj);m.document.body.appendChild(a.pe);m.addEventListener("scroll",function(a){return function(){fc(a.si)}}(a))}
+function hc(a){var b=new dc;ic();a=jc(kc(),a);var d=ic();lc();var e=(new mc).Fe(null),f=lc(),g=nc(function(a,b){return oc(new pc,a,b)}),k=qc(rc(),(new C).A(["value","children"]),sc(tc(),q(ma))),n=qc(rc(),(new C).A([null,null]),sc(tc(),q(gb))),r=ic().Ih,y=ic();uc();var S=vc().zb,y=wc(y,e,S),f=xc(f,g,k,n,r,y);e.Hj=yc(f);e=zc(f);Ac();d=wc(d,e,new Bc);b.si=(new Cc).La(yc(d).l(a));a=N().ul;d=N().Ji;e=N().Og;d=Dc(new Ec,d,"menu-item-list",e);e=Fc();e=N().Lc.Cb(e.Eb,0);f=N().ao;f=N().Lc.Cb(f.Eb,0);g=N();
+g=Hb(F(g,"flex"));k=N().qn;g=A(new B,g,1E4,k);k=N();n=Gc(b.si);r=M(function(a){return a.j.Zd});y=bc();n=n.oe(r,y.N);b.be=Hc(Jc(a,(new C).A([d,e,f,g,Kc(new Lc,k,n,M(function(a){var b=N();return Mc(b,a)}))])));a=Nc(function(a){return function(){var b=a.si;b.qe=!b.qe;if(b.qe){var d=Gc(b),e=new Oc;if(null===b)throw G(H(),null);e.ja=b;b=bc();d.oe(e,b.N)}else fc(b)}}(b));d=N().L;e=Pc().Fg;f=N().Lc;b.Wm=Hc(Rc("fa-caret-down","fa-caret-up",a,(new C).A([f.Cb(d.Eb,e)])));b.Bk=800<(m.innerWidth|0);b.Bj=Sc(new Tc,
+b.Bk,Nc(function(a){return function(){return a.pe}}(b)),Nc(function(){return m.document.body}),Nc(function(a){return function(){return a.ch}}(b)));b.Bk?(a="fa-caret-left",d="fa-caret-right"):(a="fa-caret-right",d="fa-caret-left");a=Rc(a,d,Nc(function(a){return function(){var b=a.Bj;b.qe=!b.qe;gc(a.Bj)}}(b)),(new C).A([]));d=N().L;e=N().vh;b.Vn=Hc(Jc(a,(new C).A([e.Cb(d.Eb,"0px")])));a=N().Oi;N();d=Uc(Pc().tc);d=Vc(d);e=N().Ae;N();f=(new Wc).h("Published using Scalatex");g=N().Yi;k=N().Og;g=Dc(new Ec,
+g,"https://lihaoyi.github.io/Scalatex",k);N();k=Xc(Pc().tc);b.Wi=Jc(a,(new C).A([d,Jc(e,(new C).A([f,g,Vc(k)]))]));a=N().Oi;d=Yc();e=N().Ia;d=A(new B,d,"flex",e);e=N();e=Hb(F(e,"flex-direction"));f=N().Ia;e=A(new B,e,"column",f);f=N().Mn;g=N().Ia;f=A(new B,f,"100%",g);g=N().Dj;k=N().Ia;g=A(new B,g,"opacity 0.2s ease-out",k);k=N();k=Mc(k,b.be);n=N();b.ch=Hc(Jc(a,(new C).A([d,e,f,g,k,Mc(n,b.Wm),b.Wi])));a=N().Oi;N();d=$c(Pc().tc);d=Vc(d);e=N();e=Mc(e,b.ch);f=N();b.pe=Hc(Jc(a,(new C).A([d,e,Mc(f,b.Vn)])));
+return b}
+function Rc(a,b,d,e){var f=N().ln,g=N().Ji,k="fa "+a,n=N().Og,g=Dc(new Ec,g,k,n),k=ad(),n=N().Ia,n=Hc(Jc(f,(new C).A([g,A(new B,k,"white",n)]))),f=N().Ae,g=N(),g=Mc(g,n),k=N().Yi,r=N().Og,k=Dc(new Ec,k,"javascript:",r);N();var r=bd(Pc().tc),r=Vc(r),y=N().Un;a=M(function(a,b,d,e){return function(){e.classList.toggle(a);e.classList.toggle(b);cd(d)}}(a,b,d,n));N();a=Dc(new Ec,y,a,dd(new ed,M(function(a){return function(a){return function(b){return a.l(b)}}(a)})));b=N();d=Ac().ui;return Jc(f,(new C).A([g,
+k,r,a,fd(b,e,d)]))}dc.prototype.a=new s({Ar:0},!1,"scalatex.scrollspy.Controller",{Ar:1,c:1});function gd(){this.wi=null;this.Q=!1}gd.prototype=new t;gd.prototype.b=function(){hd=this;m.document.head.appendChild(this.Q?this.wi:id(this));var a=this.Q?this.wi:id(this),b=(this.Q?this.wi:id(this)).textContent,d=Pc().tc;a.textContent=""+b+Xb(d);return this};function id(a){a.Q||(jd||(jd=(new kd).b()),a.wi=Hc(jd.xj),a.Q=!0);return a.wi}gd.prototype.main=function(a){ec(hc(a))};
+gd.prototype.a=new s({Br:0},!1,"scalatex.scrollspy.Controller$",{Br:1,c:1});var hd=void 0;function ld(){hd||(hd=(new gd).b());return hd}fa.scalatex=fa.scalatex||{};fa.scalatex.scrollspy=fa.scalatex.scrollspy||{};fa.scalatex.scrollspy.Controller=ld;function Cc(){this.ik=this.fg=null;this.Q=this.qe=!1}Cc.prototype=new t;function md(a,b){var d=m.document.body;return O(P(),b,d)?0:+b.offsetTop+md(a,b.offsetParent)}
+function nd(a){if(!a.Q){var b=(new od).Oa(-1),d=a.fg,b=M(function(a,b){return function(d){return pd(a,d,0,b)}}(a,b)),e=bc();a.ik=d.oe(b,e.N);a.Q=!0}return a.ik}function fc(a){var b=+m.document.body.scrollTop;qd(a,Gc(a),b);Gc(a).R(M(function(){return function(a){var b=a.j.ae.classList;rd(a.j);b.remove(sd(Pc().tc).Ha);a.j.Zd.classList.remove(td(Pc().tc).Ha);b.add(ud(Pc().tc).Ha)}}(a)))}function Gc(a){return a.Q?a.ik:nd(a)}
+function qd(a,b,d){var e=bc();b.Yg(e.N).Kd(M(function(a){return null!==a})).R(M(function(a,b,d,e){return function(r){if(null!==r){var y=r.Ua;r=r.$a|0;md(a,y.j.df)<=b+e?(1+r|0)>=d.q()||md(a,d.ma(1+r|0).j.df)>b+e?(y.j.ae.classList.remove(sd(Pc().tc).Ha),y.j.ae.classList.add(ud(Pc().tc).Ha),rd(y.j),qd(a,y.Bc,b),y.j.Zd.classList.remove(td(Pc().tc).Ha)):(vd(a,y),y.j.Zd.classList.add(td(Pc().tc).Ha)):(y.j.Zd.classList.remove(td(Pc().tc).Ha),vd(a,y))}else throw(new K).w(r);}}(a,d,b,10)))}
+Cc.prototype.La=function(a){this.fg=a;this.qe=!1;return this};
+function pd(a,b,d,e){var f=N().Ae;N();var g=(new Wc).h(b.j),k=N().Yi;ld();var n="#"+b.j.split(" ").join(""),r=N().Og,k=Dc(new Ec,k,n,r),n=N().Ji,r=N().Og,n=Dc(new Ec,n,"menu-item",r);N();r=wd(Pc().tc);f=Hc(Jc(f,(new C).A([g,k,n,Vc(r)])));g=e.v;n=b.Bc;uc();k=vc().zb;k=Vb(n,k);for(n=xd(n);n.Oe;)r=n.wa(),k.Da(pd(a,r,1+d|0,e));a=k.pa();d=N().ul;N();k=yd(Pc().tc);k=Vc(k);n=N();uc();for(var r=vc().zb,r=Vb(a,r),y=xd(a);y.Oe;){var S=y.wa();r.Da(S.j.Zd)}r=r.pa();d=Hc(Jc(d,(new C).A([k,Kc(new Lc,n,r,M(function(a){var b=
+N();return Mc(b,a)}))])));k=N().Gn;n=Yc().Gi;r=N();r=Mc(r,f);y=N();k=Hc(Jc(k,(new C).A([n,r,Mc(y,d)])));e.v=1+e.v|0;e=m.document;ld();e=e.getElementById(b.j.split(" ").join(""));ld();b=b.j.split(" ").join("");if(0<a.q()){uc();n=vc().zb;n=Vb(a,n);for(r=xd(a);r.Oe;)y=r.wa(),n.Da(y.j.yg);n=n.pa().Dc(zd())|0}else n=1+g|0;return oc(new pc,Ad(k,f,d,e,b,g,n),a)}
+function vd(a,b){a.qe?rd(b.j):b.j.be.style.maxHeight="0px";b.j.Zd.classList.remove(td(Pc().tc).Ha);for(var d=xd(b.Bc);d.Oe;){var e=d.wa();vd(a,e)}b.j.ae.classList.add(sd(Pc().tc).Ha);b.j.ae.classList.remove(ud(Pc().tc).Ha)}function rd(a){a.be.style.maxHeight=w(1+(a.yg-a.uh|0)|0,1+Pc().Fg|0)+"px"}function Bd(a,b,d){d.l(b.j);for(b=xd(b.Bc);b.Oe;){var e=b.wa();Bd(a,e,d)}}Cc.prototype.a=new s({Cr:0},!1,"scalatex.scrollspy.ScrollSpy",{Cr:1,c:1});function Cd(){this.Fg=0;this.Lk=this.tc=this.zp=null}
+Cd.prototype=new t;Cd.prototype.b=function(){Dd=this;this.Fg=44;this.zp="#1f8dd6";this.tc=(new Ed).b();this.Lk="#191818";return this};Cd.prototype.a=new s({Er:0},!1,"scalatex.scrollspy.Styles$",{Er:1,c:1});var Dd=void 0;function Pc(){Dd||(Dd=(new Cd).b());return Dd}
+function Fd(a){var b=Gd(a),d=N(),e=N().xf,f=Pc().zp,g=N().Ia,d=Q(new R,d,A(new B,e,f,g)),f=Hd(a.jg,"hover"),e=N(),g=N().xf,k=N().Ia,e=Q(new R,e,A(new B,g,"#369FE2",k)),g=N(),k=ad(),n=N().Ia,e=[e,Q(new R,g,A(new B,k,"white",n))],f=f.Ce,g=Id(),k=Jd(new Kd,f,Ld(g),x()),f=0,g=e.length|0,n=k;a:{var r;for(;;)if(f===g){r=n;break a}else k=1+f|0,n=e[f].Ze(n),f=k}r=Md(r);e=Hd(a.jg,"active");a=N();f=N().xf;g=N().Ia;a=Q(new R,a,A(new B,f,"#62b4e8",g));f=N();g=ad();k=N().Ia;a=[a,Q(new R,f,A(new B,g,"white",k))];
+e=e.Ce;f=Id();g=Jd(new Kd,e,Ld(f),x());e=0;f=a.length|0;k=g;a:{var y;for(;;)if(e===f){y=k;break a}else g=1+e|0,k=a[e].Ze(k),e=g}y=Md(y);a=N();e=ad();f=N().Ia;return Nd(b,(new C).A([d,r,y,Q(new R,a,A(new B,e,"white",f))]))}
+function Od(a){a=Gd(a);var b=N(),d=N().Ok,d=N().vh.Cb(d.Eb,"15px"),b=Q(new R,b,d),d=N(),e=Fc(),e=N().Lc.Cb(e.Eb,0),d=Q(new R,d,e),e=N(),f=Pd().jn,e=Q(new R,e,f),f=N(),g=Qd().jo,f=Q(new R,f,g),g=N(),k=Yc().Gi,g=Q(new R,g,k),k=N(),n=N().E,n=N().Lc.Cb(n.Eb,0),k=Q(new R,k,n),n=N(),r=N().Cj,r=N().Lc.Cb(r.Eb,0),n=Q(new R,n,r),r=N(),y=N().Dj,S=N().Ia;return Nd(a,(new C).A([b,d,e,f,g,k,n,Q(new R,r,A(new B,y,"max-height 0.2s ease-out",S))]))}
+function Sd(a){var b=Gd(a),d=N(),e;e=N();null===e.Ui&&null===e.Ui&&(e.Ui=(new Td).xb(e));e=e.Ui;var f=N().Ia,d=Q(new R,d,A(new B,e,"12px",f));e=N();var f=ad(),g=N().Ia;e=Q(new R,e,A(new B,f,"#555",g));var f=N(),g=Ud().ag,f=Q(new R,f,g),g=N(),k=Vd().Dk,g=Q(new R,g,k),n=Hd(a.jg,"hover"),k=N(),r=ad(),y=N().Ia,k=[Q(new R,k,A(new B,r,"#777",y))],n=n.Ce,r=Id(),y=Jd(new Kd,n,Ld(r),x()),n=0,r=k.length|0,S=y;a:{var Oa;for(;;)if(n===r){Oa=S;break a}else y=1+n|0,S=k[n].Ze(S),n=y}Oa=Md(Oa);k=Hd(a.jg,"active");
+a=N();n=ad();r=N().Ia;a=[Q(new R,a,A(new B,n,"#999",r))];k=k.Ce;n=Id();r=Jd(new Kd,k,Ld(n),x());k=0;n=a.length|0;y=r;a:{var pb;for(;;)if(k===n){pb=y;break a}else r=1+k|0,y=a[k].Ze(y),k=r}return Nd(b,(new C).A([d,e,f,g,Oa,Md(pb)]))}function Wd(a){a=Gd(a);var b=N(),d=ad(),e=N().Ia;return Nd(a,(new C).A([Q(new R,b,A(new B,d,"#999",e))]))}
+function Xd(a){var b=Gd(a),d=Hd(a.jg,"hover"),e=N(),f=ad(),g=N().Ia,e=Q(new R,e,A(new B,f,"#bbb",g)),f=N(),g=N().xf,k=N().Ia,e=[e,Q(new R,f,A(new B,g,"#292828",k))],d=d.Ce,f=Id(),g=Jd(new Kd,d,Ld(f),x()),d=0,f=e.length|0,k=g;a:{var n;for(;;)if(d===f){n=k;break a}else g=1+d|0,k=e[d].Ze(k),d=g}n=Md(n);e=Hd(a.jg,"active");a=N();d=ad();f=N().Ia;a=Q(new R,a,A(new B,d,"#ddd",f));d=N();f=N().xf;g=N().Ia;a=[a,Q(new R,d,A(new B,f,"#393838",g))];e=e.Ce;d=Id();f=Jd(new Kd,e,Ld(d),x());e=0;d=a.length|0;g=f;a:{var r;
+for(;;)if(e===d){r=g;break a}else f=1+e|0,g=a[e].Ze(g),e=f}r=Md(r);a=N();e=Yc().Gi;a=Q(new R,a,e);var e=N(),d=Ud().ag,e=Q(new R,e,d),d=N(),f=N().Ok,f=N().Lc.Cb(f.Eb,15),d=Q(new R,d,f),f=N(),g=N().fi,k=Pc().Fg,g=N().Lc.Cb(g.Eb,k),f=Q(new R,f,g),g=N(),k=N().Hn,y=N().Ia,g=Q(new R,g,A(new B,k,"44px",y)),k=N(),y=N().om,S=N().Ia;return Nd(b,(new C).A([n,r,a,e,d,f,g,Q(new R,k,A(new B,y,"1px solid #444",S))]))}
+function Yd(a){var b=Gd(a),d=N(),e=Qd().km,d=Q(new R,d,e),e=N(),f=N().Cj,f=N().vh.Cb(f.Eb,"0px"),e=Q(new R,e,f),f=N(),g=N().fi,k=Pc().Fg,g=N().Lc.Cb(g.Eb,k),f=Q(new R,f,g),g=N(),k=N().Sp,n=Pc().Fg,k=N().Lc.Cb(k.Eb,n),g=Q(new R,g,k),k=N(),n=Yc(),r=N().Ia,k=Q(new R,k,A(new B,n,"flex",r)),n=N(),r=N(),r=Hb(F(r,"align-items")),y=N().Ia,n=Q(new R,n,A(new B,r,"center",y)),r=N(),y=N(),y=Hb(F(y,"justify-content")),S=N().Ia,r=Q(new R,r,A(new B,y,"center",S)),y=N(),S=Ud().ag,y=Q(new R,y,S);a=ud(a);return Nd(b,
+(new C).A([d,e,f,g,k,n,r,y,Zd(a)]))}function $d(a){a=Gd(a);var b=N(),d=N().fi,d=N().vh.Cb(d.Eb,"14px"),b=Q(new R,b,d),d=N(),e=N().Gp.lj,d=Q(new R,d,e),e=N(),f=N().qm,f=N().Lc.Cb(f.Eb,0),e=Q(new R,e,f),f=N(),g=N().eo,g=N().Lc.Cb(g.Eb,5),f=Q(new R,f,g),g=N(),k=N().co,k=N().Lc.Cb(k.Eb,5),g=Q(new R,g,k),k=N(),n=N().bo,n=N().Lc.Cb(n.Eb,2),k=Q(new R,k,n),n=N(),r=N().xf,y=Pc().Lk,S=N().Ia;return Nd(a,(new C).A([b,d,e,f,g,k,Q(new R,n,A(new B,r,y,S))]))}
+function ae(a){a=Gd(a);var b=N(),d=Vd().Dk;return Nd(a,(new C).A([Q(new R,b,d)]))}
+function be(a){a=Gd(a);var b=N(),d=Qd().$m,b=Q(new R,b,d),d=N(),e=Pd().yp,d=Q(new R,d,e),e=N(),f=N();null===f.Ej&&null===f.Ej&&(f.Ej=(new ce).xb(f));var e=Q(new R,e,f.Ej.Sn),f=N(),g=N().xf,k=Pc().Lk,n=N().Ia,f=Q(new R,f,A(new B,g,k,n)),g=N(),k=N().Dj,n=N().Ia,g=Q(new R,g,A(new B,k,"width 0.2s ease-out",n)),k=N(),n=N().fi,n=N().vh.Cb(n.Eb,"100%"),k=Q(new R,k,n),n=N(),r=N().E,r=N().Lc.Cb(r.Eb,0),n=Q(new R,n,r),r=N(),y=N().Cj,y=N().Lc.Cb(y.Eb,0);return Nd(a,(new C).A([b,d,e,f,g,k,n,Q(new R,r,y)]))}
+function de(a){a=Gd(a);var b=N(),d=N().pm,e=N().Ia;return Nd(a,(new C).A([Q(new R,b,A(new B,d,"2px solid white",e))]))}function Tc(){this.qe=!1;this.ch=this.Sh=this.pe=null}Tc.prototype=new t;function Sc(a,b,d,e,f){a.qe=b;a.pe=d;a.Sh=e;a.ch=f;return a}function gc(a){cd(a.Sh).style.transition="margin-left 0.2s ease-out";var b=a.qe?"250px":Db((new Eb).La((new C).A(["","px"])),(new C).A([Pc().Fg]));cd(a.ch).style.opacity=a.qe?"1.0":"0.0";cd(a.pe).style.width=b;cd(a.Sh).style.marginLeft=b}
+Tc.prototype.a=new s({Gr:0},!1,"scalatex.scrollspy.Toggler",{Gr:1,c:1});function ee(){this.tg=this.Kh=this.sg=null}ee.prototype=new t;ee.prototype.b=function(){fe=this;ge||(ge=(new he).b());this.sg=ge;ie||(ie=(new je).b());this.Kh=ie;ke||(ke=(new le).b());this.tg=ke;return this};ee.prototype.a=new s({Hr:0},!1,"upickle.Aliases$",{Hr:1,c:1});var fe=void 0;function ne(){fe||(fe=(new ee).b());return fe}
+function xc(a,b,d,e,f,g){var k=new oe;if(null===a)throw G(H(),null);k.ja=a;k.Ym=b;k.Rm=f;k.Sm=g;a=a.ye("Object",pe(a,d,e,k));return(new qe).Fe(a)}function re(a,b,d){for(var e=p(v(gb),[b.d.length]),f=a.lc(Ac().ui),g=0,k=b.d.length;g<k;){if(f.Gb(b.d[g]))e.d[g]=f.l(b.d[g]);else if(null!==d.d[g])e.d[g]=d.d[g];else throw se(new te,(new ue).La(a),"Key Missing: "+b.d[g]);g=1+g|0}Ac();null===e?a=null:(ve||(ve=(new we).b()),a=xe(e));return a}
+function ye(a,b,d){ne().tg;d=M(function(a){return function(b){return O(P(),Infinity,b)?(new ze).h("Infinity"):O(P(),-Infinity,b)?(new ze).h("-Infinity"):Ae(new Be,a.zi(b))}}(d));a=lc().ye("Number",Ce(a,b));return De(new Ee,d,a)}
+function Fe(a){ne().sg;a.xs=(new qe).Fe((new Ge).Pd(a));ne().Kh;a.ys=He(new Ie,M(ba()));a.Op=lc().ye("Boolean",(new Je).Pd(a));ne().tg;a.aq=De(new Ee,M(function(a){return a?Ke():Le()}),a.Op);ne().tg;a.Rs=De(new Ee,M(function(){return(new ue).La(x())}),(new Me).Pd(a));a.Pp=lc().ye("String",(new Ne).Pd(a));ne().tg;var b=Oe();a.Ih=De(new Ee,b,a.Pp);a.Qp=lc().ye("Symbol",(new Pe).Pd(a));ne().tg;a.Ns=De(new Ee,M(function(a){a=a.o();return(new ze).h(a.substring(1))}),a.Qp);a.cq=Qe(M(function(a){a=65535&
+(a.charCodeAt(0)|0);return(new Re).nc(a)}));var b=M(function(a){return+a<<24>>24}),d=M(function(a){a=(new mb).h(a);Se||(Se=(new Te).b());a=a.f;var b=Ue(Ve(),a,10);if(-128>b||127<b)throw(new We).h(Db((new Eb).La((new C).A(['For input string: "','"'])),(new C).A([a])));return b<<24>>24});Xe||(Xe=(new Ye).b());a.bq=ye(b,d,Xe);b=M(function(a){return+a<<16>>16});d=M(function(a){a=(new mb).h(a);Ze||(Ze=(new $e).b());a=a.f;var b=Ue(Ve(),a,10);if(-32768>b||32767<b)throw(new We).h(Db((new Eb).La((new C).A(['For input string: "',
+'"'])),(new C).A([a])));return b<<16>>16});af||(af=(new bf).b());a.Hs=ye(b,d,af);b=M(function(a){return+a|0});d=M(function(a){a=(new mb).h(a);return Ue(Ve(),a.f,10)});cf||(cf=(new df).b());a.pq=ye(b,d,cf);a.Kl=Qe(M(function(a){a=(new mb).h(a);return ef(ff(),a.f,10)}));b=M(function(a){return qa(+a)});d=M(function(a){a=(new mb).h(a).f;return qa(gf(hf(),a))});jf||(jf=(new kf).b());a.kq=ye(b,d,jf);b=M(function(a){return+a});d=M(function(a){a=(new mb).h(a);return gf(hf(),a.f)});lf||(lf=(new mf).b());a.eq=
+ye(b,d,lf);ne().Kh;a.Ij=He(new Ie,M(function(a){return function(b){var d=nf().Jj;if(null===d?null===b:d.K(b))return of(a.Ih).l("inf");d=nf().Qj;if(null===d?null===b:d.K(b))return of(a.Ih).l("-inf");if(b===nf().Sj)return of(a.Ih).l("undef");b=b.Jp();return of(a.Kl).l(b)}}(a)));ne().Kh;b=of(a.Ij);a.oq=He(new Ie,b);ne().sg;a.Il=(new qe).Fe((new pf).Pd(a));ne().Kh;b=of(a.Ij);a.jq=He(new Ie,b);ne().sg;a.Hl=(new qe).Fe((new qf).Pd(a));ne().sg;b=lc();d=yc(a.Hl);b=b.ye("DurationString",d.lf(yc(a.Il)));a.fq=
+(new qe).Fe(b)}function Qe(a){ne().tg;var b=M(function(a){return(new ze).h(ka(a))});a=lc().ye("Number",rf(a));return De(new Ee,b,a)}function wc(a,b,d){ne().sg;a=lc().ye("Array(n)",sf(a,b,d));return(new qe).Fe(a)}function le(){}le.prototype=new t;le.prototype.a=new s({hs:0},!1,"upickle.ReadWriter$",{hs:1,c:1});var ke=void 0;function he(){}he.prototype=new t;he.prototype.a=new s({js:0},!1,"upickle.Reader$",{js:1,c:1});var ge=void 0;function yc(a){return tf(new uf,new vf,a.Rk())}function je(){}
+je.prototype=new t;je.prototype.a=new s({os:0},!1,"upickle.Writer$",{os:1,c:1});var ie=void 0;function of(a){return M(function(a){return function(d){return null===d?wf():a.Up().l(d)}}(a))}function xf(){}xf.prototype=new t;
+function jc(a,b){if(yf(b))return(new ze).h(b);if("number"===typeof b)return Ae(new Be,+b);if(O(P(),!0,b))return Ke();if(O(P(),!1,b))return Le();if(null===b)return wf();if(b instanceof m.Array){var d=[];b.length|0;for(var e=0,f=b.length|0;e<f;){var g=b[e],g=jc(kc(),g);d.push(g);e=1+e|0}return(new zf).La((new C).A(d))}if(b instanceof m.Object)return d=(new Af).ji(b),d=(new Bf).Ak(d,M(function(a){return jc(kc(),a)})),(new ue).La(Cf(d));throw(new K).w(b);}
+xf.prototype.a=new s({qs:0},!1,"upickle.json.package$",{qs:1,c:1});var Ef=void 0;function kc(){Ef||(Ef=(new xf).b());return Ef}function Te(){this.Jh=null;this.Hh=0}Te.prototype=new t;Te.prototype.a=new s({dw:0},!1,"java.lang.Byte$",{dw:1,c:1});var Se=void 0;function Ff(){this.Jh=null;this.KG=this.IF=this.JF=this.CF=this.DF=this.CG=this.rG=this.xG=this.wG=this.DG=this.uG=this.AG=this.tG=this.zG=this.vG=this.BG=this.Hh=this.Nj=this.Oj=0;this.MH=this.NH=this.OH=null;this.Q=0}Ff.prototype=new t;
+function Nb(a,b){return 65535&(m.String.fromCharCode(b).toUpperCase().charCodeAt(0)|0)}Ff.prototype.a=new s({ew:0},!1,"java.lang.Character$",{ew:1,c:1});var Gf=void 0;function Ob(){Gf||(Gf=(new Ff).b());return Gf}function Ma(){this.Ed=null}Ma.prototype=new t;function ib(a){return a.Ed.name}Ma.prototype.o=function(){return(this.Ed.isInterface?"interface ":this.Ed.isPrimitive?"":"class ")+ib(this)};Ma.prototype.a=new s({An:0},!1,"java.lang.Class",{An:1,c:1});
+function Hf(){this.Jh=null;this.Hh=this.yG=this.sG=this.Oj=this.Nj=this.GG=this.FG=this.HG=0;this.jk=null;this.Q=!1}Hf.prototype=new t;function If(a){a.Q||(a.jk=new m.RegExp("^[\\x00-\\x20]*[+-]?(NaN|Infinity|(\\d+\\.?\\d*|\\.\\d+)([eE][+-]?\\d+)?)[fFdD]?[\\x00-\\x20]*$"),a.Q=!0);return a.jk}function Jf(a,b,d){return b!==b?d!==d?0:1:d!==d?-1:b===d?0===b?(a=1/b,a===1/d?0:0>a?-1:1):0:b<d?-1:1}
+function gf(a,b){if((a.Q?a.jk:If(a)).test(b))return+m.parseFloat(b);throw(new We).h(Db((new Eb).La((new C).A(['For input string: "','"'])),(new C).A([b])));}Hf.prototype.a=new s({hw:0},!1,"java.lang.Double$",{hw:1,c:1});var Kf=void 0;function hf(){Kf||(Kf=(new Hf).b());return Kf}function Lf(){this.Jh=null;this.Hh=this.Nj=this.Oj=0}Lf.prototype=new t;Lf.prototype.Bg=function(a){throw(new We).h(Db((new Eb).La((new C).A(['For input string: "','"'])),(new C).A([a])));};
+function Ue(a,b,d){if(null===b||0===((new mb).h(b).f.length|0)||2>d||36<d)a.Bg(b);else{var e=45===(65535&(b.charCodeAt(0)|0))||43===(65535&(b.charCodeAt(0)|0))?1:0;if(((new mb).h(b).f.length|0)<=e)a.Bg(b);else{for(;;){var f=e,g=(new mb).h(b).f;if(f<(g.length|0))Ob(),f=65535&(b.charCodeAt(e)|0),0>(36<d||2>d?-1:48<=f&&57>=f&&(-48+f|0)<d?-48+f|0:65<=f&&90>=f&&(-65+f|0)<(-10+d|0)?-55+f|0:97<=f&&122>=f&&(-97+f|0)<(-10+d|0)?-87+f|0:65313<=f&&65338>=f&&(-65313+f|0)<(-10+d|0)?-65303+f|0:65345<=f&&65370>=
+f&&(-65345+f|0)<(-10+d|0)?-65303+f|0:-1)&&a.Bg(b),e=1+e|0;else break}d=+m.parseInt(b,d);return d!==d||2147483647<d||-2147483648>d?a.Bg(b):d|0}}}function Mf(a,b,d){return b<<d|b>>>(-d|0)|0}function Nf(a,b){var d=b-(1431655765&b>>1)|0,d=(858993459&d)+(858993459&d>>2)|0;return w(16843009,252645135&(d+(d>>4)|0))>>24}function Of(a,b){var d=b,d=d|d>>>1|0,d=d|d>>>2|0,d=d|d>>>4|0,d=d|d>>>8|0;return 32-Nf(0,d|d>>>16|0)|0}function Pf(a,b){return Nf(0,-1+(b&(-b|0))|0)}
+Lf.prototype.a=new s({mw:0},!1,"java.lang.Integer$",{mw:1,c:1});var Qf=void 0;function Ve(){Qf||(Qf=(new Lf).b());return Qf}function Rf(){this.Jh=null;this.Oj=Sf();this.Nj=Sf();this.Hh=0}Rf.prototype=new t;
+function ef(a,b,d){if(null===b)throw(new va).b();if(""===b)a.Bg(b);else{if(45===(65535&(b.charCodeAt(0)|0)))return Tf(ef(a,b.substring(1),d));try{var e=b,f=Sf();for(;;)if(0<(e.length|0)){var g=e.substring(0,9),k=f,n=d,r=g.length|0,y=1;b:{var S;for(;;)if(0===r){S=y;break b}else if(0===r%2)var Oa=w(n,n),pb=r/2|0,n=Oa,r=pb;else var pb=-1+r|0,Rd=w(y,n),r=pb,y=Rd}var Zc=Uf(k,(new T).Oa(S)),Ic=Ue(Ve(),g,d),Ii=(new T).Oa(Ic),Ji=e.substring(9),Ki=Vf(Zc,Ii),e=Ji,f=Ki}else return f}catch(Li){if(Wf(Li))a.Bg(b);
+else throw Li;}}}Rf.prototype.Bg=function(a){throw(new We).h(Db((new Eb).La((new C).A(['For input string: "','"'])),(new C).A([a])));};Rf.prototype.a=new s({qw:0},!1,"java.lang.Long$",{qw:1,c:1});var Xf=void 0;function ff(){Xf||(Xf=(new Rf).b());return Xf}function Yf(){}Yf.prototype=new t;function Zf(){}Zf.prototype=Yf.prototype;function $f(a){return!!(a&&a.a&&a.a.t.Gg||"number"===typeof a)}function $e(){this.Jh=null;this.Hh=0}$e.prototype=new t;
+$e.prototype.a=new s({tw:0},!1,"java.lang.Short$",{tw:1,c:1});var Ze=void 0;function ag(){this.ov=this.Gv=this.Nm=this.Wn=null}ag.prototype=new t;
+ag.prototype.b=function(){bg=this;this.Wn=cg(!1);this.Nm=cg(!0);this.Gv=null;this.ov=m.performance?m.performance.now?function(){return function(){return+m.performance.now()}}(this):m.performance.webkitNow?function(){return function(){return+m.performance.webkitNow()}}(this):function(){return function(){return+(new m.Date).getTime()}}(this):function(){return function(){return+(new m.Date).getTime()}}(this);return this};ag.prototype.a=new s({vw:0},!1,"java.lang.System$",{vw:1,c:1});var bg=void 0;
+function dg(){bg||(bg=(new ag).b());return bg}function eg(){this.Za=this.uk=null}eg.prototype=new t;function fg(){}fg.prototype=eg.prototype;eg.prototype.b=function(){this.uk=!1;return this};eg.prototype.Wc=function(){this.uk||(this.Za=this.xl.vo,this.uk=!0);return this.Za};function gg(){}gg.prototype=new t;gg.prototype.a=new s({xw:0},!1,"java.lang.reflect.Array$",{xw:1,c:1});var hg=void 0;function ig(){}ig.prototype=new t;ig.prototype.a=new s({yw:0},!1,"java.util.Arrays$",{yw:1,c:1});var jg=void 0;
+function kg(){this.un=this.tn=this.sn=this.vn=null}kg.prototype=new t;kg.prototype.b=function(){lg=this;this.vn=mg(new ng,new m.RegExp("^[^\\x25]+"));this.sn=mg(new ng,new m.RegExp("^\\x25{2}"));this.tn=mg(new ng,new m.RegExp("^\\x25n"));this.un=mg(new ng,new m.RegExp("^\\x25(?:([1-9]\\d*)\\$)?([-#+ 0,\\(\x3c]*)(\\d*)(?:\\.(\\d+))?([A-Za-z])"));return this};kg.prototype.a=new s({Bw:0},!1,"java.util.Formatter$",{Bw:1,c:1});var lg=void 0;function og(){lg||(lg=(new kg).b());return lg}
+function ng(){this.Kg=null}ng.prototype=new t;function pg(a,b){qg||(qg=(new rg).b());var d=a.Kg.exec(b);return null===d?sg():(new tg).w(d)}function mg(a,b){a.Kg=b;return a}ng.prototype.a=new s({Cw:0},!1,"java.util.Formatter$RegExpExtractor",{Cw:1,c:1});function ug(){}ug.prototype=new t;function vg(){}vg.prototype=ug.prototype;function wg(){}wg.prototype=new t;function xg(){}xg.prototype=wg.prototype;
+function yg(a){return M(function(a){return function(d){if(null!==d)return zg(a,d.Ua,d.$a);throw(new K).w(d);}}(a))}function Ag(){this.ck=null}Ag.prototype=new t;function Bg(){}Bg.prototype=Ag.prototype;Ag.prototype.b=function(){this.ck=Cg();return this};Ag.prototype.Xj=function(a){var b=this.ck,d=Dg().oh.call(b,a)?(new tg).w(b[a]):sg();if(Eg(d))return d.ig;if(sg()===d)return d=(new Fg).h(a),b[a]=d;throw(new K).w(d);};function Gg(){}Gg.prototype=new t;function Hg(){}Hg.prototype=Gg.prototype;
+function Ig(){this.Lm=this.qB=this.rj=null}Ig.prototype=new t;Ig.prototype.b=function(){Jg=this;this.rj=(new Kg).b();this.qB=M(function(){return h(!1)}(this));this.Lm=(new Lg).b();return this};Ig.prototype.a=new s({Oz:0},!1,"scala.PartialFunction$",{Oz:1,c:1});var Jg=void 0;function Mg(){Jg||(Jg=(new Ig).b());return Jg}function Ng(a,b,d){return a.Va(b)?a.l(b):d.l(b)}function Og(){}Og.prototype=new t;Og.prototype.a=new s({Wz:0},!1,"scala.Predef$any2stringadd$",{Wz:1,c:1});var Pg=void 0;
+function Qg(a,b){switch(b){case 0:return a.Zg;case 1:return a.$g;case 2:return a.ah;case 3:return a.bh;default:throw(new Rg).h(""+b);}}function Sg(){}Sg.prototype=new t;Sg.prototype.a=new s({oA:0},!1,"scala.math.Ordered$",{oA:1,c:1});var Tg=void 0;function Ug(){this.Es=this.tq=this.gq=this.Bs=this.As=this.zs=this.qq=this.lq=this.iq=this.oF=this.nF=this.Cs=this.Js=this.Ss=this.Yp=this.Is=this.Xp=this.zl=this.Wp=this.vs=this.uq=this.sq=this.nq=this.Fs=this.rq=this.Qs=this.ng=null;this.Q=0}
+Ug.prototype=new t;
+Ug.prototype.b=function(){Vg=this;this.ng=(new Wg).b();Xg||(Xg=(new Yg).b());this.Qs=Xg;this.rq=Zg();this.Fs=bc();this.nq=vc();this.sq=$g();this.uq=J();this.vs=x();fh||(fh=(new gh).b());this.Wp=fh;hh||(hh=(new ih).b());this.zl=hh;jh||(jh=(new kh).b());this.Xp=jh;this.Is=lh();mh||(mh=(new nh).b());this.Yp=mh;this.Ss=uc();oh||(oh=(new ph).b());this.Js=oh;this.Cs=qh();rh||(rh=(new sh).b());this.iq=rh;th||(th=(new uh).b());this.lq=th;vh||(vh=(new wh).b());this.qq=vh;xh||(xh=(new yh).b());this.zs=xh;Tg||
+(Tg=(new Sg).b());this.As=Tg;zh||(zh=(new Ah).b());this.Bs=zh;Bh||(Bh=(new Ch).b());this.gq=Bh;Dh||(Dh=(new Eh).b());this.tq=Dh;Fh||(Fh=(new Gh).b());this.Es=Fh;return this};Ug.prototype.a=new s({tA:0},!1,"scala.package$",{tA:1,c:1});var Vg=void 0;function Hh(){Vg||(Vg=(new Ug).b());return Vg}function Ih(){this.wf=this.vf=this.og=this.We=this.mg=this.Ye=this.Pe=this.Se=this.Te=this.Ve=this.Ue=this.Re=this.Xe=this.Qe=null}Ih.prototype=new t;
+Ih.prototype.b=function(){Jh=this;this.Qe=Kh().Qe;this.Xe=Kh().Xe;this.Re=Kh().Re;this.Ue=Kh().Ue;this.Ve=Kh().Ve;this.Te=Kh().Te;this.Se=Kh().Se;this.Pe=Kh().Pe;this.Ye=Kh().Ye;this.mg=Kh().mg;this.We=Kh().We;this.og=Kh().og;this.vf=Kh().vf;this.wf=Kh().wf;return this};Ih.prototype.a=new s({vA:0},!1,"scala.reflect.ClassManifestFactory$",{vA:1,c:1});var Jh=void 0;function Lh(a,b){return b.Ed.isArrayClass?Db((new Eb).La((new C).A(["Array[","]"])),(new C).A([Lh(a,Mh(U(),b))])):ib(b)}
+function Nh(){this.vf=this.wf=this.og=this.ng=this.We=this.mg=this.uo=this.to=this.tj=this.Ye=this.Pe=this.Se=this.Te=this.Ve=this.Ue=this.Re=this.Xe=this.Qe=null}Nh.prototype=new t;
+Nh.prototype.b=function(){Oh=this;this.Qe=(new Ph).b();this.Xe=(new Qh).b();this.Re=(new Rh).b();this.Ue=(new Sh).b();this.Ve=(new Th).b();this.Te=(new Uh).b();this.Se=(new Vh).b();this.Pe=(new Wh).b();this.Ye=(new Xh).b();this.tj=q(u);this.to=q(Yh);this.uo=q(Zh);this.mg=(new $h).b();this.ng=this.We=(new ai).b();this.og=(new bi).b();this.wf=(new ci).b();this.vf=(new di).b();return this};Nh.prototype.a=new s({yA:0},!1,"scala.reflect.ManifestFactory$",{yA:1,c:1});var Oh=void 0;
+function Kh(){Oh||(Oh=(new Nh).b());return Oh}function ei(){this.Gc=this.Gl=null}ei.prototype=new t;ei.prototype.b=function(){fi=this;Jh||(Jh=(new Ih).b());this.Gl=Jh;this.Gc=Kh();return this};ei.prototype.a=new s({OA:0},!1,"scala.reflect.package$",{OA:1,c:1});var fi=void 0;function gi(){fi||(fi=(new ei).b());return fi}function hi(){}hi.prototype=new t;function ii(a,b){throw G(H(),(new ji).h(b));}hi.prototype.a=new s({PA:0},!1,"scala.sys.package$",{PA:1,c:1});var ki=void 0;
+function li(){ki||(ki=(new hi).b());return ki}function mi(){this.wh=this.vo=null}mi.prototype=new t;mi.prototype.o=function(){return"DynamicVariable("+this.wh.Wc()+")"};mi.prototype.w=function(a){this.vo=a;a=new ni;if(null===this)throw G(H(),null);a.xl=this;oi.prototype.b.call(a);this.wh=a;return this};mi.prototype.a=new s({QA:0},!1,"scala.util.DynamicVariable",{QA:1,c:1});function Ch(){}Ch.prototype=new t;Ch.prototype.a=new s({SA:0},!1,"scala.util.Either$",{SA:1,c:1});var Bh=void 0;
+function pi(){this.sB=null}pi.prototype=new t;pi.prototype.b=function(){this.sB=(new qi).b();return this};pi.prototype.a=new s({WA:0},!1,"scala.util.control.Breaks",{WA:1,c:1});function ri(){}ri.prototype=new t;function si(){}si.prototype=ri.prototype;ri.prototype.ej=function(a,b){var d;d=w(-862048943,b);d=Mf(Ve(),d,15);d=w(461845907,d);return a^d};ri.prototype.Nc=function(a,b){var d=this.ej(a,b),d=Mf(Ve(),d,13);return-430675100+w(5,d)|0};
+function ti(a,b,d){var e=(new od).Oa(0),f=(new od).Oa(0),g=(new od).Oa(0),k=(new od).Oa(1);b.R(M(function(a,b,d,e,f){return function(a){a=ui(U(),a);b.v=b.v+a|0;d.v^=a;0!==a&&(f.v=w(f.v,a));e.v=1+e.v|0}}(a,e,f,g,k)));b=a.Nc(d,e.v);b=a.Nc(b,f.v);b=a.ej(b,k.v);return a.Cg(b,g.v)}function vi(a){var b=wi(),d=a.hb();if(0===d)return a=a.jb(),Aa(Ba(),a);for(var e=-889275714,f=0;f<d;)e=b.Nc(e,ui(U(),a.ib(f))),f=1+f|0;return b.Cg(e,d)}
+ri.prototype.Cg=function(a,b){var d=a^b,d=w(-2048144789,d^(d>>>16|0)),d=d^(d>>>13|0),d=w(-1028477387,d);return d^=d>>>16|0};function xi(a,b,d){var e=(new od).Oa(0);d=(new od).Oa(d);b.R(M(function(a,b,d){return function(e){d.v=a.Nc(d.v,ui(U(),e));b.v=1+b.v|0}}(a,e,d)));return a.Cg(d.v,e.v)}function yi(){}yi.prototype=new t;yi.prototype.a=new s({ZA:0},!1,"scala.util.hashing.package$",{ZA:1,c:1});var zi=void 0;function kh(){}kh.prototype=new t;
+kh.prototype.a=new s({bB:0},!1,"scala.collection.$colon$plus$",{bB:1,c:1});var jh=void 0;function ih(){}ih.prototype=new t;function Ai(a,b){if(b.m())return sg();var d=b.u(),e=b.s();return(new tg).w((new V).ha(d,e))}ih.prototype.a=new s({cB:0},!1,"scala.collection.$plus$colon$",{cB:1,c:1});var hh=void 0;
+function Bi(a,b){var d;if(b&&b.a&&b.a.t.Oc){var e;if(!(e=a===b)&&(e=a.U()===b.U()))try{d=a.X();for(var f=!0;f&&d.Ca();){var g=d.wa();if(null!==g){var k=g.$a,n=b.Xc(g.Ua);b:{if(Eg(n)){var r=n.ig;if(O(P(),k,r)){f=!0;break b}}f=!1}}else throw(new K).w(g);}e=f}catch(y){if(y&&y.a&&y.a.t.fw)Ci("class cast "),e=!1;else throw y;}d=e}else d=!1;return d}function Di(a,b){return 0<=b&&b<a.q()}
+function Ei(a,b){var d;if(b&&b.a&&b.a.t.Sd){if(!(d=a===b)&&(d=a.U()===b.U()))try{d=a.ol(b)}catch(e){if(e&&e.a&&e.a.t.fw)d=!1;else throw e;}}else d=!1;return d}function Fi(a,b){return a.q()-b|0}function Gi(a){return 0<a.q()?a.ma(-1+a.q()|0):Hi(a)}function Mi(a,b){return 0<a.q()?Ni(a,1,a.q(),a.ma(0),b):Oi(a,b)}function Pi(a,b,d){b=0<b?b:0;d=0<d?d:0;var e=a.q();d=d<e?d:e;var e=d-b|0,f=0<e?e:0,e=a.na();for(e.Ta(f);b<d;)e.Da(a.ma(b)),b=1+b|0;return e.pa()}
+function Ni(a,b,d,e,f){for(;;){if(b===d)return e;var g=1+b|0;e=zg(f,e,a.ma(b));b=g}}function Qi(a,b,d,e){var f=0,g=d,k=a.q();e=k<e?k:e;d=Ri(U(),b)-d|0;for(d=e<d?e:d;f<d;)Si(U(),b,g,a.ma(f)),f=1+f|0,g=1+g|0}function Ti(a,b){var d=b.Tc(a.Pb()),e=a.q();d.Ta(e);for(var f=0;f<e;)d.Da((new V).ha(a.ma(f),f)),f=1+f|0;return d.pa()}function Ui(a,b){if(b&&b.a&&b.a.t.Pc){var d=a.q();if(d===b.q()){for(var e=0;e<d&&O(P(),a.ma(e),b.ma(e));)e=1+e|0;return e===d}return!1}return Vi(a,b)}
+function Wi(a,b){for(var d=0,e=a.q();d<e;)b.l(a.ma(d)),d=1+d|0}function Xi(a){var b=a.na();b.Ta(a.q());for(var d=a.q();0<d;)d=-1+d|0,b.Da(a.ma(d));return b.pa()}function Yi(a){return 0<a.q()?a.Qc(0,-1+a.q()|0):Zi(a)}function $i(a){return aj(a)?bj(a):a.Qc(1,a.q())}function aj(a){return 0===a.q()}function cj(a){return aj(a)?W(new X,a,a.q()).wa():a.ma(0)}function dj(a,b,d){d=d.Tc(a.Pb());a=a.X();for(b=b.X();a.Ca()&&b.Ca();)d.Da((new V).ha(a.wa(),b.wa()));return d.pa()}
+function Vi(a,b){for(var d=a.X(),e=b.X();d.Ca()&&e.Ca();)if(!O(P(),d.wa(),e.wa()))return!1;return!d.Ca()&&!e.Ca()}function ej(a,b){var d=b.Tc(a.Pb()),e=(new od).Oa(0);a.R(M(function(a,b,d){return function(a){b.Da((new V).ha(a,d.v));d.v=1+d.v|0}}(a,d,e)));return d.pa()}function fj(){this.Cc=null}fj.prototype=new t;fj.prototype.b=function(){gj=this;this.Cc=(new hj).b();return this};fj.prototype.a=new s({hB:0},!1,"scala.collection.Iterator$",{hB:1,c:1});var gj=void 0;
+function $g(){gj||(gj=(new fj).b());return gj}function ij(a){if(a.Ca()){var b=a.wa();return jj(new kj,b,Nc(function(a){return function(){return a.db()}}(a)))}lh();return lj()}function mj(a){return(a.Ca()?"non-empty":"empty")+" iterator"}function nj(a,b){for(;a.Ca();)b.l(a.wa())}function oj(a,b){for(var d=!0;d&&a.Ca();)d=!!b.l(a.wa());return d}function pj(a,b){var d;if(0>b)d=1;else a:{d=a;var e=0;for(;;){if(e===b){d=d.m()?0:1;break a}if(d.m()){d=-1;break a}e=1+e|0;d=d.s()}d=void 0}return d}
+function qj(a,b,d){for(;!a.m();)b=zg(d,b,a.u()),a=a.s();return b}function rj(a,b){var d=a.Jm(b);if(0>b||d.m())throw(new Rg).h(""+b);return d.u()}function sj(a){for(var b=0;!a.m();)b=1+b|0,a=a.s();return b}function tj(a){if(a.m())throw(new uj).b();for(var b=a.s();!b.m();)a=b,b=b.s();return a.u()}function vj(a,b){if(b&&b.a&&b.a.t.pi){if(a===b)return!0;for(var d=a,e=b;!d.m()&&!e.m()&&O(P(),d.u(),e.u());)d=d.s(),e=e.s();return d.m()&&e.m()}return Vi(a,b)}
+function wj(a,b){if(a.m())throw(new xj).h("empty.reduceLeft");return a.s().le(a.u(),b)}function yj(a,b){var d=a.Xc(b);if(sg()===d)throw(new uj).h("key not found: "+b);if(Eg(d))return d.ig;throw(new K).w(d);}function zj(a,b,d,e,f){var g=a.X();a=(new Aj).Zi(g,M(function(){return function(a){if(null!==a){var b=a.Ua;a=a.$a;Pg||(Pg=(new Og).b());return""+(""+Bj(Ba(),b)+" -\x3e ")+a}throw(new K).w(a);}}(a)));return Cj(a,b,d,e,f)}function Cf(a){var b=(new Dj).Oa(a.U());a=a.Ba();Ej(b,a);return b}
+function Fj(a,b,d){d=d.Tc(a.Pb());d.Da(b);d.Ka(a.bc());return d.pa()}function Gj(a){var b=x(),d=(new Hj).w(b);a.R(M(function(a,b){return function(a){b.v=Tb(new Ub,a,b.v)}}(a,d)));b=a.na();Ij(a)&&b.Ta(a.U());for(a=d.v;!a.m();)d=a.u(),b.Da(d),a=a.s();return b.pa()}function Jj(a,b,d){d=d.Tc(a.Pb());d.Ka(a.bc());d.Da(b);return d.pa()}function Kj(a,b){var d=b.$e();Ij(a)&&d.Ta(a.U());d.Ka(a.Ja());return d.pa()}function Lj(a){return a.Ec(a.Wb()+"(",", ",")")}
+function Mj(a,b,d){d=d.Tc(a.Pb());a.R(M(function(a,b,d){return function(a){return b.Ka(d.l(a).Ba())}}(a,d,b)));return d.pa()}function Nj(a,b,d){d=Vb(a,d);a.R(M(function(a,b,d){return function(a){return b.Da(d.l(a))}}(a,d,b)));return d.pa()}function Zi(a){if(a.m())throw(new xj).h("empty.init");var b=a.u(),b=(new Hj).w(b),d=Oj(!1),e=a.na();Pj(e,a,-1);a.R(M(function(a,b,d,e){return function(a){d.v?e.Da(b.v):d.v=!0;b.v=a}}(a,b,d,e)));return e.pa()}
+function bj(a){if(a.m())throw(new xj).h("empty.tail");return a.Zb(1)}function Qj(a,b,d){d=d.Tc(a.Pb());if(Ij(b)){var e=b.Ba().U();Pj(d,a,e)}d.Ka(a.Ja());d.Ka(b.Ba());return d.pa()}function Vb(a,b){var d=b.Tc(a.Pb());Ij(a)&&d.Ta(a.U());return d}function Rj(a){a=ib(la(a.Pb()));var b;Ba();b=a;var d=Sj(46);b=b.lastIndexOf(d)|0;-1!==b&&(a=a.substring(1+b|0));b=Tj(Ba(),a,36);-1!==b&&(a=a.substring(0,b));return a}
+function Hi(a){var b=a.u(),b=(new Hj).w(b);a.R(M(function(a,b){return function(a){b.v=a}}(a,b)));return b.v}function Uj(a,b){var d=b.$e();d.Ka(a.Ba());return d.pa()}function Vj(a,b){var d=Wj(new Xj,Yj());a.R(M(function(a,b){return function(a){return b.Da(a)}}(a,d,b)));return d.ob}function Cj(a,b,d,e,f){var g=Oj(!0);Zj(b,d);a.R(M(function(a,b,d,e){return function(a){if(b.v)ak(d,a),b.v=!1;else return Zj(d,e),ak(d,a)}}(a,g,b,e)));Zj(b,f);return b}
+function Oi(a,b){if(a.m())throw(new xj).h("empty.reduceLeft");var d=Oj(!0),e=(new Hj).w(0);a.R(M(function(a,b,d,e){return function(a){b.v?(d.v=a,b.v=!1):d.v=zg(e,d.v,a)}}(a,d,e,b)));return e.v}function bk(a,b,d){b=(new Hj).w(b);a.R(M(function(a,b,d){return function(a){b.v=zg(d,b.v,a)}}(a,b,d)));return b.v}function ck(a,b){if(a.m())throw(new xj).h("empty.max");return a.Kb(nc(function(a,b){return function(a,d){return b.Dg(a,d)?a:d}}(a,b)))}function L(a,b,d,e){return a.rc((new dk).b(),b,d,e).Sc.Ob}
+function ek(a){var b=(new od).Oa(0);a.R(M(function(a,b){return function(){b.v=1+b.v|0}}(a,b)));return b.v}function fk(){}fk.prototype=new t;function gk(){}gk.prototype=fk.prototype;function hk(){}hk.prototype=new t;function ik(){}ik.prototype=hk.prototype;function jk(a,b){if(b.m())return a.Ef();var d=a.na();d.Ka(b);return d.pa()}hk.prototype.Ef=function(){return this.na().pa()};function kk(a,b){a:b:for(;;){if(!b.m()){a.tb(b.u());b=b.s();continue b}break a}}
+function lk(a,b){b&&b.a&&b.a.t.pi?kk(a,b):b.R(M(function(a){return function(b){return a.tb(b)}}(a)));return a}function mk(){}mk.prototype=new t;function nk(){}nk.prototype=mk.prototype;function ok(a,b){return Wj(new Xj,a.Mm(b))}function pk(a,b){var d=Wj(new Xj,Yj());lk(d,a);qk(d,(new V).ha(b.Ua,b.$a));return d.ob}function rk(){}rk.prototype=new t;function sk(){}sk.prototype=rk.prototype;function tk(){}tk.prototype=new t;
+function uk(a,b,d,e){if(vk(d)){if(vk(e))return d=d.zf(),e=e.zf(),Y(new wk,a,b,d,e);if(vk(d.E)){var f=d.ka,g=d.j,k=d.E.zf();e=Y(new xk,a,b,d.L,e);return Y(new wk,f,g,k,e)}return vk(d.L)?(f=d.L.ka,g=d.L.j,k=Y(new xk,d.ka,d.j,d.E,d.L.E),e=Y(new xk,a,b,d.L.L,e),Y(new wk,f,g,k,e)):Y(new xk,a,b,d,e)}if(vk(e)){if(vk(e.L))return f=e.ka,g=e.j,a=Y(new xk,a,b,d,e.E),e=e.L.zf(),Y(new wk,f,g,a,e);if(vk(e.E))return f=e.E.ka,g=e.E.j,a=Y(new xk,a,b,d,e.E.E),e=Y(new xk,e.ka,e.j,e.E.L,e.L),Y(new wk,f,g,a,e)}return Y(new xk,
+a,b,d,e)}function yk(a){return zk(a)?a.kj():ii(li(),"Defect: invariance violation; expected black, got "+a)}function Ak(a){return null===a?null:a.zf()}function Bk(a,b){return null===b?0:b.fk}function Fk(a,b,d){return Ak(Gk(a,b,d))}function Hk(a,b,d,e,f,g){if(null===b)return Y(new wk,e,f,null,null);var k=1+Bk(0,b.E)|0;return d<k?Ik(zk(b),b.ka,b.j,Hk(a,b.E,d,e,f,g),b.L):d>k?Jk(zk(b),b.ka,b.j,b.E,Hk(a,b.L,d-k|0,e,f,g)):g?Kk(zk(b),e,f,b.E,b.L):b}
+function Lk(a,b,d){if(null===b)return d;if(null===d)return b;if(vk(b)&&vk(d)){a=Lk(a,b.L,d.E);if(vk(a)){var e=a.ka,f=a.j;b=Y(new wk,b.ka,b.j,b.E,a.E);d=Y(new wk,d.ka,d.j,a.L,d.L);return Y(new wk,e,f,b,d)}e=b.ka;f=b.j;b=b.E;d=Y(new wk,d.ka,d.j,a,d.L);return Y(new wk,e,f,b,d)}if(zk(b)&&zk(d))return f=Lk(a,b.L,d.E),vk(f)?(a=f.ka,e=f.j,b=Y(new xk,b.ka,b.j,b.E,f.E),d=Y(new xk,d.ka,d.j,f.L,d.L),Y(new wk,a,e,b,d)):Mk(b.ka,b.j,b.E,Y(new xk,d.ka,d.j,f,d.L));if(vk(d))return e=d.ka,f=d.j,b=Lk(a,b,d.E),Y(new wk,
+e,f,b,d.L);if(vk(b)){var e=b.ka,f=b.j,g=b.E;d=Lk(a,b.L,d);return Y(new wk,e,f,g,d)}ii(li(),"unmatched tree on append: "+b+", "+d)}function Nk(a,b){if(null===b)throw(new uj).h("empty map");for(var d=b;null!==d.E;)d=d.E;return d}function Ok(a,b,d,e,f,g){if(null===b)return Y(new wk,d,e,null,null);var k=g.sc(d,b.ka);return 0>k?Ik(zk(b),b.ka,b.j,Ok(a,b.E,d,e,f,g),b.L):0<k?Jk(zk(b),b.ka,b.j,b.E,Ok(a,b.L,d,e,f,g)):f||!O(P(),d,b.ka)?Kk(zk(b),d,e,b.E,b.L):b}
+function Gk(a,b,d){if(0>=d)return b;if(d>=Bk(0,b))return null;var e=Bk(0,b.E);if(d>e)return Gk(a,b.L,-1+(d-e|0)|0);var f=Gk(a,b.E,d);if(f!==b.E)if(null===f)b=Hk(a,b.L,-1+(d-e|0)|0,b.ka,b.j,!1);else{a=b.L;f=Ak(f);d=Ak(a);var g=Pk(f,d);if(null!==g){var k=g.Zg,e=!!g.$g;a=!!g.ah;g=g.bh|0}else throw(new K).w(g);a=!!a;g|=0;if(e)b=Y(new xk,b.ka,b.j,f,d);else{b:{e=k;for(;;)if(null===e)ii(li(),"Defect: unexpected empty zipper while computing range");else{if(zk(e.cf)){if(1===g)break b;g=-1+g|0}e=e.yi}e=void 0}f=
+a?Y(new wk,b.ka,b.j,f,e.cf):Y(new wk,b.ka,b.j,e.cf,d);for(b=e.yi;null!==b;)d=b.cf,f=a?Ik(zk(d),d.ka,d.j,f,d.L):Jk(zk(d),d.ka,d.j,d.E,f),b=b.yi;b=f}}return b}function Qk(a,b,d,e){return Ak(Rk(a,b,d,e))}
+function Rk(a,b,d,e){if(null===b)return null;var f=e.sc(d,b.ka);if(0>f)if(zk(b.E))b=Mk(b.ka,b.j,Rk(a,b.E,d,e),b.L);else{var f=b.ka,g=b.j;a=Rk(a,b.E,d,e);b=Y(new wk,f,g,a,b.L)}else if(0<f)if(zk(b.L)){var f=b.ka,g=b.j,k=b.E;e=Rk(a,b.L,d,e);vk(e)?(b=e.zf(),b=Y(new wk,f,g,k,b)):zk(k)?b=uk(f,g,k.kj(),e):vk(k)&&zk(k.L)?(b=k.L.ka,a=k.L.j,d=uk(k.ka,k.j,yk(k.E),k.L.E),e=Y(new xk,f,g,k.L.L,e),b=Y(new wk,b,a,d,e)):(ii(li(),"Defect: invariance violation"),b=void 0)}else f=b.ka,g=b.j,k=b.E,b=Rk(a,b.L,d,e),b=Y(new wk,
+f,g,k,b);else b=Lk(a,b.E,b.L);return b}function Pk(a,b){var d=null,e=null,f=0;for(;;)if(zk(a)&&zk(b)){var g=b.E,d=Sk(a,d),e=Sk(b,e),f=1+f|0;a=a.L;b=g}else if(vk(a)&&vk(b))g=b.E,d=Sk(a,d),e=Sk(b,e),a=a.L,b=g;else if(vk(b))e=Sk(b,e),b=b.E;else if(vk(a))d=Sk(a,d),a=a.L;else{if(null===a&&null===b)return(new Tk).gf(null,!0,!1,f);if(null===a&&zk(b))return(new Tk).gf(Uk(Sk(b,e),!0),!1,!0,f);if(zk(a)&&null===b)return(new Tk).gf(Uk(Sk(a,d),!1),!1,!1,f);ii(li(),"unmatched trees in unzip: "+a+", "+b)}}
+function Ik(a,b,d,e,f){if(vk(e)&&vk(e.E)){a=e.ka;var g=e.j,k=Y(new xk,e.E.ka,e.E.j,e.E.E,e.E.L);b=Y(new xk,b,d,e.L,f);return Y(new wk,a,g,k,b)}return vk(e)&&vk(e.L)?(a=e.L.ka,g=e.L.j,k=Y(new xk,e.ka,e.j,e.E,e.L.E),b=Y(new xk,b,d,e.L.L,f),Y(new wk,a,g,k,b)):Kk(a,b,d,e,f)}
+function Jk(a,b,d,e,f){if(vk(f)&&vk(f.E)){a=f.E.ka;var g=f.E.j;b=Y(new xk,b,d,e,f.E.E);f=Y(new xk,f.ka,f.j,f.E.L,f.L);return Y(new wk,a,g,b,f)}return vk(f)&&vk(f.L)?(a=f.ka,g=f.j,b=Y(new xk,b,d,e,f.E),f=Y(new xk,f.L.ka,f.L.j,f.L.E,f.L.L),Y(new wk,a,g,b,f)):Kk(a,b,d,e,f)}function Vk(a,b,d,e,f){return Ak(Ok(a,b,d,e,!0,f))}function Wk(a,b,d){for(;;){if(null===a)return null;var e=d.sc(b,a.ka);if(0>e)a=a.E;else if(0<e)a=a.L;else return a}}
+function Kk(a,b,d,e,f){return a?Y(new xk,b,d,e,f):Y(new wk,b,d,e,f)}function Uk(a,b){for(;;){var d=b?a.cf.E:a.cf.L;if(null===d)return a;a=Sk(d,a)}}function Xk(a,b,d){a:b:for(;;){null!==b.E&&Xk(a,b.E,d);d.l((new V).ha(b.ka,b.j));if(null!==b.L){b=b.L;continue b}break a}}
+function Mk(a,b,d,e){if(vk(d)){var f=d.zf();return Y(new wk,a,b,f,e)}if(zk(e))return uk(a,b,d,e.kj());if(vk(e)&&zk(e.E)){var f=e.E.ka,g=e.E.j;a=Y(new xk,a,b,d,e.E.E);e=uk(e.ka,e.j,e.E.L,yk(e.L));return Y(new wk,f,g,a,e)}ii(li(),"Defect: invariance violation")}tk.prototype.a=new s({mC:0},!1,"scala.collection.immutable.RedBlackTree$",{mC:1,c:1});var Yk=void 0;function Zk(){Yk||(Yk=(new tk).b());return Yk}function $k(){this.yi=this.cf=null}$k.prototype=new t;
+function Sk(a,b){var d=new $k;d.cf=a;d.yi=b;return d}$k.prototype.a=new s({oC:0},!1,"scala.collection.immutable.RedBlackTree$NList",{oC:1,c:1});function al(a,b){var d=ok(bl(),a.ni());d.Ka(a);d.Da((new V).ha(b.Ua,b.$a));return d.pa()}function cl(a,b){return b.Ba().Ac(a,nc(function(){return function(a,b){return a.Gj(b)}}(a)))}function nh(){}nh.prototype=new t;nh.prototype.a=new s({BC:0},!1,"scala.collection.immutable.Stream$$hash$colon$colon$",{BC:1,c:1});var mh=void 0;function dl(){this.wh=null}
+dl.prototype=new t;function el(a,b){a.wh=b;return a}function fl(a,b){return jj(new kj,b,a.wh)}dl.prototype.a=new s({DC:0},!1,"scala.collection.immutable.Stream$ConsWrapper",{DC:1,c:1});function gl(){this.W=this.Za=this.sh=null;this.Q=!1}gl.prototype=new t;function hl(a,b,d){a.sh=d;if(null===b)throw G(H(),null);a.W=b;return a}function il(a){a.Q||(a.Za=cd(a.sh),a.Q=!0);a.sh=null;return a.Za}gl.prototype.a=new s({IC:0},!1,"scala.collection.immutable.StreamIterator$LazyCell",{IC:1,c:1});
+function jl(a,b,d){b=0<b?b:0;var e=a.q(),e=d<e?d:e;if(b>=e)return a.na().pa();d=a.na();a=a.o().substring(b,e);return d.Ka((new mb).h(a)).pa()}function kl(){}kl.prototype=new t;kl.prototype.nk=function(a,b){return b&&b.a&&b.a.t.Oo?a===(null===b?null:b.f):!1};function Pb(a,b,d,e){a=0>d?0:d;return e<=a||a>=(b.length|0)?"":b.substring(a,e>(b.length|0)?b.length|0:e)}kl.prototype.a=new s({JC:0},!1,"scala.collection.immutable.StringOps$",{JC:1,c:1});var ll=void 0;
+function Qb(){ll||(ll=(new kl).b());return ll}function ml(a,b,d){if(32>d)return a.nb().d[31&b];if(1024>d)return a.P().d[31&b>>5].d[31&b];if(32768>d)return a.aa().d[31&b>>10].d[31&b>>5].d[31&b];if(1048576>d)return a.Aa().d[31&b>>15].d[31&b>>10].d[31&b>>5].d[31&b];if(33554432>d)return a.Ra().d[31&b>>20].d[31&b>>15].d[31&b>>10].d[31&b>>5].d[31&b];if(1073741824>d)return a.Ic().d[31&b>>25].d[31&b>>20].d[31&b>>15].d[31&b>>10].d[31&b>>5].d[31&b];throw(new Cb).b();}
+function nl(a,b){var d=-1+a.Hb()|0;switch(d){case 5:a.Df(Z(a.Ic()));a.vc(Z(a.Ra()));a.eb(Z(a.Aa()));a.Fa(Z(a.aa()));a.va(Z(a.P()));a.Ic().d[31&b>>25]=a.Ra();a.Ra().d[31&b>>20]=a.Aa();a.Aa().d[31&b>>15]=a.aa();a.aa().d[31&b>>10]=a.P();a.P().d[31&b>>5]=a.nb();break;case 4:a.vc(Z(a.Ra()));a.eb(Z(a.Aa()));a.Fa(Z(a.aa()));a.va(Z(a.P()));a.Ra().d[31&b>>20]=a.Aa();a.Aa().d[31&b>>15]=a.aa();a.aa().d[31&b>>10]=a.P();a.P().d[31&b>>5]=a.nb();break;case 3:a.eb(Z(a.Aa()));a.Fa(Z(a.aa()));a.va(Z(a.P()));a.Aa().d[31&
+b>>15]=a.aa();a.aa().d[31&b>>10]=a.P();a.P().d[31&b>>5]=a.nb();break;case 2:a.Fa(Z(a.aa()));a.va(Z(a.P()));a.aa().d[31&b>>10]=a.P();a.P().d[31&b>>5]=a.nb();break;case 1:a.va(Z(a.P()));a.P().d[31&b>>5]=a.nb();break;case 0:break;default:throw(new K).w(d);}}function ol(a,b){var d=a.d[b];a.d[b]=null;return Z(d)}
+function pl(a,b,d){a.Md(d);d=-1+d|0;switch(d){case -1:break;case 0:a.Ga(b.nb());break;case 1:a.va(b.P());a.Ga(b.nb());break;case 2:a.Fa(b.aa());a.va(b.P());a.Ga(b.nb());break;case 3:a.eb(b.Aa());a.Fa(b.aa());a.va(b.P());a.Ga(b.nb());break;case 4:a.vc(b.Ra());a.eb(b.Aa());a.Fa(b.aa());a.va(b.P());a.Ga(b.nb());break;case 5:a.Df(b.Ic());a.vc(b.Ra());a.eb(b.Aa());a.Fa(b.aa());a.va(b.P());a.Ga(b.nb());break;default:throw(new K).w(d);}}
+function ql(a,b,d){if(32<=d)if(1024>d)a.Ga(a.P().d[31&b>>5]);else if(32768>d)a.va(a.aa().d[31&b>>10]),a.Ga(a.P().d[31&b>>5]);else if(1048576>d)a.Fa(a.Aa().d[31&b>>15]),a.va(a.aa().d[31&b>>10]),a.Ga(a.P().d[31&b>>5]);else if(33554432>d)a.eb(a.Ra().d[31&b>>20]),a.Fa(a.Aa().d[31&b>>15]),a.va(a.aa().d[31&b>>10]),a.Ga(a.P().d[31&b>>5]);else if(1073741824>d)a.vc(a.Ic().d[31&b>>25]),a.eb(a.Ra().d[31&b>>20]),a.Fa(a.Aa().d[31&b>>15]),a.va(a.aa().d[31&b>>10]),a.Ga(a.P().d[31&b>>5]);else throw(new Cb).b();}
+function Z(a){null===a&&Ci("NULL");var b=p(v(u),[a.d.length]);Fa(a,0,b,0,a.d.length);return b}function rl(a,b,d){var e=p(v(u),[32]);Fa(a,b,e,d,32-(d>b?d:b)|0);return e}
+function sl(a,b,d,e){if(32<=e)if(1024>e)1===a.Hb()&&(a.va(p(v(u),[32])),a.P().d[31&b>>5]=a.nb(),a.Md(1+a.Hb()|0)),a.Ga(p(v(u),[32]));else if(32768>e)2===a.Hb()&&(a.Fa(p(v(u),[32])),a.aa().d[31&b>>10]=a.P(),a.Md(1+a.Hb()|0)),a.va(a.aa().d[31&d>>10]),null===a.P()&&a.va(p(v(u),[32])),a.Ga(p(v(u),[32]));else if(1048576>e)3===a.Hb()&&(a.eb(p(v(u),[32])),a.Aa().d[31&b>>15]=a.aa(),a.Fa(p(v(u),[32])),a.va(p(v(u),[32])),a.Md(1+a.Hb()|0)),a.Fa(a.Aa().d[31&d>>15]),null===a.aa()&&a.Fa(p(v(u),[32])),a.va(a.aa().d[31&
+d>>10]),null===a.P()&&a.va(p(v(u),[32])),a.Ga(p(v(u),[32]));else if(33554432>e)4===a.Hb()&&(a.vc(p(v(u),[32])),a.Ra().d[31&b>>20]=a.Aa(),a.eb(p(v(u),[32])),a.Fa(p(v(u),[32])),a.va(p(v(u),[32])),a.Md(1+a.Hb()|0)),a.eb(a.Ra().d[31&d>>20]),null===a.Aa()&&a.eb(p(v(u),[32])),a.Fa(a.Aa().d[31&d>>15]),null===a.aa()&&a.Fa(p(v(u),[32])),a.va(a.aa().d[31&d>>10]),null===a.P()&&a.va(p(v(u),[32])),a.Ga(p(v(u),[32]));else if(1073741824>e)5===a.Hb()&&(a.Df(p(v(u),[32])),a.Ic().d[31&b>>25]=a.Ra(),a.vc(p(v(u),[32])),
+a.eb(p(v(u),[32])),a.Fa(p(v(u),[32])),a.va(p(v(u),[32])),a.Md(1+a.Hb()|0)),a.vc(a.Ic().d[31&d>>20]),null===a.Ra()&&a.vc(p(v(u),[32])),a.eb(a.Ra().d[31&d>>20]),null===a.Aa()&&a.eb(p(v(u),[32])),a.Fa(a.Aa().d[31&d>>15]),null===a.aa()&&a.Fa(p(v(u),[32])),a.va(a.aa().d[31&d>>10]),null===a.P()&&a.va(p(v(u),[32])),a.Ga(p(v(u),[32]));else throw(new Cb).b();}function tl(){}tl.prototype=new t;tl.prototype.na=function(){var a=(new dk).b();return ul(new vl,a,M(function(){return function(a){return(new wl).h(a)}}(this)))};
+tl.prototype.a=new s({TC:0},!1,"scala.collection.immutable.WrappedString$",{TC:1,c:1});var xl=void 0;function yl(a,b,d,e){var f=Ri(U(),a.Pb());e=e<f?e:f;(Ri(U(),b)-d|0)<e&&(e=Ri(U(),b)-d|0,e=0<e?e:0);zl(rc(),a.Pb(),0,b,d,e)}function Al(){}Al.prototype=new t;Al.prototype.a=new s({WC:0},!1,"scala.collection.mutable.ArrayOps$ofBoolean$",{WC:1,c:1});var Bl=void 0;function Cl(){}Cl.prototype=new t;Cl.prototype.a=new s({XC:0},!1,"scala.collection.mutable.ArrayOps$ofByte$",{XC:1,c:1});var Dl=void 0;
+function El(){}El.prototype=new t;El.prototype.a=new s({YC:0},!1,"scala.collection.mutable.ArrayOps$ofChar$",{YC:1,c:1});var Fl=void 0;function Gl(){}Gl.prototype=new t;Gl.prototype.a=new s({ZC:0},!1,"scala.collection.mutable.ArrayOps$ofDouble$",{ZC:1,c:1});var Hl=void 0;function Il(){}Il.prototype=new t;Il.prototype.a=new s({$C:0},!1,"scala.collection.mutable.ArrayOps$ofFloat$",{$C:1,c:1});var Jl=void 0;function Kl(){}Kl.prototype=new t;
+Kl.prototype.a=new s({aD:0},!1,"scala.collection.mutable.ArrayOps$ofInt$",{aD:1,c:1});var Ll=void 0;function Ml(){}Ml.prototype=new t;Ml.prototype.a=new s({bD:0},!1,"scala.collection.mutable.ArrayOps$ofLong$",{bD:1,c:1});var Nl=void 0;function Ol(){}Ol.prototype=new t;Ol.prototype.a=new s({cD:0},!1,"scala.collection.mutable.ArrayOps$ofRef$",{cD:1,c:1});var Pl=void 0;function Ql(){}Ql.prototype=new t;Ql.prototype.a=new s({dD:0},!1,"scala.collection.mutable.ArrayOps$ofShort$",{dD:1,c:1});var Rl=void 0;
+function Sl(){}Sl.prototype=new t;Sl.prototype.a=new s({eD:0},!1,"scala.collection.mutable.ArrayOps$ofUnit$",{eD:1,c:1});var Tl=void 0;function Pj(a,b,d){Ij(b)&&a.Ta(b.U()+d|0)}function Ul(a,b,d){Ij(d)&&(d=d.U(),a.Ta(b<d?b:d))}function Vl(){}Vl.prototype=new t;function Wl(a,b,d){if(!(500>b))throw(new Xl).w("assertion failed: loadFactor too large; must be \x3c 0.5");return Yl(Zl(Uf((new T).Oa(d),(new T).Oa(b)),(new T).k(1E3,0,0)))}
+Vl.prototype.a=new s({gD:0},!1,"scala.collection.mutable.FlatHashTable$",{gD:1,c:1});var $l=void 0;function am(){$l||($l=(new Vl).b());return $l}function bm(){}bm.prototype=new t;bm.prototype.o=h("NullSentinel");bm.prototype.M=h(0);bm.prototype.a=new s({iD:0},!1,"scala.collection.mutable.FlatHashTable$NullSentinel$",{iD:1,c:1});var cm=void 0;function dm(){cm||(cm=(new bm).b());return cm}
+function em(a,b){for(var d=null===b?dm():b,e=za(d),e=fm(a,e),f=a.Nb.d[e];null!==f&&!O(P(),f,d);)e=(1+e|0)%a.Nb.d.length,f=a.Nb.d[e];return f}
+function gm(a,b){for(var d=za(b),d=fm(a,d),e=a.Nb.d[d];null!==e;){if(O(P(),e,b))return;d=(1+d|0)%a.Nb.d.length;e=a.Nb.d[d]}a.Nb.d[d]=b;a.Pg=1+a.Pg|0;null!==a.eg&&(d>>=5,e=a.eg,e.d[d]=1+e.d[d]|0);if(a.Pg>=a.zj){d=a.Nb;a.Nb=p(v(u),[w(2,a.Nb.d.length)]);a.Pg=0;if(null!==a.eg)if(e=1+(a.Nb.d.length>>5)|0,a.eg.d.length!==e)a.eg=p(v(Ua),[e]);else{jg||(jg=(new ig).b());for(var e=a.eg,f=0;f!==e.d.length;)e.d[f]=0,f=1+f|0}a.vj=Nf(Ve(),-1+a.Nb.d.length|0);a.zj=Wl(am(),a.Fi,a.Nb.d.length);for(e=0;e<d.d.length;)f=
+d.d[e],null!==f&&gm(a,f),e=1+e|0}}function fm(a,b){var d=a.vj;zi||(zi=(new yi).b());var e;e=w(-1640532531,b);Ve();e=w(-1640532531,e<<24|16711680&e<<8|65280&(e>>>8|0)|e>>>24|0);var d=d%32,f=-1+a.Nb.d.length|0;return((e>>>d|0|e<<(32-d|0))>>>(32-Nf(Ve(),f)|0)|0)&f}function hm(){im||(im=(new jm).b());var a=31,a=a|a>>>1|0,a=a|a>>>2|0,a=a|a>>>4|0,a=a|a>>>8|0;return 1+(a|a>>>16|0)|0}function jm(){}jm.prototype=new t;jm.prototype.a=new s({mD:0},!1,"scala.collection.mutable.HashTable$",{mD:1,c:1});
+var im=void 0;function km(a,b){var d=(new T).Oa(a.p.d.length);if(lm((new T).Oa(b),d)){for(d=Uf((new T).k(2,0,0),d);lm((new T).Oa(b),d);)d=Uf((new T).k(2,0,0),d);lm(d,(new T).k(4194303,511,0))&&(d=(new T).k(4194303,511,0));d=p(v(u),[Yl(d)]);Fa(a.p,0,d,0,a.Mb);a.p=d}}function mm(a,b){if(b>=a.Mb)throw(new Rg).h(""+b);return a.p.d[b]}function we(){this.hq=null}we.prototype=new t;we.prototype.b=function(){ve=this;this.hq=(new Sb).me(p(v(u),[0]));return this};
+function xe(a){if(null===a)return null;if(jb(a,1))return(new Sb).me(a);if(cb(a,1))return(new nm).Of(a);if(fb(a,1))return(new om).Mf(a);if(db(a,1))return(new pm).Pf(a);if(eb(a,1))return(new qm).Nf(a);if($a(a,1))return(new rm).Lf(a);if(ab(a,1))return(new sm).Kf(a);if(bb(a,1))return(new tm).Qf(a);if(Za(a,1))return(new um).Rf(a);if(vm(a))return(new wm).Sf(a);throw(new K).w(a);}we.prototype.a=new s({vD:0},!1,"scala.collection.mutable.WrappedArray$",{vD:1,c:1});var ve=void 0;function xm(){}
+xm.prototype=new t;function Cg(){ym||(ym=(new xm).b());return{}}xm.prototype.a=new s({ED:0},!1,"scala.scalajs.js.Dictionary$",{ED:1,c:1});var ym=void 0;function zm(){this.oh=null}zm.prototype=new t;zm.prototype.b=function(){Am=this;this.oh=m.Object.prototype.hasOwnProperty;return this};zm.prototype.a=new s({ID:0},!1,"scala.scalajs.js.WrappedDictionary$Cache$",{ID:1,c:1});var Am=void 0;function Dg(){Am||(Am=(new zm).b());return Am}
+function Bm(){this.vg=!1;this.an=this.Yu=this.aj=this.Ph=null;this.Yj=!1;this.In=this.kn=0}Bm.prototype=new t;
+Bm.prototype.b=function(){Cm=this;this.Ph=(this.vg=!!(m.ArrayBuffer&&m.Int32Array&&m.Float32Array&&m.Float64Array))?new m.ArrayBuffer(8):null;this.aj=this.vg?new m.Int32Array(this.Ph,0,2):null;this.Yu=this.vg?new m.Float32Array(this.Ph,0,2):null;this.an=this.vg?new m.Float64Array(this.Ph,0,1):null;if(this.vg)this.aj[0]=16909060,a=1===((new m.Int8Array(this.Ph,0,8))[0]|0);else var a=!0;this.kn=(this.Yj=a)?0:1;this.In=this.Yj?1:0;return this};
+function Ca(a,b){var d=b|0;if(d===b&&-Infinity!==1/b)return d;if(a.vg)a.an[0]=b,d=Dm(Em((new T).Oa(a.aj[a.kn]|0),32),Fm((new T).k(4194303,1023,0),(new T).Oa(a.aj[a.In]|0)));else{if(b!==b)var d=!1,e=2047,f=+m.Math.pow(2,51);else if(Infinity===b||-Infinity===b)d=0>b,e=2047,f=0;else if(0===b)d=-Infinity===1/b,f=e=0;else{var g=(d=0>b)?-b:b;if(g>=+m.Math.pow(2,-1022)){var e=+m.Math.pow(2,52),f=+m.Math.log(g)/0.6931471805599453,f=+m.Math.floor(f)|0,f=1023>f?f:1023,k=g/+m.Math.pow(2,f)*e,g=+m.Math.floor(k),
+k=k-g,g=0.5>k?g:0.5<k?1+g:0!==g%2?1+g:g;2<=g/e&&(f=1+f|0,g=1);1023<f?(f=2047,g=0):(f=1023+f|0,g-=e);e=f;f=g}else e=g/+m.Math.pow(2,-1074),f=+m.Math.floor(e),g=e-f,e=0,f=0.5>g?f:0.5<g?1+f:0!==f%2?1+f:f}f=+ +f;g=f|0;d=Dm(Em((new T).Oa((d?-2147483648:0)|(e|0)<<20|f/4294967296|0),32),Fm((new T).k(4194303,1023,0),(new T).Oa(g)))}return Yl(Gm(d,Hm(d)))}Bm.prototype.a=new s({ND:0},!1,"scala.scalajs.runtime.Bits$",{ND:1,c:1});var Cm=void 0;function Da(){Cm||(Cm=(new Bm).b());return Cm}function Im(){}
+Im.prototype=new t;
+function Rb(a,b,d,e){if(null===b)throw(new va).b();var f=(Jm(),(new Km).gi(d,0));d=0<e?e:2147483647;a=[];b=ka(b);for(var f=Lm(new Mm,f,b,b.length|0),g=0;(a.length|0)<(-1+d|0)&&Nm(f);){var k=Om(f).index|0;a.push(b.substring(g,k));g=Pm(f)}a.push(b.substring(g));if(0===g&&2===(a.length|0)&&(2<d||!Nm(f)))a=qc(rc(),(new C).A([b]),sc(tc(),q(ma)));else{d=a.length|0;if(0===e)for(;;){if(1<d){e=a[-1+d|0];if(null===e)throw(new va).b();e=""===e}else e=!1;if(e)d=-1+d|0;else break}e=p(v(ma),[d]);f=e.d.length;b=
+d=0;g=a.length|0;f=g<f?g:f;g=e.d.length;for(f=f<g?f:g;d<f;)e.d[b]=a[d],d=1+d|0,b=1+b|0;a=e}return a}function Bj(a,b){return null===b?"null":ka(b)}function Tj(a,b,d){a=Sj(d);return b.indexOf(a)|0}function Sj(a){if(0===(-65536&a)){var b=m.String,d=b.fromCharCode;a=[a];a=[].concat(a);return d.apply(b,a)}if(0>a||1114111<a)throw(new Cb).b();a=-65536+a|0;b=m.String;d=b.fromCharCode;a=[55296|a>>10,56320|1023&a];a=[].concat(a);return d.apply(b,a)}
+function Aa(a,b){for(var d=0,e=1,f=-1+(b.length|0)|0;0<=f;)d=d+w(65535&(b.charCodeAt(f)|0),e)|0,e=w(31,e),f=-1+f|0;return d}Im.prototype.a=new s({PD:0},!1,"scala.scalajs.runtime.RuntimeString$",{PD:1,c:1});var Qm=void 0;function Ba(){Qm||(Qm=(new Im).b());return Qm}function Rm(){this.tH=!1;this.ju=this.wm=this.qu=null;this.Q=!1}Rm.prototype=new t;
+Rm.prototype.b=function(){Sm=this;for(var a={O:"java_lang_Object",T:"java_lang_String",V:"scala_Unit",Z:"scala_Boolean",C:"scala_Char",B:"scala_Byte",S:"scala_Short",I:"scala_Int",J:"scala_Long",F:"scala_Float",D:"scala_Double"},b=0;22>=b;)2<=b&&(a["T"+b]="scala_Tuple"+b),a["F"+b]="scala_Function"+b,b=1+b|0;this.qu=a;this.wm={sjsr_:"scala_scalajs_runtime_",sjs_:"scala_scalajs_",sci_:"scala_collection_immutable_",scm_:"scala_collection_mutable_",scg_:"scala_collection_generic_",sc_:"scala_collection_",
+sr_:"scala_runtime_",s_:"scala_",jl_:"java_lang_",ju_:"java_util_"};this.ju=m.Object.keys(this.wm);return this};Rm.prototype.a=new s({QD:0},!1,"scala.scalajs.runtime.StackTrace$",{QD:1,c:1});var Sm=void 0;function Tm(){Sm||(Sm=(new Rm).b());return Sm}function Um(){}Um.prototype=new t;function G(a,b){return Vm(b)?b.Gf:b}function Wm(a,b){return b&&b.a&&b.a.t.dc?b:(new Xm).w(b)}Um.prototype.a=new s({RD:0},!1,"scala.scalajs.runtime.package$",{RD:1,c:1});var Ym=void 0;
+function H(){Ym||(Ym=(new Um).b());return Ym}function vm(a){return!!(a&&a.a&&1===a.a.Qh&&a.a.Oh.t.Cp)}var ua=new s({Cp:0},!1,"scala.runtime.BoxedUnit",{Cp:1,c:1},void 0,function(a){return void 0===a});function Zm(){}Zm.prototype=new t;
+function O(a,b,d){return b===d?!0:$f(b)?$f(d)?$m(b,d):an(d)?"number"===typeof b?+b===d.j:wa(b)?bn(Ia(b),(new T).Oa(d.j)):null===b?null===d:ya(b,d):null===b?null===d:ya(b,d):an(b)?an(d)?b.j===d.j:$f(d)?"number"===typeof d?+d===b.j:wa(d)?bn(Ia(d),(new T).Oa(b.j)):null===d?null===b:ya(d,b):null===b&&null===d:null===b?null===d:ya(b,d)}
+function $m(a,b){if("number"===typeof a){var d=+a;if("number"===typeof b)return d===+b;if(wa(b)){var e=Ia(b);return d===cn(e)}return dn(b)?b.K(d):!1}return wa(a)?(d=Ia(a),wa(b)?(e=Ia(b),bn(d,e)):"number"===typeof b?(e=+b,cn(d)===e):dn(b)?b.K(d):!1):null===a?null===b:ya(a,b)}Zm.prototype.a=new s({$D:0},!1,"scala.runtime.BoxesRunTime$",{$D:1,c:1});var en=void 0;function P(){en||(en=(new Zm).b());return en}var Zh=new s({cE:0},!1,"scala.runtime.Null$",{cE:1,c:1});function fn(){}fn.prototype=new t;
+function Ri(a,b){if(jb(b,1)||cb(b,1)||fb(b,1)||db(b,1)||eb(b,1)||$a(b,1)||ab(b,1)||bb(b,1)||Za(b,1)||vm(b))return b.d.length;if(null===b)throw(new va).b();throw(new K).w(b);}function ui(a,b){var d;if(null===b)d=0;else if($f(b))if(P(),Ha(b))d=b|0;else if(wa(b))d=Yl(Ia(b)),d=bn((new T).Oa(d),Ia(b))?d:Yl(Gm(Ia(b),Hm(Ia(b))));else if("number"===typeof b){var e=+b|0;d=+b;e===d?d=e:(e=gn(Ja(),+b),d=cn(e)===d?Yl(Gm(e,Hm(e))):Ca(Da(),+b))}else d=za(b);else d=za(b);return d}
+function Si(a,b,d,e){if(jb(b,1))b.d[d]=e;else if(cb(b,1))b.d[d]=e|0;else if(fb(b,1))b.d[d]=+e;else if(db(b,1))b.d[d]=Ia(e);else if(eb(b,1))b.d[d]=qa(e);else if($a(b,1))b.d[d]=null===e?0:e.j;else if(ab(b,1))b.d[d]=e|0;else if(bb(b,1))b.d[d]=e|0;else if(Za(b,1))b.d[d]=!!e;else if(vm(b))b.d[d]=e;else{if(null===b)throw(new va).b();throw(new K).w(b);}}
+function Mh(a,b){if(b&&b.a&&b.a.t.An)return b.Ed.getComponentType();if(b&&b.a&&b.a.t.cd)return b.sd();throw(new xj).h(Db((new Eb).La((new C).A(["unsupported schematic "," (",")"])),(new C).A([b,la(b)])));}function hn(a,b){var d=b.qb(),e=b.jb()+"(";return L(d,e,",",")")}fn.prototype.a=new s({eE:0},!1,"scala.runtime.ScalaRunTime$",{eE:1,c:1});var jn=void 0;function U(){jn||(jn=(new fn).b());return jn}function kn(){}kn.prototype=new t;
+kn.prototype.ej=function(a,b){var d;d=w(-862048943,b);d=Mf(Ve(),d,15);d=w(461845907,d);return a^d};function ln(a,b){if(null===b)return 0;if(wa(b)){var d=Ia(b);return Yl(d)}return"number"===typeof b?+b|0:b!==b||qa(b)===b?qa(b)|0:za(b)}kn.prototype.Nc=function(a,b){var d=this.ej(a,b),d=Mf(Ve(),d,13);return-430675100+w(5,d)|0};kn.prototype.Cg=function(a,b){var d=a^b,d=w(-2048144789,d^(d>>>16|0)),d=d^(d>>>13|0),d=w(-1028477387,d);return d^=d>>>16|0};
+kn.prototype.a=new s({gE:0},!1,"scala.runtime.Statics$",{gE:1,c:1});var mn=void 0;function nn(){mn||(mn=(new kn).b());return mn}function on(){this.lo=null}on.prototype=new t;function Vc(a){var b=new on;b.lo=a;return b}on.prototype.ug=function(a){a.classList.add(this.lo.Ha)};on.prototype.je=function(a){this.ug(a)};on.prototype.a=new s({xq:0},!1,"scalatags.JsDom$Aggregate$$anon$1",{xq:1,c:1,tf:1});function R(){this.W=this.yb=null}R.prototype=new t;
+function Q(a,b,d){a.yb=d;if(null===b)throw G(H(),null);a.W=b;return a}R.prototype.Ze=function(a){var b=m.document.createElement("div"),d=this.yb;b.style.setProperty(d.yb.ke,ka(d.Za));b=Rb(Ba(),b.getAttribute("style"),":",2);rc();null===b?d=sg():(d=pn(Ac(),b),Ac(),d=(new tg).w(Kj(d,new Bc)));if(d.m()||null===d.Wc()||0!==d.Wc().pb(2))throw(new K).w(b);b=d.Wc().ma(0);d=d.Wc().ma(1);b=a.qf.Np(b,d);return Jd(new Kd,a.he,b,a.Bc)};
+R.prototype.a=new s({yq:0},!1,"scalatags.JsDom$Aggregate$StyleFrag",{yq:1,c:1,Vl:1});function qn(){}qn.prototype=new t;qn.prototype.mm=function(a,b,d){a.setAttribute(b.Ha,ka(d))};qn.prototype.a=new s({Bq:0},!1,"scalatags.JsDom$GenericAttr",{Bq:1,c:1,Mq:1});function wb(){this.Vc=null}wb.prototype=new t;wb.prototype.Cb=function(a,b){return A(new B,a,b,this.Vc)};wb.prototype.$d=function(a){this.Vc=a;return this};wb.prototype.a=new s({Cq:0},!1,"scalatags.JsDom$GenericPixelStyle",{Cq:1,c:1,Sq:1});
+function rn(){this.Vc=null}rn.prototype=new t;rn.prototype.Cb=function(a,b){var d=new B,e;Pg||(Pg=(new Og).b());e=""+Bj(Ba(),b)+"px";return A(d,a,e,this.Vc)};rn.prototype.$d=function(a){this.Vc=a;return this};rn.prototype.a=new s({Dq:0},!1,"scalatags.JsDom$GenericPixelStylePx",{Dq:1,c:1,Sq:1});function z(){}z.prototype=new t;z.prototype.a=new s({Eq:0},!1,"scalatags.JsDom$GenericStyle",{Eq:1,c:1,aG:1});function ed(){this.Om=null}ed.prototype=new t;function dd(a,b){a.Om=b;return a}
+ed.prototype.mm=function(a,b,d){a[b.Ha]=this.Om.l(d)};ed.prototype.a=new s({Kq:0},!1,"scalatags.LowPriorityImplicits$$anon$2",{Kq:1,c:1,Mq:1});function sb(){}sb.prototype=new t;sb.prototype.Rp=h("http://www.w3.org/1999/xhtml");sb.prototype.a=new s({Qq:0},!1,"scalatags.generic.Namespace$$anon$1",{Qq:1,c:1,Oq:1});function tb(){}tb.prototype=new t;tb.prototype.Rp=h("http://www.w3.org/2000/svg");tb.prototype.a=new s({Rq:0},!1,"scalatags.generic.Namespace$$anon$2",{Rq:1,c:1,Oq:1});
+function sn(){this.W=this.Do=this.Ei=null}sn.prototype=new t;function fd(a,b,d){var e=new sn;e.Ei=b;e.Do=d;if(null===a)throw G(H(),null);e.W=a;return e}sn.prototype.je=function(a){this.Ei.R(M(function(a,d){return function(e){a.Do.l(e).je(d)}}(this,a)))};sn.prototype.a=new s({rr:0},!1,"scalatags.generic.Util$SeqNode",{rr:1,c:1,tf:1});function tn(){this.kg=null}tn.prototype=new t;
+tn.prototype.Ze=function(a){var b=a.he,d=(this.kg.Q?this.kg.fg:ac(this.kg)).qf.Al(a.qf),e=(this.kg.Q?this.kg.fg:ac(this.kg)).Bc;a=a.Bc;var f=bc();return Jd(new Kd,b,d,e.sf(a,f.N))};function Zd(a){var b=new tn;if(null===a)throw G(H(),null);b.kg=a;return b}tn.prototype.a=new s({vr:0},!1,"scalatags.stylesheet.Cls$$anon$1",{vr:1,c:1,Vl:1});function un(){this.Ce=null}un.prototype=new t;
+function Hd(a,b){var d=a.Ce,e=x();if(null===d?null===e:d.K(e))return(new un).La(jk(bc(),(new C).A([":"+b])));var d=a.Ce.ef(),e=a.Ce.Je(),f=bc();return(new un).La(d.Dd(e+":"+b,f.N))}un.prototype.La=function(a){this.Ce=a;return this};un.prototype.a=new s({xr:0},!1,"scalatags.stylesheet.Selector",{xr:1,c:1,wr:1});function vn(){this.W=this.he=null}vn.prototype=new t;function wn(){}wn.prototype=vn.prototype;function Nd(a,b){return xn("",a.he,b)}
+vn.prototype.Kv=function(a,b){this.he=b;if(null===a)throw G(H(),null);this.W=a;return this};function yn(){this.sh=null}yn.prototype=new t;yn.prototype.Ze=function(a){var b=a.he,d=a.qf;a=a.Bc;var e=jk(bc(),(new C).A([this.sh])),f=bc();return Jd(new Kd,b,d,a.sf(e,f.N))};function Md(a){var b=new yn;b.sh=a;return b}yn.prototype.a=new s({zr:0},!1,"scalatags.stylesheet.StyleSheetFrag$StyleTreeFrag",{zr:1,c:1,Vl:1});function mc(){this.Hj=null}mc.prototype=new t;mc.prototype.Rk=c("Hj");
+mc.prototype.Fe=function(a){this.Hj=a;return this};mc.prototype.a=new s({gs:0},!1,"upickle.Knot$R",{gs:1,c:1,dm:1});function qe(){this.Dl=null}qe.prototype=new t;qe.prototype.Rk=c("Dl");qe.prototype.Fe=function(a){this.Dl=a;return this};qe.prototype.a=new s({ks:0},!1,"upickle.Reader$$anon$3",{ks:1,c:1,dm:1});function Ie(){this.Tp=null}Ie.prototype=new t;function He(a,b){a.Tp=b;return a}Ie.prototype.Up=c("Tp");Ie.prototype.a=new s({ps:0},!1,"upickle.Writer$$anon$2",{ps:1,c:1,ns:1});
+var ta=new s({bw:0},!1,"java.lang.Boolean",{bw:1,c:1,Zc:1},void 0,function(a){return"boolean"===typeof a});function Re(){this.j=0}Re.prototype=new t;l=Re.prototype;l.K=function(a){return an(a)?this.j===a.j:!1};l.o=function(){return m.String.fromCharCode(this.j)};l.nc=function(a){this.j=a;return this};l.M=c("j");function an(a){return!!(a&&a.a&&a.a.t.zn)}l.a=new s({zn:0},!1,"java.lang.Character",{zn:1,c:1,Zc:1});function oi(){eg.call(this)}oi.prototype=new fg;function zn(){}zn.prototype=oi.prototype;
+function An(){this.SI=this.Pi=this.yb=null}An.prototype=new t;function Bn(){}l=Bn.prototype=An.prototype;l.b=function(){An.prototype.Ee.call(this,null,null);return this};l.Ti=function(){var a=Tm(),b;a:try{b=a.undef()}catch(d){a=Wm(H(),d);if(null!==a){if(Vm(a)){b=a.Gf;break a}throw G(H(),a);}throw d;}this.stackdata=b;return this};l.di=c("yb");l.o=function(){var a=ib(la(this)),b=this.di();return null===b?a:a+": "+b};l.Ee=function(a,b){this.yb=a;this.Pi=b;this.Ti();return this};
+function Cn(){this.Zp=0;this.Bl=null}Cn.prototype=new t;function Dn(){}Dn.prototype=Cn.prototype;Cn.prototype.o=c("Bl");Cn.prototype.ff=function(a,b){this.Zp=a;this.Bl=b;return this};var En=new s({Uf:0},!1,"java.util.concurrent.TimeUnit",{Uf:1,c:1,e:1});Cn.prototype.a=En;function Mm(){this.pn=this.mf=null;this.ho=this.io=0;this.Ie=this.Ck=this.Kg=null;this.Hi=this.Hk=!1;this.lm=0}Mm.prototype=new t;
+function Nm(a){if(a.Hi){a.Hk=!0;a.Ie=a.Kg.exec(a.Ck);if(null!==a.Ie){var b=a.Ie[0];if(void 0===b)throw(new uj).h("undefined.get");if(null===b)throw(new va).b();""===b&&(b=a.Kg,b.lastIndex=1+(b.lastIndex|0)|0)}else a.Hi=!1;return null!==a.Ie}return!1}function Om(a){if(null===a.Ie)throw(new Fn).h("No match available");return a.Ie}function Gn(a){Hn(a);Nm(a);null===a.Ie||0===(Om(a).index|0)&&Pm(a)===(a.Ck.length|0)||Hn(a);return null!==a.Ie}
+function Pm(a){var b=Om(a).index|0;a=Om(a)[0];if(void 0===a)throw(new uj).h("undefined.get");return b+(a.length|0)|0}function Lm(a,b,d,e){a.mf=b;a.pn=d;a.io=0;a.ho=e;a.Kg=new m.RegExp(a.mf.En,a.mf.Dn);a.Ck=ka(Ea(a.pn,a.io,a.ho));a.Ie=null;a.Hk=!1;a.Hi=!0;a.lm=0;return a}function Hn(a){a.Kg.lastIndex=0;a.Ie=null;a.Hk=!1;a.Hi=!0;a.lm=0}Mm.prototype.a=new s({Pw:0},!1,"java.util.regex.Matcher",{Pw:1,c:1,yH:1});function Bc(){}Bc.prototype=new t;Bc.prototype.$e=function(){In();uc();return(new Jn).b()};
+Bc.prototype.Tc=function(){In();uc();return(new Jn).b()};Bc.prototype.a=new s({Iz:0},!1,"scala.LowPriorityImplicits$$anon$4",{Iz:1,c:1,qi:1});function Kn(){}Kn.prototype=new t;Kn.prototype.$e=function(){return(new dk).b()};Kn.prototype.Tc=function(){return(new dk).b()};Kn.prototype.a=new s({Vz:0},!1,"scala.Predef$$anon$3",{Vz:1,c:1,qi:1});function dn(a){return!!(a&&a.a&&a.a.t.pI)}function Wg(){}Wg.prototype=new t;Wg.prototype.o=h("object AnyRef");
+Wg.prototype.a=new s({uA:0},!1,"scala.package$$anon$1",{uA:1,c:1,$H:1});function Ln(){this.ml=this.Jk=this.ll=this.bJ=this.UI=this.KH=this.TI=this.XG=0}Ln.prototype=new si;Ln.prototype.b=function(){Mn=this;this.ll=Aa(Ba(),"Seq");this.Jk=Aa(Ba(),"Map");this.ml=Aa(Ba(),"Set");return this};function Nn(a,b){var d;if(b&&b.a&&b.a.t.Jo){d=0;for(var e=a.ll,f=b;!f.m();){var g=f.u(),f=f.s(),e=a.Nc(e,ui(U(),g));d=1+d|0}d=a.Cg(e,d)}else d=xi(a,b,a.ll);return d}
+Ln.prototype.a=new s({YA:0},!1,"scala.util.hashing.MurmurHash3$",{YA:1,sI:1,c:1});var Mn=void 0;function wi(){Mn||(Mn=(new Ln).b());return Mn}function On(){this.W=this.hj=null}On.prototype=new t;function Pn(){}Pn.prototype=On.prototype;On.prototype.R=function(a){this.W.R(M(function(a,d){return function(e){return a.hj.l(e)?d.l(e):void 0}}(this,a)))};On.prototype.od=function(a,b){this.hj=b;if(null===a)throw G(H(),null);this.W=a;return this};
+On.prototype.a=new s({so:0},!1,"scala.collection.TraversableLike$WithFilter",{so:1,c:1,$:1});function Qn(){this.W=null}Qn.prototype=new t;Qn.prototype.$e=function(){return Wj(new Xj,this.W.Ri())};Qn.prototype.Tc=function(){return Wj(new Xj,this.W.Ri())};Qn.prototype.a=new s({vB:0},!1,"scala.collection.generic.GenMapFactory$MapCanBuildFrom",{vB:1,c:1,qi:1});function Rn(){}Rn.prototype=new ik;function Sn(){}Sn.prototype=Rn.prototype;function Tn(){this.N=null}Tn.prototype=new ik;function Un(){}
+Un.prototype=Tn.prototype;Tn.prototype.b=function(){this.N=(new Vn).ii(this);return this};function Wn(){this.W=null}Wn.prototype=new t;function Xn(){}Xn.prototype=Wn.prototype;Wn.prototype.$e=function(){return this.W.na()};Wn.prototype.Tc=function(a){return a.Ab().na()};Wn.prototype.ii=function(a){if(null===a)throw G(H(),null);this.W=a;return this};function Yn(){}Yn.prototype=new nk;function Zn(){}Zn.prototype=Yn.prototype;function $n(){}$n.prototype=new gk;function ao(){}ao.prototype=$n.prototype;
+function bo(){this.Mk=this.Xv=null}bo.prototype=new sk;function co(a,b){a.Mk=b;var d=new eo;if(null===a)throw G(H(),null);d.ja=a;a.Xv=d;return a}bo.prototype.Wj=function(a,b){return zg(this.Mk,a,b)};bo.prototype.a=new s({EB:0},!1,"scala.collection.immutable.HashMap$$anon$2",{EB:1,JB:1,c:1});function eo(){this.ja=null}eo.prototype=new sk;eo.prototype.Wj=function(a,b){return zg(this.ja.Mk,b,a)};eo.prototype.a=new s({FB:0},!1,"scala.collection.immutable.HashMap$$anon$2$$anon$3",{FB:1,JB:1,c:1});
+function fo(){}fo.prototype=new t;fo.prototype.b=function(){return this};fo.prototype.l=function(){return this};fo.prototype.o=h("\x3cfunction1\x3e");fo.prototype.a=new s({SB:0},!1,"scala.collection.immutable.List$$anon$1",{SB:1,c:1,x:1});function go(){}go.prototype=new t;function ho(){}ho.prototype=go.prototype;go.prototype.o=h("\x3cfunction0\x3e");function io(){}io.prototype=new t;function jo(){}jo.prototype=io.prototype;io.prototype.b=function(){return this};io.prototype.o=h("\x3cfunction1\x3e");
+function ko(){}ko.prototype=new t;function lo(){}lo.prototype=ko.prototype;ko.prototype.o=h("\x3cfunction2\x3e");function mo(){this.v=!1}mo.prototype=new t;mo.prototype.o=function(){return""+this.v};function Oj(a){var b=new mo;b.v=a;return b}mo.prototype.a=new s({ZD:0},!1,"scala.runtime.BooleanRef",{ZD:1,c:1,e:1});function od(){this.v=0}od.prototype=new t;od.prototype.o=function(){return""+this.v};od.prototype.Oa=function(a){this.v=a;return this};
+od.prototype.a=new s({aE:0},!1,"scala.runtime.IntRef",{aE:1,c:1,e:1});function Hj(){this.v=null}Hj.prototype=new t;Hj.prototype.o=function(){return Bj(Ba(),this.v)};Hj.prototype.w=function(a){this.v=a;return this};Hj.prototype.a=new s({dE:0},!1,"scala.runtime.ObjectRef",{dE:1,c:1,e:1});function no(){}no.prototype=new t;function oo(){}oo.prototype=no.prototype;no.prototype.Ii=ba();function Lc(){this.W=this.wo=this.Ei=null}Lc.prototype=new t;
+Lc.prototype.ug=function(a){this.Ei.R(M(function(a,d){return function(e){a.wo.l(e).je(d)}}(this,a)))};Lc.prototype.je=function(a){this.ug(a)};function Kc(a,b,d,e){a.Ei=d;a.wo=e;if(null===b)throw G(H(),null);a.W=b;return a}Lc.prototype.a=new s({Aq:0},!1,"scalatags.JsDom$Cap$SeqFrag",{Aq:1,c:1,Lj:1,tf:1});function po(){}po.prototype=new t;po.prototype.o=h("TypedTag");po.prototype.a=new s({Hq:0},!1,"scalatags.JsDom$TypedTag$",{Hq:1,c:1,g:1,e:1});var qo=void 0;
+function ro(){qo||(qo=(new po).b());return qo}function so(){this.W=this.Pi=null}so.prototype=new t;so.prototype.ug=function(a){a.appendChild(this.Pi)};so.prototype.je=function(a){this.ug(a)};function Mc(a,b){var d=new so;d.Pi=b;if(null===a)throw G(H(),null);d.W=a;return d}so.prototype.a=new s({Lq:0},!1,"scalatags.LowPriorityImplicits$bindNode",{Lq:1,c:1,Lj:1,tf:1});function to(){vn.call(this)}to.prototype=new wn;
+to.prototype.a=new s({yr:0},!1,"scalatags.stylesheet.StyleSheet$cls$",{yr:1,jG:1,c:1,wr:1});function Ed(){this.jg=this.Tj=this.Vm=this.fo=this.bf=this.wj=this.Ln=this.Jn=this.Kn=this.pe=this.Qn=this.Rn=null;this.Q=0;this.Ki=this.jF=null}Ed.prototype=new t;function uo(a){if(0===(512&a.Q)&&0===(512&a.Q)){var b=ae(a),d=ae(a).Ha,d=cc("exact",d);a.Vm=xn(d,b.rd,b.ld);a.Q|=512}return a.Vm}Ed.prototype.b=function(){this.jg=(new un).La(x());return this};
+function sd(a){if(0===(128&a.Q)&&0===(128&a.Q)){var b=Wd(a),d=Wd(a).Ha,d=cc("closed",d);a.bf=xn(d,b.rd,b.ld);a.Q|=128}return a.bf}function $c(a){if(0===(4&a.Q)&&0===(4&a.Q)){var b=be(a),d=be(a).Ha,d=cc("menu",d);a.pe=xn(d,b.rd,b.ld);a.Q|=4}return a.pe}function wd(a){if(0===(16&a.Q)&&0===(16&a.Q)){var b=Xd(a),d=Xd(a).Ha,d=cc("menuItem",d);a.Jn=xn(d,b.rd,b.ld);a.Q|=16}return a.Jn}
+function ud(a){if(0===(64&a.Q)&&0===(64&a.Q)){var b=Fd(a),d=Fd(a).Ha,d=cc("selected",d);a.wj=xn(d,b.rd,b.ld);a.Q|=64}return a.wj}function Uc(a){if(0===(1&a.Q)&&0===(1&a.Q)){var b=$d(a),d=$d(a).Ha,d=cc("noteBox",d);a.Rn=xn(d,b.rd,b.ld);a.Q|=1}return a.Rn}function Xc(a){if(0===(2&a.Q)&&0===(2&a.Q)){var b=Sd(a),d=Sd(a).Ha,d=cc("note",d);a.Qn=xn(d,b.rd,b.ld);a.Q|=2}return a.Qn}
+function bd(a){if(0===(8&a.Q)&&0===(8&a.Q)){var b=Yd(a),d=Yd(a).Ha,d=cc("menuLink",d);a.Kn=xn(d,b.rd,b.ld);a.Q|=8}return a.Kn}function td(a){if(0===(256&a.Q)&&0===(256&a.Q)){var b=de(a),d=de(a).Ha,d=cc("pathed",d);a.fo=xn(d,b.rd,b.ld);a.Q|=256}return a.fo}function Gd(a){if(null===a.Ki&&null===a.Ki){var b=new to;vn.prototype.Kv.call(b,a,x());a.Ki=b}return a.Ki}
+function Yb(a){0===(1024&a.Q)&&(a.Tj=jk(bc(),(new C).A([Uc(a),Xc(a),$c(a),bd(a),wd(a),yd(a),ud(a),sd(a),td(a),uo(a)])),a.Q|=1024);return a.Tj}function yd(a){if(0===(32&a.Q)&&0===(32&a.Q)){var b=Od(a),d=Od(a).Ha,d=cc("menuList",d);a.Ln=xn(d,b.rd,b.ld);a.Q|=32}return a.Ln}Ed.prototype.a=new s({Fr:0},!1,"scalatex.scrollspy.Styles$$anon$1",{Fr:1,c:1,kG:1,iG:1});function Ee(){this.El=this.Fl=null}Ee.prototype=new t;function De(a,b,d){a.Fl=b;a.El=d;return a}Ee.prototype.Rk=c("El");Ee.prototype.Up=c("Fl");
+Ee.prototype.a=new s({is:0},!1,"upickle.ReadWriter$$anon$1",{is:1,c:1,ns:1,dm:1});var na=new s({cw:0},!1,"java.lang.Byte",{cw:1,Gg:1,c:1,Zc:1},void 0,function(a){return a<<24>>24===a&&1/a!==1/-0}),sa=new s({gw:0},!1,"java.lang.Double",{gw:1,Gg:1,c:1,Zc:1},void 0,function(a){return"number"===typeof a});function vo(){An.call(this)}vo.prototype=new Bn;function wo(){}wo.prototype=vo.prototype;vo.prototype.h=function(a){vo.prototype.Ee.call(this,a,null);return this};function xo(){An.call(this)}
+xo.prototype=new Bn;function yo(){}yo.prototype=xo.prototype;xo.prototype.h=function(a){xo.prototype.Ee.call(this,a,null);return this};
+var ra=new s({jw:0},!1,"java.lang.Float",{jw:1,Gg:1,c:1,Zc:1},void 0,function(a){return a!==a||qa(a)===a}),pa=new s({lw:0},!1,"java.lang.Integer",{lw:1,Gg:1,c:1,Zc:1},void 0,function(a){return Ha(a)}),xa=new s({pw:0},!1,"java.lang.Long",{pw:1,Gg:1,c:1,Zc:1},void 0,function(a){return wa(a)}),oa=new s({sw:0},!1,"java.lang.Short",{sw:1,Gg:1,c:1,Zc:1},void 0,function(a){return a<<16>>16===a&&1/a!==1/-0});function zo(){this.Bf=null;this.bf=!1}zo.prototype=new t;l=zo.prototype;
+l.b=function(){zo.prototype.Lv.call(this,(new Ao).b());return this};function Bo(a,b,d,e,f,g,k){var n=(b.length|0)+(d.length|0)|0;if(g<=n)b=""+d+b;else{var r=Co("-",f);e=Co("0",f)&&!e;var y="";for(g=g-n|0;0<g;)y=""+y+(e?"0":" "),g=-1+g|0;g=y;if(e&&r)throw(new Do).h(f);b=r?""+d+b+g:e?""+d+g+b:""+g+d+b}Ob();k=Nb(0,k)===k?b.toUpperCase():b;a.Bf.Vj(k)}l.o=function(){return(this.bf?Eo():this.Bf).o()};l.Lv=function(a){this.Bf=a;this.bf=!1;return this};
+function Fo(a,b,d,e,f,g){var k=65535&(b.charCodeAt(0)|0);43===k||45===k?Bo(a,b.substring(1),""+(new Re).nc(k)+d,!1,e,f,g):Bo(a,b,d,!1,e,f,g)}function Co(a,b){return 0<=(b.indexOf(a)|0)}function Go(a,b,d,e,f,g){var k=Ho(e).toExponential(b);101===(65535&(k.charCodeAt(-3+(k.length|0)|0)|0))?(b=k.substring(0,-1+(k.length|0)|0),k=65535&(k.charCodeAt(-1+(k.length|0)|0)|0),b=b+"0"+(new Re).nc(k)):b=k;k=Ho(e);k!==k?e=!0:(e=Ho(e),e=Infinity===e||-Infinity===e);Io(a,b,e,d,f,g)}
+function Eo(){throw(new Jo).b();}l.Ii=function(){if(!this.bf){var a=this.Bf;a&&a.a&&a.a.t.Kj&&a.Ii()}this.bf=!0};function Io(a,b,d,e,f,g){45!==(65535&(b.charCodeAt(0)|0))?Co("+",e)?Bo(a,b,"+",d,e,f,g):Co(" ",e)?Bo(a,b," ",d,e,f,g):Bo(a,b,"",d,e,f,g):Co("(",e)?Bo(a,b.substring(1)+")","(",d,e,f,g):Bo(a,b.substring(1),"-",d,e,f,g)}function Ho(a){if($f(a))return"number"===typeof a?a:cn(a);if(an(a))return null===a?0:a.j;throw(new K).w(a);}l.a=new s({Aw:0},!1,"java.util.Formatter",{Aw:1,c:1,Kj:1,Jl:1});
+function Ko(){this.$p=this.pg=this.Ah=this.Dh=this.Gh=this.Ch=this.Bh=this.Eh=null;this.pF=Sf();this.qF=Sf();this.rF=Sf();this.sF=Sf();this.tF=Sf();this.uF=Sf();this.vF=Sf();this.qG=Sf()}Ko.prototype=new t;Ko.prototype.b=function(){Lo=this;this.Eh=(new Mo).b();this.Bh=(new No).b();this.Ch=(new Oo).b();this.Gh=(new Po).b();this.Dh=(new Qo).b();this.Ah=(new Ro).b();this.pg=(new So).b();this.$p=qc(rc(),(new C).A([this.Eh,this.Bh,this.Ch,this.Gh,this.Dh,this.Ah,this.pg]),sc(tc(),q(En)));return this};
+function To(a,b,d,e){lm(b,e)?b=(new T).k(4194303,4194303,524287):(a=Tf(e),b=lm(a,b)?(new T).k(1,0,524288):Uf(b,d));return b}Ko.prototype.a=new s({Hw:0},!1,"java.util.concurrent.TimeUnit$",{Hw:1,c:1,g:1,e:1});var Lo=void 0;function $(){Lo||(Lo=(new Ko).b());return Lo}function Mo(){Cn.call(this)}Mo.prototype=new Dn;l=Mo.prototype;l.b=function(){Cn.prototype.ff.call(this,0,"NANOSECONDS");return this};l.Vg=function(a){return Zl(a,(new T).k(481280,14305,0))};
+l.Sg=function(a){return Zl(a,(new T).k(3710976,858306,0))};l.Wg=function(a){return Zl(a,(new T).k(1755648,238,0))};l.Tg=function(a){return Zl(a,(new T).k(1E3,0,0))};l.Rg=function(a){return Zl(a,(new T).k(983040,3822149,4))};l.Ug=function(a){return Zl(a,(new T).k(1E6,0,0))};l.wg=function(a,b){return b.xe(a)};l.xe=aa();l.a=new s({Iw:0},!1,"java.util.concurrent.TimeUnit$$anon$1",{Iw:1,Uf:1,c:1,e:1});function No(){Cn.call(this)}No.prototype=new Dn;l=No.prototype;
+l.b=function(){Cn.prototype.ff.call(this,1,"MICROSECONDS");return this};l.Vg=function(a){return Zl(a,(new T).k(1279744,14,0))};l.Sg=function(a){return Zl(a,(new T).k(1287168,858,0))};l.Wg=function(a){return Zl(a,(new T).k(1E6,0,0))};l.Tg=aa();l.Rg=function(a){return Zl(a,(new T).k(1531904,20599,0))};l.Ug=function(a){return Zl(a,(new T).k(1E3,0,0))};l.wg=function(a,b){return b.Tg(a)};l.xe=function(a){return To($(),a,(new T).k(1E3,0,0),(new T).k(2315255,1207959,524))};
+l.a=new s({Jw:0},!1,"java.util.concurrent.TimeUnit$$anon$2",{Jw:1,Uf:1,c:1,e:1});function Oo(){Cn.call(this)}Oo.prototype=new Dn;l=Oo.prototype;l.b=function(){Cn.prototype.ff.call(this,2,"MILLISECONDS");return this};l.Vg=function(a){return Zl(a,(new T).k(6E4,0,0))};l.Sg=function(a){return Zl(a,(new T).k(36E5,0,0))};l.Wg=function(a){return Zl(a,(new T).k(1E3,0,0))};l.Tg=function(a){return To($(),a,(new T).k(1E3,0,0),(new T).k(2315255,1207959,524))};
+l.Rg=function(a){return Zl(a,(new T).k(2513920,20,0))};l.Ug=aa();l.wg=function(a,b){return b.Ug(a)};l.xe=function(a){return To($(),a,(new T).k(1E6,0,0),(new T).k(1071862,2199023,0))};l.a=new s({Kw:0},!1,"java.util.concurrent.TimeUnit$$anon$3",{Kw:1,Uf:1,c:1,e:1});function Po(){Cn.call(this)}Po.prototype=new Dn;l=Po.prototype;l.b=function(){Cn.prototype.ff.call(this,3,"SECONDS");return this};l.Vg=function(a){return Zl(a,(new T).k(60,0,0))};l.Sg=function(a){return Zl(a,(new T).k(3600,0,0))};l.Wg=aa();
+l.Tg=function(a){return To($(),a,(new T).k(1E6,0,0),(new T).k(1071862,2199023,0))};l.Rg=function(a){return Zl(a,(new T).k(86400,0,0))};l.Ug=function(a){return To($(),a,(new T).k(1E3,0,0),(new T).k(2315255,1207959,524))};l.wg=function(a,b){return b.Wg(a)};l.xe=function(a){return To($(),a,(new T).k(1755648,238,0),(new T).k(97540,2199,0))};l.a=new s({Lw:0},!1,"java.util.concurrent.TimeUnit$$anon$4",{Lw:1,Uf:1,c:1,e:1});function Qo(){Cn.call(this)}Qo.prototype=new Dn;l=Qo.prototype;
+l.b=function(){Cn.prototype.ff.call(this,4,"MINUTES");return this};l.Vg=aa();l.Sg=function(a){return Zl(a,(new T).k(60,0,0))};l.Wg=function(a){return To($(),a,(new T).k(60,0,0),(new T).k(2236962,559240,8738))};l.Tg=function(a){return To($(),a,(new T).k(1279744,14,0),(new T).k(1625680,36650,0))};l.Rg=function(a){return Zl(a,(new T).k(1440,0,0))};l.Ug=function(a){return To($(),a,(new T).k(6E4,0,0),(new T).k(2485264,3095955,8))};l.wg=function(a,b){return b.Vg(a)};
+l.xe=function(a){return To($(),a,(new T).k(481280,14305,0),(new T).k(2727923,36,0))};l.a=new s({Mw:0},!1,"java.util.concurrent.TimeUnit$$anon$5",{Mw:1,Uf:1,c:1,e:1});function Ro(){Cn.call(this)}Ro.prototype=new Dn;l=Ro.prototype;l.b=function(){Cn.prototype.ff.call(this,5,"HOURS");return this};l.Vg=function(a){return To($(),a,(new T).k(60,0,0),(new T).k(2236962,559240,8738))};l.Sg=aa();l.Wg=function(a){return To($(),a,(new T).k(3600,0,0),(new T).k(876143,2665713,145))};
+l.Tg=function(a){return To($(),a,(new T).k(1287168,858,0),(new T).k(3522348,610,0))};l.Rg=function(a){return Zl(a,(new T).k(24,0,0))};l.Ug=function(a){return To($(),a,(new T).k(36E5,0,0),(new T).k(3326959,610839,0))};l.wg=function(a,b){return b.Sg(a)};l.xe=function(a){return To($(),a,(new T).k(3710976,858306,0),(new T).k(2562047,0,0))};l.a=new s({Nw:0},!1,"java.util.concurrent.TimeUnit$$anon$6",{Nw:1,Uf:1,c:1,e:1});function So(){Cn.call(this)}So.prototype=new Dn;l=So.prototype;
+l.b=function(){Cn.prototype.ff.call(this,6,"DAYS");return this};l.Vg=function(a){return To($(),a,(new T).k(1440,0,0),(new T).k(93206,372827,364))};l.Sg=function(a){return To($(),a,(new T).k(24,0,0),(new T).k(1398101,1398101,21845))};l.Wg=function(a){return To($(),a,(new T).k(86400,0,0),(new T).k(211268,285834,6))};l.Tg=function(a){return To($(),a,(new T).k(1531904,20599,0),(new T).k(1894391,25,0))};l.Rg=aa();l.Ug=function(a){return To($(),a,(new T).k(2513920,20,0),(new T).k(2760063,25451,0))};
+l.wg=function(a,b){return b.Rg(a)};l.xe=function(a){return To($(),a,(new T).k(983040,3822149,4),(new T).k(106751,0,0))};l.a=new s({Ow:0},!1,"java.util.concurrent.TimeUnit$$anon$7",{Ow:1,Uf:1,c:1,e:1});function Km(){this.mf=null;this.rk=0;this.En=this.vl=null;this.sk=0;this.Dn=null}Km.prototype=new t;Km.prototype.o=c("mf");
+Km.prototype.gi=function(a,b){this.mf=a;this.rk=b;if(0!==(16&b))var d=(new V).ha(Uo(Jm(),a),b);else{var e=Jm().xn.exec(a);if(null!==e){e=e[1];if(void 0===e)throw(new uj).h("undefined.get");e=(new tg).w((new V).ha(Uo(0,e),b))}else e=sg();if(e.m()){var f=Jm(),e=this.mf,g=this.rk,f=f.wn.exec(e);if(null!==f){var k=f[0];if(void 0===k)throw(new uj).h("undefined.get");e=e.substring(k.length|0);k=f[1];if(void 0===k)var n=g;else{var k=(new mb).h(k),r=0,n=k.f.length|0,y=g;a:{var S;for(;;)if(r===n){S=y;break a}else g=
+1+r|0,r=k.ma(r),y=y|0|Vo(null===r?0:r.j),r=g}n=S|0}S=f[2];if(void 0===S)d=n;else{S=(new mb).h(S);k=0;f=S.f.length|0;g=n;a:for(;;)if(k===f){d=g;break a}else n=1+k|0,k=S.ma(k),g=(g|0)&~Vo(null===k?0:k.j),k=n;d|=0}d=(new tg).w((new V).ha(e,d))}else d=sg()}else d=e;d=d.m()?(new V).ha(this.mf,this.rk):d.Wc()}if(null!==d)d=(new V).ha(d.Ua,d.$a|0);else throw(new K).w(d);this.vl=d;this.En=this.vl.Ua;this.sk=this.vl.$a|0;d="g";0!==(2&this.sk)&&(d+="i");0!==(8&this.sk)&&(d+="m");this.Dn=d;return this};
+Km.prototype.a=new s({Qw:0},!1,"java.util.regex.Pattern",{Qw:1,c:1,g:1,e:1});function Wo(){this.UG=this.wF=this.TG=this.zF=this.EF=this.EG=this.yF=this.xF=this.VG=0;this.wn=this.xn=null}Wo.prototype=new t;Wo.prototype.b=function(){Xo=this;this.xn=new m.RegExp("^\\\\Q(.|\\n|\\r)\\\\E$");this.wn=new m.RegExp("^\\(\\?([idmsuxU]*)(?:-([idmsuxU]*))?\\)");return this};
+function Uo(a,b){for(var d="",e=0;e<(b.length|0);){var f=65535&(b.charCodeAt(e)|0);switch(f){case 92:case 46:case 40:case 41:case 91:case 93:case 123:case 125:case 124:case 63:case 42:case 43:case 94:case 36:f="\\"+(new Re).nc(f);break;default:f=(new Re).nc(f)}d=""+d+f;e=1+e|0}return d}function Vo(a){switch(a){case 105:return 2;case 100:return 1;case 109:return 8;case 115:return 32;case 117:return 64;case 120:return 4;case 85:return 256;default:ii(li(),"bad in-pattern flag")}}
+Wo.prototype.a=new s({Rw:0},!1,"java.util.regex.Pattern$",{Rw:1,c:1,g:1,e:1});var Xo=void 0;function Jm(){Xo||(Xo=(new Wo).b());return Xo}function Yo(){this.Hv=this.Ru=this.Yn=null}Yo.prototype=new vg;Yo.prototype.b=function(){Zo=this;this.Yn=(new mi).w(dg().Wn);this.Ru=(new mi).w(dg().Nm);this.Hv=(new mi).w(null);return this};Yo.prototype.a=new s({Hz:0},!1,"scala.Console$",{Hz:1,QH:1,c:1,aI:1});var Zo=void 0;function rg(){}rg.prototype=new t;
+rg.prototype.a=new s({Nz:0},!1,"scala.Option$",{Nz:1,c:1,g:1,e:1});var qg=void 0;function Lg(){this.$w=null}Lg.prototype=new t;l=Lg.prototype;l.b=function(){this.$w=M(function(){return function(){return sg()}}(this));return this};l.l=function(a){throw(new K).w(a);};l.o=h("\x3cfunction1\x3e");l.lf=aa();l.Va=h(!1);l.Bb=function(a,b){return Ng(this,a,b)};l.a=new s({Pz:0},!1,"scala.PartialFunction$$anon$1",{Pz:1,c:1,la:1,x:1});function uf(){this.bi=this.ai=null}uf.prototype=new t;l=uf.prototype;
+l.l=function(a){return this.ai.Bb(a,this.bi)};l.o=h("\x3cfunction1\x3e");l.lf=function(a){return tf(new uf,this.ai,this.bi.lf(a))};l.Va=function(a){return this.ai.Va(a)||this.bi.Va(a)};l.Bb=function(a,b){var d=this.ai.Bb(a,Mg().rj);return Mg().rj===d?this.bi.Bb(a,b):d};function tf(a,b,d){a.ai=b;a.bi=d;return a}l.a=new s({Rz:0},!1,"scala.PartialFunction$OrElse",{Rz:1,c:1,la:1,x:1});function $o(){this.rB=this.ui=this.Ks=this.ws=this.ss=this.dq=this.Gs=this.ts=null}$o.prototype=new Hg;
+function ap(a,b){if(!b)throw(new Xl).w("assertion failed");}$o.prototype.b=function(){bp=this;Hh();J();cp||(cp=(new dp).b());this.ts=cp;this.Gs=ep();this.dq=gi().Gl;this.ss=gi().Gc;fp||(fp=(new gp).b());this.ws=fp;this.Ks=(new Kn).b();this.ui=(new hp).b();this.rB=(new ip).b();return this};
+function pn(a,b){if(jb(b,1))return(new jp).me(b);if(Za(b,1))return(new kp).Rf(b);if(ab(b,1))return(new lp).Kf(b);if($a(b,1))return(new mp).Lf(b);if(fb(b,1))return(new np).Mf(b);if(eb(b,1))return(new op).Nf(b);if(cb(b,1))return(new pp).Of(b);if(db(b,1))return(new qp).Pf(b);if(bb(b,1))return(new rp).Qf(b);if(vm(b))return(new sp).Sf(b);if(null===b)return null;throw(new K).w(b);}$o.prototype.a=new s({Sz:0},!1,"scala.Predef$",{Sz:1,UH:1,c:1,RH:1});var bp=void 0;
+function Ac(){bp||(bp=(new $o).b());return bp}function tp(){}tp.prototype=new t;tp.prototype.a=new s({Xz:0},!1,"scala.StringContext$",{Xz:1,c:1,g:1,e:1});var up=void 0;function Fg(){this.Ha=null}Fg.prototype=new t;l=Fg.prototype;l.K=function(a){return this===a};l.o=function(){return"'"+this.Ha};l.h=function(a){this.Ha=a;return this};l.M=function(){var a=this.Ha;return Aa(Ba(),a)};l.a=new s({Zz:0},!1,"scala.Symbol",{Zz:1,c:1,g:1,e:1});
+function vp(){this.EH=0;this.OE=this.Hp=this.rl=null;this.gJ=Sf();this.GH=Sf();this.PH=Sf();this.FH=Sf();this.sH=Sf();this.kH=Sf();this.Qj=this.Jj=this.Sj=this.kd=null}vp.prototype=new t;
+vp.prototype.b=function(){wp=this;J();var a=$().pg,a=(new V).ha(a,"d day"),b=$().Ah,b=(new V).ha(b,"h hour"),d=$().Dh,d=(new V).ha(d,"min minute"),e=$().Gh,e=(new V).ha(e,"s sec second"),f=$().Ch,f=(new V).ha(f,"ms milli millisecond"),g=$().Bh,g=(new V).ha(g,"\u00b5s micro microsecond"),k=$().Eh,a=(new C).A([a,b,d,e,f,g,(new V).ha(k,"ns nano nanosecond")]),b=J().N,a=this.rl=Kj(a,b),b=Ac().ui;this.Hp=Vj(a,b).cj(M(function(){return function(a){a=xp(a);return tj(a)}}(this)));b=this.rl;a=function(a){return function(b){if(null!==
+b){var d=b.Ua;b=yp(a,b.$a);var d=function(a,b){return function(a){return(new V).ha(a,b)}}(a,d),e=J().N;if(e===J().N){if(b===x())return x();var e=b.u(),f=e=Tb(new Ub,d(e),x());for(b=b.s();b!==x();){var g=b.u(),g=Tb(new Ub,d(g),x()),f=f.Cd=g;b=b.s()}return e}for(e=Vb(b,e);!b.m();)f=b.u(),e.Da(d(f)),b=b.s();return e.pa()}throw(new K).w(b);}}(this);if(J().N===J().N)if(b===x())a=x();else{d=b;e=Oj(!1);f=(new Hj).w(null);for(g=(new Hj).w(null);d!==x();)k=d.u(),a(k).R(M(function(a,b,d,e){return function(a){b.v?
+(a=Tb(new Ub,a,x()),e.v.Cd=a,e.v=a):(d.v=Tb(new Ub,a,x()),e.v=d.v,b.v=!0)}}(b,e,f,g))),d=d.s();a=e.v?f.v:x()}else{J();for(d=(new zp).b();!b.m();)e=b.u(),e=a(e).Ba(),Ap(d,e),b=b.s();a=d.Fb()}this.OE=a.lc(Ac().ui);this.kd=Bp(new Cp,Sf(),$().pg);this.Sj=(new Dp).b();this.Jj=(new Ep).b();this.Qj=(new Fp).b();return this};
+function Gp(a){if(bn(Hp(a,(new T).k(983040,3822149,4)),Sf())){nf();a=Zl(a,(new T).k(983040,3822149,4));var b=$().pg;return Bp(new Cp,a,b)}if(bn(Hp(a,(new T).k(3710976,858306,0)),Sf()))return nf(),a=Zl(a,(new T).k(3710976,858306,0)),b=$().Ah,Bp(new Cp,a,b);if(bn(Hp(a,(new T).k(481280,14305,0)),Sf()))return nf(),a=Zl(a,(new T).k(481280,14305,0)),b=$().Dh,Bp(new Cp,a,b);if(bn(Hp(a,(new T).k(1755648,238,0)),Sf()))return nf(),a=Zl(a,(new T).k(1755648,238,0)),b=$().Gh,Bp(new Cp,a,b);if(bn(Hp(a,(new T).k(1E6,
+0,0)),Sf()))return nf(),a=Zl(a,(new T).k(1E6,0,0)),b=$().Ch,Bp(new Cp,a,b);if(bn(Hp(a,(new T).k(1E3,0,0)),Sf()))return nf(),a=Zl(a,(new T).k(1E3,0,0)),b=$().Bh,Bp(new Cp,a,b);nf();b=$().Eh;return Bp(new Cp,a,b)}function xp(a){a=a.trim();a=Rb(Ba(),a,"\\s+",0);var b=J().N.$e();b.Ta(a.d.length);b.Ka((new Sb).me(a));return b.pa()}
+function yp(a,b){var d=xp(b);if(d&&d.a&&d.a.t.el)var e=d.Jf,d=d.Cd;else throw(new K).w(d);var f=d,d=function(){return function(a){J();a=(new C).A([a,a+"s"]);var b=J().N;return Kj(a,b)}}(a);if(J().N===J().N)if(f===x())d=x();else{for(var g=f,k=Oj(!1),n=(new Hj).w(null),r=(new Hj).w(null);g!==x();){var y=g.u();d(y).R(M(function(a,b,d,e){return function(a){b.v?(a=Tb(new Ub,a,x()),e.v.Cd=a,e.v=a):(d.v=Tb(new Ub,a,x()),e.v=d.v,b.v=!0)}}(f,k,n,r)));g=g.s()}d=k.v?n.v:x()}else{J();for(g=(new zp).b();!f.m();)k=
+f.u(),k=d(k).Ba(),Ap(g,k),f=f.s();d=g.Fb()}return Tb(new Ub,e,d)}vp.prototype.a=new s({aA:0},!1,"scala.concurrent.duration.Duration$",{aA:1,c:1,g:1,e:1});var wp=void 0;function nf(){wp||(wp=(new vp).b());return wp}function uh(){}uh.prototype=new t;uh.prototype.a=new s({gA:0},!1,"scala.math.Fractional$",{gA:1,c:1,g:1,e:1});var th=void 0;function wh(){}wh.prototype=new t;wh.prototype.a=new s({hA:0},!1,"scala.math.Integral$",{hA:1,c:1,g:1,e:1});var vh=void 0;function yh(){}yh.prototype=new t;
+yh.prototype.a=new s({iA:0},!1,"scala.math.Numeric$",{iA:1,c:1,g:1,e:1});var xh=void 0;function Ip(){this.wf=this.vf=this.ng=this.og=this.We=this.mg=this.Ye=this.Pe=this.Se=this.Te=this.Ve=this.Ue=this.Re=this.Xe=this.Qe=this.fm=this.em=this.gm=null}Ip.prototype=new t;
+Ip.prototype.b=function(){Vp=this;this.gm=q(u);this.em=q(Yh);this.fm=q(Zh);this.Qe=gi().Gc.Qe;this.Xe=gi().Gc.Xe;this.Re=gi().Gc.Re;this.Ue=gi().Gc.Ue;this.Ve=gi().Gc.Ve;this.Te=gi().Gc.Te;this.Se=gi().Gc.Se;this.Pe=gi().Gc.Pe;this.Ye=gi().Gc.Ye;this.mg=gi().Gc.mg;this.We=gi().Gc.We;this.og=gi().Gc.og;this.ng=gi().Gc.ng;this.vf=gi().Gc.vf;this.wf=gi().Gc.wf;return this};
+function sc(a,b){var d;b===q(Sa)?d=tc().Qe:b===q(Ta)?d=tc().Xe:b===q(Qa)?d=tc().Re:b===q(Ua)?d=tc().Ue:b===q(Va)?d=tc().Ve:b===q(Xa)?d=tc().Te:b===q(Ya)?d=tc().Se:b===q(Pa)?d=tc().Pe:b===q(Na)?d=tc().Ye:a.gm===b?d=tc().We:a.em===b?d=tc().vf:a.fm===b?d=tc().wf:(d=new Wp,d.nj=b);return d}Ip.prototype.a=new s({wA:0},!1,"scala.reflect.ClassTag$",{wA:1,c:1,g:1,e:1});var Vp=void 0;function tc(){Vp||(Vp=(new Ip).b());return Vp}function ni(){eg.call(this);this.xl=null}ni.prototype=new zn;
+ni.prototype.a=new s({RA:0},!1,"scala.util.DynamicVariable$$anon$1",{RA:1,vH:1,wH:1,c:1});function Eh(){}Eh.prototype=new t;Eh.prototype.o=h("Left");Eh.prototype.a=new s({TA:0},!1,"scala.util.Left$",{TA:1,c:1,g:1,e:1});var Dh=void 0;function Gh(){}Gh.prototype=new t;Gh.prototype.o=h("Right");Gh.prototype.a=new s({UA:0},!1,"scala.util.Right$",{UA:1,c:1,g:1,e:1});var Fh=void 0;function Xp(){this.Cl=!1}Xp.prototype=new t;Xp.prototype.b=function(){Yp=this;this.Cl=!1;return this};
+Xp.prototype.a=new s({XA:0},!1,"scala.util.control.NoStackTrace$",{XA:1,c:1,g:1,e:1});var Yp=void 0;function Zp(){this.tB=this.oi=null}Zp.prototype=new t;function nb(a,b){var d=new Zp;Zp.prototype.Mv.call(d,(Jm(),(new Km).gi(a,0)),b);return d}Zp.prototype.Mv=function(a,b){this.oi=a;this.tB=b;return this};Zp.prototype.o=function(){return this.oi.mf};
+function Bb(a,b){if(null===b)return sg();var d=Lm(new Mm,a.oi,b,"string"===typeof b?b.length|0:b.q());if(Gn(d)){var e=-1+(Om(d).length|0)|0,e=(new $p).k(1,e,1),f=J().N,e=Kj(e,f),d=function(a,b){return function(a){a|=0;a=Om(b)[a];return void 0===a?null:a}}(a,d),f=J().N;if(f===J().N)if(e===x())d=x();else{for(var f=e.u(),g=f=Tb(new Ub,d(f),x()),e=e.s();e!==x();)var k=e.u(),k=Tb(new Ub,d(k),x()),g=g.Cd=k,e=e.s();d=f}else{for(f=Vb(e,f);!e.m();)g=e.u(),f.Da(d(g)),e=e.s();d=f.pa()}return(new tg).w(d)}return sg()}
+Zp.prototype.a=new s({$A:0},!1,"scala.util.matching.Regex",{$A:1,c:1,g:1,e:1});function aq(){this.W=null}aq.prototype=new Xn;aq.prototype.b=function(){Wn.prototype.ii.call(this,vc());return this};aq.prototype.$e=function(){vc();In();uc();return(new Jn).b()};aq.prototype.a=new s({eB:0},!1,"scala.collection.IndexedSeq$$anon$1",{eB:1,cl:1,c:1,qi:1});function bq(){this.N=null}bq.prototype=new Un;function cq(){}cq.prototype=bq.prototype;function Vn(){this.ja=this.W=null}Vn.prototype=new Xn;
+Vn.prototype.$e=function(){return this.ja.na()};Vn.prototype.ii=function(a){if(null===a)throw G(H(),null);this.ja=a;Wn.prototype.ii.call(this,a);return this};Vn.prototype.a=new s({wB:0},!1,"scala.collection.generic.GenTraversableFactory$$anon$1",{wB:1,cl:1,c:1,qi:1});function dq(){}dq.prototype=new ao;function eq(){}eq.prototype=dq.prototype;function gh(){}gh.prototype=new t;gh.prototype.o=h("::");gh.prototype.a=new s({CB:0},!1,"scala.collection.immutable.$colon$colon$",{CB:1,c:1,g:1,e:1});
+var fh=void 0;function fq(){this.Mj=0}fq.prototype=new t;fq.prototype.b=function(){gq=this;this.Mj=512;return this};
+function hq(a,b,d,e){var f=(new mb).h("%d %s %d by %s"),g=[a,e?"to":"until",b,d];Ba();var k=f.f,n=bc();n.N;iq();var r=[];g.length|0;for(var y=0,S=g.length|0;y<S;){var Oa=dn(g[y])?g[y].cJ():g[y];r.push(Oa);y=1+y|0}for(var pb=tc().ng.xc(r.length|0),Rd=Ri(U(),pb),Zc=0,Ic=0,Ii=r.length|0,Ji=Ii<Rd?Ii:Rd,Ki=Ri(U(),pb),Li=Ji<Ki?Ji:Ki;Zc<Li;)Si(U(),pb,Ic,r[Zc]),Zc=1+Zc|0,Ic=1+Ic|0;var Wa=(new zo).b(),Ck;if(Wa.bf)Eo(),Ck=void 0;else{for(var Qc=k,bv=0,cv=0;;){var dv=Qc;if(null===dv){var ev;throw(new va).b();
+}ev=dv;if(""!==ev){var ah=Qc;var fv=pg(og().vn,ah);if(fv.m())if(pg(og().sn,ah).m())if(pg(og().tn,ah).m()){var gv=pg(og().un,ah);if(gv.m())throw(new K).w(ah);var me=gv.Wc(),zy=Qc,hv=me[0];if(void 0===hv){var iv;throw(new uj).h("undefined.get");}iv=hv;var Qc=zy.substring(iv.length|0),jv=me[2];if(void 0===jv){var Ra;throw(new uj).h("undefined.get");}Ra=jv;var kv=me[1],Jp=void 0===kv?"":kv;if(null===Jp){var lv;throw(new va).b();}lv=Jp;var Df=""!==lv?Ue(Ve(),Jp,10):Co("\x3c",Ra)?cv:bv=1+bv|0;cv=Df;if(0>=
+Df||Df>pb.d.length){var mv=me[5];if(void 0===mv){var nv;throw(new uj).h("undefined.get");}nv=mv;throw(new jq).h(nv);}var ca=pb.d[-1+Df|0],ov=me[3],Kp=void 0===ov?"":ov;if(null===Kp){var pv;throw(new va).b();}pv=Kp;var qv=""!==pv,Zb=qv?Ue(Ve(),Kp,10):0,rv=me[4],Lp=void 0===rv?"":rv;if(null===Lp){var sv;throw(new va).b();}sv=Lp;var bh=""!==sv,ch=bh?Ue(Ve(),Lp,10):0,tv=me[5];if(void 0===tv){var uv;throw(new uj).h("undefined.get");}uv=tv;var Kb=65535&(uv.charCodeAt(0)|0);switch(Kb){case 98:case 66:if(null===
+ca)var Mp="false";else if("boolean"===typeof ca)var Ay=ca,Mp=Bj(Ba(),Ay);else Mp="true";Bo(Wa,Mp,"",!1,Ra,Zb,Kb);break;case 104:case 72:var By=null===ca?"null":(+(za(ca)>>>0)).toString(16);Bo(Wa,By,"",!1,Ra,Zb,Kb);break;case 115:case 83:if(null!==ca||Co("#",Ra))if(ca&&ca.a&&ca.a.t.xH){var Cy=ca,Dy=(Co("-",Ra)?1:0)|(Co("#",Ra)?4:0),vv;Ob();var wv=Kb;vv=Nb(0,wv)===wv;Cy.rH(Wa,Dy|(vv?2:0),qv?Zb:-1,bh?ch:-1);sg()}else{if(null===ca||Co("#",Ra))throw kq();Bo(Wa,ka(ca),"",!1,Ra,Zb,Kb)}else Bo(Wa,"null",
+"",!1,Ra,Zb,Kb);break;case 99:case 67:var Np;if(Ha(ca))Np=ca|0;else if(an(ca))Np=null===ca?0:ca.j;else throw(new K).w(ca);Bo(Wa,m.String.fromCharCode(65535&Np),"",!1,Ra,Zb,Kb);break;case 100:var Fy=Ho(ca);Io(Wa,""+Fy,!1,Ra,Zb,Kb);break;case 111:if(Ha(ca))var Dk=(+((ca|0)>>>0)).toString(8);else if(wa(ca)){var dh=Ia(ca),Op=2097151&dh.oa,Pp=(1048575&dh.Y)<<1|dh.oa>>21,xv=dh.z<<2|dh.Y>>20;if(0!==xv)var Gy=(+(xv>>>0)).toString(8),yv=(+(Pp>>>0)).toString(8),Hy="0000000".substring(yv.length|0),zv=(+(Op>>>
+0)).toString(8),Dk=Gy+(""+Hy+yv)+(""+"0000000".substring(zv.length|0)+zv);else if(0!==Pp)var Iy=(+(Pp>>>0)).toString(8),Av=(+(Op>>>0)).toString(8),Dk=Iy+(""+"0000000".substring(Av.length|0)+Av);else Dk=(+(Op>>>0)).toString(8)}else throw(new K).w(ca);Fo(Wa,Dk,Co("#",Ra)?"0":"",Ra,Zb,Kb);break;case 120:case 88:if(Ha(ca))var Ek=(+((ca|0)>>>0)).toString(16);else if(wa(ca)){var eh=Ia(ca),Qp=eh.Y>>2,Rp=eh.oa|(3&eh.Y)<<22;if(0!==eh.z)var Jy=(+(eh.z>>>0)).toString(16),Bv=(+(Qp>>>0)).toString(16),Ky="000000".substring(1+
+(Bv.length|0)|0),Cv=(+(Rp>>>0)).toString(16),Ek=Jy+(""+Ky+Bv)+(""+"000000".substring(Cv.length|0)+Cv);else if(0!==Qp)var Ly=(+(Qp>>>0)).toString(16),Dv=(+(Rp>>>0)).toString(16),Ek=Ly+(""+"000000".substring(Dv.length|0)+Dv);else Ek=(+(Rp>>>0)).toString(16)}else throw(new K).w(ca);Fo(Wa,Ek,Co("#",Ra)?"0x":"",Ra,Zb,Kb);break;case 101:case 69:Go(Wa,bh?ch:6,Ra,ca,Zb,Kb);break;case 103:case 71:var Sp=Ho(ca),Tp=0>Sp?-Sp:Sp,Up=bh?0===ch?1:ch:6;if(1E-4<=Tp&&Tp<+m.Math.pow(10,Up)){var My=+m.Math.log(Tp)/2.302585092994046,
+Ny=+m.Math.ceil(My)|0,Oy=Ho(ca),Ev=Up-Ny|0,Py=Oy.toFixed(0<Ev?Ev:0);Io(Wa,Py,!1,Ra,Zb,Kb)}else Go(Wa,-1+Up|0,Ra,ca,Zb,Kb);break;case 102:var Qy=Ho(ca).toFixed(bh?ch:6),Fv=Ho(ca);if(Fv!==Fv)var Gv=!0;else var Hv=Ho(ca),Gv=Infinity===Hv||-Infinity===Hv;Io(Wa,Qy,Gv,Ra,Zb,Kb);break;default:throw(new K).w((new Re).nc(Kb));}}else Qc=Qc.substring(2),Wa.Bf.Uj(10);else Qc=Qc.substring(2),Wa.Bf.Uj(37);else{var Iv=fv.Wc(),Ry=Qc,Jv=Iv[0];if(void 0===Jv){var Kv;throw(new uj).h("undefined.get");}Kv=Jv;var Qc=Ry.substring(Kv.length|
+0),Sy=Wa.Bf,Lv=Iv[0];if(void 0===Lv){var Mv;throw(new uj).h("undefined.get");}Mv=Lv;Sy.Vj(Mv)}}else break}Ck=Wa}var Ty=(Ck.bf?Eo():Ck.Bf).o();Wa.Ii();return Ty}function lq(a,b,d,e,f){throw(new Cb).h(hq(b,d,e,f)+": seqs cannot contain more than Int.MaxValue elements.");}fq.prototype.a=new s({kC:0},!1,"scala.collection.immutable.Range$",{kC:1,c:1,g:1,e:1});var gq=void 0;function qh(){gq||(gq=(new fq).b());return gq}function mq(){this.L=this.E=this.j=this.ka=null;this.fk=0}mq.prototype=new t;
+function nq(){}nq.prototype=mq.prototype;function Y(a,b,d,e,f){a.ka=b;a.j=d;a.E=e;a.L=f;a.fk=(1+Bk(Zk(),e)|0)+Bk(Zk(),f)|0;return a}var oq=new s({jl:0},!1,"scala.collection.immutable.RedBlackTree$Tree",{jl:1,c:1,g:1,e:1});mq.prototype.a=oq;function pq(){}pq.prototype=new Zn;pq.prototype.Mm=function(a){return Ld(a)};pq.prototype.a=new s({xC:0},!1,"scala.collection.immutable.SortedMap$",{xC:1,yB:1,BB:1,c:1});var qq=void 0;function bl(){qq||(qq=(new pq).b());return qq}function rq(){this.W=null}
+rq.prototype=new Xn;rq.prototype.b=function(){Wn.prototype.ii.call(this,lh());return this};rq.prototype.a=new s({FC:0},!1,"scala.collection.immutable.Stream$StreamCanBuildFrom",{FC:1,cl:1,c:1,qi:1});function sq(){On.call(this);this.$n=null}sq.prototype=new Pn;sq.prototype.R=function(a){var b=this.W;a:b:for(;;){if(!b.m()){var d=b.u();this.$n.l(d)&&a.l(d);b=b.s();continue b}break a}};sq.prototype.a=new s({GC:0},!1,"scala.collection.immutable.Stream$StreamWithFilter",{GC:1,so:1,c:1,$:1});
+function ph(){}ph.prototype=new t;ph.prototype.a=new s({uD:0},!1,"scala.collection.mutable.StringBuilder$",{uD:1,c:1,g:1,e:1});var oh=void 0;function tq(){this.Hf=null}tq.prototype=new ho;function cd(a){return(0,a.Hf)()}function Nc(a){var b=new tq;b.Hf=a;return b}tq.prototype.a=new s({KD:0},!1,"scala.scalajs.runtime.AnonFunction0",{KD:1,QI:1,c:1,AF:1});function uq(){this.Hf=null}uq.prototype=new jo;uq.prototype.l=function(a){return(0,this.Hf)(a)};function M(a){var b=new uq;b.Hf=a;return b}
+uq.prototype.a=new s({LD:0},!1,"scala.scalajs.runtime.AnonFunction1",{LD:1,vi:1,c:1,x:1});function vq(){this.Hf=null}vq.prototype=new lo;function nc(a){var b=new vq;b.Hf=a;return b}function zg(a,b,d){return(0,a.Hf)(b,d)}vq.prototype.a=new s({MD:0},!1,"scala.scalajs.runtime.AnonFunction2",{MD:1,RI:1,c:1,BF:1});function T(){this.z=this.Y=this.oa=0}T.prototype=new Zf;function Dm(a,b){return(new T).k(a.oa|b.oa,a.Y|b.Y,a.z|b.z)}
+function wq(a,b){return 0===(524288&a.z)?0!==(524288&b.z)||a.z>b.z||a.z===b.z&&a.Y>b.Y||a.z===b.z&&a.Y===b.Y&&a.oa>=b.oa:!(0===(524288&b.z)||a.z<b.z||a.z===b.z&&a.Y<b.Y||a.z===b.z&&a.Y===b.Y&&a.oa<b.oa)}l=T.prototype;l.K=function(a){return wa(a)?bn(this,a):!1};
+function Uf(a,b){var d=8191&a.oa,e=a.oa>>13|(15&a.Y)<<9,f=8191&a.Y>>4,g=a.Y>>17|(255&a.z)<<5,k=(1048320&a.z)>>8;d|=0;e|=0;f|=0;g|=0;k|=0;var n=8191&b.oa,r=b.oa>>13|(15&b.Y)<<9,y=8191&b.Y>>4,S=b.Y>>17|(255&b.z)<<5,Oa=(1048320&b.z)>>8;var n=n|0,r=r|0,y=y|0,pb=S|0,Rd=Oa|0,Zc=w(d,n),Ic=w(e,n),Oa=w(f,n),S=w(g,n),k=w(k,n);0!==r&&(Ic=Ic+w(d,r)|0,Oa=Oa+w(e,r)|0,S=S+w(f,r)|0,k=k+w(g,r)|0);0!==y&&(Oa=Oa+w(d,y)|0,S=S+w(e,y)|0,k=k+w(f,y)|0);0!==pb&&(S=S+w(d,pb)|0,k=k+w(e,pb)|0);0!==Rd&&(k=k+w(d,Rd)|0);d=(4194303&
+Zc)+((511&Ic)<<13)|0;e=((((Zc>>22)+(Ic>>9)|0)+((262143&Oa)<<4)|0)+((31&S)<<17)|0)+(d>>22)|0;return(new T).k(4194303&d,4194303&e,1048575&((((Oa>>18)+(S>>5)|0)+((4095&k)<<8)|0)+(e>>22)|0))}l.k=function(a,b,d){this.oa=a;this.Y=b;this.z=d;return this};function Hp(a,b){return xq(a,b)[1]}
+l.o=function(){if(0===this.oa&&0===this.Y&&0===this.z)return"0";if(bn(this,Ja().rg))return"-9223372036854775808";if(0!==(524288&this.z))return"-"+Tf(this).o();var a=Ja().jm,b=this,d="";for(;;){var e=b;if(0===e.oa&&0===e.Y&&0===e.z)return d;e=xq(b,a);b=e[0];e=""+Yl(e[1]);d=(0===b.oa&&0===b.Y&&0===b.z?"":"000000000".substring(e.length|0))+e+d}};
+function xq(a,b){if(0===b.oa&&0===b.Y&&0===b.z)throw(new yq).h("/ by zero");if(0===a.oa&&0===a.Y&&0===a.z)return[Ja().kd,Ja().kd];if(bn(b,Ja().rg))return bn(a,Ja().rg)?[Ja().Rj,Ja().kd]:[Ja().kd,a];var d=0!==(524288&a.z),e=0!==(524288&b.z),f=bn(a,Ja().rg),g=0===b.z&&0===b.Y&&0!==b.oa&&0===(b.oa&(-1+b.oa|0))?Pf(Ve(),b.oa):0===b.z&&0!==b.Y&&0===b.oa&&0===(b.Y&(-1+b.Y|0))?22+Pf(Ve(),b.Y)|0:0!==b.z&&0===b.Y&&0===b.oa&&0===(b.z&(-1+b.z|0))?44+Pf(Ve(),b.z)|0:-1;if(0<=g){if(f)return d=zq(a,g),[e?Tf(d):d,
+Ja().kd];var f=0!==(524288&a.z)?Tf(a):a,k=zq(f,g),e=d!==e?Tf(k):k,f=22>=g?(new T).k(f.oa&(-1+(1<<g)|0),0,0):44>=g?(new T).k(f.oa,f.Y&(-1+(1<<(-22+g|0))|0),0):(new T).k(f.oa,f.Y,f.z&(-1+(1<<(-44+g|0))|0)),d=d?Tf(f):f;return[e,d]}g=0!==(524288&b.z)?Tf(b):b;if(f)var n=Ja().Pj;else{var r=0!==(524288&a.z)?Tf(a):a;if(lm(g,r))return[Ja().kd,a];n=r}var r=Aq(g)-Aq(n)|0,y=Em(g,r),g=r,r=y,y=n,n=Ja().kd;a:for(;;){if(0>g)var S=!0;else S=y,S=0===S.oa&&0===S.Y&&0===S.z;if(S){var Oa=n,k=y;break a}else S=Vf(y,Tf(r)),
+0===(524288&S.z)?(y=-1+g|0,r=zq(r,1),n=22>g?(new T).k(n.oa|1<<g,n.Y,n.z):44>g?(new T).k(n.oa,n.Y|1<<(-22+g|0),n.z):(new T).k(n.oa,n.Y,n.z|1<<(-44+g|0)),g=y,y=S):(g=-1+g|0,r=zq(r,1))}e=d!==e?Tf(Oa):Oa;d&&f?(d=Tf(k),f=Ja().Rj,d=Vf(d,Tf(f))):d=d?Tf(k):k;return[e,d]}function Fm(a,b){return(new T).k(a.oa&b.oa,a.Y&b.Y,a.z&b.z)}function Hm(a){return(new T).k(4194303&(a.Y>>10|a.z<<12),4194303&(a.z>>>10|0),0)}
+function lm(a,b){return 0===(524288&a.z)?0!==(524288&b.z)||a.z>b.z||a.z===b.z&&a.Y>b.Y||a.z===b.z&&a.Y===b.Y&&a.oa>b.oa:!(0===(524288&b.z)||a.z<b.z||a.z===b.z&&a.Y<b.Y||a.z===b.z&&a.Y===b.Y&&a.oa<=b.oa)}function Em(a,b){var d=63&b;if(22>d){var e=22-d|0;return(new T).k(4194303&a.oa<<d,4194303&(a.Y<<d|a.oa>>e),1048575&(a.z<<d|a.Y>>e))}return 44>d?(e=-22+d|0,(new T).k(0,4194303&a.oa<<e,1048575&(a.Y<<e|a.oa>>(44-d|0)))):(new T).k(0,0,1048575&a.oa<<(-44+d|0))}function Yl(a){return a.oa|a.Y<<22}
+l.Oa=function(a){T.prototype.k.call(this,4194303&a,4194303&a>>22,0>a?1048575:0);return this};function Tf(a){var b=4194303&(1+~a.oa|0),d=4194303&(~a.Y+(0===b?1:0)|0);return(new T).k(b,d,1048575&(~a.z+(0===b&&0===d?1:0)|0))}function Vf(a,b){var d=a.oa+b.oa|0,e=(a.Y+b.Y|0)+(d>>22)|0;return(new T).k(4194303&d,4194303&e,1048575&((a.z+b.z|0)+(e>>22)|0))}
+function zq(a,b){var d=63&b,e=0!==(524288&a.z),f=e?-1048576|a.z:a.z;if(22>d)return e=22-d|0,(new T).k(4194303&(a.oa>>d|a.Y<<e),4194303&(a.Y>>d|f<<e),1048575&f>>d);if(44>d){var g=-22+d|0;return(new T).k(4194303&(a.Y>>g|f<<(44-d|0)),4194303&f>>g,1048575&(e?1048575:0))}return(new T).k(4194303&f>>(-44+d|0),4194303&(e?4194303:0),1048575&(e?1048575:0))}function cn(a){return bn(a,Ja().rg)?-9223372036854775E3:0!==(524288&a.z)?-cn(Tf(a)):a.oa+4194304*a.Y+17592186044416*a.z}
+function Zl(a,b){return xq(a,b)[0]}function Aq(a){return 0!==a.z?-12+Of(Ve(),a.z)|0:0!==a.Y?10+Of(Ve(),a.Y)|0:32+Of(Ve(),a.oa)|0}l.M=function(){return Yl(Gm(this,Hm(this)))};function Gm(a,b){return(new T).k(a.oa^b.oa,a.Y^b.Y,a.z^b.z)}function bn(a,b){return a.oa===b.oa&&a.Y===b.Y&&a.z===b.z}function wa(a){return!!(a&&a.a&&a.a.t.Bp)}l.a=new s({Bp:0},!1,"scala.scalajs.runtime.RuntimeLong",{Bp:1,Gg:1,c:1,Zc:1});
+function Bq(){this.RG=this.QG=this.PG=this.OG=this.NG=this.MG=this.LG=this.JG=this.IG=this.pG=this.oG=this.mF=this.lF=this.kF=0;this.jm=this.Pj=this.rg=this.us=this.Rj=this.kd=null}Bq.prototype=new t;Bq.prototype.b=function(){Cq=this;this.kd=(new T).k(0,0,0);this.Rj=(new T).k(1,0,0);this.us=(new T).k(4194303,4194303,1048575);this.rg=(new T).k(0,0,524288);this.Pj=(new T).k(4194303,4194303,524287);this.jm=(new T).k(1755648,238,0);return this};function Sf(){return Ja().kd}
+function gn(a,b){if(b!==b)return a.kd;if(-9223372036854775E3>b)return a.rg;if(9223372036854775E3<=b)return a.Pj;if(0>b)return Tf(gn(a,-b));var d=b,e=17592186044416<=d?d/17592186044416|0:0,d=d-17592186044416*e,f=4194304<=d?d/4194304|0:0;return(new T).k(d-4194304*f|0,f,e)}Bq.prototype.a=new s({OD:0},!1,"scala.scalajs.runtime.RuntimeLong$",{OD:1,c:1,g:1,e:1});var Cq=void 0;function Ja(){Cq||(Cq=(new Bq).b());return Cq}function Dq(){}Dq.prototype=new t;function Eq(){}Eq.prototype=Dq.prototype;
+Dq.prototype.b=function(){return this};Dq.prototype.l=function(a){return this.Bb(a,Mg().Lm)};Dq.prototype.o=h("\x3cfunction1\x3e");Dq.prototype.lf=function(a){return tf(new uf,this,a)};var Yh=new s({bE:0},!1,"scala.runtime.Nothing$",{bE:1,dc:1,c:1,e:1});function Fq(){this.Xn=null}Fq.prototype=new oo;function Gq(){}Gq.prototype=Fq.prototype;Fq.prototype.yk=function(a){this.Xn=a;return this};function yf(a){return"string"===typeof a}
+var ma=new s({Os:0},!1,"java.lang.String",{Os:1,c:1,e:1,yn:1,Zc:1},void 0,yf);function Xl(){An.call(this)}Xl.prototype=new wo;Xl.prototype.w=function(a){Xl.prototype.h.call(this,ka(a));return this};Xl.prototype.a=new s({aw:0},!1,"java.lang.AssertionError",{aw:1,iw:1,dc:1,c:1,e:1});function Hq(){}Hq.prototype=new oo;Hq.prototype.a=new s({ow:0},!1,"java.lang.JSConsoleBasedPrintStream$DummyOutputStream",{ow:1,vq:1,c:1,Kj:1,Jl:1});function ji(){An.call(this)}ji.prototype=new yo;function Iq(){}
+Iq.prototype=ji.prototype;ji.prototype.b=function(){ji.prototype.Ee.call(this,null,null);return this};ji.prototype.h=function(a){ji.prototype.Ee.call(this,a,null);return this};ji.prototype.a=new s({ad:0},!1,"java.lang.RuntimeException",{ad:1,$c:1,dc:1,c:1,e:1});function Ao(){this.Ob=null}Ao.prototype=new t;l=Ao.prototype;l.b=function(){Ao.prototype.h.call(this,"");return this};function Jq(a,b){a.Ob=""+a.Ob+(null===b?"null":b);return a}l.Dp=function(a,b){return this.Ob.substring(a,b)};l.o=c("Ob");
+function Kq(a){var b=new Ao;Ao.prototype.h.call(b,ka(a));return b}l.Vj=function(a){return Lq(this,a)};function Lq(a,b){return null===b?Jq(a,null):Jq(a,ka(b))}l.Oa=function(){Ao.prototype.h.call(this,"");return this};function Mq(a,b,d,e){return null===b?Mq(a,"null",d,e):Jq(a,ka(Ea(b,d,e)))}l.q=function(){return this.Ob.length|0};function Nq(a,b){return Jq(a,m.String.fromCharCode(b))}l.h=function(a){this.Ob=a;return this};l.Uj=function(a){return Nq(this,a)};
+function Oq(a){for(var b=a.Ob,d="",e=0;e<(b.length|0);){var f=65535&(b.charCodeAt(e)|0);if(55296===(64512&f)&&(1+e|0)<(b.length|0)){var g=65535&(b.charCodeAt(1+e|0)|0);56320===(64512&g)?(d=""+m.String.fromCharCode(f)+m.String.fromCharCode(g)+d,e=2+e|0):(d=""+m.String.fromCharCode(f)+d,e=1+e|0)}else d=""+m.String.fromCharCode(f)+d,e=1+e|0}a.Ob=d;return a}l.a=new s({uw:0},!1,"java.lang.StringBuilder",{uw:1,c:1,yn:1,Zv:1,e:1});
+function Pq(){this.Pu=this.Qu=this.Ou=this.Nu=this.Mu=this.Lu=this.Ku=this.Ju=this.Iu=null}Pq.prototype=new xg;Pq.prototype.b=function(){Qq=this;this.Iu=p(v(Pa),[0]);this.Ju=p(v(Sa),[0]);this.Ku=p(v(Qa),[0]);this.Lu=p(v(Ya),[0]);this.Mu=p(v(Xa),[0]);this.Nu=p(v(Ua),[0]);this.Ou=p(v(Va),[0]);this.Qu=p(v(Ta),[0]);this.Pu=p(v(u),[0]);return this};function qc(a,b,d){a=d.xc(b.q());d=d=0;for(b=b.X();b.Ca();){var e=b.wa();Si(U(),a,d,e);d=1+d|0}return a}
+function zl(a,b,d,e,f,g){a=la(b);var k;if(k=!!a.Ed.isArrayClass)k=la(e),k.Ed.isPrimitive||a.Ed.isPrimitive?a=k===a||(k===q(Ta)?a===q(Sa):k===q(Ua)?a===q(Sa)||a===q(Ta):k===q(Xa)?a===q(Sa)||a===q(Ta)||a===q(Ua):k===q(Ya)&&(a===q(Sa)||a===q(Ta)||a===q(Ua)||a===q(Xa))):(a=a.Ed.getFakeInstance(),a=!!k.Ed.isInstance(a)),k=a;if(k)Fa(b,d,e,f,g);else for(a=d,d=d+g|0;a<d;){U();g=e;k=f;var n;U();n=b;var r=a;if(jb(n,1)||cb(n,1)||fb(n,1)||db(n,1)||eb(n,1))n=n.d[r];else if($a(n,1))n=(new Re).nc(n.d[r]);else if(ab(n,
+1)||bb(n,1)||Za(n,1)||vm(n))n=n.d[r];else{if(null===n)throw(new va).b();throw(new K).w(n);}Si(0,g,k,n);a=1+a|0;f=1+f|0}}Pq.prototype.a=new s({Gz:0},!1,"scala.Array$",{Gz:1,SH:1,c:1,g:1,e:1});var Qq=void 0;function rc(){Qq||(Qq=(new Pq).b());return Qq}function Rq(){An.call(this)}Rq.prototype=new wo;Rq.prototype.b=function(){Rq.prototype.h.call(this,"an implementation is missing");return this};Rq.prototype.a=new s({Lz:0},!1,"scala.NotImplementedError",{Lz:1,iw:1,dc:1,c:1,e:1});function Sq(){}
+Sq.prototype=new t;function Tq(){}Tq.prototype=Sq.prototype;Sq.prototype.b=function(){return this};Sq.prototype.o=h("\x3cfunction1\x3e");function Uq(){}Uq.prototype=new t;function Vq(){}Vq.prototype=Uq.prototype;Uq.prototype.b=function(){return this};Uq.prototype.o=h("\x3cfunction1\x3e");function Wq(){this.ck=null}Wq.prototype=new Bg;Wq.prototype.a=new s({$z:0},!1,"scala.Symbol$",{$z:1,TH:1,c:1,g:1,e:1});var Xq=void 0;function sh(){}sh.prototype=new t;sh.prototype.b=function(){rh=this;return this};
+sh.prototype.a=new s({eA:0},!1,"scala.math.Equiv$",{eA:1,c:1,bI:1,g:1,e:1});var rh=void 0;function Ah(){}Ah.prototype=new t;Ah.prototype.b=function(){zh=this;return this};Ah.prototype.a=new s({pA:0},!1,"scala.math.Ordering$",{pA:1,c:1,cI:1,g:1,e:1});var zh=void 0;function gp(){}gp.prototype=new t;gp.prototype.o=h("\x3c?\x3e");gp.prototype.a=new s({NA:0},!1,"scala.reflect.NoManifest$",{NA:1,c:1,vd:1,g:1,e:1});var fp=void 0;function Yq(){}Yq.prototype=new t;function Zq(){}l=Zq.prototype=Yq.prototype;
+l.Ba=function(){return this};l.b=function(){return this};l.m=function(){return!this.Ca()};l.Fb=function(){var a=J().N;return Uj(this,a)};l.fc=function(a){return L(this,"",a,"")};l.o=function(){return mj(this)};l.R=function(a){nj(this,a)};l.Rc=function(){uc();var a=vc().zb;return Uj(this,a)};l.U=function(){return ek(this)};l.ec=function(){return L(this,"","","")};l.db=function(){return ij(this)};l.rc=function(a,b,d,e){return Cj(this,a,b,d,e)};l.Dc=function(a){return ck(this,a)};
+l.Ac=function(a,b){return bk(this,a,b)};l.Yc=h(!1);l.lc=function(a){return Vj(this,a)};l.Kb=function(a){return Oi(this,a)};function $q(){}$q.prototype=new Sn;function ar(){}ar.prototype=$q.prototype;function br(){this.kl=this.ob=null}br.prototype=new t;l=br.prototype;l.b=function(){br.prototype.gh.call(this,cr());return this};l.tb=function(a){return dr(this,a)};l.gh=function(a){var b=Ap((new zp).b(),a);this.ob=Gj(b);b=(new er).b();this.kl=lk(b,a);return this};
+l.pa=function(){for(var a=this.ob,b=cr(),a=a.Ya;!a.m();)var d=a.u(),b=fr(b,d),a=a.s();return b};l.hd=function(a,b){Ul(this,a,b)};l.Da=function(a){return dr(this,a)};l.Ta=ba();function dr(a,b){null===em(a.kl,b)&&(gr(a.ob,b),hr(a.kl,b));return a}l.Ka=function(a){return lk(this,a)};l.a=new s({aC:0},!1,"scala.collection.immutable.ListSet$ListSetBuilder",{aC:1,c:1,Vb:1,Ub:1,Tb:1});function dp(){}dp.prototype=new eq;dp.prototype.Ri=function(){return Yj()};
+dp.prototype.a=new s({cC:0},!1,"scala.collection.immutable.Map$",{cC:1,xB:1,zB:1,uB:1,c:1});var cp=void 0;function xk(){mq.call(this)}xk.prototype=new nq;xk.prototype.zf=function(){return this};xk.prototype.o=function(){return"BlackTree("+this.ka+", "+this.j+", "+this.E+", "+this.L+")"};xk.prototype.kj=function(){return Y(new wk,this.ka,this.j,this.E,this.L)};function zk(a){return!!(a&&a.a&&a.a.t.Ko)}
+xk.prototype.a=new s({Ko:0},!1,"scala.collection.immutable.RedBlackTree$BlackTree",{Ko:1,jl:1,c:1,g:1,e:1});function wk(){mq.call(this)}wk.prototype=new nq;wk.prototype.zf=function(){return Y(new xk,this.ka,this.j,this.E,this.L)};wk.prototype.o=function(){return"RedTree("+this.ka+", "+this.j+", "+this.E+", "+this.L+")"};wk.prototype.kj=function(){return this};function vk(a){return!!(a&&a.a&&a.a.t.Lo)}
+wk.prototype.a=new s({Lo:0},!1,"scala.collection.immutable.RedBlackTree$RedTree",{Lo:1,jl:1,c:1,g:1,e:1});function ir(){this.th=this.bd=this.mj=null;this.nd=0;this.bj=null}ir.prototype=new t;function jr(){}l=jr.prototype=ir.prototype;l.Ba=function(){return this};l.wa=function(){var a=this.bj;if(null===a)throw(new uj).h("next on empty iterator");this.bj=kr(this,a.L);return(new V).ha(a.ka,a.j)};function kr(a,b){for(;;){if(null===b)return lr(a);if(null===b.E)return b;b=mr(a,b)}}l.m=function(){return!this.Ca()};
+l.Fb=function(){var a=J().N;return Uj(this,a)};l.fc=function(a){return L(this,"",a,"")};l.o=function(){return mj(this)};l.R=function(a){nj(this,a)};function nr(a,b){var d;if(null===a.mj)d=null;else a:{d=a.mj;for(;;){if(null===d){d=lr(a);break a}d=a.bd.Ig(b,d.ka)?mr(a,d):d.L}d=void 0}return d}l.Rc=function(){uc();var a=vc().zb;return Uj(this,a)};function lr(a){if(0===a.nd)return null;a.nd=-1+a.nd|0;return a.th.d[a.nd]}l.U=function(){return ek(this)};l.Ca=function(){return null!==this.bj};
+l.ec=function(){return L(this,"","","")};l.db=function(){return ij(this)};l.rc=function(a,b,d,e){return Cj(this,a,b,d,e)};l.Dc=function(a){return ck(this,a)};l.Ac=function(a,b){return bk(this,a,b)};l.Yc=h(!1);function mr(a,b){a:b:for(;;){try{a.th.d[a.nd]=b,a.nd=1+a.nd|0}catch(d){if(d&&d.a&&d.a.t.uH){ap(Ac(),a.nd>=a.th.d.length);var e=a.th,f=sc(tc(),q(oq));rc();f=f.xc(1+e.d.length|0);zl(rc(),e,0,f,0,e.d.length);Si(U(),f,e.d.length,null);a.th=f;continue b}else throw d;}break a}return b.E}
+l.lc=function(a){return Vj(this,a)};l.Kb=function(a){return Oi(this,a)};function or(){this.ob=this.Cc=null}or.prototype=new t;function pr(a,b){a.Cc=b;a.ob=b;return a}l=or.prototype;l.tb=function(a){this.ob.tb(a);return this};l.pa=c("ob");l.hd=function(a,b){Ul(this,a,b)};l.Da=function(a){this.ob.tb(a);return this};l.Ta=ba();l.Ka=function(a){return lk(this,a)};l.a=new s({jD:0},!1,"scala.collection.mutable.GrowingBuilder",{jD:1,c:1,Vb:1,Ub:1,Tb:1});function qr(){this.Qd=null}qr.prototype=new t;
+function rr(){}l=rr.prototype=qr.prototype;l.b=function(){this.Qd=(new zp).b();return this};l.tb=function(a){return sr(this,a)};function sr(a,b){var d=a.Qd;J();var e=(new C).A([b]),f=J().N;gr(d,Kj(e,f));return a}l.hd=function(a,b){Ul(this,a,b)};l.Da=function(a){return sr(this,a)};l.Ta=ba();l.Ka=function(a){gr(this.Qd,a);return this};function Xj(){this.ob=this.Cc=null}Xj.prototype=new t;function qk(a,b){a.ob=a.ob.Yd(b);return a}l=Xj.prototype;l.tb=function(a){return qk(this,a)};l.pa=c("ob");
+l.hd=function(a,b){Ul(this,a,b)};function Wj(a,b){a.Cc=b;a.ob=b;return a}l.Da=function(a){return qk(this,a)};l.Ta=ba();l.Ka=function(a){return lk(this,a)};l.a=new s({rD:0},!1,"scala.collection.mutable.MapBuilder",{rD:1,c:1,Vb:1,Ub:1,Tb:1});function tr(){this.ob=this.Cc=null}tr.prototype=new t;l=tr.prototype;l.tb=function(a){return ur(this,a)};l.pa=c("ob");l.hd=function(a,b){Ul(this,a,b)};function ur(a,b){a.ob=a.ob.ze(b);return a}function vr(a,b){a.Cc=b;a.ob=b;return a}
+l.Da=function(a){return ur(this,a)};l.Ta=ba();l.Ka=function(a){return lk(this,a)};l.a=new s({sD:0},!1,"scala.collection.mutable.SetBuilder",{sD:1,c:1,Vb:1,Ub:1,Tb:1});function wr(){this.ob=this.ix=this.we=null;this.ve=this.af=0}wr.prototype=new t;l=wr.prototype;l.zk=function(a){this.ix=this.we=a;this.ve=this.af=0;return this};l.tb=function(a){return xr(this,a)};
+function xr(a,b){var d=1+a.ve|0;if(a.af<d){for(var e=0===a.af?16:w(2,a.af);e<d;)e=w(2,e);d=e;a.ob=yr(a,d);a.af=d}a.ob.Ne(a.ve,b);a.ve=1+a.ve|0;return a}
+function yr(a,b){var d=Mh(U(),a.we),d=d===q(Sa)?(new sm).Kf(p(v(Sa),[b])):d===q(Ta)?(new tm).Qf(p(v(Ta),[b])):d===q(Qa)?(new rm).Lf(p(v(Qa),[b])):d===q(Ua)?(new nm).Of(p(v(Ua),[b])):d===q(Va)?(new pm).Pf(p(v(Va),[b])):d===q(Xa)?(new qm).Nf(p(v(Xa),[b])):d===q(Ya)?(new om).Mf(p(v(Ya),[b])):d===q(Pa)?(new um).Rf(p(v(Pa),[b])):d===q(Na)?(new wm).Sf(p(v(ua),[b])):(new Sb).me(a.we.xc(b));0<a.ve&&zl(rc(),a.ob.p,0,d.p,0,a.ve);return d}
+l.pa=function(){return 0!==this.af&&this.af===this.ve?this.ob:yr(this,this.ve)};l.hd=function(a,b){Ul(this,a,b)};l.Da=function(a){return xr(this,a)};l.Ta=function(a){this.af<a&&(this.ob=yr(this,a),this.af=a)};l.Ka=function(a){return lk(this,a)};l.a=new s({wD:0},!1,"scala.collection.mutable.WrappedArrayBuilder",{wD:1,c:1,Vb:1,Ub:1,Tb:1});function zr(){this.Fk=this.ym=null;this.nd=0}zr.prototype=new t;l=zr.prototype;l.wa=function(){return this.Nk()};l.Ba=function(){return this};l.m=function(){return!this.Ca()};
+l.Fb=function(){var a=J().N;return Uj(this,a)};l.ji=function(a){this.ym=a;this.Fk=m.Object.keys(a);this.nd=0;return this};l.fc=function(a){return L(this,"",a,"")};l.o=function(){return mj(this)};l.R=function(a){nj(this,a)};l.Rc=function(){uc();var a=vc().zb;return Uj(this,a)};l.U=function(){return ek(this)};l.Nk=function(){var a=this.Fk[this.nd];this.nd=1+this.nd|0;var b=this.ym;if(Dg().oh.call(b,a))b=b[a];else throw(new uj).h("key not found: "+a);return(new V).ha(a,b)};
+l.Ca=function(){return this.nd<(this.Fk.length|0)};l.ec=function(){return L(this,"","","")};l.db=function(){return ij(this)};l.rc=function(a,b,d,e){return Cj(this,a,b,d,e)};l.Dc=function(a){return ck(this,a)};l.Ac=function(a,b){return bk(this,a,b)};l.Yc=h(!1);l.lc=function(a){return Vj(this,a)};l.Kb=function(a){return Oi(this,a)};l.a=new s({JD:0},!1,"scala.scalajs.js.WrappedDictionary$DictionaryIterator",{JD:1,c:1,ed:1,H:1,G:1});function Ar(){}Ar.prototype=new t;
+Ar.prototype.b=function(){Br=this;return this};Ar.prototype.l=function(a){return(new Cr).h(a)};Ar.prototype.o=h("\x3cfunction1\x3e");Ar.prototype.a=new s({Fq:0},!1,"scalatags.JsDom$RawFrag$",{Fq:1,c:1,ur:1,x:1,g:1,e:1});var Br=void 0;function Dr(){}Dr.prototype=new t;Dr.prototype.b=function(){Er=this;return this};Dr.prototype.l=function(a){return(new Wc).h(a)};Dr.prototype.o=h("\x3cfunction1\x3e");Dr.prototype.a=new s({Gq:0},!1,"scalatags.JsDom$StringFrag$",{Gq:1,c:1,ur:1,x:1,g:1,e:1});var Er=void 0;
+function Lb(){this.Ha=null}Lb.prototype=new t;l=Lb.prototype;l.jb=h("Attr");l.hb=h(1);l.K=function(a){return this===a?!0:a&&a.a&&a.a.t.Ol?this.Ha===a.Ha:!1};l.ib=function(a){switch(a){case 0:return this.Ha;default:throw(new Rg).h(""+a);}};l.o=function(){return hn(U(),this)};l.h=function(a){this.Ha=a;var b=ob();if(!Ab(Bb(b.$j,a)))throw(new Cb).h(Db((new Eb).La((new C).A(["Illegal attribute name: "," is not a valid XML attribute name"])),(new C).A([a])));return this};l.M=function(){return vi(this)};
+l.qb=function(){return Fr(new Gr,this)};l.a=new s({Ol:0},!1,"scalatags.generic.Attr",{Ol:1,c:1,xa:1,n:1,g:1,e:1});function Hr(){this.Eb=this.ke=this.hf=null}Hr.prototype=new t;function Ir(){}l=Ir.prototype=Hr.prototype;l.jb=h("PixelStyle");l.ia=function(a,b){this.hf=a;this.ke=b;this.Eb=(new E).ia(a,b);return this};l.hb=h(2);l.K=function(a){return this===a?!0:a&&a.a&&a.a.t.qg?this.hf===a.hf&&this.ke===a.ke:!1};
+l.ib=function(a){switch(a){case 0:return this.hf;case 1:return this.ke;default:throw(new Rg).h(""+a);}};l.o=function(){return hn(U(),this)};l.M=function(){return vi(this)};l.qb=function(){return Fr(new Gr,this)};l.a=new s({qg:0},!1,"scalatags.generic.PixelStyle",{qg:1,c:1,xa:1,n:1,g:1,e:1});function E(){this.ke=this.hf=null}E.prototype=new t;function Jr(){}l=Jr.prototype=E.prototype;l.ia=function(a,b){this.hf=a;this.ke=b;return this};l.jb=h("Style");l.hb=h(2);
+l.K=function(a){return this===a?!0:a&&a.a&&a.a.t.cc?this.hf===a.hf&&this.ke===a.ke:!1};l.ib=function(a){switch(a){case 0:return this.hf;case 1:return this.ke;default:throw(new Rg).h(""+a);}};l.o=function(){return hn(U(),this)};l.M=function(){return vi(this)};l.qb=function(){return Fr(new Gr,this)};l.a=new s({cc:0},!1,"scalatags.generic.Style",{cc:1,c:1,xa:1,n:1,g:1,e:1});function Kr(){this.fg=this.ld=this.rd=this.Ha=null;this.Q=!1}Kr.prototype=new t;l=Kr.prototype;l.jb=h("Cls");l.hb=h(3);
+l.K=function(a){if(this===a)return!0;if(a&&a.a&&a.a.t.Ul){if(this.Ha===a.Ha)var b=this.rd,d=a.rd,b=null===b?null===d:b.K(d);else b=!1;if(b)return b=this.ld,a=a.ld,null===b?null===a:b.K(a)}return!1};l.ib=function(a){switch(a){case 0:return this.Ha;case 1:return this.rd;case 2:return this.ld;default:throw(new Rg).h(""+a);}};l.o=function(){return hn(U(),this)};
+function ac(a){if(!a.Q){var b=a.ld,d=bc(),e=a.Ha,f=a.rd,g=M(function(a){return""+(new Re).nc(58)+a}),k=bc(),d=jk(d,(new C).A(["."+e+f.oe(g,k.N).ec()])),e=Id();a.fg=b.le(Jd(new Kd,d,Ld(e),x()),nc(function(a,b){return b.Ze(a)}));a.Q=!0}return a.fg}l.M=function(){return vi(this)};l.qb=function(){return Fr(new Gr,this)};function xn(a,b,d){var e=new Kr;e.Ha=a;e.rd=b;e.ld=d;return e}l.a=new s({Ul:0},!1,"scalatags.stylesheet.Cls",{Ul:1,c:1,xa:1,n:1,g:1,e:1});function Kd(){this.Bc=this.qf=this.he=null}
+Kd.prototype=new t;l=Kd.prototype;l.jb=h("StyleTree");l.hb=h(3);l.K=function(a){if(this===a)return!0;if(a&&a.a&&a.a.t.Wl){var b=this.he,d=a.he;(null===b?null===d:b.K(d))?(b=this.qf,d=a.qf,b=null===b?null===d:Bi(b,d)):b=!1;if(b)return b=this.Bc,a=a.Bc,null===b?null===a:b.K(a)}return!1};l.ib=function(a){switch(a){case 0:return this.he;case 1:return this.qf;case 2:return this.Bc;default:throw(new Rg).h(""+a);}};l.o=function(){return hn(U(),this)};
+function $b(a,b){var d=a.qf,e=M(function(a){if(null!==a)return Db((new Eb).La((new C).A([" ",":",""])),(new C).A([a.Ua,a.$a]));throw(new K).w(a);}),f=Zg().N,d=Nj(d,e,f).fc("\n"),e=a.he,f=bc(),e=b.sf(e,f.N);f=Ai(Hh().zl,e);if(f.m())throw(new K).w(e);e=f.Wc().Ua;f=f.Wc().$a;var g=M(function(a){return 58===(65535&(a.charCodeAt(0)|0))?a:" "+a}),k=bc(),f=f.oe(g,k.N),g=bc(),e=f.Fc(e,g.N).fc(""),d=""===d?"":Db((new Eb).La((new C).A(["","{\\n","\\n}\\n"])),(new C).A([e,d])),e=a.Bc,f=M(function(a,b){return function(d){var e=
+a.he,f=bc();return $b(d,b.sf(e,f.N))}}(a,b)),g=bc(),e=e.oe(f,g.N),f=bc();return e.Fc(d,f.N).ec()}l.M=function(){return vi(this)};function Jd(a,b,d,e){a.he=b;a.qf=d;a.Bc=e;return a}l.qb=function(){return Fr(new Gr,this)};l.a=new s({Wl:0},!1,"scalatags.stylesheet.StyleTree",{Wl:1,c:1,xa:1,n:1,g:1,e:1});function Lr(){this.Eg=this.df=this.be=this.ae=this.Zd=null;this.yg=this.uh=0}Lr.prototype=new t;l=Lr.prototype;l.jb=h("MenuNode");l.hb=h(7);
+l.K=function(a){return this===a?!0:a&&a.a&&a.a.t.Xl?O(P(),this.Zd,a.Zd)&&O(P(),this.ae,a.ae)&&O(P(),this.be,a.be)&&O(P(),this.df,a.df)&&this.Eg===a.Eg&&this.uh===a.uh&&this.yg===a.yg:!1};l.ib=function(a){switch(a){case 0:return this.Zd;case 1:return this.ae;case 2:return this.be;case 3:return this.df;case 4:return this.Eg;case 5:return this.uh;case 6:return this.yg;default:throw(new Rg).h(""+a);}};l.o=function(){return hn(U(),this)};
+l.M=function(){var a=-889275714,a=nn().Nc(a,ln(nn(),this.Zd)),a=nn().Nc(a,ln(nn(),this.ae)),a=nn().Nc(a,ln(nn(),this.be)),a=nn().Nc(a,ln(nn(),this.df)),a=nn().Nc(a,ln(nn(),this.Eg)),a=nn().Nc(a,this.uh),a=nn().Nc(a,this.yg);return nn().Cg(a,7)};function Ad(a,b,d,e,f,g,k){var n=new Lr;n.Zd=a;n.ae=b;n.be=d;n.df=e;n.Eg=f;n.uh=g;n.yg=k;return n}l.qb=function(){return Fr(new Gr,this)};l.a=new s({Xl:0},!1,"scalatex.scrollspy.MenuNode",{Xl:1,c:1,xa:1,n:1,g:1,e:1});function Oc(){this.ja=null}
+Oc.prototype=new jo;Oc.prototype.l=function(a){Mr(this,a)};function Mr(a,b){Bd(a.ja,b,M(function(){return function(a){rd(a)}}(a)))}Oc.prototype.a=new s({Dr:0},!1,"scalatex.scrollspy.ScrollSpy$$anonfun$toggleOpen$1",{Dr:1,vi:1,c:1,x:1,g:1,e:1});function pc(){this.Bc=this.j=null}pc.prototype=new t;l=pc.prototype;l.jb=h("Tree");l.hb=h(2);l.K=function(a){if(this===a)return!0;if(a&&a.a&&a.a.t.Yl&&O(P(),this.j,a.j)){var b=this.Bc;a=a.Bc;return null===b?null===a:Nr(a)?b.Qb(a):!1}return!1};
+l.ib=function(a){switch(a){case 0:return this.j;case 1:return this.Bc;default:throw(new Rg).h(""+a);}};l.o=function(){return hn(U(),this)};l.M=function(){return vi(this)};l.qb=function(){return Fr(new Gr,this)};function oc(a,b,d){a.j=b;a.Bc=d;return a}l.a=new s({Yl:0},!1,"scalatex.scrollspy.Tree",{Yl:1,c:1,xa:1,n:1,g:1,e:1});function Or(){}Or.prototype=new t;Or.prototype.b=function(){Pr=this;return this};Or.prototype.ye=function(a,b){return b.lf((new Qr).h(a))};
+function zc(a){a=yc(a).lf((new Rr).h("Tagged Object scalatex.scrollspy.Tree"));return(new qe).Fe(a)}Or.prototype.a=new s({Xr:0},!1,"upickle.Internal$",{Xr:1,c:1,lG:1,Ir:1,ms:1,Lr:1});var Pr=void 0;function lc(){Pr||(Pr=(new Or).b());return Pr}function Sr(){}Sr.prototype=new jo;l=Sr.prototype;l.l=function(a){return(new zf).La(a)};l.tl=function(a){return hn(U(),(new zf).La(a))};l.Qk=function(a){return Fr(new Gr,(new zf).La(a))};l.o=h("Arr");
+l.Pk=function(a,b){switch(b){case 0:return a;default:throw(new Rg).h(""+b);}};l.ok=function(a,b){if(Tr(b)){var d=null===b?null:b.j;return null===a?null===d:a.K(d)}return!1};l.a=new s({$r:0},!1,"upickle.Js$Arr$",{$r:1,vi:1,c:1,x:1,g:1,e:1});var Ur=void 0;function Vr(){Ur||(Ur=(new Sr).b());return Ur}function Wr(){}Wr.prototype=new jo;Wr.prototype.l=function(a){return Ae(new Be,+a)};Wr.prototype.o=h("Num");Wr.prototype.a=new s({cs:0},!1,"upickle.Js$Num$",{cs:1,vi:1,c:1,x:1,g:1,e:1});var Xr=void 0;
+function Yr(){Xr||(Xr=(new Wr).b())}function Zr(){}Zr.prototype=new jo;l=Zr.prototype;l.l=function(a){return(new ue).La(a)};l.tl=function(a){return hn(U(),(new ue).La(a))};l.Qk=function(a){return Fr(new Gr,(new ue).La(a))};l.o=h("Obj");l.Pk=function(a,b){switch(b){case 0:return a;default:throw(new Rg).h(""+b);}};l.ok=function(a,b){if($r(b)){var d=null===b?null:b.j;return null===a?null===d:a.K(d)}return!1};l.a=new s({ds:0},!1,"upickle.Js$Obj$",{ds:1,vi:1,c:1,x:1,g:1,e:1});var as=void 0;
+function bs(){as||(as=(new Zr).b());return as}function cs(){}cs.prototype=new jo;cs.prototype.l=function(a){return(new ze).h(a)};cs.prototype.nk=function(a,b){return ds(b)?a===(null===b?null:b.j):!1};cs.prototype.o=h("Str");cs.prototype.a=new s({es:0},!1,"upickle.Js$Str$",{es:1,vi:1,c:1,x:1,g:1,e:1});var es=void 0;function Oe(){es||(es=(new cs).b());return es}
+function fs(){this.Qp=this.Pp=this.Op=this.fq=this.Hl=this.jq=this.Il=this.oq=this.Ij=this.eq=this.kq=this.Kl=this.pq=this.Hs=this.bq=this.cq=this.Ns=this.Ih=this.Rs=this.aq=this.ys=this.xs=null}fs.prototype=new t;fs.prototype.b=function(){gs=this;Fe(this);return this};fs.prototype.ye=function(a,b){return lc().ye(a,b)};fs.prototype.a=new s({rs:0},!1,"upickle.package$",{rs:1,c:1,ms:1,mG:1,Ir:1,Lr:1});var gs=void 0;function ic(){gs||(gs=(new fs).b());return gs}function yq(){An.call(this)}
+yq.prototype=new Iq;yq.prototype.a=new s({$v:0},!1,"java.lang.ArithmeticException",{$v:1,ad:1,$c:1,dc:1,c:1,e:1});function Cb(){An.call(this)}Cb.prototype=new Iq;function hs(){}hs.prototype=Cb.prototype;Cb.prototype.b=function(){Cb.prototype.Ee.call(this,null,null);return this};Cb.prototype.h=function(a){Cb.prototype.Ee.call(this,a,null);return this};Cb.prototype.a=new s({hh:0},!1,"java.lang.IllegalArgumentException",{hh:1,ad:1,$c:1,dc:1,c:1,e:1});function Fn(){An.call(this)}Fn.prototype=new Iq;
+function is(){}is.prototype=Fn.prototype;Fn.prototype.b=function(){Fn.prototype.Ee.call(this,null,null);return this};Fn.prototype.h=function(a){Fn.prototype.Ee.call(this,a,null);return this};Fn.prototype.a=new s({Bn:0},!1,"java.lang.IllegalStateException",{Bn:1,ad:1,$c:1,dc:1,c:1,e:1});function Rg(){An.call(this)}Rg.prototype=new Iq;Rg.prototype.a=new s({kw:0},!1,"java.lang.IndexOutOfBoundsException",{kw:1,ad:1,$c:1,dc:1,c:1,e:1});function va(){An.call(this)}va.prototype=new Iq;
+va.prototype.b=function(){va.prototype.h.call(this,null);return this};va.prototype.a=new s({rw:0},!1,"java.lang.NullPointerException",{rw:1,ad:1,$c:1,dc:1,c:1,e:1});function xj(){An.call(this)}xj.prototype=new Iq;xj.prototype.h=function(a){xj.prototype.Ee.call(this,a,null);return this};xj.prototype.a=new s({ww:0},!1,"java.lang.UnsupportedOperationException",{ww:1,ad:1,$c:1,dc:1,c:1,e:1});function uj(){An.call(this)}uj.prototype=new Iq;uj.prototype.b=function(){uj.prototype.h.call(this,null);return this};
+uj.prototype.a=new s({Gw:0},!1,"java.util.NoSuchElementException",{Gw:1,ad:1,$c:1,dc:1,c:1,e:1});function K(){An.call(this);this.Tn=this.mi=null;this.ak=!1}K.prototype=new Iq;K.prototype.di=function(){if(!this.ak&&!this.ak){var a;if(null===this.mi)a="null";else try{a=ka(this.mi)+" ("+("of class "+ib(la(this.mi)))+")"}catch(b){if(null!==Wm(H(),b))a="an instance of class "+ib(la(this.mi));else throw b;}this.Tn=a;this.ak=!0}return this.Tn};
+K.prototype.w=function(a){this.mi=a;ji.prototype.b.call(this);return this};K.prototype.a=new s({Jz:0},!1,"scala.MatchError",{Jz:1,ad:1,$c:1,dc:1,c:1,e:1});function js(){}js.prototype=new t;function ks(){}ks.prototype=js.prototype;js.prototype.b=function(){return this};function Ab(a){return!a.m()}function hp(){}hp.prototype=new Vq;hp.prototype.l=aa();hp.prototype.a=new s({Tz:0},!1,"scala.Predef$$anon$1",{Tz:1,WH:1,c:1,x:1,g:1,e:1});function ip(){}ip.prototype=new Tq;ip.prototype.l=aa();
+ip.prototype.a=new s({Uz:0},!1,"scala.Predef$$anon$2",{Uz:1,VH:1,c:1,x:1,g:1,e:1});function Eb(){this.Qd=null}Eb.prototype=new t;l=Eb.prototype;l.jb=h("StringContext");l.hb=h(1);l.K=function(a){if(this===a)return!0;if(a&&a.a&&a.a.t.no){var b=this.Qd;a=a.Qd;return null===b?null===a:b.K(a)}return!1};l.ib=function(a){switch(a){case 0:return this.Qd;default:throw(new Rg).h(""+a);}};l.o=function(){return hn(U(),this)};
+function ls(a,b){if(a.Qd.q()!==(1+b.q()|0))throw(new Cb).h("wrong number of arguments ("+b.q()+") for interpolated string with "+a.Qd.q()+" parts");}
+function Db(a,b){var d=function(){return function(a){up||(up=(new tp).b());a:{var b=a.length|0,d=Tj(Ba(),a,92);switch(d){case -1:break a;default:var e=(new Ao).b();b:{var f=d,d=0;for(;;)if(0<=f){f>d&&Mq(e,a,d,f);d=1+f|0;if(d>=b)throw(new ms).gi(a,f);var g=65535&(a.charCodeAt(d)|0);switch(g){case 98:f=8;break;case 116:f=9;break;case 110:f=10;break;case 102:f=12;break;case 114:f=13;break;case 34:f=34;break;case 39:f=39;break;case 92:f=92;break;default:if(48<=g&&55>=g){g=65535&(a.charCodeAt(d)|0);f=
+-48+g|0;d=1+d|0;if(d<b&&48<=(65535&(a.charCodeAt(d)|0))&&55>=(65535&(a.charCodeAt(d)|0))){var k=d,f=-48+(w(8,f)+(65535&(a.charCodeAt(k)|0))|0)|0,d=1+d|0;d<b&&51>=g&&48<=(65535&(a.charCodeAt(d)|0))&&55>=(65535&(a.charCodeAt(d)|0))&&(g=d,f=-48+(w(8,f)+(65535&(a.charCodeAt(g)|0))|0)|0,d=1+d|0)}d=-1+d|0;f&=65535}else throw(new ms).gi(a,f);}d=1+d|0;Nq(e,f);f=d;Ba();g=a;k=Sj(92);g=g.indexOf(k,d)|0;d=f;f=g}else{d<b&&Mq(e,a,d,b);a=e.Ob;break b}a=void 0}}}return a}}(a);ls(a,b);for(var e=a.Qd.X(),f=b.X(),g=
+e.wa(),g=(new Ao).h(d(g));f.Ca();){Lq(g,f.wa());var k=e.wa();Jq(g,d(k))}return g.Ob}l.La=function(a){this.Qd=a;return this};l.M=function(){return vi(this)};l.qb=function(){return Fr(new Gr,this)};l.a=new s({no:0},!1,"scala.StringContext",{no:1,c:1,xa:1,n:1,g:1,e:1});function ns(){}ns.prototype=new t;function os(){}os.prototype=ns.prototype;ns.prototype.b=function(){return this};function qi(){An.call(this)}qi.prototype=new Bn;qi.prototype.b=function(){An.prototype.b.call(this);return this};
+qi.prototype.Ti=function(){Yp||(Yp=(new Xp).b());return Yp.Cl?An.prototype.Ti.call(this):this};qi.prototype.a=new s({VA:0},!1,"scala.util.control.BreakControl",{VA:1,dc:1,c:1,e:1,qI:1,rI:1});function ps(){this.N=null}ps.prototype=new Un;ps.prototype.na=function(){qs();return(new zp).b()};ps.prototype.a=new s({gB:0},!1,"scala.collection.Iterable$",{gB:1,xd:1,yc:1,c:1,yd:1,zc:1});var rs=void 0;function Zg(){rs||(rs=(new ps).b());return rs}function Aj(){this.Zm=this.ja=null}Aj.prototype=new Zq;
+Aj.prototype.wa=function(){return this.Zm.l(this.ja.wa())};Aj.prototype.Zi=function(a,b){if(null===a)throw G(H(),null);this.ja=a;this.Zm=b;return this};Aj.prototype.Ca=function(){return this.ja.Ca()};Aj.prototype.a=new s({iB:0},!1,"scala.collection.Iterator$$anon$11",{iB:1,Hd:1,c:1,ed:1,H:1,G:1});function ss(){this.vk=null;this.Xi=!1;this.Zn=this.ja=null}ss.prototype=new Zq;ss.prototype.wa=function(){return this.Ca()?(this.Xi=!1,this.vk):$g().Cc.wa()};
+ss.prototype.Zi=function(a,b){if(null===a)throw G(H(),null);this.ja=a;this.Zn=b;this.Xi=!1;return this};ss.prototype.Ca=function(){if(!this.Xi){do{if(!this.ja.Ca())return!1;this.vk=this.ja.wa()}while(!this.Zn.l(this.vk));this.Xi=!0}return!0};ss.prototype.a=new s({jB:0},!1,"scala.collection.Iterator$$anon$13",{jB:1,Hd:1,c:1,ed:1,H:1,G:1});function hj(){}hj.prototype=new Zq;hj.prototype.wa=function(){throw(new uj).h("next on empty iterator");};hj.prototype.Ca=h(!1);
+hj.prototype.a=new s({kB:0},!1,"scala.collection.Iterator$$anon$2",{kB:1,Hd:1,c:1,ed:1,H:1,G:1});function ts(){this.jc=null}ts.prototype=new Zq;ts.prototype.wa=function(){if(this.Ca()){var a=this.jc.u();this.jc=this.jc.s();return a}return $g().Cc.wa()};ts.prototype.Fb=function(){var a=this.jc.Fb();this.jc=this.jc.Ep(0);return a};ts.prototype.Ca=function(){return!this.jc.m()};ts.prototype.a=new s({lB:0},!1,"scala.collection.LinearSeqLike$$anon$1",{lB:1,Hd:1,c:1,ed:1,H:1,G:1});
+function Yg(){this.St=this.N=null}Yg.prototype=new Un;Yg.prototype.b=function(){Tn.prototype.b.call(this);Xg=this;this.St=(new pi).b();return this};Yg.prototype.na=function(){us||(us=(new vs).b());return(new zp).b()};Yg.prototype.a=new s({pB:0},!1,"scala.collection.Traversable$",{pB:1,xd:1,yc:1,c:1,yd:1,zc:1});var Xg=void 0;function ws(){}ws.prototype=new ar;function xs(){}xs.prototype=ws.prototype;ws.prototype.Ef=function(){return this.Qi()};ws.prototype.na=function(){return vr(new tr,this.Qi())};
+function ys(){}ys.prototype=new ar;function zs(){}zs.prototype=ys.prototype;ys.prototype.na=function(){return pr(new or,this.Ef())};function As(){this.N=null}As.prototype=new Un;As.prototype.na=function(){return(new zp).b()};As.prototype.a=new s({QB:0},!1,"scala.collection.immutable.Iterable$",{QB:1,xd:1,yc:1,c:1,yd:1,zc:1});var Bs=void 0;function qs(){Bs||(Bs=(new As).b());return Bs}function Cs(){this.rh=null}Cs.prototype=new Zq;Cs.prototype.wa=function(){return this.Nk()};
+Cs.prototype.Nk=function(){if(this.Ca()){var a=(new V).ha(this.rh.jh(),this.rh.Di());this.rh=this.rh.$f();return a}throw(new uj).h("next on empty iterator");};Cs.prototype.Ca=function(){return!this.rh.m()};Cs.prototype.a=new s({UB:0},!1,"scala.collection.immutable.ListMap$$anon$1",{UB:1,Hd:1,c:1,ed:1,H:1,G:1});function Ds(){this.Qg=null}Ds.prototype=new Zq;Ds.prototype.wa=function(){if(!this.Qg.m()){var a=this.Qg.u();this.Qg=this.Qg.ql();return a}return $g().Cc.wa()};
+Ds.prototype.gh=function(a){this.Qg=a;return this};Ds.prototype.Ca=function(){return!this.Qg.m()};Ds.prototype.a=new s({ZB:0},!1,"scala.collection.immutable.ListSet$$anon$1",{ZB:1,Hd:1,c:1,ed:1,H:1,G:1});function Es(){ir.call(this)}Es.prototype=new jr;Es.prototype.a=new s({nC:0},!1,"scala.collection.immutable.RedBlackTree$EntriesIterator",{nC:1,BI:1,c:1,ed:1,H:1,G:1});function Fs(){this.Qd=null}Fs.prototype=new rr;Fs.prototype.pa=function(){return Gs(this)};
+function Gs(a){return Hs(a.Qd.Ya.db(),M(function(){return function(a){return a.db()}}(a)))}function Is(a){return!!(a&&a.a&&a.a.t.Mo)}Fs.prototype.a=new s({Mo:0},!1,"scala.collection.immutable.Stream$StreamBuilder",{Mo:1,II:1,c:1,Vb:1,Ub:1,Tb:1});function Js(){this.jc=null}Js.prototype=new Zq;l=Js.prototype;l.wa=function(){if(!this.Ca())return $g().Cc.wa();var a=this.jc.Q?this.jc.Za:il(this.jc),b=a.u();this.jc=hl(new gl,this,Nc(function(a,b){return function(){return b.s()}}(this,a)));return b};
+l.Fb=function(){var a=this.db(),b=J().N;return Kj(a,b)};function Ks(a){var b=new Js;b.jc=hl(new gl,b,Nc(function(a,b){return function(){return b}}(b,a)));return b}l.Ca=function(){return!(this.jc.Q?this.jc.Za:il(this.jc)).m()};l.db=function(){var a=this.jc.Q?this.jc.Za:il(this.jc);this.jc=hl(new gl,this,Nc(function(){return function(){lh();return lj()}}(this)));return a};l.a=new s({HC:0},!1,"scala.collection.immutable.StreamIterator",{HC:1,Hd:1,c:1,ed:1,H:1,G:1});function vs(){this.N=null}
+vs.prototype=new Un;vs.prototype.na=function(){return(new zp).b()};vs.prototype.a=new s({KC:0},!1,"scala.collection.immutable.Traversable$",{KC:1,xd:1,yc:1,c:1,yd:1,zc:1});var us=void 0;function Ls(){}Ls.prototype=new Zn;Ls.prototype.Mm=function(a){return Ld(a)};Ls.prototype.a=new s({MC:0},!1,"scala.collection.immutable.TreeMap$",{MC:1,yB:1,BB:1,c:1,g:1,e:1});var Ms=void 0;function Ns(){this.y=null;this.Td=0;this.ph=this.$k=this.sj=null;this.cg=0;this.Lg=null}Ns.prototype=new Zq;function Os(){}
+Os.prototype=Ns.prototype;
+Ns.prototype.wa=function(){if(null!==this.Lg){var a=this.Lg.wa();this.Lg.Ca()||(this.Lg=null);return a}a:{var a=this.ph,b=this.cg;for(;;){b===(-1+a.d.length|0)?(this.Td=-1+this.Td|0,0<=this.Td?(this.ph=this.sj.d[this.Td],this.cg=this.$k.d[this.Td],this.sj.d[this.Td]=null):(this.ph=null,this.cg=0)):this.cg=1+this.cg|0;if((a=a.d[b])&&a.a&&a.a.t.Go||a&&a.a&&a.a.t.Ho){a=this.en(a);break a}if(a&&a.a&&a.a.t.fl||Ps(a))0<=this.Td&&(this.sj.d[this.Td]=this.ph,this.$k.d[this.Td]=this.cg),this.Td=1+this.Td|
+0,this.ph=Qs(a),this.cg=0,a=Qs(a),b=0;else{this.Lg=a.X();a=this.wa();break a}}a=void 0}return a};Ns.prototype.Ca=function(){return null!==this.Lg||0<=this.Td};function Qs(a){if(a&&a.a&&a.a.t.fl)return a.md;if(Ps(a))return a.Jc;throw(new K).w(a);}Ns.prototype.mn=function(a){this.y=a;this.Td=0;this.sj=p(v(v(Rs)),[6]);this.$k=p(v(Ua),[6]);this.ph=this.y;this.cg=0;this.Lg=null;return this};function Ss(){this.Kc=0;this.ja=null}Ss.prototype=new Zq;
+Ss.prototype.wa=function(){return 0<this.Kc?(this.Kc=-1+this.Kc|0,this.ja.ma(this.Kc)):$g().Cc.wa()};Ss.prototype.Ca=function(){return 0<this.Kc};function Ts(a){var b=new Ss;if(null===a)throw G(H(),null);b.ja=a;b.Kc=a.q();return b}Ss.prototype.a=new s({PC:0},!1,"scala.collection.immutable.Vector$$anon$1",{PC:1,Hd:1,c:1,ed:1,H:1,G:1});function Jn(){this.Yh=this.Hg=this.Rh=0;this.Hm=this.Fm=this.Dm=this.Bm=this.zm=this.Zh=null}Jn.prototype=new t;l=Jn.prototype;l.Aa=c("Dm");
+l.b=function(){this.Zh=p(v(u),[32]);this.Yh=1;this.Hg=this.Rh=0;return this};l.Hb=c("Yh");l.tb=function(a){return Us(this,a)};l.Df=da("Hm");l.nb=c("Zh");l.Ra=c("Fm");l.Fa=da("Bm");
+function Us(a,b){if(a.Hg>=a.Zh.d.length){var d=32+a.Rh|0,e=a.Rh^d;if(1024>e)1===a.Hb()&&(a.va(p(v(u),[32])),a.P().d[0]=a.nb(),a.Md(1+a.Hb()|0)),a.Ga(p(v(u),[32])),a.P().d[31&d>>5]=a.nb();else if(32768>e)2===a.Hb()&&(a.Fa(p(v(u),[32])),a.aa().d[0]=a.P(),a.Md(1+a.Hb()|0)),a.Ga(p(v(u),[32])),a.va(p(v(u),[32])),a.P().d[31&d>>5]=a.nb(),a.aa().d[31&d>>10]=a.P();else if(1048576>e)3===a.Hb()&&(a.eb(p(v(u),[32])),a.Aa().d[0]=a.aa(),a.Md(1+a.Hb()|0)),a.Ga(p(v(u),[32])),a.va(p(v(u),[32])),a.Fa(p(v(u),[32])),
+a.P().d[31&d>>5]=a.nb(),a.aa().d[31&d>>10]=a.P(),a.Aa().d[31&d>>15]=a.aa();else if(33554432>e)4===a.Hb()&&(a.vc(p(v(u),[32])),a.Ra().d[0]=a.Aa(),a.Md(1+a.Hb()|0)),a.Ga(p(v(u),[32])),a.va(p(v(u),[32])),a.Fa(p(v(u),[32])),a.eb(p(v(u),[32])),a.P().d[31&d>>5]=a.nb(),a.aa().d[31&d>>10]=a.P(),a.Aa().d[31&d>>15]=a.aa(),a.Ra().d[31&d>>20]=a.Aa();else if(1073741824>e)5===a.Hb()&&(a.Df(p(v(u),[32])),a.Ic().d[0]=a.Ra(),a.Md(1+a.Hb()|0)),a.Ga(p(v(u),[32])),a.va(p(v(u),[32])),a.Fa(p(v(u),[32])),a.eb(p(v(u),[32])),
+a.vc(p(v(u),[32])),a.P().d[31&d>>5]=a.nb(),a.aa().d[31&d>>10]=a.P(),a.Aa().d[31&d>>15]=a.aa(),a.Ra().d[31&d>>20]=a.Aa(),a.Ic().d[31&d>>25]=a.Ra();else throw(new Cb).b();a.Rh=d;a.Hg=0}a.Zh.d[a.Hg]=b;a.Hg=1+a.Hg|0;return a}l.pa=function(){var a;a=this.Rh+this.Hg|0;if(0===a)a=uc().Fh;else{var b=(new Vs).k(0,a,0);pl(b,this,this.Yh);1<this.Yh&&ql(b,0,-1+a|0);a=b}return a};l.va=da("zm");l.hd=function(a,b){Ul(this,a,b)};l.vc=da("Fm");l.P=c("zm");l.Ic=c("Hm");l.Da=function(a){return Us(this,a)};l.Ta=ba();
+l.Md=da("Yh");l.aa=c("Bm");l.Ga=da("Zh");l.Ka=function(a){return lk(this,a)};l.eb=da("Dm");l.a=new s({QC:0},!1,"scala.collection.immutable.VectorBuilder",{QC:1,c:1,Vb:1,Ub:1,Tb:1,Qo:1});function vl(){this.Xm=this.ue=null}vl.prototype=new t;function ul(a,b,d){a.Xm=d;a.ue=b;return a}l=vl.prototype;l.K=function(a){return null!==a&&(a===this||a===this.ue||ya(a,this.ue))};l.tb=function(a){this.ue.Da(a);return this};l.o=function(){return""+this.ue};l.pa=function(){return this.Xm.l(this.ue.pa())};
+l.hd=function(a,b){this.ue.hd(a,b)};l.Da=function(a){this.ue.Da(a);return this};l.M=function(){return this.ue.M()};l.Ta=function(a){this.ue.Ta(a)};l.Ka=function(a){this.ue.Ka(a);return this};l.a=new s({fD:0},!1,"scala.collection.mutable.Builder$$anon$1",{fD:1,c:1,Vb:1,Ub:1,Tb:1,ZH:1});function Ws(){this.Kc=0;this.ja=null}Ws.prototype=new Zq;Ws.prototype.wa=function(){return this.Ca()?(this.Kc=1+this.Kc|0,this.ja.Nb.d[-1+this.Kc|0]===dm()?null:this.ja.Nb.d[-1+this.Kc|0]):$g().Cc.wa()};
+function Xs(a){var b=new Ws;if(null===a)throw G(H(),null);b.ja=a;b.Kc=0;return b}Ws.prototype.Ca=function(){for(;this.Kc<this.ja.Nb.d.length&&null===this.ja.Nb.d[this.Kc];)this.Kc=1+this.Kc|0;return this.Kc<this.ja.Nb.d.length};Ws.prototype.a=new s({hD:0},!1,"scala.collection.mutable.FlatHashTable$$anon$1",{hD:1,Hd:1,c:1,ed:1,H:1,G:1});function Ys(){this.N=null}Ys.prototype=new Un;Ys.prototype.na=function(){return(new Dj).b()};
+Ys.prototype.a=new s({oD:0},!1,"scala.collection.mutable.Iterable$",{oD:1,xd:1,yc:1,c:1,yd:1,zc:1});var Zs=void 0;function $s(){this.Xh=null}$s.prototype=new Zq;$s.prototype.wa=function(){if(this.Ca()){var a=this.Xh.u();this.Xh=this.Xh.s();return a}throw(new uj).h("next on empty Iterator");};$s.prototype.Ca=function(){return this.Xh!==x()};$s.prototype.a=new s({qD:0},!1,"scala.collection.mutable.ListBuffer$$anon$1",{qD:1,Hd:1,c:1,ed:1,H:1,G:1});function Gr(){this.um=this.Uh=0;this.Vp=null}
+Gr.prototype=new Zq;Gr.prototype.wa=function(){var a=this.Vp.ib(this.Uh);this.Uh=1+this.Uh|0;return a};function Fr(a,b){a.Vp=b;a.Uh=0;a.um=b.hb();return a}Gr.prototype.Ca=function(){return this.Uh<this.um};Gr.prototype.a=new s({fE:0},!1,"scala.runtime.ScalaRunTime$$anon$1",{fE:1,Hd:1,c:1,ed:1,H:1,G:1});function at(){this.Xn=null;this.dt=!1;this.oH=this.$t=null;this.cH=this.Su=this.Yv=this.cu=!1}at.prototype=new Gq;function bt(){}bt.prototype=at.prototype;
+at.prototype.Vj=function(a){a=null===a?"null":ka(a);ct(this,null===a?"null":a);return this};function Ci(a){Zo||(Zo=(new Yo).b());var b=Zo.Yn.wh.Wc();ct(b,Bj(Ba(),a));ct(b,"\n")}at.prototype.Jv=function(a,b,d){this.dt=b;this.$t=d;Fq.prototype.yk.call(this,a);this.Su=this.Yv=this.cu=!1;return this};at.prototype.Uj=function(a){Ba();a=m.String.fromCharCode(a);ct(this,a);return this};at.prototype.yk=function(a){at.prototype.Jv.call(this,a,!1,null);return this};function Cr(){this.Za=null}Cr.prototype=new t;
+l=Cr.prototype;l.jb=h("RawFrag");l.hb=h(1);l.K=function(a){return this===a?!0:a&&a.a&&a.a.t.Ll?this.Za===a.Za:!1};l.ib=function(a){switch(a){case 0:return this.Za;default:throw(new Rg).h(""+a);}};l.o=function(){return hn(U(),this)};l.ug=function(a){a.insertAdjacentHTML("beforeend",this.Za)};l.je=function(a){this.ug(a)};l.h=function(a){this.Za=a;return this};l.M=function(){return vi(this)};l.qb=function(){return Fr(new Gr,this)};
+l.a=new s({Ll:0},!1,"scalatags.JsDom$RawFrag",{Ll:1,c:1,tf:1,xa:1,n:1,g:1,e:1});function kd(){this.pe=this.iu=this.mE=this.tu=this.xx=this.sz=this.fz=this.Tw=this.nt=this.mt=this.Dz=this.Ez=this.Fz=this.ox=this.qx=this.Sw=this.aB=this.WE=this.NE=this.Ed=this.Ts=this.uu=this.uz=this.hx=this.Xs=this.bt=this.at=this.Cx=this.yD=this.Fx=this.xj=this.sl=null}kd.prototype=new t;
+kd.prototype.b=function(){jd=this;this.sl=D(F(this,"title"));this.xj=D(F(this,"style"));this.Fx=D(F(this,"noscript"));this.yD=D(F(this,"section"));this.Cx=D(F(this,"nav"));this.at=D(F(this,"article"));this.bt=D(F(this,"aside"));this.Xs=D(F(this,"address"));this.hx=D(F(this,"main"));this.uz=D(F(this,"q"));this.uu=D(F(this,"dfn"));this.Ts=D(F(this,"abbr"));this.Ed=D(F(this,"data"));this.NE=D(F(this,"time"));this.WE=D(F(this,"var"));this.aB=D(F(this,"samp"));this.Sw=D(F(this,"kbd"));this.qx=D(F(this,
+"math"));this.ox=D(F(this,"mark"));this.Fz=D(F(this,"ruby"));this.Ez=D(F(this,"rt"));this.Dz=D(F(this,"rp"));this.mt=D(F(this,"bdi"));this.nt=D(F(this,"bdo"));this.Tw=zb(F(this,"keygen"));this.fz=D(F(this,"output"));this.sz=D(F(this,"progress"));this.xx=D(F(this,"meter"));this.tu=D(F(this,"details"));this.mE=D(F(this,"summary"));this.iu=zb(F(this,"command"));this.pe=D(F(this,"menu"));return this};kd.prototype.a=new s({Jq:0},!1,"scalatags.JsDom$tags2$",{Jq:1,c:1,zq:1,pr:1,Nq:1,hG:1,dG:1});var jd=void 0;
+function Ec(){this.Vc=this.Za=this.Ae=null}Ec.prototype=new t;l=Ec.prototype;l.jb=h("AttrPair");l.hb=h(3);l.K=function(a){if(this===a)return!0;if(a&&a.a&&a.a.t.Pl){var b=this.Ae,d=a.Ae;return(null===b?null===d:b.K(d))&&O(P(),this.Za,a.Za)?this.Vc===a.Vc:!1}return!1};l.ib=function(a){switch(a){case 0:return this.Ae;case 1:return this.Za;case 2:return this.Vc;default:throw(new Rg).h(""+a);}};function Dc(a,b,d,e){a.Ae=b;a.Za=d;a.Vc=e;return a}l.o=function(){return hn(U(),this)};
+l.je=function(a){this.Vc.mm(a,this.Ae,this.Za)};l.M=function(){return vi(this)};l.qb=function(){return Fr(new Gr,this)};l.a=new s({Pl:0},!1,"scalatags.generic.AttrPair",{Pl:1,c:1,tf:1,xa:1,n:1,g:1,e:1});function dt(){E.call(this);this.W=this.Ld=null}dt.prototype=new Jr;dt.prototype.Ea=function(a,b,d){if(null===a)throw G(H(),null);this.W=a;E.prototype.ia.call(this,b,d);a=(new z).b();this.Ld=A(new B,this,"auto",a);return this};
+dt.prototype.a=new s({Tq:0},!1,"scalatags.generic.StyleMisc$AutoStyle",{Tq:1,cc:1,c:1,xa:1,n:1,g:1,e:1});function et(){E.call(this);this.W=null}et.prototype=new Jr;et.prototype.Ea=function(a,b,d){if(null===a)throw G(H(),null);this.W=a;E.prototype.ia.call(this,b,d);return this};et.prototype.a=new s({Uq:0},!1,"scalatags.generic.StyleMisc$BorderRadius",{Uq:1,cc:1,c:1,xa:1,n:1,g:1,e:1});function ft(){E.call(this);this.W=this.LE=this.Kk=this.ME=null}ft.prototype=new Jr;
+ft.prototype.Ea=function(a,b,d){if(null===a)throw G(H(),null);this.W=a;E.prototype.ia.call(this,b,d);a=(new z).b();this.ME=A(new B,this,"thin",a);a=(new z).b();this.Kk=A(new B,this,"medium",a);a=(new z).b();this.LE=A(new B,this,"thick",a);return this};ft.prototype.a=new s({Wq:0},!1,"scalatags.generic.StyleMisc$BorderWidth",{Wq:1,cc:1,c:1,xa:1,n:1,g:1,e:1});function gt(){E.call(this);this.W=this.mu=null}gt.prototype=new Jr;function ht(){}ht.prototype=gt.prototype;
+gt.prototype.Ea=function(a,b,d){if(null===a)throw G(H(),null);this.W=a;E.prototype.ia.call(this,b,d);this.mu=(new V).ha(this,"currentColor");return this};function it(){E.call(this);this.W=null}it.prototype=new Jr;it.prototype.Ea=function(a,b,d){if(null===a)throw G(H(),null);this.W=a;E.prototype.ia.call(this,b,d);return this};it.prototype.a=new s({Xq:0},!1,"scalatags.generic.StyleMisc$MultiImageStyle",{Xq:1,cc:1,c:1,xa:1,n:1,g:1,e:1});function jt(){E.call(this);this.W=this.ag=null}jt.prototype=new Jr;
+jt.prototype.Ea=function(a,b,d){if(null===a)throw G(H(),null);this.W=a;E.prototype.ia.call(this,b,d);a=(new z).b();this.ag=A(new B,this,"none",a);return this};jt.prototype.a=new s({Yq:0},!1,"scalatags.generic.StyleMisc$NoneOpenStyle",{Yq:1,cc:1,c:1,xa:1,n:1,g:1,e:1});function kt(){E.call(this);this.W=this.li=null}kt.prototype=new Jr;kt.prototype.Ea=function(a,b,d){if(null===a)throw G(H(),null);this.W=a;E.prototype.ia.call(this,b,d);a=(new z).b();this.li=A(new B,this,"normal",a);return this};
+kt.prototype.a=new s({Zq:0},!1,"scalatags.generic.StyleMisc$NormalOpenStyle",{Zq:1,cc:1,c:1,xa:1,n:1,g:1,e:1});function lt(){E.call(this);this.W=this.gz=this.Vv=this.zz=this.rv=this.zu=this.VD=this.nu=this.yu=null}lt.prototype=new Jr;function mt(){}mt.prototype=lt.prototype;
+lt.prototype.Ea=function(a,b,d){if(null===a)throw G(H(),null);this.W=a;E.prototype.ia.call(this,b,d);a=(new z).b();this.yu=A(new B,this,"dotted",a);a=(new z).b();this.nu=A(new B,this,"dashed",a);a=(new z).b();this.VD=A(new B,this,"solid",a);a=(new z).b();this.zu=A(new B,this,"double",a);a=(new z).b();this.rv=A(new B,this,"groove",a);a=(new z).b();this.zz=A(new B,this,"ridge",a);a=(new z).b();this.Vv=A(new B,this,"inset",a);a=(new z).b();this.gz=A(new B,this,"outset",a);return this};
+lt.prototype.a=new s({Rl:0},!1,"scalatags.generic.StyleMisc$OutlineStyle",{Rl:1,cc:1,c:1,xa:1,n:1,g:1,e:1});function nt(){E.call(this);this.W=this.Ld=this.yp=this.jn=this.YE=null}nt.prototype=new Jr;function ot(){}ot.prototype=nt.prototype;
+nt.prototype.Ea=function(a,b,d){if(null===a)throw G(H(),null);this.W=a;E.prototype.ia.call(this,b,d);a=(new z).b();this.YE=A(new B,this,"visible",a);a=(new z).b();this.jn=A(new B,this,"hidden",a);a=(new z).b();this.yp=A(new B,this,"scroll",a);a=(new z).b();this.Ld=A(new B,this,"auto",a);return this};nt.prototype.a=new s({Sl:0},!1,"scalatags.generic.StyleMisc$Overflow",{Sl:1,cc:1,c:1,xa:1,n:1,g:1,e:1});function pt(){Hr.call(this);this.W=this.Ld=null}pt.prototype=new Ir;
+pt.prototype.Ea=function(a,b,d){if(null===a)throw G(H(),null);this.W=a;Hr.prototype.ia.call(this,b,d);this.Ld=(new wb).$d((new z).b()).Cb(this.Eb,"auto");return this};pt.prototype.a=new s({$q:0},!1,"scalatags.generic.StyleMisc$PixelAutoStyle",{$q:1,qg:1,c:1,xa:1,n:1,g:1,e:1});function B(){this.Vc=this.Za=this.yb=null}B.prototype=new t;l=B.prototype;l.jb=h("StylePair");l.hb=h(3);
+l.K=function(a){if(this===a)return!0;if(a&&a.a&&a.a.t.Tl){var b=this.yb,d=a.yb;return(null===b?null===d:b.K(d))&&O(P(),this.Za,a.Za)?this.Vc===a.Vc:!1}return!1};l.ib=function(a){switch(a){case 0:return this.yb;case 1:return this.Za;case 2:return this.Vc;default:throw(new Rg).h(""+a);}};l.o=function(){return hn(U(),this)};l.je=function(a){a.style.setProperty(this.yb.ke,ka(this.Za))};l.M=function(){return vi(this)};l.qb=function(){return Fr(new Gr,this)};
+function A(a,b,d,e){a.yb=b;a.Za=d;a.Vc=e;return a}l.a=new s({Tl:0},!1,"scalatags.generic.StylePair",{Tl:1,c:1,tf:1,xa:1,n:1,g:1,e:1});function qt(){E.call(this);this.ja=this.Rv=this.Xu=this.zE=this.yE=this.xE=this.wE=this.vE=this.uE=this.tE=this.sE=this.rE=this.Sv=this.Qv=this.cx=this.Gi=this.Pv=this.ag=null}qt.prototype=new Jr;
+qt.prototype.xb=function(a){if(null===a)throw G(H(),null);this.ja=a;E.prototype.ia.call(this,"display","display");a=(new z).b();this.ag=A(new B,this,"none",a);a=(new z).b();this.Pv=A(new B,this,"inline",a);a=(new z).b();this.Gi=A(new B,this,"block",a);a=(new z).b();this.cx=A(new B,this,"list-item",a);a=(new z).b();this.Qv=A(new B,this,"inline-block",a);a=(new z).b();this.Sv=A(new B,this,"inline-table",a);a=(new z).b();this.rE=A(new B,this,"table",a);a=(new z).b();this.sE=A(new B,this,"table-caption",
+a);a=(new z).b();this.tE=A(new B,this,"table-cell",a);a=(new z).b();this.uE=A(new B,this,"table-column",a);a=(new z).b();this.vE=A(new B,this,"table-column-group",a);a=(new z).b();this.wE=A(new B,this,"table-footer-group",a);a=(new z).b();this.xE=A(new B,this,"table-header-group",a);a=(new z).b();this.yE=A(new B,this,"table-row",a);a=(new z).b();this.zE=A(new B,this,"table-row-group",a);a=(new z).b();this.Xu=A(new B,this,"flex",a);a=(new z).b();this.Rv=A(new B,this,"inline-flex",a);return this};
+qt.prototype.a=new s({hr:0},!1,"scalatags.generic.Styles$display$",{hr:1,cc:1,c:1,xa:1,n:1,g:1,e:1});function Td(){E.call(this);this.ja=this.UD=this.Xw=this.fF=this.cF=this.Ww=this.Kk=this.TD=this.dF=this.gF=null}Td.prototype=new Jr;
+Td.prototype.xb=function(a){if(null===a)throw G(H(),null);this.ja=a;E.prototype.ia.call(this,"fontSize","font-size");a=(new z).b();this.gF=A(new B,this,"xx-small",a);a=(new z).b();this.dF=A(new B,this,"x-small",a);a=(new z).b();this.TD=A(new B,this,"small",a);a=(new z).b();this.Kk=A(new B,this,"medium",a);a=(new z).b();this.Ww=A(new B,this,"large",a);a=(new z).b();this.cF=A(new B,this,"x-large",a);a=(new z).b();this.fF=A(new B,this,"xx-large",a);a=(new z).b();this.Xw=A(new B,this,"larger",a);a=(new z).b();
+this.UD=A(new B,this,"smaller",a);return this};Td.prototype.a=new s({ir:0},!1,"scalatags.generic.Styles$fontSize$",{ir:1,cc:1,c:1,xa:1,n:1,g:1,e:1});function rt(){E.call(this);this.ja=this.Hx=this.Dk=this.li=null}rt.prototype=new Jr;rt.prototype.xb=function(a){if(null===a)throw G(H(),null);this.ja=a;E.prototype.ia.call(this,"fontStyle","font-style");a=(new z).b();this.li=A(new B,this,"normal",a);a=(new z).b();this.Dk=A(new B,this,"italic",a);a=(new z).b();this.Hx=A(new B,this,"oblique",a);return this};
+rt.prototype.a=new s({jr:0},!1,"scalatags.generic.Styles$fontStyle$",{jr:1,cc:1,c:1,xa:1,n:1,g:1,e:1});function st(){Hr.call(this);this.ja=this.Ld=null}st.prototype=new Ir;st.prototype.xb=function(a){if(null===a)throw G(H(),null);this.ja=a;Hr.prototype.ia.call(this,"margin","margin");this.Ld=(new wb).$d((new z).b()).Cb(this.Eb,"auto");return this};st.prototype.a=new s({kr:0},!1,"scalatags.generic.Styles$margin$",{kr:1,qg:1,c:1,xa:1,n:1,g:1,e:1});
+function tt(){E.call(this);this.ja=this.$m=this.km=this.jo=this.iE=null}tt.prototype=new Jr;tt.prototype.xb=function(a){if(null===a)throw G(H(),null);this.ja=a;E.prototype.ia.call(this,"position","position");a=(new z).b();this.iE=A(new B,this,"static",a);a=(new z).b();this.jo=A(new B,this,"relative",a);a=(new z).b();this.km=A(new B,this,"absolute",a);a=(new z).b();this.$m=A(new B,this,"fixed",a);return this};
+tt.prototype.a=new s({mr:0},!1,"scalatags.generic.Styles$position$",{mr:1,cc:1,c:1,xa:1,n:1,g:1,e:1});function ut(){E.call(this);this.ja=this.bx=this.jz=this.VE=this.ag=null}ut.prototype=new Jr;
+ut.prototype.xb=function(a){if(null===a)throw G(H(),null);this.ja=a;E.prototype.ia.call(this,"textDecoration","text-decoration");a=(new z).b();this.ag=A(new B,this,"none",a);a=(new z).b();this.VE=A(new B,this,"underline",a);a=(new z).b();this.jz=A(new B,this,"overline",a);a=(new z).b();this.bx=A(new B,this,"line-through",a);return this};ut.prototype.a=new s({nr:0},!1,"scalatags.generic.Styles$textDecoration$",{nr:1,cc:1,c:1,xa:1,n:1,g:1,e:1});
+function ce(){E.call(this);this.ja=this.pz=this.qz=this.oz=this.Sn=this.li=null}ce.prototype=new Jr;ce.prototype.xb=function(a){if(null===a)throw G(H(),null);this.ja=a;E.prototype.ia.call(this,"whiteSpace","white-space");a=(new z).b();this.li=A(new B,this,"normal",a);a=(new z).b();this.Sn=A(new B,this,"nowrap",a);a=(new z).b();this.oz=A(new B,this,"pre",a);a=(new z).b();this.qz=A(new B,this,"pre-wrap",a);a=(new z).b();this.pz=A(new B,this,"pre-line",a);return this};
+ce.prototype.a=new s({or:0},!1,"scalatags.generic.Styles$whiteSpace$",{or:1,cc:1,c:1,xa:1,n:1,g:1,e:1});function vt(){this.Tm=this.Qm=this.ja=null}vt.prototype=new Eq;l=vt.prototype;l.bb=function(a,b){if(Tr(a)){var d=null===a?null:a.j;if(null!==d&&0===d.pb(2)){var e=d.ma(0),d=d.ma(1),e=yc(this.Qm).l(e);return(new V).ha(e,yc(this.Tm).l(d))}}return b.l(a)};l.Va=function(a){return this.cb(a)};l.Bb=function(a,b){return this.bb(a,b)};
+l.cb=function(a){return Tr(a)&&(a=null===a?null:a.j,null!==a&&0===a.pb(2))?!0:!1};function wt(a,b,d){var e=new vt;if(null===a)throw G(H(),null);e.ja=a;e.Qm=b;e.Tm=d;return e}l.a=new s({Jr:0},!1,"upickle.Generated$$anonfun$Tuple2R$1",{Jr:1,id:1,c:1,x:1,la:1,g:1,e:1});function oe(){this.Sm=this.Rm=this.Ym=this.ja=null}oe.prototype=new Eq;l=oe.prototype;l.bb=function(a){var b=yg(this.Ym),d=this.ja,e=this.Rm,f=this.Sm;ne().sg;d=d.ye("Array(2)",wt(d,e,f));return b.l(yc((new qe).Fe(d)).l(a))};l.Va=function(a){return this.cb(a)};
+l.Bb=function(a,b){return this.bb(a,b)};l.cb=h(!0);l.a=new s({Kr:0},!1,"upickle.GeneratedInternal$$anonfun$Case2R$1",{Kr:1,id:1,c:1,x:1,la:1,g:1,e:1});function xt(){this.go=this.xm=this.Pn=this.ja=null}xt.prototype=new Eq;function pe(a,b,d,e){var f=new xt;if(null===a)throw G(H(),null);f.ja=a;f.Pn=b;f.xm=d;f.go=e;return f}l=xt.prototype;l.bb=function(a,b){return $r(a)?this.go.l((new zf).La(re(null===a?null:a.j,this.Pn,this.xm))):b.l(a)};l.Va=function(a){return this.cb(a)};
+l.Bb=function(a,b){return this.bb(a,b)};l.cb=function(a){return $r(a)};l.a=new s({Mr:0},!1,"upickle.GeneratedUtil$$anonfun$readerCaseFunction$1",{Mr:1,id:1,c:1,x:1,la:1,g:1,e:1});function Pe(){}Pe.prototype=new Eq;l=Pe.prototype;l.bb=function(a,b){if(ds(a)){var d=null===a?null:a.j;Xq||(Xq=(new Wq).b());return Ag.prototype.Xj.call(Xq,d)}return b.l(a)};l.Pd=function(){return this};l.Va=function(a){return this.cb(a)};l.Bb=function(a,b){return this.bb(a,b)};l.cb=function(a){return ds(a)};
+l.a=new s({Nr:0},!1,"upickle.Implicits$$anonfun$10",{Nr:1,id:1,c:1,x:1,la:1,g:1,e:1});function qf(){}qf.prototype=new Eq;l=qf.prototype;l.bb=function(a,b){if(ds(a)){var d=null===a?null:a.j;nf();var d=(new mb).h(d),e=ff();return Gp(ef(e,d.f,10))}return b.l(a)};l.Pd=function(){return this};l.Va=function(a){return this.cb(a)};l.Bb=function(a,b){return this.bb(a,b)};l.cb=function(a){return ds(a)};l.a=new s({Or:0},!1,"upickle.Implicits$$anonfun$4",{Or:1,id:1,c:1,x:1,la:1,g:1,e:1});function Ge(){}
+Ge.prototype=new Eq;l=Ge.prototype;l.bb=function(){Ac();throw(new Rq).b();};l.Pd=function(){return this};l.Va=function(a){return this.cb(a)};l.Bb=function(a,b){return this.bb(a,b)};l.cb=h(!0);l.a=new s({Pr:0},!1,"upickle.Implicits$$anonfun$5",{Pr:1,id:1,c:1,x:1,la:1,g:1,e:1});function Me(){}Me.prototype=new Eq;l=Me.prototype;l.bb=ba();l.Pd=function(){return this};l.Va=function(a){return this.cb(a)};l.Bb=function(a,b){return this.bb(a,b)};l.cb=h(!0);
+l.a=new s({Qr:0},!1,"upickle.Implicits$$anonfun$6",{Qr:1,id:1,c:1,x:1,la:1,g:1,e:1});function pf(){}pf.prototype=new Eq;l=pf.prototype;l.bb=function(a,b){var d=!1,e=null;return ds(a)&&(d=!0,e=null===a?null:a.j,"inf"===e)?nf().Jj:d&&"-inf"===e?nf().Qj:d&&"undef"===e?nf().Sj:b.l(a)};l.Pd=function(){return this};l.Va=function(a){return this.cb(a)};l.Bb=function(a,b){return this.bb(a,b)};
+l.cb=function(a){var b=!1,d=null;return ds(a)&&(b=!0,d=null===a?null:a.j,"inf"===d)?!0:b&&"-inf"===d||b&&"undef"===d?!0:!1};l.a=new s({Rr:0},!1,"upickle.Implicits$$anonfun$7",{Rr:1,id:1,c:1,x:1,la:1,g:1,e:1});function Je(){}Je.prototype=new Eq;l=Je.prototype;l.bb=function(a,b){return Ke()===a?!0:Le()===a?!1:b.l(a)};l.Pd=function(){return this};l.Va=function(a){return this.cb(a)};l.Bb=function(a,b){return this.bb(a,b)};l.cb=function(a){return Ke()===a?!0:Le()===a};
+l.a=new s({Sr:0},!1,"upickle.Implicits$$anonfun$8",{Sr:1,id:1,c:1,x:1,la:1,g:1,e:1});function Ne(){}Ne.prototype=new Eq;l=Ne.prototype;l.bb=function(a,b){return ds(a)?null===a?null:a.j:b.l(a)};l.Pd=function(){return this};l.Va=function(a){return this.cb(a)};l.Bb=function(a,b){return this.bb(a,b)};l.cb=function(a){return ds(a)};l.a=new s({Tr:0},!1,"upickle.Implicits$$anonfun$9",{Tr:1,id:1,c:1,x:1,la:1,g:1,e:1});function yt(){this.sm=this.Um=this.ja=null}yt.prototype=new Eq;l=yt.prototype;
+l.bb=function(a,b){if(Tr(a)){var d=null===a?null:a.j,e=M(function(a){return function(b){return yc(a.Um).l(b)}}(this)),f=bc(),d=d.oe(e,f.N);return Kj(d,this.sm)}return b.l(a)};function sf(a,b,d){var e=new yt;if(null===a)throw G(H(),null);e.ja=a;e.Um=b;e.sm=d;return e}l.Va=function(a){return this.cb(a)};l.Bb=function(a,b){return this.bb(a,b)};l.cb=function(a){return Tr(a)};l.a=new s({Ur:0},!1,"upickle.Implicits$$anonfun$SeqishR$1",{Ur:1,id:1,c:1,x:1,la:1,g:1,e:1});
+function zt(){this.dn=this.cn=null}zt.prototype=new Eq;l=zt.prototype;l.bb=function(a,b){if(At(a)){var d=a.j;try{return this.cn.l(d)}catch(e){if(Wf(e))throw se(new te,Ae(new Be,d),"Number");throw e;}}else if(ds(a)){d=null===a?null:a.j;try{return this.dn.l(d)}catch(f){if(Wf(f))throw se(new te,(new ze).h(d),"Number");throw f;}}else return b.l(a)};function Ce(a,b){var d=new zt;d.cn=a;d.dn=b;return d}l.Va=function(a){return this.cb(a)};l.Bb=function(a,b){return this.bb(a,b)};
+l.cb=function(a){return At(a)||ds(a)};l.a=new s({Vr:0},!1,"upickle.Implicits$$anonfun$upickle$Implicits$$numericReaderFunc$1",{Vr:1,id:1,c:1,x:1,la:1,g:1,e:1});function Bt(){this.bn=null}Bt.prototype=new Eq;l=Bt.prototype;l.bb=function(a,b){return ds(a)?this.bn.l(null===a?null:a.j):b.l(a)};l.Va=function(a){return this.cb(a)};l.Bb=function(a,b){return this.bb(a,b)};function rf(a){var b=new Bt;b.bn=a;return b}l.cb=function(a){return ds(a)};
+l.a=new s({Wr:0},!1,"upickle.Implicits$$anonfun$upickle$Implicits$$numericStringReaderFunc$1",{Wr:1,id:1,c:1,x:1,la:1,g:1,e:1});function Qr(){this.Nn=null}Qr.prototype=new Eq;l=Qr.prototype;l.bb=function(a){throw se(new te,a,this.Nn);};l.Va=function(a){return this.cb(a)};l.h=function(a){this.Nn=a;return this};l.Bb=function(a,b){return this.bb(a,b)};l.cb=h(!0);l.a=new s({Yr:0},!1,"upickle.Internal$$anonfun$validate$1",{Yr:1,id:1,c:1,x:1,la:1,g:1,e:1});function Rr(){this.On=null}Rr.prototype=new Eq;
+l=Rr.prototype;l.bb=function(a){throw se(new te,a,this.On);};l.Va=function(a){return this.cb(a)};l.h=function(a){this.On=a;return this};l.Bb=function(a,b){return this.bb(a,b)};l.cb=h(!0);l.a=new s({Zr:0},!1,"upickle.Internal$$anonfun$validateReader$1",{Zr:1,id:1,c:1,x:1,la:1,g:1,e:1});function zf(){this.j=null}zf.prototype=new t;l=zf.prototype;l.jb=function(){this.j;return"Arr"};l.hb=function(){this.j;return 1};l.K=function(a){return Vr().ok(this.j,a)};l.ib=function(a){return Vr().Pk(this.j,a)};
+l.o=function(){return Vr().tl(this.j)};l.La=function(a){this.j=a;return this};l.M=function(){return this.j.M()};l.qb=function(){return Vr().Qk(this.j)};function Tr(a){return!!(a&&a.a&&a.a.t.$l)}l.a=new s({$l:0},!1,"upickle.Js$Arr",{$l:1,c:1,uf:1,xa:1,n:1,g:1,e:1});function Ct(){}Ct.prototype=new t;l=Ct.prototype;l.b=function(){Dt=this;return this};l.jb=h("False");l.hb=h(0);l.ib=function(a){throw(new Rg).h(""+a);};l.o=h("False");l.M=h(67643651);l.qb=function(){return Fr(new Gr,this)};
+l.a=new s({as:0},!1,"upickle.Js$False$",{as:1,c:1,uf:1,xa:1,n:1,g:1,e:1});var Dt=void 0;function Le(){Dt||(Dt=(new Ct).b());return Dt}function Et(){}Et.prototype=new t;l=Et.prototype;l.b=function(){Ft=this;return this};l.jb=h("Null");l.hb=h(0);l.ib=function(a){throw(new Rg).h(""+a);};l.o=h("Null");l.M=h(2439591);l.qb=function(){return Fr(new Gr,this)};l.a=new s({bs:0},!1,"upickle.Js$Null$",{bs:1,c:1,uf:1,xa:1,n:1,g:1,e:1});var Ft=void 0;function wf(){Ft||(Ft=(new Et).b());return Ft}
+function Be(){this.j=0}Be.prototype=new t;l=Be.prototype;l.jb=function(){this.j;return"Num"};l.hb=function(){this.j;return 1};l.K=function(a){Yr();return At(a)?this.j===a.j:!1};function Ae(a,b){a.j=b;return a}l.ib=function(a){a:switch(Yr(),a){case 0:a=this.j;break a;default:throw(new Rg).h(""+a);}return a};l.o=function(){Yr();var a=this.j;return hn(U(),Ae(new Be,a))};l.M=function(){var a=this.j;return Ca(Da(),a)};l.qb=function(){Yr();return Fr(new Gr,Ae(new Be,this.j))};
+function At(a){return!!(a&&a.a&&a.a.t.am)}l.a=new s({am:0},!1,"upickle.Js$Num",{am:1,c:1,uf:1,xa:1,n:1,g:1,e:1});function ue(){this.j=null}ue.prototype=new t;l=ue.prototype;l.jb=function(){this.j;return"Obj"};l.hb=function(){this.j;return 1};l.K=function(a){return bs().ok(this.j,a)};l.ib=function(a){return bs().Pk(this.j,a)};l.o=function(){return bs().tl(this.j)};l.La=function(a){this.j=a;return this};l.M=function(){return this.j.M()};l.qb=function(){return bs().Qk(this.j)};
+function $r(a){return!!(a&&a.a&&a.a.t.bm)}l.a=new s({bm:0},!1,"upickle.Js$Obj",{bm:1,c:1,uf:1,xa:1,n:1,g:1,e:1});function ze(){this.j=null}ze.prototype=new t;l=ze.prototype;l.jb=function(){this.j;return"Str"};l.hb=function(){this.j;return 1};l.K=function(a){return Oe().nk(this.j,a)};l.ib=function(a){a:switch(Oe(),a){case 0:a=this.j;break a;default:throw(new Rg).h(""+a);}return a};l.o=function(){Oe();var a=this.j;return hn(U(),(new ze).h(a))};l.h=function(a){this.j=a;return this};
+l.M=function(){var a=this.j;return Aa(Ba(),a)};l.qb=function(){Oe();var a=(new ze).h(this.j);return Fr(new Gr,a)};function ds(a){return!!(a&&a.a&&a.a.t.cm)}l.a=new s({cm:0},!1,"upickle.Js$Str",{cm:1,c:1,uf:1,xa:1,n:1,g:1,e:1});function Gt(){}Gt.prototype=new t;l=Gt.prototype;l.b=function(){Ht=this;return this};l.jb=h("True");l.hb=h(0);l.ib=function(a){throw(new Rg).h(""+a);};l.o=h("True");l.M=h(2615726);l.qb=function(){return Fr(new Gr,this)};
+l.a=new s({fs:0},!1,"upickle.Js$True$",{fs:1,c:1,uf:1,xa:1,n:1,g:1,e:1});var Ht=void 0;function Ke(){Ht||(Ht=(new Gt).b());return Ht}function vf(){}vf.prototype=new Eq;l=vf.prototype;l.bb=function(a,b){return wf()===a?null:b.l(a)};l.Va=function(a){return this.cb(a)};l.Bb=function(a,b){return this.bb(a,b)};l.cb=function(a){return wf()===a};l.a=new s({ls:0},!1,"upickle.Reader$$anonfun$read$1",{ls:1,id:1,c:1,x:1,la:1,g:1,e:1});function V(){this.$a=this.Ua=null}V.prototype=new t;l=V.prototype;l.jb=h("Tuple2");
+l.hb=h(2);l.K=function(a){return this===a?!0:a&&a.a&&a.a.t.hm?O(P(),this.Ua,a.Ua)&&O(P(),this.$a,a.$a):!1};l.ha=function(a,b){this.Ua=a;this.$a=b;return this};l.ib=function(a){a:switch(a){case 0:a=this.Ua;break a;case 1:a=this.$a;break a;default:throw(new Rg).h(""+a);}return a};l.o=function(){return"("+this.Ua+","+this.$a+")"};l.M=function(){return vi(this)};l.qb=function(){return Fr(new Gr,this)};l.a=new s({hm:0},!1,"scala.Tuple2",{hm:1,c:1,XH:1,xa:1,n:1,g:1,e:1});
+function Tk(){this.bh=this.ah=this.$g=this.Zg=null}Tk.prototype=new t;l=Tk.prototype;l.jb=h("Tuple4");l.hb=h(4);l.K=function(a){return this===a?!0:a&&a.a&&a.a.t.im?O(P(),this.Zg,a.Zg)&&O(P(),this.$g,a.$g)&&O(P(),this.ah,a.ah)&&O(P(),this.bh,a.bh):!1};l.ib=function(a){return Qg(this,a)};l.o=function(){return"("+this.Zg+","+this.$g+","+this.ah+","+this.bh+")"};l.gf=function(a,b,d,e){this.Zg=a;this.$g=b;this.ah=d;this.bh=e;return this};l.M=function(){return vi(this)};
+l.qb=function(){return Fr(new Gr,this)};l.a=new s({im:0},!1,"scala.Tuple4",{im:1,c:1,YH:1,xa:1,n:1,g:1,e:1});function We(){An.call(this)}We.prototype=new hs;function Wf(a){return!!(a&&a.a&&a.a.t.Cn)}We.prototype.a=new s({Cn:0},!1,"java.lang.NumberFormatException",{Cn:1,hh:1,ad:1,$c:1,dc:1,c:1,e:1});function Jo(){An.call(this)}Jo.prototype=new is;Jo.prototype.a=new s({Dw:0},!1,"java.util.FormatterClosedException",{Dw:1,Bn:1,ad:1,$c:1,dc:1,c:1,e:1});function It(){An.call(this)}It.prototype=new hs;
+function Jt(){}Jt.prototype=It.prototype;function Kt(){}Kt.prototype=new ks;l=Kt.prototype;l.jb=h("None");l.hb=h(0);l.m=h(!0);l.Wc=function(){throw(new uj).h("None.get");};l.ib=function(a){throw(new Rg).h(""+a);};l.o=h("None");l.M=h(2433880);l.qb=function(){return Fr(new Gr,this)};l.a=new s({Kz:0},!1,"scala.None$",{Kz:1,Mz:1,c:1,xa:1,n:1,g:1,e:1});var Lt=void 0;function sg(){Lt||(Lt=(new Kt).b());return Lt}function Kg(){}Kg.prototype=new Eq;Kg.prototype.Va=h(!0);Kg.prototype.Bb=function(){return Mg().rj};
+Kg.prototype.a=new s({Qz:0},!1,"scala.PartialFunction$$anonfun$4",{Qz:1,id:1,c:1,x:1,la:1,g:1,e:1});function tg(){this.ig=null}tg.prototype=new ks;l=tg.prototype;l.jb=h("Some");l.hb=h(1);l.K=function(a){return this===a?!0:Eg(a)?O(P(),this.ig,a.ig):!1};l.m=h(!1);l.ib=function(a){switch(a){case 0:return this.ig;default:throw(new Rg).h(""+a);}};l.Wc=c("ig");l.o=function(){return hn(U(),this)};l.w=function(a){this.ig=a;return this};l.M=function(){return vi(this)};l.qb=function(){return Fr(new Gr,this)};
+function Eg(a){return!!(a&&a.a&&a.a.t.mo)}l.a=new s({mo:0},!1,"scala.Some",{mo:1,Mz:1,c:1,xa:1,n:1,g:1,e:1});function ms(){An.call(this);this.Iv=0}ms.prototype=new hs;
+ms.prototype.gi=function(a,b){this.Iv=b;var d=(new Eb).La((new C).A(["invalid escape "," index ",' in "','". Use \\\\\\\\ for literal \\\\.']));Ac();if(!(0<=b&&b<(a.length|0)))throw(new Cb).h("requirement failed");if(b===(-1+(a.length|0)|0))var e="at terminal";else var e=(new Eb).La((new C).A(["'\\\\","' not one of "," at"])),f=65535&(a.charCodeAt(1+b|0)|0),e=Db(e,(new C).A([(new Re).nc(f),"[\\b, \\t, \\n, \\f, \\r, \\\\, \\\", \\']"]));Cb.prototype.h.call(this,Db(d,(new C).A([e,b,a])));return this};
+ms.prototype.a=new s({Yz:0},!1,"scala.StringContext$InvalidEscapeException",{Yz:1,hh:1,ad:1,$c:1,dc:1,c:1,e:1});function Mt(){}Mt.prototype=new os;function Nt(){}Nt.prototype=Mt.prototype;Mt.prototype.Jp=function(){throw(new Cb).h(Db((new Eb).La((new C).A([""," not allowed on infinite Durations"])),(new C).A(["toNanos"])));};function Cp(){this.jf=Sf();this.xh=null}Cp.prototype=new os;l=Cp.prototype;l.K=function(a){return a&&a.a&&a.a.t.po?bn(this.xh.xe(this.jf),a.xh.xe(a.jf)):this===a};
+l.o=function(){return""+this.jf+" "+(nf().Hp.l(this.xh)+(bn(this.jf,(new T).k(1,0,0))?"":"s"))};
+function Bp(a,b,d){a.jf=b;a.xh=d;if($().Eh===d)b=Ot(a,(new T).k(4194303,4194303,524287));else if($().Bh===d)b=Ot(a,(new T).k(2315255,1207959,524));else if($().Ch===d)b=Ot(a,(new T).k(1071862,2199023,0));else if($().Gh===d)b=Ot(a,(new T).k(97540,2199,0));else if($().Dh===d)b=Ot(a,(new T).k(2727923,36,0));else if($().Ah===d)b=Ot(a,(new T).k(2562047,0,0));else if($().pg===d)b=Ot(a,(new T).k(106751,0,0));else{b=$().pg.wg(b,d);if(d=wq(b,(new T).k(4087553,4194303,1048575)))d=(new T).k(106751,0,0),d=wq(d,
+b);b=d}if(!b)throw(new Cb).h("requirement failed: Duration is limited to +-(2^63-1)ns (ca. 292 years)");return a}function Ot(a,b){var d=Tf(b);return wq(a.jf,d)&&wq(b,a.jf)}l.M=function(){return Yl(this.xh.xe(this.jf))};l.Jp=function(){return this.xh.xe(this.jf)};l.a=new s({po:0},!1,"scala.concurrent.duration.FiniteDuration",{po:1,Uk:1,c:1,g:1,e:1,lh:1,Zc:1});function Pt(){this.N=null}Pt.prototype=new cq;function Qt(){}Qt.prototype=Pt.prototype;function Rt(){Ns.call(this)}Rt.prototype=new Os;
+Rt.prototype.en=function(a){return St(a)};Rt.prototype.a=new s({IB:0},!1,"scala.collection.immutable.HashMap$HashTrieMap$$anon$1",{IB:1,NC:1,Hd:1,c:1,ed:1,H:1,G:1});function Tt(){Ns.call(this)}Tt.prototype=new Os;Tt.prototype.en=function(a){return a.Mc};Tt.prototype.a=new s({NB:0},!1,"scala.collection.immutable.HashSet$HashTrieSet$$anon$1",{NB:1,NC:1,Hd:1,c:1,ed:1,H:1,G:1});function Ut(){}Ut.prototype=new xs;Ut.prototype.Qi=function(){return Vt()};
+Ut.prototype.a=new s({qC:0},!1,"scala.collection.immutable.Set$",{qC:1,Eo:1,dl:1,bl:1,yc:1,c:1,zc:1});var Wt=void 0;function ep(){Wt||(Wt=(new Ut).b());return Wt}function Xt(){this.mk=this.Yf=this.Af=this.lk=0;this.Oe=!1;this.gk=0;this.Im=this.Gm=this.Em=this.Cm=this.Am=this.hk=null}Xt.prototype=new Zq;l=Xt.prototype;
+l.wa=function(){if(!this.Oe)throw(new uj).h("reached iterator end");var a=this.hk.d[this.Yf];this.Yf=1+this.Yf|0;if(this.Yf===this.mk)if((this.Af+this.Yf|0)<this.lk){var b=32+this.Af|0,d=this.Af^b;if(1024>d)this.Ga(this.P().d[31&b>>5]);else if(32768>d)this.va(this.aa().d[31&b>>10]),this.Ga(this.P().d[0]);else if(1048576>d)this.Fa(this.Aa().d[31&b>>15]),this.va(this.aa().d[0]),this.Ga(this.P().d[0]);else if(33554432>d)this.eb(this.Ra().d[31&b>>20]),this.Fa(this.Aa().d[0]),this.va(this.aa().d[0]),this.Ga(this.P().d[0]);
+else if(1073741824>d)this.vc(this.Ic().d[31&b>>25]),this.eb(this.Ra().d[0]),this.Fa(this.Aa().d[0]),this.va(this.aa().d[0]),this.Ga(this.P().d[0]);else throw(new Cb).b();this.Af=b;b=this.lk-this.Af|0;this.mk=32>b?b:32;this.Yf=0}else this.Oe=!1;return a};l.Aa=c("Em");l.Hb=c("gk");l.Df=da("Im");l.nb=c("hk");l.Ra=c("Gm");l.Fa=da("Cm");l.va=da("Am");l.Ca=c("Oe");l.vc=da("Gm");l.P=c("Am");l.Ic=c("Im");l.Md=da("gk");l.aa=c("Cm");l.Ga=da("hk");l.eb=da("Em");
+l.a=new s({RC:0},!1,"scala.collection.immutable.VectorIterator",{RC:1,Hd:1,c:1,ed:1,H:1,G:1,Qo:1});function Yt(){}Yt.prototype=new t;function Zt(){}Zt.prototype=Yt.prototype;Yt.prototype.hd=function(a,b){Ul(this,a,b)};function $t(){lt.call(this);this.Av=this.Ex=null}$t.prototype=new mt;$t.prototype.Ea=function(a,b,d){lt.prototype.Ea.call(this,a,b,d);a=(new z).b();this.Ex=A(new B,this,"none",a);a=(new z).b();this.Av=A(new B,this,"hidden",a);return this};
+$t.prototype.a=new s({Vq:0},!1,"scalatags.generic.StyleMisc$BorderStyle",{Vq:1,Rl:1,cc:1,c:1,xa:1,n:1,g:1,e:1});function au(){Hr.call(this);this.Ld=this.ja=null}au.prototype=new Ir;au.prototype.al=da("Ld");au.prototype.xb=function(a){if(null===a)throw G(H(),null);this.ja=a;Hr.prototype.ia.call(this,"marginRight","margin-right");vb(this);return this};au.prototype.a=new s({ar:0},!1,"scalatags.generic.Styles$$anon$1",{ar:1,qg:1,c:1,xa:1,n:1,g:1,e:1,Ql:1});
+function bu(){Hr.call(this);this.Ld=this.ja=null}bu.prototype=new Ir;bu.prototype.al=da("Ld");bu.prototype.xb=function(a){if(null===a)throw G(H(),null);this.ja=a;Hr.prototype.ia.call(this,"marginTop","margin-top");vb(this);return this};bu.prototype.a=new s({br:0},!1,"scalatags.generic.Styles$$anon$2",{br:1,qg:1,c:1,xa:1,n:1,g:1,e:1,Ql:1});function cu(){Hr.call(this);this.Ld=this.ja=null}cu.prototype=new Ir;cu.prototype.al=da("Ld");
+cu.prototype.xb=function(a){if(null===a)throw G(H(),null);this.ja=a;Hr.prototype.ia.call(this,"marginLeft","margin-left");vb(this);return this};cu.prototype.a=new s({cr:0},!1,"scalatags.generic.Styles$$anon$3",{cr:1,qg:1,c:1,xa:1,n:1,g:1,e:1,Ql:1});function du(){E.call(this);this.Ek=this.dk=this.lj=this.Ik=this.zg=this.nl=this.ja=null}du.prototype=new Jr;l=du.prototype;l.Co=da("nl");l.zo=da("Ek");l.xo=da("dk");l.Ao=da("Ik");l.Bo=da("lj");l.yo=da("zg");
+l.xb=function(a){if(null===a)throw G(H(),null);this.ja=a;E.prototype.ia.call(this,"textAlignLast","text-align-last");xb(this);return this};l.a=new s({dr:0},!1,"scalatags.generic.Styles$$anon$4",{dr:1,cc:1,c:1,xa:1,n:1,g:1,e:1,fr:1});function eu(){E.call(this);this.Ek=this.dk=this.lj=this.Ik=this.zg=this.nl=this.ja=null}eu.prototype=new Jr;l=eu.prototype;l.Co=da("nl");l.zo=da("Ek");l.xo=da("dk");l.Ao=da("Ik");l.Bo=da("lj");l.yo=da("zg");
+l.xb=function(a){if(null===a)throw G(H(),null);this.ja=a;E.prototype.ia.call(this,"textAlign","text-align");xb(this);return this};l.a=new s({er:0},!1,"scalatags.generic.Styles$$anon$5",{er:1,cc:1,c:1,xa:1,n:1,g:1,e:1,fr:1});function fu(){gt.call(this);this.Zs=this.DE=this.qt=this.Dx=this.hF=this.Jx=this.ax=this.qv=this.nv=this.tz=this.wz=this.px=this.$E=this.pv=this.DD=this.ot=null}fu.prototype=new ht;
+fu.prototype.xb=function(a){gt.prototype.Ea.call(this,a,"color","color");a=(new z).b();this.ot=A(new B,this,"black",a);a=(new z).b();this.DD=A(new B,this,"silver",a);a=(new z).b();this.pv=A(new B,this,"gray",a);a=(new z).b();this.$E=A(new B,this,"white",a);a=(new z).b();this.px=A(new B,this,"maroon",a);a=(new z).b();this.wz=A(new B,this,"red",a);a=(new z).b();this.tz=A(new B,this,"purple",a);a=(new z).b();this.nv=A(new B,this,"fuschia",a);a=(new z).b();this.qv=A(new B,this,"green",a);a=(new z).b();
+this.ax=A(new B,this,"lime",a);a=(new z).b();this.Jx=A(new B,this,"olive",a);a=(new z).b();this.hF=A(new B,this,"yellow",a);a=(new z).b();this.Dx=A(new B,this,"navy",a);a=(new z).b();this.qt=A(new B,this,"blue",a);a=(new z).b();this.DE=A(new B,this,"teal",a);a=(new z).b();this.Zs=A(new B,this,"aqua",a);return this};fu.prototype.a=new s({gr:0},!1,"scalatags.generic.Styles$color$",{gr:1,$F:1,cc:1,c:1,xa:1,n:1,g:1,e:1});function gu(){nt.call(this)}gu.prototype=new ot;
+gu.prototype.xb=function(a){nt.prototype.Ea.call(this,a,"overflow","overflow");return this};gu.prototype.a=new s({lr:0},!1,"scalatags.generic.Styles$overflow$",{lr:1,Sl:1,cc:1,c:1,xa:1,n:1,g:1,e:1});function hu(){at.call(this);this.rn=null;this.tk=!1;this.Th=null}hu.prototype=new bt;function cg(a){var b=new hu;b.rn=a;at.prototype.yk.call(b,(new Hq).b());b.tk=!0;b.Th="";return b}
+function ct(a,b){for(var d=b;""!==d;){var e=d.indexOf("\n")|0;if(0>e)a.Th=""+a.Th+d,a.tk=!1,d="";else{var f=""+a.Th+d.substring(0,e);m.console&&(a.rn&&m.console.error?m.console.error(f):m.console.log(f));a.Th="";a.tk=!0;d=d.substring(1+e|0)}}}hu.prototype.Ii=ba();hu.prototype.a=new s({nw:0},!1,"java.lang.JSConsoleBasedPrintStream",{nw:1,GF:1,FF:1,vq:1,c:1,Kj:1,Jl:1,Zv:1});function iu(){An.call(this);this.rm=0;this.pk=null}iu.prototype=new Jt;
+iu.prototype.di=function(){return"Conversion \x3d "+(new Re).nc(this.rm)+", Flags \x3d "+this.pk};iu.prototype.nc=function(a){this.rm=a;It.prototype.b.call(this);this.pk=null;return this};function kq(){var a=new iu;iu.prototype.nc.call(a,115);a.pk="#";return a}iu.prototype.a=new s({zw:0},!1,"java.util.FormatFlagsConversionMismatchException",{zw:1,Fn:1,hh:1,ad:1,$c:1,dc:1,c:1,e:1});function Do(){An.call(this);this.qk=null}Do.prototype=new Jt;
+Do.prototype.b=function(){It.prototype.b.call(this);this.qk=null;return this};Do.prototype.di=function(){return"Flags \x3d '"+this.qk+"'"};Do.prototype.h=function(a){Do.prototype.b.call(this);if(null===a)throw(new va).b();this.qk=a;return this};Do.prototype.a=new s({Ew:0},!1,"java.util.IllegalFormatFlagsException",{Ew:1,Fn:1,hh:1,ad:1,$c:1,dc:1,c:1,e:1});function jq(){An.call(this);this.Tk=null}jq.prototype=new Jt;jq.prototype.b=function(){It.prototype.b.call(this);this.Tk=null;return this};
+jq.prototype.di=function(){return"Format specifier '"+this.Tk+"'"};jq.prototype.h=function(a){jq.prototype.b.call(this);if(null===a)throw(new va).b();this.Tk=a;return this};jq.prototype.a=new s({Fw:0},!1,"java.util.MissingFormatArgumentException",{Fw:1,Fn:1,hh:1,ad:1,$c:1,dc:1,c:1,e:1});function Dp(){}Dp.prototype=new Nt;Dp.prototype.K=h(!1);Dp.prototype.o=h("Duration.Undefined");Dp.prototype.a=new s({bA:0},!1,"scala.concurrent.duration.Duration$$anon$1",{bA:1,oo:1,Uk:1,c:1,g:1,e:1,lh:1,Zc:1});
+function Ep(){}Ep.prototype=new Nt;Ep.prototype.o=h("Duration.Inf");Ep.prototype.a=new s({cA:0},!1,"scala.concurrent.duration.Duration$$anon$2",{cA:1,oo:1,Uk:1,c:1,g:1,e:1,lh:1,Zc:1});function Fp(){}Fp.prototype=new Nt;Fp.prototype.o=h("Duration.MinusInf");Fp.prototype.a=new s({dA:0},!1,"scala.concurrent.duration.Duration$$anon$3",{dA:1,oo:1,Uk:1,c:1,g:1,e:1,lh:1,Zc:1});function Wp(){this.nj=null}Wp.prototype=new t;l=Wp.prototype;
+l.xc=function(a){var b=this.sd();b===q(Sa)?a=p(v(Sa),[a]):b===q(Ta)?a=p(v(Ta),[a]):b===q(Qa)?a=p(v(Qa),[a]):b===q(Ua)?a=p(v(Ua),[a]):b===q(Va)?a=p(v(Va),[a]):b===q(Xa)?a=p(v(Xa),[a]):b===q(Ya)?a=p(v(Ya),[a]):b===q(Pa)?a=p(v(Pa),[a]):b===q(Na)?a=p(v(ua),[a]):(hg||(hg=(new gg).b()),a=this.sd().Ed.newArrayOfThisClass([a]));return a};l.K=function(a){var b;a&&a.a&&a.a.t.cd?(b=this.sd(),a=a.sd(),b=b===a):b=!1;return b};l.o=function(){return Lh(this,this.nj)};l.sd=c("nj");l.M=function(){return ui(U(),this.nj)};
+l.a=new s({xA:0},!1,"scala.reflect.ClassTag$$anon$1",{xA:1,c:1,cd:1,Gd:1,vd:1,g:1,e:1,n:1});function ju(){this.N=null}ju.prototype=new Qt;ju.prototype.na=function(){ku||(ku=(new lu).b());return(new zp).b()};ju.prototype.a=new s({mB:0},!1,"scala.collection.Seq$",{mB:1,Le:1,Ke:1,xd:1,yc:1,c:1,yd:1,zc:1});var mu=void 0;function bc(){mu||(mu=(new ju).b());return mu}function nu(){this.N=null}nu.prototype=new Qt;function ou(){}ou.prototype=nu.prototype;function pu(){this.ru=null}pu.prototype=new eq;
+pu.prototype.b=function(){qu=this;this.ru=co(new bo,nc(function(){return aa()}(this)));return this};function ru(a,b,d,e,f,g,k){var n=31&(b>>>g|0),r=31&(e>>>g|0);if(n!==r)return a=1<<n|1<<r,b=p(v(su),[2]),n<r?(b.d[0]=d,b.d[1]=f):(b.d[0]=f,b.d[1]=d),tu(new uu,a,b,k);r=p(v(su),[1]);n=1<<n;r.d[0]=ru(a,b,d,e,f,5+g|0,k);return tu(new uu,n,r,k)}pu.prototype.Ri=function(){return vu()};pu.prototype.a=new s({DB:0},!1,"scala.collection.immutable.HashMap$",{DB:1,xB:1,zB:1,uB:1,c:1,vI:1,g:1,e:1});var qu=void 0;
+function wu(){qu||(qu=(new pu).b());return qu}function lu(){this.N=null}lu.prototype=new Qt;lu.prototype.na=function(){return(new zp).b()};lu.prototype.a=new s({pC:0},!1,"scala.collection.immutable.Seq$",{pC:1,Le:1,Ke:1,xd:1,yc:1,c:1,yd:1,zc:1});var ku=void 0;function xu(){this.y=null;this.i=this.r=0}xu.prototype=new Zt;l=xu.prototype;l.b=function(){this.i=this.r=0;return this};function yu(a,b){var d=p(v(Pa),[b]);0<a.i&&zl(rc(),a.y,0,d,0,a.i);return d}
+l.K=function(a){return a&&a.a&&a.a.t.So?this.i===a.i&&this.y===a.y:!1};l.tb=function(a){return zu(this,!!a)};l.o=h("ArrayBuilder.ofBoolean");l.pa=function(){return 0!==this.r&&this.r===this.i?this.y:yu(this,this.i)};l.kb=function(a){this.y=yu(this,a);this.r=a};l.Da=function(a){return zu(this,!!a)};l.Ta=function(a){this.r<a&&this.kb(a)};l.fb=function(a){if(this.r<a||0===this.r){for(var b=0===this.r?16:w(2,this.r);b<a;)b=w(2,b);this.kb(b)}};
+function zu(a,b){a.fb(1+a.i|0);a.y.d[a.i]=b;a.i=1+a.i|0;return a}l.Ka=function(a){a&&a.a&&a.a.t.op?(this.fb(this.i+a.q()|0),zl(rc(),a.p,0,this.y,this.i,a.q()),this.i=this.i+a.q()|0,a=this):a=lk(this,a);return a};l.a=new s({So:0},!1,"scala.collection.mutable.ArrayBuilder$ofBoolean",{So:1,nf:1,c:1,Vb:1,Ub:1,Tb:1,g:1,e:1});function Au(){this.y=null;this.i=this.r=0}Au.prototype=new Zt;l=Au.prototype;l.b=function(){this.i=this.r=0;return this};
+l.K=function(a){return a&&a.a&&a.a.t.To?this.i===a.i&&this.y===a.y:!1};l.tb=function(a){return Bu(this,a|0)};function Cu(a,b){var d=p(v(Sa),[b]);0<a.i&&zl(rc(),a.y,0,d,0,a.i);return d}l.o=h("ArrayBuilder.ofByte");l.pa=function(){return 0!==this.r&&this.r===this.i?this.y:Cu(this,this.i)};l.kb=function(a){this.y=Cu(this,a);this.r=a};l.Da=function(a){return Bu(this,a|0)};function Bu(a,b){a.fb(1+a.i|0);a.y.d[a.i]=b;a.i=1+a.i|0;return a}l.Ta=function(a){this.r<a&&this.kb(a)};
+l.fb=function(a){if(this.r<a||0===this.r){for(var b=0===this.r?16:w(2,this.r);b<a;)b=w(2,b);this.kb(b)}};l.Ka=function(a){a&&a.a&&a.a.t.pp?(this.fb(this.i+a.q()|0),zl(rc(),a.p,0,this.y,this.i,a.q()),this.i=this.i+a.q()|0,a=this):a=lk(this,a);return a};l.a=new s({To:0},!1,"scala.collection.mutable.ArrayBuilder$ofByte",{To:1,nf:1,c:1,Vb:1,Ub:1,Tb:1,g:1,e:1});function Du(){this.y=null;this.i=this.r=0}Du.prototype=new Zt;l=Du.prototype;l.b=function(){this.i=this.r=0;return this};
+l.K=function(a){return a&&a.a&&a.a.t.Uo?this.i===a.i&&this.y===a.y:!1};l.tb=function(a){return Eu(this,null===a?0:a.j)};l.o=h("ArrayBuilder.ofChar");l.pa=function(){return 0!==this.r&&this.r===this.i?this.y:Fu(this,this.i)};l.kb=function(a){this.y=Fu(this,a);this.r=a};l.Da=function(a){return Eu(this,null===a?0:a.j)};l.Ta=function(a){this.r<a&&this.kb(a)};function Fu(a,b){var d=p(v(Qa),[b]);0<a.i&&zl(rc(),a.y,0,d,0,a.i);return d}
+l.fb=function(a){if(this.r<a||0===this.r){for(var b=0===this.r?16:w(2,this.r);b<a;)b=w(2,b);this.kb(b)}};function Eu(a,b){a.fb(1+a.i|0);a.y.d[a.i]=b;a.i=1+a.i|0;return a}l.Ka=function(a){a&&a.a&&a.a.t.qp?(this.fb(this.i+a.q()|0),zl(rc(),a.p,0,this.y,this.i,a.q()),this.i=this.i+a.q()|0,a=this):a=lk(this,a);return a};l.a=new s({Uo:0},!1,"scala.collection.mutable.ArrayBuilder$ofChar",{Uo:1,nf:1,c:1,Vb:1,Ub:1,Tb:1,g:1,e:1});function Gu(){this.y=null;this.i=this.r=0}Gu.prototype=new Zt;l=Gu.prototype;
+l.b=function(){this.i=this.r=0;return this};l.K=function(a){return a&&a.a&&a.a.t.Vo?this.i===a.i&&this.y===a.y:!1};l.tb=function(a){return Hu(this,+a)};l.o=h("ArrayBuilder.ofDouble");l.pa=function(){return 0!==this.r&&this.r===this.i?this.y:Iu(this,this.i)};function Iu(a,b){var d=p(v(Ya),[b]);0<a.i&&zl(rc(),a.y,0,d,0,a.i);return d}l.kb=function(a){this.y=Iu(this,a);this.r=a};l.Da=function(a){return Hu(this,+a)};l.Ta=function(a){this.r<a&&this.kb(a)};
+function Hu(a,b){a.fb(1+a.i|0);a.y.d[a.i]=b;a.i=1+a.i|0;return a}l.fb=function(a){if(this.r<a||0===this.r){for(var b=0===this.r?16:w(2,this.r);b<a;)b=w(2,b);this.kb(b)}};l.Ka=function(a){a&&a.a&&a.a.t.rp?(this.fb(this.i+a.q()|0),zl(rc(),a.p,0,this.y,this.i,a.q()),this.i=this.i+a.q()|0,a=this):a=lk(this,a);return a};l.a=new s({Vo:0},!1,"scala.collection.mutable.ArrayBuilder$ofDouble",{Vo:1,nf:1,c:1,Vb:1,Ub:1,Tb:1,g:1,e:1});function Ju(){this.y=null;this.i=this.r=0}Ju.prototype=new Zt;l=Ju.prototype;
+l.b=function(){this.i=this.r=0;return this};l.K=function(a){return a&&a.a&&a.a.t.Wo?this.i===a.i&&this.y===a.y:!1};l.tb=function(a){return Ku(this,qa(a))};l.o=h("ArrayBuilder.ofFloat");l.pa=function(){return 0!==this.r&&this.r===this.i?this.y:Lu(this,this.i)};l.kb=function(a){this.y=Lu(this,a);this.r=a};function Ku(a,b){a.fb(1+a.i|0);a.y.d[a.i]=b;a.i=1+a.i|0;return a}l.Da=function(a){return Ku(this,qa(a))};l.Ta=function(a){this.r<a&&this.kb(a)};
+function Lu(a,b){var d=p(v(Xa),[b]);0<a.i&&zl(rc(),a.y,0,d,0,a.i);return d}l.fb=function(a){if(this.r<a||0===this.r){for(var b=0===this.r?16:w(2,this.r);b<a;)b=w(2,b);this.kb(b)}};l.Ka=function(a){a&&a.a&&a.a.t.sp?(this.fb(this.i+a.q()|0),zl(rc(),a.p,0,this.y,this.i,a.q()),this.i=this.i+a.q()|0,a=this):a=lk(this,a);return a};l.a=new s({Wo:0},!1,"scala.collection.mutable.ArrayBuilder$ofFloat",{Wo:1,nf:1,c:1,Vb:1,Ub:1,Tb:1,g:1,e:1});function Mu(){this.y=null;this.i=this.r=0}Mu.prototype=new Zt;l=Mu.prototype;
+l.b=function(){this.i=this.r=0;return this};l.K=function(a){return a&&a.a&&a.a.t.Xo?this.i===a.i&&this.y===a.y:!1};l.tb=function(a){return Nu(this,a|0)};l.o=h("ArrayBuilder.ofInt");l.pa=function(){return 0!==this.r&&this.r===this.i?this.y:Ou(this,this.i)};l.kb=function(a){this.y=Ou(this,a);this.r=a};function Nu(a,b){a.fb(1+a.i|0);a.y.d[a.i]=b;a.i=1+a.i|0;return a}l.Da=function(a){return Nu(this,a|0)};function Ou(a,b){var d=p(v(Ua),[b]);0<a.i&&zl(rc(),a.y,0,d,0,a.i);return d}
+l.Ta=function(a){this.r<a&&this.kb(a)};l.fb=function(a){if(this.r<a||0===this.r){for(var b=0===this.r?16:w(2,this.r);b<a;)b=w(2,b);this.kb(b)}};l.Ka=function(a){a&&a.a&&a.a.t.tp?(this.fb(this.i+a.q()|0),zl(rc(),a.p,0,this.y,this.i,a.q()),this.i=this.i+a.q()|0,a=this):a=lk(this,a);return a};l.a=new s({Xo:0},!1,"scala.collection.mutable.ArrayBuilder$ofInt",{Xo:1,nf:1,c:1,Vb:1,Ub:1,Tb:1,g:1,e:1});function Pu(){this.y=null;this.i=this.r=0}Pu.prototype=new Zt;l=Pu.prototype;
+l.b=function(){this.i=this.r=0;return this};function Qu(a,b){a.fb(1+a.i|0);a.y.d[a.i]=b;a.i=1+a.i|0;return a}l.K=function(a){return a&&a.a&&a.a.t.Yo?this.i===a.i&&this.y===a.y:!1};l.tb=function(a){return Qu(this,Ia(a))};l.o=h("ArrayBuilder.ofLong");l.pa=function(){return 0!==this.r&&this.r===this.i?this.y:Ru(this,this.i)};l.kb=function(a){this.y=Ru(this,a);this.r=a};function Ru(a,b){var d=p(v(Va),[b]);0<a.i&&zl(rc(),a.y,0,d,0,a.i);return d}l.Da=function(a){return Qu(this,Ia(a))};
+l.Ta=function(a){this.r<a&&this.kb(a)};l.fb=function(a){if(this.r<a||0===this.r){for(var b=0===this.r?16:w(2,this.r);b<a;)b=w(2,b);this.kb(b)}};l.Ka=function(a){a&&a.a&&a.a.t.up?(this.fb(this.i+a.q()|0),zl(rc(),a.p,0,this.y,this.i,a.q()),this.i=this.i+a.q()|0,a=this):a=lk(this,a);return a};l.a=new s({Yo:0},!1,"scala.collection.mutable.ArrayBuilder$ofLong",{Yo:1,nf:1,c:1,Vb:1,Ub:1,Tb:1,g:1,e:1});function Su(){this.y=this.Pm=null;this.i=this.r=0}Su.prototype=new Zt;l=Su.prototype;
+l.zk=function(a){this.Pm=a;this.i=this.r=0;return this};l.K=function(a){return a&&a.a&&a.a.t.Zo?this.i===a.i&&this.y===a.y:!1};l.tb=function(a){return Tu(this,a)};l.o=h("ArrayBuilder.ofRef");l.pa=function(){return 0!==this.r&&this.r===this.i?this.y:Uu(this,this.i)};l.kb=function(a){this.y=Uu(this,a);this.r=a};function Tu(a,b){a.fb(1+a.i|0);a.y.d[a.i]=b;a.i=1+a.i|0;return a}l.Da=function(a){return Tu(this,a)};l.Ta=function(a){this.r<a&&this.kb(a)};
+l.fb=function(a){if(this.r<a||0===this.r){for(var b=0===this.r?16:w(2,this.r);b<a;)b=w(2,b);this.kb(b)}};function Uu(a,b){var d=a.Pm.xc(b);0<a.i&&zl(rc(),a.y,0,d,0,a.i);return d}l.Ka=function(a){a&&a.a&&a.a.t.vp?(this.fb(this.i+a.q()|0),zl(rc(),a.p,0,this.y,this.i,a.q()),this.i=this.i+a.q()|0,a=this):a=lk(this,a);return a};l.a=new s({Zo:0},!1,"scala.collection.mutable.ArrayBuilder$ofRef",{Zo:1,nf:1,c:1,Vb:1,Ub:1,Tb:1,g:1,e:1});function Vu(){this.y=null;this.i=this.r=0}Vu.prototype=new Zt;l=Vu.prototype;
+l.b=function(){this.i=this.r=0;return this};l.K=function(a){return a&&a.a&&a.a.t.$o?this.i===a.i&&this.y===a.y:!1};function Wu(a,b){a.fb(1+a.i|0);a.y.d[a.i]=b;a.i=1+a.i|0;return a}l.tb=function(a){return Wu(this,a|0)};l.o=h("ArrayBuilder.ofShort");l.pa=function(){return 0!==this.r&&this.r===this.i?this.y:Xu(this,this.i)};l.kb=function(a){this.y=Xu(this,a);this.r=a};function Xu(a,b){var d=p(v(Ta),[b]);0<a.i&&zl(rc(),a.y,0,d,0,a.i);return d}l.Da=function(a){return Wu(this,a|0)};
+l.Ta=function(a){this.r<a&&this.kb(a)};l.fb=function(a){if(this.r<a||0===this.r){for(var b=0===this.r?16:w(2,this.r);b<a;)b=w(2,b);this.kb(b)}};l.Ka=function(a){a&&a.a&&a.a.t.wp?(this.fb(this.i+a.q()|0),zl(rc(),a.p,0,this.y,this.i,a.q()),this.i=this.i+a.q()|0,a=this):a=lk(this,a);return a};l.a=new s({$o:0},!1,"scala.collection.mutable.ArrayBuilder$ofShort",{$o:1,nf:1,c:1,Vb:1,Ub:1,Tb:1,g:1,e:1});function Yu(){this.y=null;this.i=this.r=0}Yu.prototype=new Zt;l=Yu.prototype;
+l.b=function(){this.i=this.r=0;return this};l.K=function(a){return a&&a.a&&a.a.t.ap?this.i===a.i&&this.y===a.y:!1};l.tb=function(a){return Zu(this,a)};l.o=h("ArrayBuilder.ofUnit");function Zu(a,b){a.fb(1+a.i|0);a.y.d[a.i]=b;a.i=1+a.i|0;return a}l.pa=function(){return 0!==this.r&&this.r===this.i?this.y:$u(this,this.i)};l.kb=function(a){this.y=$u(this,a);this.r=a};function $u(a,b){var d=p(v(ua),[b]);0<a.i&&zl(rc(),a.y,0,d,0,a.i);return d}l.Da=function(a){return Zu(this,a)};
+l.Ta=function(a){this.r<a&&this.kb(a)};l.fb=function(a){if(this.r<a||0===this.r){for(var b=0===this.r?16:w(2,this.r);b<a;)b=w(2,b);this.kb(b)}};l.Ka=function(a){a&&a.a&&a.a.t.xp?(this.fb(this.i+a.q()|0),zl(rc(),a.p,0,this.y,this.i,a.q()),this.i=this.i+a.q()|0,a=this):a=lk(this,a);return a};l.a=new s({ap:0},!1,"scala.collection.mutable.ArrayBuilder$ofUnit",{ap:1,nf:1,c:1,Vb:1,Ub:1,Tb:1,g:1,e:1});function av(){this.N=null}av.prototype=new Qt;av.prototype.na=function(){return(new Dj).b()};
+av.prototype.a=new s({nD:0},!1,"scala.collection.mutable.IndexedSeq$",{nD:1,Le:1,Ke:1,xd:1,yc:1,c:1,yd:1,zc:1});var Nv=void 0;function Ov(){Nv||(Nv=(new av).b());return Nv}function Pv(){this.N=null}Pv.prototype=new Qt;Pv.prototype.na=function(){return(new C).b()};Pv.prototype.a=new s({GD:0},!1,"scala.scalajs.js.WrappedArray$",{GD:1,Le:1,Ke:1,xd:1,yc:1,c:1,yd:1,zc:1});var Qv=void 0;function iq(){Qv||(Qv=(new Pv).b());return Qv}function Wc(){this.Za=null}Wc.prototype=new t;l=Wc.prototype;l.jb=h("StringFrag");
+l.hb=h(1);l.K=function(a){return this===a?!0:a&&a.a&&a.a.t.Ml?this.Za===a.Za:!1};l.ib=function(a){switch(a){case 0:return this.Za;default:throw(new Rg).h(""+a);}};l.o=function(){return hn(U(),this)};l.je=function(a){a.appendChild(this.Sk())};l.Sk=function(){return m.document.createTextNode(this.Za)};l.h=function(a){this.Za=a;return this};l.M=function(){return vi(this)};l.qb=function(){return Fr(new Gr,this)};l.a=new s({Ml:0},!1,"scalatags.JsDom$StringFrag",{Ml:1,c:1,sr:1,Lj:1,tf:1,xa:1,n:1,g:1,e:1});
+function te(){An.call(this);this.fj=this.Mi=null}te.prototype=new yo;l=te.prototype;l.jb=h("Data");l.hb=h(2);l.K=function(a){if(this===a)return!0;if(a&&a.a&&a.a.t.Zl){var b=this.Mi,d=a.Mi;return(null===b?null===d:b.K(d))?this.fj===a.fj:!1}return!1};l.ib=function(a){switch(a){case 0:return this.Mi;case 1:return this.fj;default:throw(new Rg).h(""+a);}};function se(a,b,d){a.Mi=b;a.fj=d;xo.prototype.h.call(a,Db((new Eb).La((new C).A(["data: "," msg: ",""])),(new C).A([b,d])));return a}l.M=function(){return vi(this)};
+l.qb=function(){return Fr(new Gr,this)};l.a=new s({Zl:0},!1,"upickle.Invalid$Data",{Zl:1,$c:1,dc:1,c:1,e:1,nG:1,xa:1,n:1,g:1});function Rv(){}Rv.prototype=new t;l=Rv.prototype;l.b=function(){Sv=this;return this};l.Dg=function(a,b){return 0<=this.sc(a,b)};l.sc=function(a,b){return(a|0)<(b|0)?-1:(a|0)===(b|0)?0:1};l.Ig=function(a,b){return 0>=this.sc(a,b)};l.a=new s({qA:0},!1,"scala.math.Ordering$Int$",{qA:1,c:1,rA:1,mh:1,ih:1,nh:1,kh:1,g:1,e:1});var Sv=void 0;
+function zd(){Sv||(Sv=(new Rv).b());return Sv}function Tv(){}Tv.prototype=new t;l=Tv.prototype;l.b=function(){Uv=this;return this};l.Dg=function(a,b){return 0<=this.sc(a,b)};l.sc=function(a,b){return a===b?0:a<b?-1:1};l.Ig=function(a,b){return 0>=this.sc(a,b)};l.a=new s({sA:0},!1,"scala.math.Ordering$String$",{sA:1,c:1,oI:1,mh:1,ih:1,nh:1,kh:1,g:1,e:1});var Uv=void 0;function Id(){Uv||(Uv=(new Tv).b());return Uv}function Vv(){this.Kp=null;this.fn=0}Vv.prototype=new t;function Wv(){}Wv.prototype=Vv.prototype;
+Vv.prototype.K=function(a){return this===a};Vv.prototype.o=c("Kp");Vv.prototype.h=function(a){this.Kp=a;this.fn=Ga(this);return this};Vv.prototype.M=c("fn");function Xv(){this.TE=this.ko=this.rz=null}Xv.prototype=new t;function Yv(){}Yv.prototype=Xv.prototype;Xv.prototype.sd=c("ko");Xv.prototype.Nv=function(a,b,d){this.rz=a;this.ko=b;this.TE=d;return this};function Zv(){this.zb=this.N=null}Zv.prototype=new ou;Zv.prototype.b=function(){nu.prototype.b.call(this);$v=this;this.zb=(new aq).b();return this};
+Zv.prototype.na=function(){In();uc();return(new Jn).b()};Zv.prototype.a=new s({dB:0},!1,"scala.collection.IndexedSeq$",{dB:1,Fo:1,Le:1,Ke:1,xd:1,yc:1,c:1,yd:1,zc:1});var $v=void 0;function vc(){$v||($v=(new Zv).b());return $v}function X(){this.fh=this.zg=0;this.W=null}X.prototype=new Zq;X.prototype.wa=function(){this.fh>=this.zg&&$g().Cc.wa();var a=this.W.ma(this.fh);this.fh=1+this.fh|0;return a};function W(a,b,d){a.zg=d;if(null===b)throw G(H(),null);a.W=b;a.fh=0;return a}
+X.prototype.Ca=function(){return this.fh<this.zg};X.prototype.a=new s({fB:0},!1,"scala.collection.IndexedSeqLike$Elements",{fB:1,Hd:1,c:1,ed:1,H:1,G:1,tI:1,g:1,e:1});function aw(){}aw.prototype=new xs;function bw(a,b,d,e,f,g){var k=31&(b>>>g|0),n=31&(e>>>g|0);if(k!==n)return a=1<<k|1<<n,b=p(v(cw),[2]),k<n?(b.d[0]=d,b.d[1]=f):(b.d[0]=f,b.d[1]=d),dw(new ew,a,b,d.U()+f.U()|0);n=p(v(cw),[1]);k=1<<k;d=bw(a,b,d,e,f,5+g|0);n.d[0]=d;return dw(new ew,k,n,d.Ng)}aw.prototype.Qi=function(){return fw()};
+aw.prototype.a=new s({KB:0},!1,"scala.collection.immutable.HashSet$",{KB:1,Eo:1,dl:1,bl:1,yc:1,c:1,zc:1,g:1,e:1});var gw=void 0;function hw(){gw||(gw=(new aw).b());return gw}function iw(){this.N=null}iw.prototype=new ou;iw.prototype.na=function(){uc();return(new Jn).b()};iw.prototype.a=new s({PB:0},!1,"scala.collection.immutable.IndexedSeq$",{PB:1,Fo:1,Le:1,Ke:1,xd:1,yc:1,c:1,yd:1,zc:1});var jw=void 0;function In(){jw||(jw=(new iw).b());return jw}function kw(){}kw.prototype=new xs;
+kw.prototype.Qi=function(){return cr()};kw.prototype.na=function(){return(new br).b()};kw.prototype.a=new s({YB:0},!1,"scala.collection.immutable.ListSet$",{YB:1,Eo:1,dl:1,bl:1,yc:1,c:1,zc:1,g:1,e:1});var lw=void 0;function mw(){}mw.prototype=new zs;mw.prototype.Ef=function(){return(new er).b()};mw.prototype.a=new s({lD:0},!1,"scala.collection.mutable.HashSet$",{lD:1,xI:1,dl:1,bl:1,yc:1,c:1,zc:1,g:1,e:1});var nw=void 0;function Xm(){An.call(this);this.Gf=null}Xm.prototype=new Iq;l=Xm.prototype;
+l.jb=h("JavaScriptException");l.hb=h(1);l.Ti=function(){Tm();this.stackdata=this.Gf;return this};l.K=function(a){return this===a?!0:Vm(a)?O(P(),this.Gf,a.Gf):!1};l.ib=function(a){switch(a){case 0:return this.Gf;default:throw(new Rg).h(""+a);}};l.o=function(){return ka(this.Gf)};l.w=function(a){this.Gf=a;ji.prototype.b.call(this);return this};l.M=function(){return vi(this)};l.qb=function(){return Fr(new Gr,this)};function Vm(a){return!!(a&&a.a&&a.a.t.Ap)}
+l.a=new s({Ap:0},!1,"scala.scalajs.js.JavaScriptException",{Ap:1,ad:1,$c:1,dc:1,c:1,e:1,xa:1,n:1,g:1});function Gb(){this.Zf=this.we=null;this.yh=!1;this.Jg=null}Gb.prototype=new t;l=Gb.prototype;l.jb=h("TypedTag");l.hb=h(4);l.K=function(a){if(this===a)return!0;if(a&&a.a&&a.a.t.Nl){if(this.we===a.we)var b=this.Zf,d=a.Zf,b=null===b?null===d:b.K(d);else b=!1;return b&&this.yh===a.yh?this.Jg===a.Jg:!1}return!1};
+l.ib=function(a){switch(a){case 0:return this.we;case 1:return this.Zf;case 2:return this.yh;case 3:return this.Jg;default:throw(new Rg).h(""+a);}};l.o=function(){return Hc(this).outerHTML};l.je=function(a){a.appendChild(this.Sk())};l.Sk=function(){return Hc(this)};function Jc(a,b){return Fb(new Gb,a.we,Tb(new Ub,b,a.Zf),a.yh,a.Jg)}function Fb(a,b,d,e,f){a.we=b;a.Zf=d;a.yh=e;a.Jg=f;return a}
+l.M=function(){var a=-889275714,a=nn().Nc(a,ln(nn(),this.we)),a=nn().Nc(a,ln(nn(),this.Zf)),a=nn().Nc(a,this.yh?1231:1237),a=nn().Nc(a,ln(nn(),this.Jg));return nn().Cg(a,4)};l.qb=function(){return Fr(new Gr,this)};function Hc(a){var b=m.document.createElementNS(a.Jg.Rp(),a.we),d=a.Zf;a=a.Zf;a=p(v(ow),[sj(a)]);for(var e=0;;){var f=d,g=x();if(null===f?null===g:f.K(g))break;else a.d[e]=d.u(),d=d.s(),e=1+e|0}for(d=a.d.length;0<d;)for(d=-1+d|0,e=a.d[d],f=0;f<e.q();)e.ma(f).je(b),f=1+f|0;return b}
+l.a=new s({Nl:0},!1,"scalatags.JsDom$TypedTag",{Nl:1,c:1,eG:1,Lj:1,tf:1,sr:1,xa:1,n:1,g:1,e:1});function Th(){Vv.call(this)}Th.prototype=new Wv;Th.prototype.b=function(){Vv.prototype.h.call(this,"Long");return this};Th.prototype.xc=function(a){return p(v(Va),[a])};Th.prototype.sd=function(){return q(Va)};Th.prototype.a=new s({AA:0},!1,"scala.reflect.ManifestFactory$$anon$10",{AA:1,bg:1,c:1,Rd:1,cd:1,Gd:1,vd:1,g:1,e:1,n:1});function Uh(){Vv.call(this)}Uh.prototype=new Wv;
+Uh.prototype.b=function(){Vv.prototype.h.call(this,"Float");return this};Uh.prototype.xc=function(a){return p(v(Xa),[a])};Uh.prototype.sd=function(){return q(Xa)};Uh.prototype.a=new s({BA:0},!1,"scala.reflect.ManifestFactory$$anon$11",{BA:1,bg:1,c:1,Rd:1,cd:1,Gd:1,vd:1,g:1,e:1,n:1});function Vh(){Vv.call(this)}Vh.prototype=new Wv;Vh.prototype.b=function(){Vv.prototype.h.call(this,"Double");return this};Vh.prototype.xc=function(a){return p(v(Ya),[a])};Vh.prototype.sd=function(){return q(Ya)};
+Vh.prototype.a=new s({CA:0},!1,"scala.reflect.ManifestFactory$$anon$12",{CA:1,bg:1,c:1,Rd:1,cd:1,Gd:1,vd:1,g:1,e:1,n:1});function Wh(){Vv.call(this)}Wh.prototype=new Wv;Wh.prototype.b=function(){Vv.prototype.h.call(this,"Boolean");return this};Wh.prototype.xc=function(a){return p(v(Pa),[a])};Wh.prototype.sd=function(){return q(Pa)};Wh.prototype.a=new s({DA:0},!1,"scala.reflect.ManifestFactory$$anon$13",{DA:1,bg:1,c:1,Rd:1,cd:1,Gd:1,vd:1,g:1,e:1,n:1});function Xh(){Vv.call(this)}Xh.prototype=new Wv;
+Xh.prototype.b=function(){Vv.prototype.h.call(this,"Unit");return this};Xh.prototype.xc=function(a){return p(v(ua),[a])};Xh.prototype.sd=function(){return q(Na)};Xh.prototype.a=new s({EA:0},!1,"scala.reflect.ManifestFactory$$anon$14",{EA:1,bg:1,c:1,Rd:1,cd:1,Gd:1,vd:1,g:1,e:1,n:1});function Ph(){Vv.call(this)}Ph.prototype=new Wv;Ph.prototype.b=function(){Vv.prototype.h.call(this,"Byte");return this};Ph.prototype.xc=function(a){return p(v(Sa),[a])};Ph.prototype.sd=function(){return q(Sa)};
+Ph.prototype.a=new s({JA:0},!1,"scala.reflect.ManifestFactory$$anon$6",{JA:1,bg:1,c:1,Rd:1,cd:1,Gd:1,vd:1,g:1,e:1,n:1});function Qh(){Vv.call(this)}Qh.prototype=new Wv;Qh.prototype.b=function(){Vv.prototype.h.call(this,"Short");return this};Qh.prototype.xc=function(a){return p(v(Ta),[a])};Qh.prototype.sd=function(){return q(Ta)};Qh.prototype.a=new s({KA:0},!1,"scala.reflect.ManifestFactory$$anon$7",{KA:1,bg:1,c:1,Rd:1,cd:1,Gd:1,vd:1,g:1,e:1,n:1});function Rh(){Vv.call(this)}Rh.prototype=new Wv;
+Rh.prototype.b=function(){Vv.prototype.h.call(this,"Char");return this};Rh.prototype.xc=function(a){return p(v(Qa),[a])};Rh.prototype.sd=function(){return q(Qa)};Rh.prototype.a=new s({LA:0},!1,"scala.reflect.ManifestFactory$$anon$8",{LA:1,bg:1,c:1,Rd:1,cd:1,Gd:1,vd:1,g:1,e:1,n:1});function Sh(){Vv.call(this)}Sh.prototype=new Wv;Sh.prototype.b=function(){Vv.prototype.h.call(this,"Int");return this};Sh.prototype.xc=function(a){return p(v(Ua),[a])};Sh.prototype.sd=function(){return q(Ua)};
+Sh.prototype.a=new s({MA:0},!1,"scala.reflect.ManifestFactory$$anon$9",{MA:1,bg:1,c:1,Rd:1,cd:1,Gd:1,vd:1,g:1,e:1,n:1});function pw(){Xv.call(this);this.Lp=null;this.gn=0}pw.prototype=new Yv;function qw(){}qw.prototype=pw.prototype;pw.prototype.K=function(a){return this===a};pw.prototype.o=c("Lp");pw.prototype.M=c("gn");pw.prototype.hi=function(a,b){this.Lp=b;Xv.prototype.Nv.call(this,sg(),a,x());this.gn=Ga(this);return this};function rw(){this.lz=this.N=null}rw.prototype=new Qt;
+rw.prototype.b=function(){Pt.prototype.b.call(this);sw=this;this.lz=(new fo).b();return this};rw.prototype.Ef=function(){return x()};rw.prototype.na=function(){return(new zp).b()};rw.prototype.a=new s({RB:0},!1,"scala.collection.immutable.List$",{RB:1,Le:1,Ke:1,xd:1,yc:1,c:1,yd:1,zc:1,g:1,e:1});var sw=void 0;function J(){sw||(sw=(new rw).b());return sw}function tw(){this.N=null}tw.prototype=new Qt;
+function uw(a,b,d){return jj(new kj,b,Nc(function(a,b,d){return function(){return uw(a,b+d|0,d)}}(a,b,d)))}tw.prototype.Ef=function(){return lj()};tw.prototype.na=function(){return(new Fs).b()};tw.prototype.a=new s({AC:0},!1,"scala.collection.immutable.Stream$",{AC:1,Le:1,Ke:1,xd:1,yc:1,c:1,yd:1,zc:1,g:1,e:1});var vw=void 0;function lh(){vw||(vw=(new tw).b());return vw}function ww(){this.N=null}ww.prototype=new Qt;ww.prototype.na=function(){return(new Dj).b()};
+ww.prototype.a=new s({VC:0},!1,"scala.collection.mutable.ArrayBuffer$",{VC:1,Le:1,Ke:1,xd:1,yc:1,c:1,yd:1,zc:1,g:1,e:1});var xw=void 0;function yw(){this.N=null}yw.prototype=new Qt;yw.prototype.na=function(){return pr(new or,(new zp).b())};yw.prototype.a=new s({pD:0},!1,"scala.collection.mutable.ListBuffer$",{pD:1,Le:1,Ke:1,xd:1,yc:1,c:1,yd:1,zc:1,g:1,e:1});var zw=void 0;function $h(){pw.call(this)}$h.prototype=new qw;$h.prototype.b=function(){pw.prototype.hi.call(this,Kh().tj,"Any");return this};
+$h.prototype.xc=function(a){return this.kf(a)};$h.prototype.kf=function(a){return p(v(u),[a])};$h.prototype.a=new s({zA:0},!1,"scala.reflect.ManifestFactory$$anon$1",{zA:1,qj:1,pj:1,c:1,Rd:1,cd:1,Gd:1,vd:1,g:1,e:1,n:1});function ai(){pw.call(this)}ai.prototype=new qw;ai.prototype.b=function(){pw.prototype.hi.call(this,Kh().tj,"Object");return this};ai.prototype.xc=function(a){return this.kf(a)};ai.prototype.kf=function(a){return p(v(u),[a])};
+ai.prototype.a=new s({FA:0},!1,"scala.reflect.ManifestFactory$$anon$2",{FA:1,qj:1,pj:1,c:1,Rd:1,cd:1,Gd:1,vd:1,g:1,e:1,n:1});function bi(){pw.call(this)}bi.prototype=new qw;bi.prototype.b=function(){pw.prototype.hi.call(this,Kh().tj,"AnyVal");return this};bi.prototype.xc=function(a){return this.kf(a)};bi.prototype.kf=function(a){return p(v(u),[a])};bi.prototype.a=new s({GA:0},!1,"scala.reflect.ManifestFactory$$anon$3",{GA:1,qj:1,pj:1,c:1,Rd:1,cd:1,Gd:1,vd:1,g:1,e:1,n:1});
+function ci(){pw.call(this)}ci.prototype=new qw;ci.prototype.b=function(){pw.prototype.hi.call(this,Kh().uo,"Null");return this};ci.prototype.xc=function(a){return this.kf(a)};ci.prototype.kf=function(a){return p(v(u),[a])};ci.prototype.a=new s({HA:0},!1,"scala.reflect.ManifestFactory$$anon$4",{HA:1,qj:1,pj:1,c:1,Rd:1,cd:1,Gd:1,vd:1,g:1,e:1,n:1});function di(){pw.call(this)}di.prototype=new qw;di.prototype.b=function(){pw.prototype.hi.call(this,Kh().to,"Nothing");return this};di.prototype.xc=function(a){return this.kf(a)};
+di.prototype.kf=function(a){return p(v(u),[a])};di.prototype.a=new s({IA:0},!1,"scala.reflect.ManifestFactory$$anon$5",{IA:1,qj:1,pj:1,c:1,Rd:1,cd:1,Gd:1,vd:1,g:1,e:1,n:1});function Nr(a){return!!(a&&a.a&&a.a.t.Rb)}function Aw(){this.Fh=this.N=null;this.SG=this.HF=0}Aw.prototype=new ou;Aw.prototype.b=function(){nu.prototype.b.call(this);Bw=this;this.Fh=(new Vs).k(0,0,0);return this};Aw.prototype.Ef=c("Fh");Aw.prototype.na=function(){return(new Jn).b()};
+Aw.prototype.a=new s({OC:0},!1,"scala.collection.immutable.Vector$",{OC:1,Fo:1,Le:1,Ke:1,xd:1,yc:1,c:1,yd:1,zc:1,g:1,e:1});var Bw=void 0;function uc(){Bw||(Bw=(new Aw).b());return Bw}function Ye(){}Ye.prototype=new t;l=Ye.prototype;l.b=function(){Xe=this;return this};l.zi=function(a){return a|0};l.Dg=function(a,b){return 0<=this.sc(a,b)};l.sc=function(a,b){return(a|0)-(b|0)|0};l.Ig=function(a,b){return 0>=this.sc(a,b)};
+l.a=new s({jA:0},!1,"scala.math.Numeric$ByteIsIntegral$",{jA:1,c:1,dI:1,qo:1,oj:1,mh:1,ih:1,nh:1,kh:1,g:1,e:1,kI:1});var Xe=void 0;function df(){}df.prototype=new t;l=df.prototype;l.b=function(){cf=this;return this};l.zi=function(a){return a|0};l.Dg=function(a,b){return 0<=this.sc(a,b)};l.sc=function(a,b){return(a|0)<(b|0)?-1:(a|0)===(b|0)?0:1};l.Ig=function(a,b){return 0>=this.sc(a,b)};l.a=new s({mA:0},!1,"scala.math.Numeric$IntIsIntegral$",{mA:1,c:1,iI:1,qo:1,oj:1,mh:1,ih:1,nh:1,kh:1,g:1,e:1,rA:1});
+var cf=void 0;function bf(){}bf.prototype=new t;l=bf.prototype;l.b=function(){af=this;return this};l.zi=function(a){return a|0};l.Dg=function(a,b){return 0<=this.sc(a,b)};l.sc=function(a,b){return(a|0)-(b|0)|0};l.Ig=function(a,b){return 0>=this.sc(a,b)};l.a=new s({nA:0},!1,"scala.math.Numeric$ShortIsIntegral$",{nA:1,c:1,jI:1,qo:1,oj:1,mh:1,ih:1,nh:1,kh:1,g:1,e:1,nI:1});var af=void 0;function Cw(){}Cw.prototype=new t;function Dw(){}l=Dw.prototype=Cw.prototype;
+l.Fb=function(){var a=J().N;return Kj(this,a)};l.fc=function(a){return this.Ec("",a,"")};l.Ec=function(a,b,d){return L(this,a,b,d)};l.Kd=function(a){return(new On).od(this,a)};l.ef=function(){return Zi(this)};l.le=function(a,b){return bk(this,a,b)};l.Rc=function(){uc();var a=vc().zb;return Kj(this,a)};l.U=function(){return ek(this)};l.ec=function(){return this.fc("")};l.sf=function(a,b){return Qj(this,a,b)};l.s=function(){return bj(this)};l.rc=function(a,b,d,e){return Cj(this,a,b,d,e)};
+l.Dc=function(a){return ck(this,a)};l.Pb=function(){return this};l.Ac=function(a,b){return this.le(a,b)};l.Yc=h(!0);l.lc=function(a){return Vj(this,a)};l.oe=function(a,b){return Nj(this,a,b)};l.Kb=function(a){return Oi(this,a)};l.na=function(){return this.Ab().na()};l.Wb=function(){return Rj(this)};function mf(){}mf.prototype=new t;l=mf.prototype;l.b=function(){lf=this;return this};l.zi=function(a){return+a};l.Dg=function(a,b){return+a>=+b};l.sc=function(a,b){var d=+a,e=+b;return Jf(hf(),d,e)};
+l.Ig=function(a,b){return+a<=+b};l.a=new s({kA:0},!1,"scala.math.Numeric$DoubleIsFractional$",{kA:1,c:1,fI:1,eI:1,oj:1,mh:1,ih:1,nh:1,kh:1,g:1,e:1,fA:1,lI:1});var lf=void 0;function kf(){}kf.prototype=new t;l=kf.prototype;l.b=function(){jf=this;return this};l.zi=function(a){return qa(a)};l.Dg=function(a,b){var d=qa(a),e=qa(b);return d>=e};l.sc=function(a,b){var d=qa(a),e=qa(b);return Jf(hf(),d,e)};l.Ig=function(a,b){var d=qa(a),e=qa(b);return d<=e};
+l.a=new s({lA:0},!1,"scala.math.Numeric$FloatIsFractional$",{lA:1,c:1,hI:1,gI:1,oj:1,mh:1,ih:1,nh:1,kh:1,g:1,e:1,fA:1,mI:1});var jf=void 0;function Ij(a){return!!(a&&a.a&&a.a.t.rb)}function Ew(){}Ew.prototype=new Dw;function Fw(){}l=Fw.prototype=Ew.prototype;l.u=function(){return this.X().wa()};l.Qb=function(a){return Vi(this,a)};l.Ab=function(){return Zg()};l.ci=function(a){var b=this.X();return oj(b,a)};l.R=function(a){var b=this.X();nj(b,a)};l.Yg=function(a){return ej(this,a)};
+l.Zb=function(a){var b=this.na();Pj(b,this,-(0>a?0:a)|0);for(var d=0,e=this.X();d<a&&e.Ca();)e.wa(),d=1+d|0;return b.Ka(e).pa()};l.db=function(){return this.X().db()};l.Hc=function(a,b,d){var e=b;b=b+d|0;d=Ri(U(),a);b=b<d?b:d;for(d=this.X();e<b&&d.Ca();)Si(U(),a,e,d.wa()),e=1+e|0};var Rs=new s({Na:0},!0,"scala.collection.immutable.Iterable",{Na:1,Qa:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,Pa:1,sa:1,qa:1,ba:1,da:1,n:1});function mb(){this.f=null}mb.prototype=new t;l=mb.prototype;l.Ba=function(){return(new wl).h(this.f)};
+l.u=function(){return cj(this)};l.ma=function(a){a=65535&(this.f.charCodeAt(a)|0);return(new Re).nc(a)};l.pb=function(a){return Fi(this,a)};l.Qb=function(a){return Ui(this,a)};l.m=function(){return aj(this)};l.Fb=function(){var a=J().N;return Kj(this,a)};l.Ja=function(){return(new wl).h(this.f)};l.K=function(a){return Qb().nk(this.f,a)};l.Ec=function(a,b,d){return L(this,a,b,d)};l.fc=function(a){return L(this,"",a,"")};l.Kd=function(a){return(new On).od(this,a)};
+l.Dd=function(a,b){return Jj(this,a,b)};l.o=c("f");l.R=function(a){Wi(this,a)};l.Qc=function(a,b){return Pb(Qb(),this.f,a,b)};l.Rc=function(){uc();var a=vc().zb;return Kj(this,a)};l.pc=function(){return Xi(this)};l.U=function(){return this.f.length|0};l.Fc=function(a,b){return Fj(this,a,b)};l.X=function(){return W(new X,this,this.f.length|0)};l.q=function(){return this.f.length|0};l.ec=c("f");l.db=function(){var a=W(new X,this,this.f.length|0);return ij(a)};
+l.Zb=function(a){var b=this.f.length|0;return Pb(Qb(),this.f,a,b)};l.bc=function(){return(new wl).h(this.f)};l.s=function(){return $i(this)};l.rc=function(a,b,d,e){return Cj(this,a,b,d,e)};l.Dc=function(a){return ck(this,a)};l.Pb=c("f");l.Ac=function(a,b){return Ni(this,0,this.f.length|0,a,b)};l.Hc=function(a,b,d){Qi(this,a,b,d)};l.M=function(){var a=this.f;return Aa(Ba(),a)};l.Yc=h(!0);l.h=function(a){this.f=a;return this};l.lc=function(a){return Vj(this,a)};l.kc=function(a){this.f;return(new wl).h(a)};
+l.Kb=function(a){return Mi(this,a)};l.na=function(){this.f;return(new dk).b()};l.Wb=function(){return Rj(this)};l.a=new s({Oo:0},!1,"scala.collection.immutable.StringOps",{Oo:1,c:1,No:1,Lb:1,rb:1,Xa:1,da:1,n:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ba:1,Wa:1,lh:1,Zc:1});var ow=new s({Sb:0},!0,"scala.collection.Seq",{Sb:1,la:1,x:1,sa:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,qa:1,ba:1,da:1,n:1,Rb:1,Wa:1,Xa:1});function kp(){this.f=null}kp.prototype=new t;l=kp.prototype;l.Ba=function(){return(new um).Rf(this.f)};
+l.u=function(){return cj(this)};l.ma=function(a){return this.f.d[a]};l.pb=function(a){return Fi(this,a)};l.Qb=function(a){return Ui(this,a)};l.m=function(){return aj(this)};l.Fb=function(){var a=J().N;return Kj(this,a)};l.Ja=function(){return(new um).Rf(this.f)};l.K=function(a){Bl||(Bl=(new Al).b());return a&&a.a&&a.a.t.bp?this.f===(null===a?null:a.f):!1};l.Ec=function(a,b,d){return L(this,a,b,d)};l.fc=function(a){return L(this,"",a,"")};l.Kd=function(a){return(new On).od(this,a)};
+l.Dd=function(a,b){return Jj(this,a,b)};l.o=function(){return Lj(this)};l.R=function(a){Wi(this,a)};l.Qc=function(a,b){return Pi(this,a,b)};l.Rc=function(){uc();var a=vc().zb;return Kj(this,a)};l.pc=function(){return Xi(this)};l.U=function(){return this.f.d.length};l.Fc=function(a,b){return Fj(this,a,b)};l.X=function(){return W(new X,this,this.f.d.length)};l.ec=function(){return L(this,"","","")};l.q=function(){return this.f.d.length};l.db=function(){var a=W(new X,this,this.f.d.length);return ij(a)};
+l.Zb=function(a){return Pi(this,a,this.f.d.length)};l.bc=function(){return(new um).Rf(this.f)};l.s=function(){return $i(this)};l.rc=function(a,b,d,e){return Cj(this,a,b,d,e)};l.Dc=function(a){return ck(this,a)};l.Rf=function(a){this.f=a;return this};l.Pb=c("f");l.Ac=function(a,b){return Ni(this,0,this.f.d.length,a,b)};l.Hc=function(a,b,d){yl(this,a,b,d)};l.Yc=h(!0);l.M=function(){return this.f.M()};l.lc=function(a){return Vj(this,a)};l.kc=function(a){this.f;return(new um).Rf(a)};
+l.Kb=function(a){return Mi(this,a)};l.na=function(){this.f;return(new xu).b()};l.Wb=function(){return Rj(this)};l.a=new s({bp:0},!1,"scala.collection.mutable.ArrayOps$ofBoolean",{bp:1,c:1,of:1,qc:1,hc:1,$b:1,rb:1,Xa:1,da:1,n:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ba:1,Wa:1,Lb:1,Sa:1});function lp(){this.f=null}lp.prototype=new t;l=lp.prototype;l.Ba=function(){return(new sm).Kf(this.f)};l.u=function(){return cj(this)};l.ma=function(a){return this.f.d[a]};l.pb=function(a){return Fi(this,a)};
+l.Qb=function(a){return Ui(this,a)};l.m=function(){return aj(this)};l.Fb=function(){var a=J().N;return Kj(this,a)};l.Ja=function(){return(new sm).Kf(this.f)};l.K=function(a){Dl||(Dl=(new Cl).b());return a&&a.a&&a.a.t.cp?this.f===(null===a?null:a.f):!1};l.Ec=function(a,b,d){return L(this,a,b,d)};l.fc=function(a){return L(this,"",a,"")};l.Kd=function(a){return(new On).od(this,a)};l.Dd=function(a,b){return Jj(this,a,b)};l.o=function(){return Lj(this)};l.R=function(a){Wi(this,a)};
+l.Qc=function(a,b){return Pi(this,a,b)};l.Rc=function(){uc();var a=vc().zb;return Kj(this,a)};l.pc=function(){return Xi(this)};l.U=function(){return this.f.d.length};l.Fc=function(a,b){return Fj(this,a,b)};l.X=function(){return W(new X,this,this.f.d.length)};l.ec=function(){return L(this,"","","")};l.q=function(){return this.f.d.length};l.db=function(){var a=W(new X,this,this.f.d.length);return ij(a)};l.Zb=function(a){return Pi(this,a,this.f.d.length)};l.bc=function(){return(new sm).Kf(this.f)};
+l.s=function(){return $i(this)};l.rc=function(a,b,d,e){return Cj(this,a,b,d,e)};l.Dc=function(a){return ck(this,a)};l.Pb=c("f");l.Ac=function(a,b){return Ni(this,0,this.f.d.length,a,b)};l.Hc=function(a,b,d){yl(this,a,b,d)};l.Yc=h(!0);l.M=function(){return this.f.M()};l.Kf=function(a){this.f=a;return this};l.lc=function(a){return Vj(this,a)};l.kc=function(a){this.f;return(new sm).Kf(a)};l.Kb=function(a){return Mi(this,a)};l.na=function(){this.f;return(new Au).b()};l.Wb=function(){return Rj(this)};
+l.a=new s({cp:0},!1,"scala.collection.mutable.ArrayOps$ofByte",{cp:1,c:1,of:1,qc:1,hc:1,$b:1,rb:1,Xa:1,da:1,n:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ba:1,Wa:1,Lb:1,Sa:1});function mp(){this.f=null}mp.prototype=new t;l=mp.prototype;l.Ba=function(){return(new rm).Lf(this.f)};l.u=function(){return cj(this)};l.ma=function(a){return(new Re).nc(this.f.d[a])};l.pb=function(a){return Fi(this,a)};l.Qb=function(a){return Ui(this,a)};l.m=function(){return aj(this)};l.Fb=function(){var a=J().N;return Kj(this,a)};
+l.Ja=function(){return(new rm).Lf(this.f)};l.K=function(a){Fl||(Fl=(new El).b());return a&&a.a&&a.a.t.dp?this.f===(null===a?null:a.f):!1};l.Ec=function(a,b,d){return L(this,a,b,d)};l.fc=function(a){return L(this,"",a,"")};l.Kd=function(a){return(new On).od(this,a)};l.Dd=function(a,b){return Jj(this,a,b)};l.o=function(){return Lj(this)};l.R=function(a){Wi(this,a)};l.Qc=function(a,b){return Pi(this,a,b)};l.Rc=function(){uc();var a=vc().zb;return Kj(this,a)};l.pc=function(){return Xi(this)};l.U=function(){return this.f.d.length};
+l.Fc=function(a,b){return Fj(this,a,b)};l.X=function(){return W(new X,this,this.f.d.length)};l.ec=function(){return L(this,"","","")};l.q=function(){return this.f.d.length};l.Lf=function(a){this.f=a;return this};l.db=function(){var a=W(new X,this,this.f.d.length);return ij(a)};l.Zb=function(a){return Pi(this,a,this.f.d.length)};l.bc=function(){return(new rm).Lf(this.f)};l.s=function(){return $i(this)};l.rc=function(a,b,d,e){return Cj(this,a,b,d,e)};l.Dc=function(a){return ck(this,a)};l.Pb=c("f");
+l.Ac=function(a,b){return Ni(this,0,this.f.d.length,a,b)};l.Hc=function(a,b,d){yl(this,a,b,d)};l.Yc=h(!0);l.M=function(){return this.f.M()};l.lc=function(a){return Vj(this,a)};l.kc=function(a){this.f;return(new rm).Lf(a)};l.Kb=function(a){return Mi(this,a)};l.na=function(){this.f;return(new Du).b()};l.Wb=function(){return Rj(this)};l.a=new s({dp:0},!1,"scala.collection.mutable.ArrayOps$ofChar",{dp:1,c:1,of:1,qc:1,hc:1,$b:1,rb:1,Xa:1,da:1,n:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ba:1,Wa:1,Lb:1,Sa:1});
+function np(){this.f=null}np.prototype=new t;l=np.prototype;l.Ba=function(){return(new om).Mf(this.f)};l.u=function(){return cj(this)};l.ma=function(a){return this.f.d[a]};l.pb=function(a){return Fi(this,a)};l.Qb=function(a){return Ui(this,a)};l.m=function(){return aj(this)};l.Fb=function(){var a=J().N;return Kj(this,a)};l.Ja=function(){return(new om).Mf(this.f)};l.K=function(a){Hl||(Hl=(new Gl).b());return a&&a.a&&a.a.t.ep?this.f===(null===a?null:a.f):!1};l.Mf=function(a){this.f=a;return this};
+l.Ec=function(a,b,d){return L(this,a,b,d)};l.fc=function(a){return L(this,"",a,"")};l.Kd=function(a){return(new On).od(this,a)};l.Dd=function(a,b){return Jj(this,a,b)};l.o=function(){return Lj(this)};l.R=function(a){Wi(this,a)};l.Qc=function(a,b){return Pi(this,a,b)};l.Rc=function(){uc();var a=vc().zb;return Kj(this,a)};l.pc=function(){return Xi(this)};l.U=function(){return this.f.d.length};l.Fc=function(a,b){return Fj(this,a,b)};l.X=function(){return W(new X,this,this.f.d.length)};
+l.ec=function(){return L(this,"","","")};l.q=function(){return this.f.d.length};l.db=function(){var a=W(new X,this,this.f.d.length);return ij(a)};l.Zb=function(a){return Pi(this,a,this.f.d.length)};l.bc=function(){return(new om).Mf(this.f)};l.s=function(){return $i(this)};l.rc=function(a,b,d,e){return Cj(this,a,b,d,e)};l.Dc=function(a){return ck(this,a)};l.Pb=c("f");l.Ac=function(a,b){return Ni(this,0,this.f.d.length,a,b)};l.Hc=function(a,b,d){yl(this,a,b,d)};l.Yc=h(!0);l.M=function(){return this.f.M()};
+l.lc=function(a){return Vj(this,a)};l.kc=function(a){this.f;return(new om).Mf(a)};l.Kb=function(a){return Mi(this,a)};l.na=function(){this.f;return(new Gu).b()};l.Wb=function(){return Rj(this)};l.a=new s({ep:0},!1,"scala.collection.mutable.ArrayOps$ofDouble",{ep:1,c:1,of:1,qc:1,hc:1,$b:1,rb:1,Xa:1,da:1,n:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ba:1,Wa:1,Lb:1,Sa:1});function op(){this.f=null}op.prototype=new t;l=op.prototype;l.Ba=function(){return(new qm).Nf(this.f)};l.u=function(){return cj(this)};
+l.ma=function(a){return this.f.d[a]};l.pb=function(a){return Fi(this,a)};l.Qb=function(a){return Ui(this,a)};l.m=function(){return aj(this)};l.Fb=function(){var a=J().N;return Kj(this,a)};l.Ja=function(){return(new qm).Nf(this.f)};l.K=function(a){Jl||(Jl=(new Il).b());return a&&a.a&&a.a.t.fp?this.f===(null===a?null:a.f):!1};l.Ec=function(a,b,d){return L(this,a,b,d)};l.fc=function(a){return L(this,"",a,"")};l.Kd=function(a){return(new On).od(this,a)};l.Dd=function(a,b){return Jj(this,a,b)};l.o=function(){return Lj(this)};
+l.R=function(a){Wi(this,a)};l.Qc=function(a,b){return Pi(this,a,b)};l.Rc=function(){uc();var a=vc().zb;return Kj(this,a)};l.pc=function(){return Xi(this)};l.U=function(){return this.f.d.length};l.Fc=function(a,b){return Fj(this,a,b)};l.Nf=function(a){this.f=a;return this};l.X=function(){return W(new X,this,this.f.d.length)};l.ec=function(){return L(this,"","","")};l.q=function(){return this.f.d.length};l.db=function(){var a=W(new X,this,this.f.d.length);return ij(a)};
+l.Zb=function(a){return Pi(this,a,this.f.d.length)};l.bc=function(){return(new qm).Nf(this.f)};l.s=function(){return $i(this)};l.rc=function(a,b,d,e){return Cj(this,a,b,d,e)};l.Dc=function(a){return ck(this,a)};l.Pb=c("f");l.Ac=function(a,b){return Ni(this,0,this.f.d.length,a,b)};l.Hc=function(a,b,d){yl(this,a,b,d)};l.Yc=h(!0);l.M=function(){return this.f.M()};l.lc=function(a){return Vj(this,a)};l.kc=function(a){this.f;return(new qm).Nf(a)};l.Kb=function(a){return Mi(this,a)};
+l.na=function(){this.f;return(new Ju).b()};l.Wb=function(){return Rj(this)};l.a=new s({fp:0},!1,"scala.collection.mutable.ArrayOps$ofFloat",{fp:1,c:1,of:1,qc:1,hc:1,$b:1,rb:1,Xa:1,da:1,n:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ba:1,Wa:1,Lb:1,Sa:1});function pp(){this.f=null}pp.prototype=new t;l=pp.prototype;l.Ba=function(){return(new nm).Of(this.f)};l.u=function(){return cj(this)};l.ma=function(a){return this.f.d[a]};l.pb=function(a){return Fi(this,a)};l.Qb=function(a){return Ui(this,a)};l.m=function(){return aj(this)};
+l.Fb=function(){var a=J().N;return Kj(this,a)};l.Ja=function(){return(new nm).Of(this.f)};l.K=function(a){Ll||(Ll=(new Kl).b());return a&&a.a&&a.a.t.gp?this.f===(null===a?null:a.f):!1};l.Ec=function(a,b,d){return L(this,a,b,d)};l.fc=function(a){return L(this,"",a,"")};l.Kd=function(a){return(new On).od(this,a)};l.Dd=function(a,b){return Jj(this,a,b)};l.o=function(){return Lj(this)};l.R=function(a){Wi(this,a)};l.Qc=function(a,b){return Pi(this,a,b)};
+l.Rc=function(){uc();var a=vc().zb;return Kj(this,a)};l.pc=function(){return Xi(this)};l.U=function(){return this.f.d.length};l.Fc=function(a,b){return Fj(this,a,b)};l.X=function(){return W(new X,this,this.f.d.length)};l.Of=function(a){this.f=a;return this};l.ec=function(){return L(this,"","","")};l.q=function(){return this.f.d.length};l.db=function(){var a=W(new X,this,this.f.d.length);return ij(a)};l.Zb=function(a){return Pi(this,a,this.f.d.length)};l.bc=function(){return(new nm).Of(this.f)};
+l.s=function(){return $i(this)};l.rc=function(a,b,d,e){return Cj(this,a,b,d,e)};l.Dc=function(a){return ck(this,a)};l.Pb=c("f");l.Ac=function(a,b){return Ni(this,0,this.f.d.length,a,b)};l.Hc=function(a,b,d){yl(this,a,b,d)};l.Yc=h(!0);l.M=function(){return this.f.M()};l.lc=function(a){return Vj(this,a)};l.kc=function(a){this.f;return(new nm).Of(a)};l.Kb=function(a){return Mi(this,a)};l.na=function(){this.f;return(new Mu).b()};l.Wb=function(){return Rj(this)};
+l.a=new s({gp:0},!1,"scala.collection.mutable.ArrayOps$ofInt",{gp:1,c:1,of:1,qc:1,hc:1,$b:1,rb:1,Xa:1,da:1,n:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ba:1,Wa:1,Lb:1,Sa:1});function qp(){this.f=null}qp.prototype=new t;l=qp.prototype;l.Ba=function(){return(new pm).Pf(this.f)};l.u=function(){return cj(this)};l.ma=function(a){return this.f.d[a]};l.pb=function(a){return Fi(this,a)};l.Qb=function(a){return Ui(this,a)};l.m=function(){return aj(this)};l.Fb=function(){var a=J().N;return Kj(this,a)};
+l.Pf=function(a){this.f=a;return this};l.Ja=function(){return(new pm).Pf(this.f)};l.K=function(a){Nl||(Nl=(new Ml).b());return a&&a.a&&a.a.t.hp?this.f===(null===a?null:a.f):!1};l.Ec=function(a,b,d){return L(this,a,b,d)};l.fc=function(a){return L(this,"",a,"")};l.Kd=function(a){return(new On).od(this,a)};l.Dd=function(a,b){return Jj(this,a,b)};l.o=function(){return Lj(this)};l.R=function(a){Wi(this,a)};l.Qc=function(a,b){return Pi(this,a,b)};l.Rc=function(){uc();var a=vc().zb;return Kj(this,a)};
+l.pc=function(){return Xi(this)};l.U=function(){return this.f.d.length};l.Fc=function(a,b){return Fj(this,a,b)};l.X=function(){return W(new X,this,this.f.d.length)};l.ec=function(){return L(this,"","","")};l.q=function(){return this.f.d.length};l.db=function(){var a=W(new X,this,this.f.d.length);return ij(a)};l.Zb=function(a){return Pi(this,a,this.f.d.length)};l.bc=function(){return(new pm).Pf(this.f)};l.s=function(){return $i(this)};l.rc=function(a,b,d,e){return Cj(this,a,b,d,e)};
+l.Dc=function(a){return ck(this,a)};l.Pb=c("f");l.Ac=function(a,b){return Ni(this,0,this.f.d.length,a,b)};l.Hc=function(a,b,d){yl(this,a,b,d)};l.Yc=h(!0);l.M=function(){return this.f.M()};l.lc=function(a){return Vj(this,a)};l.kc=function(a){this.f;return(new pm).Pf(a)};l.Kb=function(a){return Mi(this,a)};l.na=function(){this.f;return(new Pu).b()};l.Wb=function(){return Rj(this)};
+l.a=new s({hp:0},!1,"scala.collection.mutable.ArrayOps$ofLong",{hp:1,c:1,of:1,qc:1,hc:1,$b:1,rb:1,Xa:1,da:1,n:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ba:1,Wa:1,Lb:1,Sa:1});function jp(){this.f=null}jp.prototype=new t;l=jp.prototype;l.Ba=function(){return(new Sb).me(this.f)};l.u=function(){return cj(this)};l.ma=function(a){return this.f.d[a]};l.pb=function(a){return Fi(this,a)};l.Qb=function(a){return Ui(this,a)};l.m=function(){return aj(this)};l.Fb=function(){var a=J().N;return Kj(this,a)};l.Ja=function(){return(new Sb).me(this.f)};
+l.K=function(a){Pl||(Pl=(new Ol).b());return a&&a.a&&a.a.t.ip?this.f===(null===a?null:a.f):!1};l.Ec=function(a,b,d){return L(this,a,b,d)};l.fc=function(a){return L(this,"",a,"")};l.Kd=function(a){return(new On).od(this,a)};l.Dd=function(a,b){return Jj(this,a,b)};l.o=function(){return Lj(this)};l.R=function(a){Wi(this,a)};l.Qc=function(a,b){return Pi(this,a,b)};l.Rc=function(){uc();var a=vc().zb;return Kj(this,a)};l.pc=function(){return Xi(this)};l.U=function(){return this.f.d.length};
+l.Fc=function(a,b){return Fj(this,a,b)};l.me=function(a){this.f=a;return this};l.X=function(){return W(new X,this,this.f.d.length)};l.ec=function(){return L(this,"","","")};l.q=function(){return this.f.d.length};l.db=function(){var a=W(new X,this,this.f.d.length);return ij(a)};l.Zb=function(a){return Pi(this,a,this.f.d.length)};l.bc=function(){return(new Sb).me(this.f)};l.s=function(){return $i(this)};l.rc=function(a,b,d,e){return Cj(this,a,b,d,e)};l.Dc=function(a){return ck(this,a)};l.Pb=c("f");
+l.Ac=function(a,b){return Ni(this,0,this.f.d.length,a,b)};l.Hc=function(a,b,d){yl(this,a,b,d)};l.Yc=h(!0);l.M=function(){return this.f.M()};l.lc=function(a){return Vj(this,a)};l.kc=function(a){this.f;return(new Sb).me(a)};l.Kb=function(a){return Mi(this,a)};l.na=function(){Pl||(Pl=(new Ol).b());var a=this.f;return(new Su).zk(sc(tc(),Mh(U(),la(a))))};l.Wb=function(){return Rj(this)};
+l.a=new s({ip:0},!1,"scala.collection.mutable.ArrayOps$ofRef",{ip:1,c:1,of:1,qc:1,hc:1,$b:1,rb:1,Xa:1,da:1,n:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ba:1,Wa:1,Lb:1,Sa:1});function rp(){this.f=null}rp.prototype=new t;l=rp.prototype;l.Ba=function(){return(new tm).Qf(this.f)};l.u=function(){return cj(this)};l.ma=function(a){return this.f.d[a]};l.pb=function(a){return Fi(this,a)};l.Qb=function(a){return Ui(this,a)};l.m=function(){return aj(this)};l.Fb=function(){var a=J().N;return Kj(this,a)};
+l.Qf=function(a){this.f=a;return this};l.Ja=function(){return(new tm).Qf(this.f)};l.K=function(a){Rl||(Rl=(new Ql).b());return a&&a.a&&a.a.t.jp?this.f===(null===a?null:a.f):!1};l.Ec=function(a,b,d){return L(this,a,b,d)};l.fc=function(a){return L(this,"",a,"")};l.Kd=function(a){return(new On).od(this,a)};l.Dd=function(a,b){return Jj(this,a,b)};l.o=function(){return Lj(this)};l.R=function(a){Wi(this,a)};l.Qc=function(a,b){return Pi(this,a,b)};l.Rc=function(){uc();var a=vc().zb;return Kj(this,a)};
+l.pc=function(){return Xi(this)};l.U=function(){return this.f.d.length};l.Fc=function(a,b){return Fj(this,a,b)};l.X=function(){return W(new X,this,this.f.d.length)};l.ec=function(){return L(this,"","","")};l.q=function(){return this.f.d.length};l.db=function(){var a=W(new X,this,this.f.d.length);return ij(a)};l.Zb=function(a){return Pi(this,a,this.f.d.length)};l.bc=function(){return(new tm).Qf(this.f)};l.s=function(){return $i(this)};l.rc=function(a,b,d,e){return Cj(this,a,b,d,e)};
+l.Dc=function(a){return ck(this,a)};l.Pb=c("f");l.Ac=function(a,b){return Ni(this,0,this.f.d.length,a,b)};l.Hc=function(a,b,d){yl(this,a,b,d)};l.Yc=h(!0);l.M=function(){return this.f.M()};l.lc=function(a){return Vj(this,a)};l.kc=function(a){this.f;return(new tm).Qf(a)};l.Kb=function(a){return Mi(this,a)};l.na=function(){this.f;return(new Vu).b()};l.Wb=function(){return Rj(this)};
+l.a=new s({jp:0},!1,"scala.collection.mutable.ArrayOps$ofShort",{jp:1,c:1,of:1,qc:1,hc:1,$b:1,rb:1,Xa:1,da:1,n:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ba:1,Wa:1,Lb:1,Sa:1});function sp(){this.f=null}sp.prototype=new t;l=sp.prototype;l.Ba=function(){return(new wm).Sf(this.f)};l.u=function(){return cj(this)};l.ma=ba();l.pb=function(a){return Fi(this,a)};l.Qb=function(a){return Ui(this,a)};l.m=function(){return aj(this)};l.Fb=function(){var a=J().N;return Kj(this,a)};l.Ja=function(){return(new wm).Sf(this.f)};
+l.K=function(a){Tl||(Tl=(new Sl).b());return a&&a.a&&a.a.t.kp?this.f===(null===a?null:a.f):!1};l.Ec=function(a,b,d){return L(this,a,b,d)};l.fc=function(a){return L(this,"",a,"")};l.Kd=function(a){return(new On).od(this,a)};l.Dd=function(a,b){return Jj(this,a,b)};l.o=function(){return Lj(this)};l.R=function(a){Wi(this,a)};l.Qc=function(a,b){return Pi(this,a,b)};l.Rc=function(){uc();var a=vc().zb;return Kj(this,a)};l.pc=function(){return Xi(this)};l.U=function(){return this.f.d.length};
+l.Fc=function(a,b){return Fj(this,a,b)};l.X=function(){return W(new X,this,this.f.d.length)};l.ec=function(){return L(this,"","","")};l.q=function(){return this.f.d.length};l.db=function(){var a=W(new X,this,this.f.d.length);return ij(a)};l.Zb=function(a){return Pi(this,a,this.f.d.length)};l.Sf=function(a){this.f=a;return this};l.bc=function(){return(new wm).Sf(this.f)};l.s=function(){return $i(this)};l.rc=function(a,b,d,e){return Cj(this,a,b,d,e)};l.Dc=function(a){return ck(this,a)};l.Pb=c("f");
+l.Ac=function(a,b){return Ni(this,0,this.f.d.length,a,b)};l.Hc=function(a,b,d){yl(this,a,b,d)};l.Yc=h(!0);l.M=function(){return this.f.M()};l.lc=function(a){return Vj(this,a)};l.kc=function(a){this.f;return(new wm).Sf(a)};l.Kb=function(a){return Mi(this,a)};l.na=function(){this.f;return(new Yu).b()};l.Wb=function(){return Rj(this)};l.a=new s({kp:0},!1,"scala.collection.mutable.ArrayOps$ofUnit",{kp:1,c:1,of:1,qc:1,hc:1,$b:1,rb:1,Xa:1,da:1,n:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ba:1,Wa:1,Lb:1,Sa:1});
+function Gw(){}Gw.prototype=new Fw;function Hw(){}Hw.prototype=Gw.prototype;
+function Iw(){this.lH=this.WG=this.Ej=this.eJ=this.ZI=this.$I=this.YI=this.yj=this.HH=this.IH=this.dj=this.hH=this.Vi=this.qH=this.Ui=this.VI=this.LH=this.jj=this.gH=this.BH=this.nH=this.DH=this.gj=this.dJ=this.fJ=this.AH=this.zH=this.JH=this.Ni=this.mH=this.pH=this.jH=this.iH=this.Li=this.fH=this.eH=this.dH=this.aH=this.ZG=this.$G=this.YG=this.bH=this.SE=this.sl=this.pE=this.xj=this.YD=this.Vw=this.Eg=this.zv=this.Eu=this.Du=this.vu=this.lu=this.ku=this.Ji=this.tm=this.Vs=this.aF=this.j=this.PE=
+this.Mp=this.AE=this.jE=this.ve=this.yz=this.vz=this.mz=this.oi=this.Ha=this.yx=this.ux=this.Bx=this.zx=this.rx=this.be=this.yv=this.mv=this.lv=this.kv=this.jv=this.iv=this.hv=this.au=this.ft=this.et=this.Ws=this.Cy=this.Vx=this.Tx=this.gy=this.Zy=this.Yy=this.Vy=this.Uy=this.Ry=this.Oy=this.Ny=this.Iy=this.Hy=this.Fy=this.Ey=this.Dy=this.ry=this.qy=this.py=this.fy=this.ey=this.dy=this.Ux=this.Qx=this.Px=this.Kx=this.Wy=this.Qy=this.my=this.ny=this.ly=this.$y=this.Ly=this.xy=this.wy=this.vy=this.uy=
+this.ty=this.cy=this.by=this.ay=this.$x=this.Zx=this.Yx=this.Xx=this.Wx=this.Un=this.Xy=this.Sy=this.Ky=this.Gy=this.By=this.Ay=this.zy=this.yy=this.sy=this.iy=this.Nx=this.Mx=this.Lx=this.oy=this.wj=this.My=this.ky=this.jy=this.Sx=this.Jy=this.Ty=this.Py=this.hy=this.Rx=this.Ox=this.Cz=this.hu=this.vx=this.Dv=this.Ob=this.Az=this.gu=this.Bz=this.fv=this.wu=this.Zt=this.Us=this.eF=this.hE=this.xz=this.Ys=this.Yi=this.iF=this.bF=this.Dj=this.GE=this.FE=this.Gp=this.EE=this.hz=this.ez=this.dz=this.Mn=
+this.Ax=this.sx=this.Zw=this.qm=this.Sp=this.Cj=this.lx=this.nx=this.mx=this.kx=this.dv=this.bv=this.cv=this.ev=this.Qt=this.iz=this.dx=this.E=this.Hn=this.L=this.bo=this.ao=this.Ok=this.eo=this.co=this.fi=this.tx=this.az=this.zt=this.Lt=this.wt=this.Pt=this.Dt=this.Jt=this.Ot=this.Ct=this.xt=this.Et=this.Bt=this.pm=this.ut=this.At=this.yt=this.tt=this.om=this.Ft=this.vt=this.Mt=this.Ht=this.Gt=this.Nt=this.It=this.Kt=this.it=this.xf=this.jt=this.kt=this.ht=this.HE=this.cz=this.bz=this.ou=this.zD=
+this.Tt=this.Tv=this.Uw=this.Yw=this.Uu=this.gv=this.JE=this.CE=this.QE=this.IE=this.KE=this.BE=this.eu=this.fu=this.Yt=this.qE=this.$s=this.jx=this.Xt=this.RE=this.WD=this.ct=this.XE=this.kz=this.Gx=this.Hu=this.Ev=this.Fv=this.su=this.Uv=this.ZE=this.Rt=this.XD=this.UE=this.gt=this.ln=this.nE=this.lE=this.du=this.bu=this.yb=this.SD=this.kE=this.Gu=this.Ae=this.Oi=this.Vu=this.Wu=this.pu=this.Fu=this.xu=this.Gn=this.ul=this.Ix=this.pt=this.nz=this.Bv=this.hj=this.Wi=this.df=this.xv=this.wv=this.vv=
+this.uv=this.tv=this.sv=this.Sh=this.xD=this.wx=this.ae=this.lt=this.cf=this.Cv=this.Bu=this.$u=this.fx=this.Lc=this.BD=this.Vt=this.st=this.vh=this.Cu=this.av=this.gx=this.qn=this.CD=this.Wt=this.nm=this.Ia=this.Au=this.Zu=this.ex=this.Wv=this.AD=this.Ut=this.rt=this.Og=this.Ps=this.Ms=this.mq=this.Ls=this.Ds=null}Iw.prototype=new t;
+Iw.prototype.b=function(){Jw=this;this.Vs=I(F(this,"accesskey"));this.Ji=this.tm=I(F(this,"class"));this.ku=I(F(this,"contenteditable"));this.lu=I(F(this,"contextmenu"));this.vu=I(F(this,"dir"));this.Du=I(F(this,"draggable"));this.Eu=I(F(this,"dropzone"));this.zv=I(F(this,"hidden"));this.Eg=I(F(this,"id"));this.Vw=I(F(this,"lang"));var a=I(F(this,"spellcheck")),b=(new qn).b();this.YD=Dc(new Ec,a,"spellcheck",b);this.xj=I(F(this,"style"));this.pE=I(F(this,"tabindex"));this.sl=I(F(this,"title"));this.SE=
+I(F(this,"translate"));this.Ws=I(F(this,"action"));this.et=I(F(this,"autocomplete"));a=I(F(this,"autofocus"));b=(new qn).b();this.ft=Dc(new Ec,a,"autofocus",b);this.au=I(F(this,"checked"));this.hv=I(F(this,"form"));this.iv=I(F(this,"formaction"));this.jv=I(F(this,"formenctype"));this.kv=I(F(this,"formmethod"));this.lv=I(F(this,"formnovalidate"));this.mv=I(F(this,"formtarget"));this.yv=I(F(this,"height"));this.be=I(F(this,"list"));this.rx=I(F(this,"max"));this.zx=I(F(this,"min"));this.Bx=I(F(this,
+"multiple"));this.ux=I(F(this,"maxlength"));this.yx=I(F(this,"method"));this.Ha=I(F(this,"name"));this.oi=I(F(this,"pattern"));this.mz=I(F(this,"placeholder"));a=I(F(this,"readonly"));b=(new qn).b();this.vz=Dc(new Ec,a,"readonly",b);a=I(F(this,"required"));b=(new qn).b();this.yz=Dc(new Ec,a,"required",b);this.ve=I(F(this,"size"));this.jE=I(F(this,"step"));this.AE=I(F(this,"target"));this.PE=this.Mp=I(F(this,"type"));this.j=I(F(this,"value"));this.aF=I(F(this,"width"));this.Tx=I(F(this,"oncopy"));
+this.Vx=I(F(this,"oncut"));this.Cy=I(F(this,"onpaste"));this.gy=I(F(this,"onerror"));this.Kx=I(F(this,"onabort"));this.Px=I(F(this,"oncanplay"));this.Qx=I(F(this,"oncanplaythrough"));this.Ux=I(F(this,"oncuechange"));this.dy=I(F(this,"ondurationchange"));this.ey=I(F(this,"onemptied"));this.fy=I(F(this,"onended"));this.py=I(F(this,"onloadeddata"));this.qy=I(F(this,"onloadedmetadata"));this.ry=I(F(this,"onloadstart"));this.Dy=I(F(this,"onpause"));this.Ey=I(F(this,"onplay"));this.Fy=I(F(this,"onplaying"));
+this.Hy=I(F(this,"onprogress"));this.Iy=I(F(this,"onratechange"));this.Ny=I(F(this,"onseeked"));this.Oy=I(F(this,"onseeking"));this.Ry=I(F(this,"onstalled"));this.Uy=I(F(this,"onsuspend"));this.Vy=I(F(this,"ontimeupdate"));this.Yy=I(F(this,"onvolumechange"));this.Zy=I(F(this,"onwaiting"));this.Qy=I(F(this,"onshow"));this.Wy=I(F(this,"ontoggle"));this.ly=I(F(this,"onkeydown"));this.ny=I(F(this,"onkeyup"));this.my=I(F(this,"onkeypress"));this.Un=I(F(this,"onclick"));this.Wx=I(F(this,"ondblclick"));
+this.Xx=I(F(this,"ondrag"));this.Yx=I(F(this,"ondragend"));this.Zx=I(F(this,"ondragenter"));this.$x=I(F(this,"ondragleave"));this.ay=I(F(this,"ondragover"));this.by=I(F(this,"ondragstart"));this.cy=I(F(this,"ondrop"));this.ty=I(F(this,"onmousedown"));this.uy=I(F(this,"onmousemove"));this.vy=I(F(this,"onmouseout"));this.wy=I(F(this,"onmouseover"));this.xy=I(F(this,"onmouseup"));this.Ly=I(F(this,"onscroll"));this.$y=I(F(this,"onwheel"));this.oy=I(F(this,"onload"));this.Lx=I(F(this,"onafterprint"));
+this.Mx=I(F(this,"onbeforeprint"));this.Nx=I(F(this,"onbeforeunload"));this.iy=I(F(this,"onhashchange"));this.sy=I(F(this,"onmessage"));this.yy=I(F(this,"onoffline"));this.zy=I(F(this,"ononline"));this.Ay=I(F(this,"onpagehide"));this.By=I(F(this,"onpageshow"));this.Gy=I(F(this,"onpopstate"));this.Ky=I(F(this,"onresize"));this.Sy=I(F(this,"onstorage"));this.Xy=I(F(this,"onunload"));this.Ox=I(F(this,"onblur"));this.Rx=I(F(this,"onchange"));this.hy=I(F(this,"onfocus"));this.Py=I(F(this,"onselect"));
+this.Ty=I(F(this,"onsubmit"));this.Jy=I(F(this,"onreset"));this.Sx=I(F(this,"oncontextmenu"));this.jy=I(F(this,"oninput"));this.ky=I(F(this,"oninvalid"));this.My=I(F(this,"onsearch"));this.wj=I(F(this,"selected"));this.Yi=I(F(this,"href"));this.Ys=I(F(this,"alt"));this.xz=I(F(this,"rel"));this.hE=I(F(this,"src"));this.eF=I(F(this,"xmlns"));this.Us=I(F(this,"accept"));this.Zt=I(F(this,"charset"));a=I(F(this,"disabled"));b=(new qn).b();this.wu=Dc(new Ec,a,"disabled",b);this.fv=I(F(this,"for"));this.Bz=
+I(F(this,"rows"));this.gu=I(F(this,"cols"));this.Az=I(F(this,"role"));this.Ob=I(F(this,"content"));this.Dv=I(F(this,"http-equiv"));this.vx=I(F(this,"media"));this.hu=I(F(this,"colspan"));this.Cz=I(F(this,"rowspan"));this.ht=(new E).ia("background","background");this.kt=(new E).ia("backgroundRepeat","background-repeat");this.jt=(new E).ia("backgroundPosition","background-position");this.xf=(new E).ia("backgroundColor","background-color");this.it=(new it).Ea(this,"backgroundImage","background-image");
+this.Kt=(new E).ia("borderTopColor","border-top-color");this.It=(new E).ia("borderStyle","border-style");this.Nt=(new $t).Ea(this,"borderTopStyle","border-top-style");this.Gt=(new $t).Ea(this,"borderRightStyle","border-right-style");this.Ht=(new ft).Ea(this,"borderRightWidth","border-right-width");this.Mt=(new et).Ea(this,"borderTopRightRadius","border-top-right-radius");this.vt=(new et).Ea(this,"borderBottomLeftRadius","border-bottom-left-radius");this.Ft=(new E).ia("borderRightColor","border-right-color");
+this.om=(new E).ia("borderBottom","border-bottom");this.tt=(new E).ia("border","border");this.yt=(new ft).Ea(this,"borderBottomWidth","border-bottom-width");this.At=(new E).ia("borderLeftColor","border-left-color");this.ut=(new E).ia("borderBottomColor","border-bottom-color");this.pm=(new E).ia("borderLeft","border-left");this.Bt=(new $t).Ea(this,"borderLeftStyle","border-left-style");this.Et=(new E).ia("borderRight","border-right");this.xt=(new $t).Ea(this,"borderBottomStyle","border-bottom-style");
+this.Ct=(new ft).Ea(this,"borderLeftWidth","border-left-width");this.Ot=(new ft).Ea(this,"borderTopWidth","border-top-width");this.Jt=(new E).ia("borderTop","border-top");this.Dt=(new E).ia("borderRadius","border-radius");this.Pt=(new E).ia("borderWidth","border-width");this.wt=(new et).Ea(this,"borderBottomRightRadius","border-bottom-right-radius");this.Lt=(new et).Ea(this,"borderTopLeftRadius","border-top-left-radius");this.zt=(new E).ia("borderColor","border-color");this.az=(new E).ia("opacity",
+"opacity");this.tx=(new E).ia("maxWidth","max-width");this.fi=(new pt).Ea(this,"height","height");this.co=(new Hr).ia("paddingRight","padding-right");this.eo=(new Hr).ia("paddingTop","padding-top");this.Ok=(new Hr).ia("paddingLeft","padding-left");this.ao=(new Hr).ia("padding","padding");this.bo=(new Hr).ia("paddingBottom","padding-bottom");this.L=(new pt).Ea(this,"right","right");this.Hn=(new kt).Ea(this,"lineHeight","line-height");this.E=(new pt).Ea(this,"left","left");this.dx=(new E).ia("listStyle",
+"list-style");this.iz=(new nt).Ea(this,"overflowY","overflow-y");this.Qt=(new E).ia("boxShadow","box-shadow");this.ev=(new E).ia("fontSizeAdjust","font-size-adjust");this.cv=(new E).ia("fontFamily","font-family");this.bv=(new E).ia("font","font");this.dv=(new E).ia("fontFeatureSettings","font-feature-settings");this.kx=(new pt).Ea(this,"marginBottom","margin-bottom");this.mx=(new au).xb(this);this.nx=(new bu).xb(this);this.lx=(new cu).xb(this);this.Cj=(new pt).Ea(this,"top","top");this.Sp=(new pt).Ea(this,
+"width","width");this.qm=(new pt).Ea(this,"bottom","bottom");this.Zw=(new kt).Ea(this,"letterSpacing","letter-spacing");this.sx=(new jt).Ea(this,"maxHeight","max-height");this.Ax=(new E).ia("minWidth","min-width");this.Mn=(new E).ia("minHeight","min-height");this.dz=(new E).ia("outline","outline");this.ez=(new lt).Ea(this,"outlineStyle","outline-style");this.hz=(new nt).Ea(this,"overflowX","overflow-x");this.EE=(new du).xb(this);this.Gp=(new eu).xb(this);this.FE=(new E).ia("textIndent","text-indent");
+this.GE=(new jt).Ea(this,"textShadow","text-shadow");this.Dj=(new E).ia("transition","transition");this.bF=(new kt).Ea(this,"wordSpacing","word-spacing");this.iF=(new dt).Ea(this,"zIndex","z-index");this.Cv=D(F(this,"html"));this.cf=D(F(this,"head"));this.lt=zb(F(this,"base"));this.ae=zb(F(this,"link"));this.wx=zb(F(this,"meta"));this.xD=D(F(this,"script"));this.Sh=D(F(this,"body"));this.sv=D(F(this,"h1"));this.tv=D(F(this,"h2"));this.uv=D(F(this,"h3"));this.vv=D(F(this,"h4"));this.wv=D(F(this,"h5"));
+this.xv=D(F(this,"h6"));this.df=D(F(this,"header"));this.Wi=D(F(this,"footer"));this.hj=D(F(this,"p"));this.Bv=zb(F(this,"hr"));this.nz=D(F(this,"pre"));this.pt=D(F(this,"blockquote"));this.Ix=D(F(this,"ol"));this.ul=D(F(this,"ul"));this.Gn=D(F(this,"li"));this.xu=D(F(this,"dl"));this.Fu=D(F(this,"dt"));this.pu=D(F(this,"dd"));this.Wu=D(F(this,"figure"));this.Vu=D(F(this,"figcaption"));this.Oi=D(F(this,"div"));this.Ae=D(F(this,"a"));this.Gu=D(F(this,"em"));this.kE=D(F(this,"strong"));this.SD=D(F(this,
+"small"));this.yb=D(F(this,"s"));this.bu=D(F(this,"cite"));this.du=D(F(this,"code"));this.lE=D(F(this,"sub"));this.nE=D(F(this,"sup"));this.ln=D(F(this,"i"));this.gt=D(F(this,"b"));this.UE=D(F(this,"u"));this.XD=D(F(this,"span"));this.Rt=zb(F(this,"br"));this.ZE=zb(F(this,"wbr"));this.Uv=D(F(this,"ins"));this.su=D(F(this,"del"));this.Fv=zb(F(this,"img"));this.Ev=D(F(this,"iframe"));this.Hu=zb(F(this,"embed"));this.Gx=D(F(this,"object"));this.kz=zb(F(this,"param"));this.XE=D(F(this,"video"));this.ct=
+D(F(this,"audio"));this.WD=zb(F(this,"source"));this.RE=zb(F(this,"track"));this.Xt=D(F(this,"canvas"));this.jx=D(F(this,"map"));this.$s=zb(F(this,"area"));this.qE=D(F(this,"table"));this.Yt=D(F(this,"caption"));this.fu=D(F(this,"colgroup"));this.eu=zb(F(this,"col"));this.BE=D(F(this,"tbody"));this.KE=D(F(this,"thead"));this.IE=D(F(this,"tfoot"));this.QE=D(F(this,"tr"));this.CE=D(F(this,"td"));this.JE=D(F(this,"th"));this.gv=D(F(this,"form"));this.Uu=D(F(this,"fieldset"));this.Yw=D(F(this,"legend"));
+this.Uw=D(F(this,"label"));this.Tv=zb(F(this,"input"));this.Tt=D(F(this,"button"));this.zD=D(F(this,"select"));this.ou=D(F(this,"datalist"));this.bz=D(F(this,"optgroup"));this.cz=D(F(this,"option"));this.HE=D(F(this,"textarea"));this.Og=(new qn).b();this.rt=(new qn).b();this.Ut=(new qn).b();this.AD=(new qn).b();this.Wv=(new qn).b();this.ex=(new qn).b();this.Zu=(new qn).b();this.Au=(new qn).b();this.Ia=(new z).b();this.nm=(new z).b();this.Wt=(new z).b();this.CD=(new z).b();this.qn=(new z).b();this.gx=
+(new z).b();this.av=(new z).b();this.Cu=(new z).b();this.vh=(new wb).$d(this.Ia);this.st=(new wb).$d(this.nm);this.Vt=(new rn).$d(this.Ia);this.BD=(new rn).$d(this.Ia);this.Lc=(new rn).$d(this.Ia);this.fx=(new rn).$d(this.Ia);this.$u=(new rn).$d(this.Ia);this.Bu=(new rn).$d(this.Ia);Br||(Br=(new Ar).b());this.Ds=Br;Er||(Er=(new Dr).b());this.Ls=Er;this.mq=ro();this.Ms=ro();this.Ps=ro();return this};function Pd(){var a=N();null===a.gj&&null===a.gj&&(a.gj=(new gu).xb(a));return a.gj}
+function Yc(){var a=N();null===a.Ni&&null===a.Ni&&(a.Ni=(new qt).xb(a));return a.Ni}function Vd(){var a=N();null===a.Vi&&null===a.Vi&&(a.Vi=(new rt).xb(a));return a.Vi}function Qd(){var a=N();null===a.jj&&null===a.jj&&(a.jj=(new tt).xb(a));return a.jj}function ad(){var a=N();null===a.Li&&null===a.Li&&(a.Li=(new fu).xb(a));return a.Li}function Ud(){var a=N();null===a.yj&&null===a.yj&&(a.yj=(new ut).xb(a));return a.yj}
+function Fc(){var a=N();null===a.dj&&null===a.dj&&(a.dj=(new st).xb(a));return a.dj}Iw.prototype.a=new s({Iq:0},!1,"scalatags.JsDom$all$",{Iq:1,c:1,zq:1,pr:1,Nq:1,PF:1,TF:1,SF:1,QF:1,VF:1,YF:1,WF:1,UF:1,XF:1,fG:1,RF:1,bG:1,ZF:1,gG:1,cG:1,KF:1,LF:1,NF:1,OF:1,MF:1});var Jw=void 0;function N(){Jw||(Jw=(new Iw).b());return Jw}function Kw(){}Kw.prototype=new Fw;function Lw(){}l=Lw.prototype=Kw.prototype;
+l.pb=function(a){a:if(0>a)a=1;else{for(var b=0,d=this.X();d.Ca();){if(b===a){a=d.Ca()?1:0;break a}d.wa();b=1+b|0}a=b-a|0}return a};l.m=function(){return 0===this.pb(0)};l.K=function(a){return Nr(a)?this.Qb(a):!1};l.Dd=function(a,b){return Jj(this,a,b)};l.o=function(){return Lj(this)};l.pc=function(){return Gj(this)};l.lf=function(a){return tf(new uf,this,a)};l.U=function(){return this.q()};l.Fc=function(a,b){return Fj(this,a,b)};l.bc=function(){return this};l.Bb=function(a,b){return Ng(this,a,b)};
+l.M=function(){return Nn(wi(),this.Me())};l.kc=aa();function Mw(){}Mw.prototype=new Fw;function Nw(){}l=Nw.prototype=Mw.prototype;l.Ba=function(){return this.dg()};l.l=function(a){return yj(this,a)};l.Ja=function(){return this};l.m=function(){return 0===this.U()};l.K=function(a){return Bi(this,a)};l.o=function(){return Lj(this)};l.Ff=function(){return Yj()};l.lf=function(a){return tf(new uf,this,a)};l.dg=function(){return this};l.Gb=function(a){return Ab(this.Xc(a))};
+l.rc=function(a,b,d,e){return zj(this,a,b,d,e)};l.Va=function(a){return this.Gb(a)};l.M=function(){var a=wi();return ti(a,this.dg(),a.Jk)};l.Bb=function(a,b){return Ng(this,a,b)};l.na=function(){return Wj(new Xj,this.Ff())};l.Wb=h("Map");function Ow(){}Ow.prototype=new Fw;function Pw(){}l=Pw.prototype=Ow.prototype;l.m=function(){return 0===this.U()};l.K=function(a){return Ei(this,a)};l.o=function(){return Lj(this)};l.ol=function(a){return this.ci(a)};l.M=function(){var a=wi();return ti(a,this,a.ml)};
+l.na=function(){return vr(new tr,this.xg())};l.Wb=h("Set");function Bf(){this.W=this.Si=null}Bf.prototype=new Nw;function Qw(){}l=Qw.prototype=Bf.prototype;l.Fj=function(a){var b=Wj(new Xj,Yj());lk(b,this);qk(b,(new V).ha(a.Ua,a.$a));return b.ob};l.R=function(a){(new On).od(this.W,M(function(){return function(a){return null!==a}}(this))).R(M(function(a,d){return function(e){if(null!==e)return d.l((new V).ha(e.Ua,a.Si.l(e.$a)));throw(new K).w(e);}}(this,a)))};
+l.Ak=function(a,b){this.Si=b;if(null===a)throw G(H(),null);this.W=a;return this};l.U=function(){return this.W.U()};l.X=function(){var a=this.W.X(),a=(new ss).Zi(a,M(function(){return function(a){return null!==a}}(this)));return(new Aj).Zi(a,M(function(a){return function(d){if(null!==d)return(new V).ha(d.Ua,a.Si.l(d.$a));throw(new K).w(d);}}(this)))};l.Xc=function(a){a=this.W.Xc(a);var b=this.Si;return a.m()?sg():(new tg).w(b.l(a.Wc()))};l.Gb=function(a){return this.W.Gb(a)};l.Yd=function(a){return this.Fj(a)};
+l.a=new s({Xk:0},!1,"scala.collection.MapLike$MappedValues",{Xk:1,wd:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,fd:1,Oc:1,dd:1,gd:1,la:1,x:1,ab:1,ro:1});function Rw(){}Rw.prototype=new Nw;function Sw(){}l=Sw.prototype=Rw.prototype;l.b=function(){return this};l.Ba=function(){return this};l.Ja=function(){return this};l.Ab=function(){return qs()};l.Ff=function(){return this.kk()};l.kk=function(){return Yj()};l.dg=function(){return this};l.lc=function(){return this};
+l.cj=function(a){return Tw(this,a)};function Uw(){}Uw.prototype=new Pw;function Vw(){}l=Vw.prototype=Uw.prototype;l.Ba=function(){return this};l.b=function(){return this};l.u=function(){throw(new uj).h("Set has no elements");};l.l=function(a){return this.Gb(a)};l.m=h(!0);l.Ja=function(){return this};l.Zk=function(){throw(new uj).h("Empty ListSet has no outer pointer");};l.Ab=function(){lw||(lw=(new kw).b());return lw};l.zh=function(a){return fr(this,a)};l.U=h(0);l.X=function(){return(new Ds).gh(this)};
+l.xg=function(){return cr()};l.s=function(){return this.ql()};l.Gb=h(!1);l.ze=function(a){return this.zh(a)};l.ql=function(){throw(new uj).h("Next of an empty set");};l.Wb=h("ListSet");function Ww(){}Ww.prototype=new Pw;l=Ww.prototype;l.Ba=function(){return this};l.b=function(){Xw=this;return this};l.l=h(!1);l.Ja=function(){return this};l.Ab=function(){return ep()};l.R=ba();l.U=h(0);l.X=function(){return $g().Cc};l.xg=function(){return Vt()};l.ze=function(a){return(new Yw).w(a)};
+l.a=new s({rC:0},!1,"scala.collection.immutable.Set$EmptySet$",{rC:1,re:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,de:1,x:1,Sd:1,ce:1,fe:1,ee:1,ab:1,te:1,Na:1,Qa:1,Pa:1,g:1,e:1});var Xw=void 0;function Vt(){Xw||(Xw=(new Ww).b());return Xw}function Yw(){this.wb=null}Yw.prototype=new Pw;l=Yw.prototype;l.Ba=function(){return this};l.l=function(a){return this.Gb(a)};l.Ja=function(){return this};l.Ab=function(){return ep()};l.ci=function(a){return!!a.l(this.wb)};
+l.R=function(a){a.l(this.wb)};l.U=h(1);l.w=function(a){this.wb=a;return this};l.X=function(){$g();var a=(new C).A([this.wb]);return W(new X,a,a.p.length|0)};l.xg=function(){return Vt()};l.lg=function(a){return this.Gb(a)?this:(new Zw).ha(this.wb,a)};l.Gb=function(a){return O(P(),a,this.wb)};l.ze=function(a){return this.lg(a)};
+l.a=new s({sC:0},!1,"scala.collection.immutable.Set$Set1",{sC:1,re:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,de:1,x:1,Sd:1,ce:1,fe:1,ee:1,ab:1,te:1,Na:1,Qa:1,Pa:1,g:1,e:1});function Zw(){this.mc=this.wb=null}Zw.prototype=new Pw;l=Zw.prototype;l.Ba=function(){return this};l.l=function(a){return this.Gb(a)};l.Ja=function(){return this};l.ha=function(a,b){this.wb=a;this.mc=b;return this};l.Ab=function(){return ep()};
+l.ci=function(a){return!!a.l(this.wb)&&!!a.l(this.mc)};l.R=function(a){a.l(this.wb);a.l(this.mc)};l.U=h(2);l.X=function(){$g();var a=(new C).A([this.wb,this.mc]);return W(new X,a,a.p.length|0)};l.xg=function(){return Vt()};l.lg=function(a){if(this.Gb(a))a=this;else{var b=this.mc,d=new $w;d.wb=this.wb;d.mc=b;d.Od=a;a=d}return a};l.Gb=function(a){return O(P(),a,this.wb)||O(P(),a,this.mc)};l.ze=function(a){return this.lg(a)};
+l.a=new s({tC:0},!1,"scala.collection.immutable.Set$Set2",{tC:1,re:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,de:1,x:1,Sd:1,ce:1,fe:1,ee:1,ab:1,te:1,Na:1,Qa:1,Pa:1,g:1,e:1});function $w(){this.Od=this.mc=this.wb=null}$w.prototype=new Pw;l=$w.prototype;l.Ba=function(){return this};l.l=function(a){return this.Gb(a)};l.Ja=function(){return this};l.Ab=function(){return ep()};l.ci=function(a){return!!a.l(this.wb)&&!!a.l(this.mc)&&!!a.l(this.Od)};
+l.R=function(a){a.l(this.wb);a.l(this.mc);a.l(this.Od)};l.U=h(3);l.X=function(){$g();var a=(new C).A([this.wb,this.mc,this.Od]);return W(new X,a,a.p.length|0)};l.xg=function(){return Vt()};l.lg=function(a){return this.Gb(a)?this:(new ax).gf(this.wb,this.mc,this.Od,a)};l.Gb=function(a){return O(P(),a,this.wb)||O(P(),a,this.mc)||O(P(),a,this.Od)};l.ze=function(a){return this.lg(a)};
+l.a=new s({uC:0},!1,"scala.collection.immutable.Set$Set3",{uC:1,re:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,de:1,x:1,Sd:1,ce:1,fe:1,ee:1,ab:1,te:1,Na:1,Qa:1,Pa:1,g:1,e:1});function ax(){this.dh=this.Od=this.mc=this.wb=null}ax.prototype=new Pw;l=ax.prototype;l.Ba=function(){return this};l.l=function(a){return this.Gb(a)};l.Ja=function(){return this};l.Ab=function(){return ep()};l.ci=function(a){return!!a.l(this.wb)&&!!a.l(this.mc)&&!!a.l(this.Od)&&!!a.l(this.dh)};
+l.R=function(a){a.l(this.wb);a.l(this.mc);a.l(this.Od);a.l(this.dh)};l.U=h(4);l.X=function(){$g();var a=(new C).A([this.wb,this.mc,this.Od,this.dh]);return W(new X,a,a.p.length|0)};l.xg=function(){return Vt()};l.lg=function(a){if(this.Gb(a))return this;var b=(new bx).b(),d=this.mc;a=[this.Od,this.dh,a];var e=cx(cx(b,this.wb),d),b=0,d=a.length|0,f=e;for(;;){if(b===d)return f;e=1+b|0;f=f.ze(a[b]);b=e}};l.Gb=function(a){return O(P(),a,this.wb)||O(P(),a,this.mc)||O(P(),a,this.Od)||O(P(),a,this.dh)};
+l.gf=function(a,b,d,e){this.wb=a;this.mc=b;this.Od=d;this.dh=e;return this};l.ze=function(a){return this.lg(a)};l.a=new s({vC:0},!1,"scala.collection.immutable.Set$Set4",{vC:1,re:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,de:1,x:1,Sd:1,ce:1,fe:1,ee:1,ab:1,te:1,Na:1,Qa:1,Pa:1,g:1,e:1});function bx(){}bx.prototype=new Pw;function dx(){}l=dx.prototype=bx.prototype;l.Ba=function(){return this};l.Bi=function(a,b){return ex(a,b)};
+l.Wh=function(a){return this.xk(ui(U(),a))};l.b=function(){return this};l.l=function(a){return this.Gb(a)};function cx(a,b){return a.Bi(b,a.Wh(b),0)}l.Ja=function(){return this};l.Ab=function(){return hw()};l.R=ba();l.ol=function(a){if(a&&a.a&&a.a.t.qh)return this.xi(a,0);var b=this.X();return oj(b,a)};l.U=h(0);l.X=function(){return $g().Cc};l.xg=function(){return fw()};l.xk=function(a){a=a+~(a<<9)|0;a^=a>>>14|0;a=a+(a<<4)|0;return a^(a>>>10|0)};l.Gb=function(a){return this.If(a,this.Wh(a),0)};
+l.ze=function(a){return cx(this,a)};l.If=h(!1);l.xi=h(!0);var cw=new s({qh:0},!1,"scala.collection.immutable.HashSet",{qh:1,re:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,de:1,x:1,Sd:1,ce:1,fe:1,ee:1,ab:1,te:1,Na:1,Qa:1,Pa:1,Sa:1,g:1,e:1});bx.prototype.a=cw;function fx(){}fx.prototype=new Vw;
+fx.prototype.a=new s({$B:0},!1,"scala.collection.immutable.ListSet$EmptyListSet$",{$B:1,XB:1,re:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,de:1,x:1,Sd:1,ce:1,fe:1,ee:1,ab:1,te:1,Na:1,Qa:1,Pa:1,g:1,e:1});var gx=void 0;function cr(){gx||(gx=(new fx).b());return gx}function hx(){this.W=this.Jf=null}hx.prototype=new Vw;l=hx.prototype;l.u=c("Jf");l.m=h(!1);l.Zk=c("W");l.zh=function(a){return ix(this,a)?this:fr(this,a)};
+l.U=function(){var a;a:{a=this;var b=0;for(;;){if(a.m()){a=b;break a}a=a.Zk();b=1+b|0}a=void 0}return a};function fr(a,b){var d=new hx;d.Jf=b;if(null===a)throw G(H(),null);d.W=a;return d}l.Gb=function(a){return ix(this,a)};l.s=c("W");function ix(a,b){for(;;){if(a.m())return!1;if(O(P(),a.u(),b))return!0;a=a.Zk()}}l.ql=c("W");l.ze=function(a){return this.zh(a)};
+l.a=new s({bC:0},!1,"scala.collection.immutable.ListSet$Node",{bC:1,XB:1,re:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,de:1,x:1,Sd:1,ce:1,fe:1,ee:1,ab:1,te:1,Na:1,Qa:1,Pa:1,g:1,e:1});function jx(){}jx.prototype=new Lw;function kx(){}kx.prototype=jx.prototype;jx.prototype.Ba=function(){return this.ti()};jx.prototype.ti=function(){return this};function lx(){}lx.prototype=new dx;
+lx.prototype.a=new s({LB:0},!1,"scala.collection.immutable.HashSet$EmptyHashSet$",{LB:1,qh:1,re:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,de:1,x:1,Sd:1,ce:1,fe:1,ee:1,ab:1,te:1,Na:1,Qa:1,Pa:1,Sa:1,g:1,e:1});var mx=void 0;function fw(){mx||(mx=(new lx).b());return mx}function ew(){this.Be=0;this.Jc=null;this.Ng=0}ew.prototype=new dx;l=ew.prototype;
+l.Bi=function(a,b,d){var e=1<<(31&(b>>>d|0)),f=Nf(Ve(),this.Be&(-1+e|0));if(0!==(this.Be&e)){e=this.Jc.d[f];a=e.Bi(a,b,5+d|0);if(e===a)return this;b=p(v(cw),[this.Jc.d.length]);zl(rc(),this.Jc,0,b,0,this.Jc.d.length);b.d[f]=a;return dw(new ew,this.Be,b,this.Ng+(a.U()-e.U()|0)|0)}d=p(v(cw),[1+this.Jc.d.length|0]);zl(rc(),this.Jc,0,d,0,f);d.d[f]=ex(a,b);zl(rc(),this.Jc,f,d,1+f|0,this.Jc.d.length-f|0);return dw(new ew,this.Be|e,d,1+this.Ng|0)};
+l.R=function(a){for(var b=0;b<this.Jc.d.length;)this.Jc.d[b].R(a),b=1+b|0};l.X=function(){var a=new Tt;Ns.prototype.mn.call(a,this.Jc);return a};l.U=c("Ng");function dw(a,b,d,e){a.Be=b;a.Jc=d;a.Ng=e;ap(Ac(),Nf(Ve(),b)===d.d.length);return a}l.If=function(a,b,d){var e=31&(b>>>d|0),f=1<<e;return-1===this.Be?this.Jc.d[31&e].If(a,b,5+d|0):0!==(this.Be&f)?(e=Nf(Ve(),this.Be&(-1+f|0)),this.Jc.d[e].If(a,b,5+d|0)):!1};
+l.xi=function(a,b){if(a===this)return!0;if(Ps(a)&&this.Ng<=a.Ng){var d=this.Be,e=this.Jc,f=0,g=a.Jc,k=a.Be,n=0;if((d&k)===d){for(;0!==d;){var r=d^d&(-1+d|0),y=k^k&(-1+k|0);if(r===y){if(!e.d[f].xi(g.d[n],5+b|0))return!1;d&=~r;f=1+f|0}k&=~y;n=1+n|0}return!0}}return!1};function Ps(a){return!!(a&&a.a&&a.a.t.Io)}
+l.a=new s({Io:0},!1,"scala.collection.immutable.HashSet$HashTrieSet",{Io:1,qh:1,re:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,de:1,x:1,Sd:1,ce:1,fe:1,ee:1,ab:1,te:1,Na:1,Qa:1,Pa:1,Sa:1,g:1,e:1});function nx(){}nx.prototype=new dx;function ox(){}ox.prototype=nx.prototype;function px(){}px.prototype=new Sw;function qx(){}l=qx.prototype=px.prototype;l.Di=function(){throw(new uj).h("empty map");};l.Ja=function(){return this};l.Ff=function(){return rx()};
+l.kk=function(){return rx()};l.U=h(0);l.dg=function(){return this};l.X=function(){var a=new Cs;a.rh=this;var b=J().N,a=Uj(a,b);return a.kc(a.pc()).X()};l.jh=function(){throw(new uj).h("empty map");};l.Ci=function(a,b){return sx(new tx,this,a,b)};l.Xc=function(){return sg()};l.$f=function(){throw(new uj).h("empty map");};l.Yd=function(a){return this.Ci(a.Ua,a.$a)};function ux(){}ux.prototype=new Sw;l=ux.prototype;l.X=function(){return $g().Cc};l.U=h(0);l.Xc=function(){return sg()};
+l.Yd=function(a){return(new vx).ha(a.Ua,a.$a)};l.a=new s({dC:0},!1,"scala.collection.immutable.Map$EmptyMap$",{dC:1,se:1,wd:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,fd:1,Oc:1,dd:1,gd:1,la:1,x:1,ab:1,Id:1,Na:1,Qa:1,Pa:1,Jd:1,g:1,e:1});var wx=void 0;function Yj(){wx||(wx=(new ux).b());return wx}function vx(){this.lb=this.Ma=null}vx.prototype=new Sw;l=vx.prototype;l.ha=function(a,b){this.Ma=a;this.lb=b;return this};
+l.R=function(a){a.l((new V).ha(this.Ma,this.lb))};l.X=function(){$g();var a=(new C).A([(new V).ha(this.Ma,this.lb)]);return W(new X,a,a.p.length|0)};l.U=h(1);l.Xg=function(a,b){return O(P(),a,this.Ma)?(new vx).ha(this.Ma,b):(new xx).gf(this.Ma,this.lb,a,b)};l.Xc=function(a){return O(P(),a,this.Ma)?(new tg).w(this.lb):sg()};l.Yd=function(a){return this.Xg(a.Ua,a.$a)};
+l.a=new s({eC:0},!1,"scala.collection.immutable.Map$Map1",{eC:1,se:1,wd:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,fd:1,Oc:1,dd:1,gd:1,la:1,x:1,ab:1,Id:1,Na:1,Qa:1,Pa:1,Jd:1,g:1,e:1});function xx(){this.Xb=this.gb=this.lb=this.Ma=null}xx.prototype=new Sw;l=xx.prototype;l.R=function(a){a.l((new V).ha(this.Ma,this.lb));a.l((new V).ha(this.gb,this.Xb))};
+l.X=function(){$g();var a=(new C).A([(new V).ha(this.Ma,this.lb),(new V).ha(this.gb,this.Xb)]);return W(new X,a,a.p.length|0)};l.U=h(2);l.Xg=function(a,b){return O(P(),a,this.Ma)?(new xx).gf(this.Ma,b,this.gb,this.Xb):O(P(),a,this.gb)?(new xx).gf(this.Ma,this.lb,this.gb,b):yx(this.Ma,this.lb,this.gb,this.Xb,a,b)};l.Xc=function(a){return O(P(),a,this.Ma)?(new tg).w(this.lb):O(P(),a,this.gb)?(new tg).w(this.Xb):sg()};l.gf=function(a,b,d,e){this.Ma=a;this.lb=b;this.gb=d;this.Xb=e;return this};
+l.Yd=function(a){return this.Xg(a.Ua,a.$a)};l.a=new s({fC:0},!1,"scala.collection.immutable.Map$Map2",{fC:1,se:1,wd:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,fd:1,Oc:1,dd:1,gd:1,la:1,x:1,ab:1,Id:1,Na:1,Qa:1,Pa:1,Jd:1,g:1,e:1});function zx(){this.jd=this.oc=this.Xb=this.gb=this.lb=this.Ma=null}zx.prototype=new Sw;l=zx.prototype;l.R=function(a){a.l((new V).ha(this.Ma,this.lb));a.l((new V).ha(this.gb,this.Xb));a.l((new V).ha(this.oc,this.jd))};
+function yx(a,b,d,e,f,g){var k=new zx;k.Ma=a;k.lb=b;k.gb=d;k.Xb=e;k.oc=f;k.jd=g;return k}l.X=function(){$g();var a=(new C).A([(new V).ha(this.Ma,this.lb),(new V).ha(this.gb,this.Xb),(new V).ha(this.oc,this.jd)]);return W(new X,a,a.p.length|0)};l.U=h(3);
+l.Xg=function(a,b){return O(P(),a,this.Ma)?yx(this.Ma,b,this.gb,this.Xb,this.oc,this.jd):O(P(),a,this.gb)?yx(this.Ma,this.lb,this.gb,b,this.oc,this.jd):O(P(),a,this.oc)?yx(this.Ma,this.lb,this.gb,this.Xb,this.oc,b):Ax(this.Ma,this.lb,this.gb,this.Xb,this.oc,this.jd,a,b)};l.Xc=function(a){return O(P(),a,this.Ma)?(new tg).w(this.lb):O(P(),a,this.gb)?(new tg).w(this.Xb):O(P(),a,this.oc)?(new tg).w(this.jd):sg()};l.Yd=function(a){return this.Xg(a.Ua,a.$a)};
+l.a=new s({gC:0},!1,"scala.collection.immutable.Map$Map3",{gC:1,se:1,wd:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,fd:1,Oc:1,dd:1,gd:1,la:1,x:1,ab:1,Id:1,Na:1,Qa:1,Pa:1,Jd:1,g:1,e:1});function Bx(){this.hg=this.Ge=this.jd=this.oc=this.Xb=this.gb=this.lb=this.Ma=null}Bx.prototype=new Sw;l=Bx.prototype;l.R=function(a){a.l((new V).ha(this.Ma,this.lb));a.l((new V).ha(this.gb,this.Xb));a.l((new V).ha(this.oc,this.jd));a.l((new V).ha(this.Ge,this.hg))};
+l.X=function(){$g();var a=(new C).A([(new V).ha(this.Ma,this.lb),(new V).ha(this.gb,this.Xb),(new V).ha(this.oc,this.jd),(new V).ha(this.Ge,this.hg)]);return W(new X,a,a.p.length|0)};l.U=h(4);function Ax(a,b,d,e,f,g,k,n){var r=new Bx;r.Ma=a;r.lb=b;r.gb=d;r.Xb=e;r.oc=f;r.jd=g;r.Ge=k;r.hg=n;return r}
+l.Xg=function(a,b){if(O(P(),a,this.Ma))return Ax(this.Ma,b,this.gb,this.Xb,this.oc,this.jd,this.Ge,this.hg);if(O(P(),a,this.gb))return Ax(this.Ma,this.lb,this.gb,b,this.oc,this.jd,this.Ge,this.hg);if(O(P(),a,this.oc))return Ax(this.Ma,this.lb,this.gb,this.Xb,this.oc,b,this.Ge,this.hg);if(O(P(),a,this.Ge))return Ax(this.Ma,this.lb,this.gb,this.Xb,this.oc,this.jd,this.Ge,b);var d=(new Cx).b(),e=(new V).ha(this.gb,this.Xb),f=[(new V).ha(this.oc,this.jd),(new V).ha(this.Ge,this.hg),(new V).ha(a,b)],d=
+Dx(Dx(d,(new V).ha(this.Ma,this.lb)),e),e=wu(),g=new Qn;if(null===e)throw G(H(),null);g.W=e;e=Wj(new Xj,g.W.Ri());Pj(e,d,f.length|0);lk(e,d);d=0;for(g=f.length|0;d<g;)qk(e,f[d]),d=1+d|0;return e.ob};l.Xc=function(a){return O(P(),a,this.Ma)?(new tg).w(this.lb):O(P(),a,this.gb)?(new tg).w(this.Xb):O(P(),a,this.oc)?(new tg).w(this.jd):O(P(),a,this.Ge)?(new tg).w(this.hg):sg()};l.Yd=function(a){return this.Xg(a.Ua,a.$a)};
+l.a=new s({hC:0},!1,"scala.collection.immutable.Map$Map4",{hC:1,se:1,wd:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,fd:1,Oc:1,dd:1,gd:1,la:1,x:1,ab:1,Id:1,Na:1,Qa:1,Pa:1,Jd:1,g:1,e:1});function Ex(){Bf.call(this)}Ex.prototype=new Qw;l=Ex.prototype;l.Ba=function(){return this};function Tw(a,b){var d=new Ex;Bf.prototype.Ak.call(d,a,b);return d}l.Ja=function(){return this};l.Fj=function(a){return pk(this,a)};l.Ab=function(){return qs()};l.Ff=function(){return Yj()};
+l.dg=function(){return this};l.lc=function(){return this};l.cj=function(a){return Tw(this,a)};l.Yd=function(a){return pk(this,a)};l.a=new s({iC:0},!1,"scala.collection.immutable.MapLike$$anon$2",{iC:1,Xk:1,wd:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,fd:1,Oc:1,dd:1,gd:1,la:1,x:1,ab:1,ro:1,AI:1,Id:1,Na:1,Qa:1,Pa:1,Jd:1});function Fx(){this.bd=this.ie=null}Fx.prototype=new t;l=Fx.prototype;l.Ba=function(){return this};
+l.u=function(){var a=Nk(Zk(),this.ie);return(new V).ha(a.ka,a.j)};l.l=function(a){return yj(this,a)};l.m=function(){return 0===this.U()};l.Fb=function(){var a=J().N;return Kj(this,a)};l.Ja=function(){return this};l.K=function(a){return Bi(this,a)};l.Np=function(a,b){return Gx(this,a,b)};l.Ec=function(a,b,d){return L(this,a,b,d)};l.fc=function(a){return L(this,"",a,"")};function Ld(a){var b=new Fx;Fx.prototype.$i.call(b,null,a);return b}l.Kd=function(a){return(new On).od(this,a)};l.Ab=function(){return qs()};
+l.o=function(){return Lj(this)};l.R=function(a){var b=Zk(),d=this.ie;null!==d&&Xk(b,d,a)};l.Rc=function(){uc();var a=vc().zb;return Kj(this,a)};l.lf=function(a){return tf(new uf,this,a)};l.U=function(){return Bk(Zk(),this.ie)};l.X=function(){var a=this.ie,b=sg(),d=this.bd,e=new Es;e.mj=a;e.bd=d;null===a?a=null:(a=-3+w(2,32-Of(Ve(),1+a.fk|0)|0)|0,a=p(v(oq),[a]));e.th=a;e.nd=0;b.m()?b=sg():(b=b.Wc(),b=(new tg).w(nr(e,b)));e.bj=b.m()?kr(e,e.mj):b.Wc();return e};l.ni=c("bd");
+l.$i=function(a,b){this.ie=a;this.bd=b;return this};l.ec=function(){return L(this,"","","")};l.Xc=function(a){Zk();a=Wk(this.ie,a,this.bd);return null===a?sg():(new tg).w(a.j)};l.db=function(){return this.X().db()};function Hx(a,b){return b.Ba().Ac(a,nc(function(){return function(a,b){return Gx(a,b.Ua,b.$a)}}(a)))}l.Zb=function(a){return 0>=a?this:a>=this.U()?Ld(this.bd):(new Fx).$i(Fk(Zk(),this.ie,a),this.bd)};l.s=function(){return(new Fx).$i(Qk(Zk(),this.ie,Nk(Zk(),this.ie).ka,this.bd),this.bd)};
+l.Gb=function(a){Zk();return null!==Wk(this.ie,a,this.bd)};function Gx(a,b,d){return(new Fx).$i(Vk(Zk(),a.ie,b,d,a.bd),a.bd)}l.rc=function(a,b,d,e){return zj(this,a,b,d,e)};l.Dc=function(a){return ck(this,a)};l.Va=function(a){Zk();return null!==Wk(this.ie,a,this.bd)};l.Pb=function(){return this};l.Ac=function(a,b){return bk(this,a,b)};l.Bb=function(a,b){return Ng(this,a,b)};l.M=function(){var a=wi();return ti(a,this,a.Jk)};l.Yc=h(!0);l.lc=function(){return this};
+l.Gj=function(a){return Gx(this,a.Ua,a.$a)};l.Al=function(a){return Hx(this,a)};l.cj=function(a){return Ix(this,a)};l.Yd=function(a){return Gx(this,a.Ua,a.$a)};l.Kb=function(a){return Oi(this,a)};l.na=function(){Ms||(Ms=(new Ls).b());return ok(Ms,this.bd)};l.Wb=h("Map");l.a=new s({LC:0},!1,"scala.collection.immutable.TreeMap",{LC:1,c:1,wC:1,Id:1,Na:1,Qa:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,Pa:1,sa:1,qa:1,ba:1,da:1,n:1,fd:1,Oc:1,dd:1,gd:1,la:1,x:1,ab:1,Jd:1,nB:1,oB:1,AB:1,g:1,e:1});
+function Cx(){}Cx.prototype=new Sw;function Jx(){}l=Jx.prototype=Cx.prototype;l.Ba=function(){return this};l.Wh=function(a){return this.xk(ui(U(),a))};l.b=function(){return this};l.Ja=function(){return this};l.Ai=function(a,b,d,e,f){return Kx(a,b,e,f)};l.eh=function(){return sg()};l.R=ba();function Dx(a,b){return a.Ai(b.Ua,a.Wh(b.Ua),0,b.$a,b,null)}l.Ff=function(){wu();return vu()};l.kk=function(){wu();return vu()};l.dg=function(){return this};l.U=h(0);l.X=function(){return $g().Cc};
+l.Xc=function(a){return this.eh(a,this.Wh(a),0)};l.xk=function(a){a=a+~(a<<9)|0;a^=a>>>14|0;a=a+(a<<4)|0;return a^(a>>>10|0)};l.Yd=function(a){return Dx(this,a)};var su=new s({ri:0},!1,"scala.collection.immutable.HashMap",{ri:1,se:1,wd:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,fd:1,Oc:1,dd:1,gd:1,la:1,x:1,ab:1,Id:1,Na:1,Qa:1,Pa:1,Jd:1,g:1,e:1,Sa:1});Cx.prototype.a=su;function Lx(){this.Mc=null;this.Jb=0}Lx.prototype=new ox;l=Lx.prototype;
+l.Bi=function(a,b,d){if(b===this.Jb&&O(P(),a,this.Mc))return this;if(b!==this.Jb)return bw(hw(),this.Jb,this,b,ex(a,b),d);var e=cr();d=new Mx;a=fr(e,this.Mc).zh(a);d.Jb=b;d.Vf=a;return d};function ex(a,b){var d=new Lx;d.Mc=a;d.Jb=b;return d}l.R=function(a){a.l(this.Mc)};l.X=function(){$g();var a=(new C).A([this.Mc]);return W(new X,a,a.p.length|0)};l.U=h(1);l.If=function(a,b){return b===this.Jb&&O(P(),a,this.Mc)};l.xi=function(a,b){return a.If(this.Mc,this.Jb,b)};
+l.a=new s({Ho:0},!1,"scala.collection.immutable.HashSet$HashSet1",{Ho:1,OB:1,qh:1,re:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,de:1,x:1,Sd:1,ce:1,fe:1,ee:1,ab:1,te:1,Na:1,Qa:1,Pa:1,Sa:1,g:1,e:1});function Mx(){this.Jb=0;this.Vf=null}Mx.prototype=new ox;l=Mx.prototype;l.Bi=function(a,b,d){b===this.Jb?(d=new Mx,a=this.Vf.zh(a),d.Jb=b,d.Vf=a,b=d):b=bw(hw(),this.Jb,this,b,ex(a,b),d);return b};l.R=function(a){var b=(new Ds).gh(this.Vf);nj(b,a)};l.X=function(){return(new Ds).gh(this.Vf)};
+l.U=function(){return this.Vf.U()};l.If=function(a,b){return b===this.Jb&&this.Vf.Gb(a)};l.xi=function(a,b){for(var d=(new Ds).gh(this.Vf),e=!0;;)if(e&&!d.Qg.m())e=d.wa(),e=a.If(e,this.Jb,b);else break;return e};l.a=new s({MB:0},!1,"scala.collection.immutable.HashSet$HashSetCollision1",{MB:1,OB:1,qh:1,re:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,de:1,x:1,Sd:1,ce:1,fe:1,ee:1,ab:1,te:1,Na:1,Qa:1,Pa:1,Sa:1,g:1,e:1});function Nx(){}Nx.prototype=new Lw;
+function Ox(){}l=Ox.prototype=Nx.prototype;l.Ba=function(){return this};l.b=function(){return this};l.ma=function(a){return rj(this,a)};l.pb=function(a){return pj(this,a)};l.l=function(a){return rj(this,a|0)};l.Qb=function(a){return vj(this,a)};l.Fb=function(){return this};l.Ja=function(){return this};l.Jm=function(a){return Px(this,a)};l.Ab=function(){return J()};l.R=function(a){for(var b=this;!b.m();)a.l(b.u()),b=b.s()};l.le=function(a,b){return qj(this,a,b)};
+l.pc=function(){for(var a=x(),b=this;!b.m();)var d=b.u(),a=Tb(new Ub,d,a),b=b.s();return a};l.Fc=function(a,b){return b&&b.a&&b.a.t.cl?Tb(new Ub,a,this):Fj(this,a,b)};l.X=function(){var a=new ts;a.jc=this;return a};function Px(a,b){for(var d=a,e=b;!d.m()&&0<e;)d=d.s(),e=-1+e|0;return d}l.Me=function(){return this};l.q=function(){return sj(this)};
+l.sf=function(a,b){var d;if(b===J().N)if(d=a.Ba().Fb(),d.m())d=this;else{if(!this.m()){var e=Ap((new zp).b(),this);e.Ya.m()||(e.$h&&Qx(e),e.Wf.Cd=d,d=e.Fb())}}else d=Qj(this,a,b);return d};l.Ep=function(a){a:if(this.m()||0>=a)a=x();else{for(var b=Tb(new Ub,this.u(),x()),d=b,e=this.s(),f=1;;){if(e.m()){a=this;break a}if(f<a)var f=1+f|0,g=Tb(new Ub,e.u(),x()),d=d.Cd=g,e=e.s();else break}a=b}return a};l.db=function(){return this.m()?lj():jj(new kj,this.u(),Nc(function(a){return function(){return a.s().db()}}(this)))};
+l.Zb=function(a){return Px(this,a)};l.Je=function(){return tj(this)};l.bc=function(){return this};l.Va=function(a){return 0<=(a|0)&&0<pj(this,a|0)};l.M=function(){return Nn(wi(),this)};l.oe=function(a,b){if(b===J().N){if(this===x())return x();for(var d=Tb(new Ub,a.l(this.u()),x()),e=d,f=this.s();f!==x();)var g=Tb(new Ub,a.l(f.u()),x()),e=e.Cd=g,f=f.s();return d}return Nj(this,a,b)};l.kc=aa();l.Kb=function(a){return wj(this,a)};l.Wb=h("List");function Rx(){}Rx.prototype=new qx;
+Rx.prototype.a=new s({VB:0},!1,"scala.collection.immutable.ListMap$EmptyListMap$",{VB:1,TB:1,se:1,wd:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,fd:1,Oc:1,dd:1,gd:1,la:1,x:1,ab:1,Id:1,Na:1,Qa:1,Pa:1,Jd:1,g:1,e:1});var Sx=void 0;function rx(){Sx||(Sx=(new Rx).b());return Sx}function tx(){this.W=this.gg=this.Mc=null}tx.prototype=new qx;l=tx.prototype;l.Di=c("gg");
+l.l=function(a){a:{var b=this;for(;;){if(b.m())throw(new uj).h("key not found: "+a);if(O(P(),a,b.jh())){a=b.Di();break a}b=b.$f()}a=void 0}return a};l.m=h(!1);l.U=function(){var a;a:{a=this;var b=0;for(;;){if(a.m()){a=b;break a}a=a.$f();b=1+b|0}a=void 0}return a};l.jh=c("Mc");
+l.Ci=function(a,b){var d;a:{d=this;var e=x();for(;;){if(d.m()){d=tj(e);break a}if(O(P(),a,d.jh())){var f=d.$f();for(d=e;!d.m();)e=f,f=d.u(),f=sx(new tx,e,f.jh(),f.Di()),d=d.s();d=f;break a}f=d.$f();e=Tb(new Ub,d,e);d=f}d=void 0}return sx(new tx,d,a,b)};l.Xc=function(a){a:{var b=this;for(;;){if(O(P(),a,b.jh())){a=(new tg).w(b.Di());break a}if(b.$f().m()){a=sg();break a}else b=b.$f()}a=void 0}return a};function sx(a,b,d,e){a.Mc=d;a.gg=e;if(null===b)throw G(H(),null);a.W=b;return a}l.$f=c("W");
+l.a=new s({WB:0},!1,"scala.collection.immutable.ListMap$Node",{WB:1,TB:1,se:1,wd:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,fd:1,Oc:1,dd:1,gd:1,la:1,x:1,ab:1,Id:1,Na:1,Qa:1,Pa:1,Jd:1,g:1,e:1});function Tx(){this.ac=this.Ag=this.ic=0;this.pd=!1;this.Fp=this.Gk=this.Fd=0}Tx.prototype=new Lw;function Ux(){}l=Ux.prototype=Tx.prototype;l.Ba=function(){return this};l.Tf=h(!1);l.u=function(){return this.pd?x().ei():this.ic};l.ma=function(a){return this.Nh(a)};
+l.l=function(a){return this.Nh(a|0)};l.m=c("pd");l.Ja=function(){return this};l.K=function(a){if(a&&a.a&&a.a.t.il){if(this.pd)return a.pd;if(!a.m()&&this.ic===a.ic){var b=Vx(this);return b===Vx(a)&&(this.ic===b||this.ac===a.ac)}return!1}return Nr(a)?this.Qb(a):!1};l.Nh=function(a){Wx(this);if(0>a||a>=this.Fd)throw(new Rg).h(""+a);return this.ic+w(this.ac,a)|0};
+l.k=function(a,b,d){this.ic=a;this.Ag=b;this.ac=d;this.pd=a>b&&0<d||a<b&&0>d||a===b&&!this.Tf();if(0===d){var e;throw(new Cb).h("step cannot be 0.");}this.pd?e=0:(e=Vf(Zl(Xx(this),(new T).Oa(this.ac)),(new T).Oa(this.Tf()||!bn(Hp(Xx(this),(new T).Oa(this.ac)),Sf())?1:0)),e=lm(e,(new T).k(4194303,511,0))?-1:Yl(e));this.Fd=e;if(this.pd)b=a-d|0;else switch(d){case 1:b=this.Tf()?b:-1+b|0;break;case -1:b=this.Tf()?b:1+b|0;break;default:a=Yl(Hp(Xx(this),(new T).Oa(d))),b=0!==a?b-a|0:this.Tf()?b:b-d|0}this.Gk=
+b;this.Fp=this.Gk+d|0;return this};l.ef=function(){if(this.pd){var a=x();Zi(a)}0<=this.Fd?a=Yx(this,this.Fd-1|0):(a=Vx(this)-w(this.ac,1)|0,0<this.ac&&a<this.ic||0>this.ac&&a>this.ic?(a=this.ic,a=(new Tx).k(a,a,this.ac)):a=(new $p).k(this.ic,a,this.ac));return a};l.Ab=function(){return In()};l.o=function(){var a=this.Fd>qh().Mj||!this.pd&&0>this.Fd?", ... )":")",b=Yx(this,qh().Mj);return L(b,"Range(",", ",a)};
+l.R=function(a){Wx(this);for(var b=-2147483648!==this.ic||-2147483648!==this.Ag,d=this.ic,e=0,f=this.Fp,g=this.ac;b?d!==f:e<this.Fd;)a.l(d),e=1+e|0,d=d+g|0};l.vm=function(a,b,d){return(new Tx).k(a,b,d)};l.pc=function(){return this.pd?this:(new $p).k(Vx(this),this.ic,-this.ac|0)};l.U=function(){return this.q()};l.X=function(){return W(new X,this,this.q())};function Wx(a){0>a.Fd&&lq(qh(),a.ic,a.Ag,a.ac,a.Tf())}l.q=function(){return 0>this.Fd?lq(qh(),this.ic,this.Ag,this.ac,this.Tf()):this.Fd};
+l.Me=function(){return this};function Zx(a,b){if(0>=b||a.pd)return a;if(b>=a.Fd&&0<=a.Fd){var d=a.Ag;return(new Tx).k(d,d,a.ac)}return a.vm(a.ic+w(a.ac,b)|0,a.Ag,a.ac)}l.Je=function(){return Vx(this)};l.Zb=function(a){return Zx(this,a)};l.s=function(){this.pd&&$x(x());return Zx(this,1)};l.bc=function(){return this};l.Dc=function(a){return a===zd()?0<this.ac?Vx(this):this.pd?x().ei():this.ic:ck(this,a)|0};
+function Yx(a,b){if(0>=b||a.pd){var d=a.ic;return(new Tx).k(d,d,a.ac)}return b>=a.Fd&&0<=a.Fd?a:(new $p).k(a.ic,a.ic+w(a.ac,-1+b|0)|0,a.ac)}function Vx(a){return a.pd?(a=x(),tj(a)|0):a.Gk}l.Va=function(a){return Di(this,a|0)};l.M=function(){return Nn(wi(),this)};l.kc=aa();function Xx(a){var b=(new T).Oa(a.Ag);a=(new T).Oa(a.ic);return Vf(b,Tf(a))}
+l.a=new s({il:0},!1,"scala.collection.immutable.Range",{il:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,gl:1,Mg:1,Na:1,Qa:1,Pa:1,Pc:1,rb:1,Sa:1,g:1,e:1});function ay(){}ay.prototype=new Lw;function by(){}l=by.prototype=ay.prototype;l.Ba=function(){return this};
+function cy(a){for(var b=lj(),b=(new Hj).w(b),d=a;!d.m();){lh();var e=fl(el(new dl,Nc(function(a,b){return function(){return b.v}}(a,b))),d.u());e.s();b.v=e;d=d.s()}return b.v}l.b=function(){return this};l.ma=function(a){return rj(this,a)};l.pb=function(a){return pj(this,a)};l.Qb=function(a){return vj(this,a)};l.l=function(a){return rj(this,a|0)};l.Ja=function(){return this};
+function Hs(a,b){var d=(lh(),(new rq).b());if(Is(d.Tc(a))){if(a.m())d=lj();else{for(var d=(new Hj).w(a),e=b.l(d.v.u()).db();!d.v.m()&&e.m();)d.v=d.v.s(),d.v.m()||(e=b.l(d.v.u()).db());d=d.v.m()?(lh(),lj()):dy(e,Nc(function(a,b,d){return function(){return Hs(d.v.s(),b)}}(a,b,d)))}return d}return Mj(a,b,d)}l.Jm=function(a){return ey(this,a)};l.fc=function(a){return this.Ec("",a,"")};
+l.Ec=function(a,b,d){var e=this,f=this;for(e.m()||(e=e.s());f!==e&&!e.m();){e=e.s();if(e.m())break;e=e.s();if(e===f)break;f=f.s()}return L(this,a,b,d)};l.Kd=function(a){var b=new sq;b.$n=a;On.prototype.od.call(b,this,a);return b};l.ef=function(){return fy(this)};l.Ab=function(){return lh()};l.o=function(){return L(this,"Stream(",", ",")")};l.R=function(a){var b=this;a:b:for(;;){if(!b.m()){a.l(b.u());b=b.s();continue b}break a}};
+l.le=function(a,b){var d=this;for(;;){if(d.m())return a;var e=d.s(),f=zg(b,a,d.u()),d=e;a=f}};l.pc=function(){return cy(this)};l.Fc=function(a,b){return Is(b.Tc(this))?jj(new kj,a,Nc(function(a){return function(){return a}}(this))):Fj(this,a,b)};l.X=function(){return Ks(this)};l.sf=function(a,b){if(Is(b.Tc(this))){if(this.m())var d=a.db();else d=this.u(),d=jj(new kj,d,Nc(function(a,b){return function(){return a.s().sf(b,(lh(),(new rq).b()))}}(this,a)));return d}return Qj(this,a,b)};
+l.q=function(){for(var a=0,b=this;!b.m();)a=1+a|0,b=b.s();return a};l.Yg=function(a){var b=lh();return gy(this,uw(b,0,1),a)};l.ec=function(){return this.Ec("","","")};l.Me=function(){return this};l.Ep=function(a){return hy(this,a)};l.db=function(){return this};l.Je=function(){return tj(this)};l.Zb=function(a){return ey(this,a)};function ey(a,b){var d=a;for(;;){if(0>=b||d.m())return d;var d=d.s(),e=-1+b|0;b=e}}l.bc=function(){return this};
+l.rc=function(a,b,d,e){Zj(a,b);if(!this.m()){ak(a,this.u());b=this;if(b.rf()){var f=this.s();if(f.m())return Zj(a,e),a;if(b!==f&&f.rf())for(b=f,f=f.s();b!==f&&f.rf();)ak(Zj(a,d),b.u()),b=b.s(),f=f.s(),f.rf()&&(f=f.s());if(f.rf()){for(var g=this,k=0;g!==f;)g=g.s(),f=f.s(),k=1+k|0;b===f&&0<k&&(ak(Zj(a,d),b.u()),b=b.s())}for(;b!==f;)ak(Zj(a,d),b.u()),b=b.s()}b.m()||(b.rf()?Zj(Zj(a,d),"..."):Zj(Zj(a,d),"?"))}Zj(a,e);return a};l.Va=function(a){return 0<=(a|0)&&0<pj(this,a|0)};
+l.M=function(){return Nn(wi(),this)};function fy(a){if(a.m())return Zi(a);if(a.s().m())return lj();var b=a.u();return jj(new kj,b,Nc(function(a){return function(){return fy(a.s())}}(a)))}l.oe=function(a,b){if(Is(b.Tc(this))){if(this.m())var d=lj();else d=a.l(this.u()),d=jj(new kj,d,Nc(function(a,b){return function(){return a.s().oe(b,(lh(),(new rq).b()))}}(this,a)));return d}return Nj(this,a,b)};
+function hy(a,b){if(0>=b||a.m())return lh(),lj();if(1===b){var d=a.u();return jj(new kj,d,Nc(function(){return function(){lh();return lj()}}(a)))}d=a.u();return jj(new kj,d,Nc(function(a,b){return function(){return hy(a.s(),-1+b|0)}}(a,b)))}l.kc=aa();l.Kb=function(a){if(this.m())throw(new xj).h("empty.reduceLeft");for(var b=this.u(),d=this.s();!d.m();)b=zg(a,b,d.u()),d=d.s();return b};
+function dy(a,b){if(a.m())return cd(b).db();var d=a.u();return jj(new kj,d,Nc(function(a,b){return function(){return dy(a.s(),b)}}(a,b)))}l.Wb=h("Stream");function gy(a,b,d){return Is(d.Tc(a))?(a.m()||b.m()?a=lj():(d=(new V).ha(a.u(),b.u()),a=jj(new kj,d,Nc(function(a,b){return function(){return gy(a.s(),b.s(),(lh(),(new rq).b()))}}(a,b)))),a):dj(a,b,d)}function iy(){}iy.prototype=new Jx;
+iy.prototype.a=new s({GB:0},!1,"scala.collection.immutable.HashMap$EmptyHashMap$",{GB:1,ri:1,se:1,wd:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,fd:1,Oc:1,dd:1,gd:1,la:1,x:1,ab:1,Id:1,Na:1,Qa:1,Pa:1,Jd:1,g:1,e:1,Sa:1});var jy=void 0;function vu(){jy||(jy=(new iy).b());return jy}function ky(){this.Mc=null;this.Jb=0;this.ki=this.gg=null}ky.prototype=new Jx;function St(a){null===a.ki&&(a.ki=(new V).ha(a.Mc,a.gg));return a.ki}
+function Kx(a,b,d,e){var f=new ky;f.Mc=a;f.Jb=b;f.gg=d;f.ki=e;return f}l=ky.prototype;l.Ai=function(a,b,d,e,f,g){if(b===this.Jb&&O(P(),a,this.Mc)){if(null===g)return this.gg===e?this:Kx(a,b,e,f);a=g.Wj(this.ki,f);return Kx(a.Ua,b,a.$a,a)}if(b!==this.Jb)return a=Kx(a,b,e,f),ru(wu(),this.Jb,this,b,a,d,2);d=rx();return ly(new my,b,sx(new tx,d,this.Mc,this.gg).Ci(a,e))};l.eh=function(a,b){return b===this.Jb&&O(P(),a,this.Mc)?(new tg).w(this.gg):sg()};l.R=function(a){a.l(St(this))};
+l.X=function(){$g();var a=(new C).A([St(this)]);return W(new X,a,a.p.length|0)};l.U=h(1);l.a=new s({Go:0},!1,"scala.collection.immutable.HashMap$HashMap1",{Go:1,ri:1,se:1,wd:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,fd:1,Oc:1,dd:1,gd:1,la:1,x:1,ab:1,Id:1,Na:1,Qa:1,Pa:1,Jd:1,g:1,e:1,Sa:1});function my(){this.Jb=0;this.He=null}my.prototype=new Jx;l=my.prototype;
+l.Ai=function(a,b,d,e,f,g){if(b===this.Jb){if(null===g||!Ab(this.He.Xc(a)))return ly(new my,b,this.He.Ci(a,e));d=this.He;a=g.Wj((new V).ha(a,this.He.l(a)),f);return ly(new my,b,d.Ci(a.Ua,a.$a))}a=Kx(a,b,e,f);return ru(wu(),this.Jb,this,b,a,d,1+this.He.U()|0)};l.eh=function(a,b){return b===this.Jb?this.He.Xc(a):sg()};l.R=function(a){var b=this.He.X();nj(b,a)};l.X=function(){return this.He.X()};l.U=function(){return this.He.U()};function ly(a,b,d){a.Jb=b;a.He=d;return a}
+l.a=new s({HB:0},!1,"scala.collection.immutable.HashMap$HashMapCollision1",{HB:1,ri:1,se:1,wd:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,fd:1,Oc:1,dd:1,gd:1,la:1,x:1,ab:1,Id:1,Na:1,Qa:1,Pa:1,Jd:1,g:1,e:1,Sa:1});function uu(){this.yf=0;this.md=null;this.Mb=0}uu.prototype=new Jx;l=uu.prototype;
+l.Ai=function(a,b,d,e,f,g){var k=1<<(31&(b>>>d|0)),n=Nf(Ve(),this.yf&(-1+k|0));if(0!==(this.yf&k)){k=this.md.d[n];a=k.Ai(a,b,5+d|0,e,f,g);if(a===k)return this;b=p(v(su),[this.md.d.length]);zl(rc(),this.md,0,b,0,this.md.d.length);b.d[n]=a;return tu(new uu,this.yf,b,this.Mb+(a.U()-k.U()|0)|0)}d=p(v(su),[1+this.md.d.length|0]);zl(rc(),this.md,0,d,0,n);d.d[n]=Kx(a,b,e,f);zl(rc(),this.md,n,d,1+n|0,this.md.d.length-n|0);return tu(new uu,this.yf|k,d,1+this.Mb|0)};
+l.eh=function(a,b,d){var e=31&(b>>>d|0),f=1<<e;return-1===this.yf?this.md.d[31&e].eh(a,b,5+d|0):0!==(this.yf&f)?(e=Nf(Ve(),this.yf&(-1+f|0)),this.md.d[e].eh(a,b,5+d|0)):sg()};l.R=function(a){for(var b=0;b<this.md.d.length;)this.md.d[b].R(a),b=1+b|0};l.X=function(){var a=new Rt;Ns.prototype.mn.call(a,this.md);return a};l.U=c("Mb");function tu(a,b,d,e){a.yf=b;a.md=d;a.Mb=e;return a}
+l.a=new s({fl:0},!1,"scala.collection.immutable.HashMap$HashTrieMap",{fl:1,ri:1,se:1,wd:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,fd:1,Oc:1,dd:1,gd:1,la:1,x:1,ab:1,Id:1,Na:1,Qa:1,Pa:1,Jd:1,g:1,e:1,Sa:1});function $p(){Tx.call(this)}$p.prototype=new Ux;$p.prototype.Tf=h(!0);$p.prototype.vm=function(a,b,d){return(new $p).k(a,b,d)};
+$p.prototype.a=new s({lC:0},!1,"scala.collection.immutable.Range$Inclusive",{lC:1,il:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,gl:1,Mg:1,Na:1,Qa:1,Pa:1,Pc:1,rb:1,Sa:1,g:1,e:1});function kj(){this.Aj=this.Ip=this.hn=null}kj.prototype=new by;l=kj.prototype;l.u=c("hn");l.rf=function(){return null===this.Aj};l.m=h(!1);l.s=function(){this.rf()||this.rf()||(this.Ip=cd(this.Aj),this.Aj=null);return this.Ip};
+function jj(a,b,d){a.hn=b;a.Aj=d;return a}l.a=new s({CC:0},!1,"scala.collection.immutable.Stream$Cons",{CC:1,zC:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,hl:1,Mg:1,Na:1,Qa:1,Pa:1,pi:1,Vk:1,Wk:1,g:1,e:1});function ny(){}ny.prototype=new by;l=ny.prototype;l.u=function(){this.ei()};l.rf=h(!1);l.m=h(!0);l.ei=function(){throw(new uj).h("head of empty stream");};l.s=function(){throw(new xj).h("tail of empty stream");};
+l.a=new s({EC:0},!1,"scala.collection.immutable.Stream$Empty$",{EC:1,zC:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,hl:1,Mg:1,Na:1,Qa:1,Pa:1,pi:1,Vk:1,Wk:1,g:1,e:1});var oy=void 0;function lj(){oy||(oy=(new ny).b());return oy}function Vs(){this.wc=this.Ib=this.sb=0;this.mb=!1;this.ub=0;this.Nd=this.Uc=this.uc=this.Yb=this.Db=this.vb=null}Vs.prototype=new Lw;l=Vs.prototype;l.Ba=function(){return this};l.Aa=c("uc");
+function py(a,b,d,e){if(a.mb)if(32>e)a.Ga(Z(a.nb()));else if(1024>e)a.va(Z(a.P())),a.P().d[31&b>>5]=a.nb(),a.Ga(ol(a.P(),31&d>>5));else if(32768>e)a.va(Z(a.P())),a.Fa(Z(a.aa())),a.P().d[31&b>>5]=a.nb(),a.aa().d[31&b>>10]=a.P(),a.va(ol(a.aa(),31&d>>10)),a.Ga(ol(a.P(),31&d>>5));else if(1048576>e)a.va(Z(a.P())),a.Fa(Z(a.aa())),a.eb(Z(a.Aa())),a.P().d[31&b>>5]=a.nb(),a.aa().d[31&b>>10]=a.P(),a.Aa().d[31&b>>15]=a.aa(),a.Fa(ol(a.Aa(),31&d>>15)),a.va(ol(a.aa(),31&d>>10)),a.Ga(ol(a.P(),31&d>>5));else if(33554432>
+e)a.va(Z(a.P())),a.Fa(Z(a.aa())),a.eb(Z(a.Aa())),a.vc(Z(a.Ra())),a.P().d[31&b>>5]=a.nb(),a.aa().d[31&b>>10]=a.P(),a.Aa().d[31&b>>15]=a.aa(),a.Ra().d[31&b>>20]=a.Aa(),a.eb(ol(a.Ra(),31&d>>20)),a.Fa(ol(a.Aa(),31&d>>15)),a.va(ol(a.aa(),31&d>>10)),a.Ga(ol(a.P(),31&d>>5));else if(1073741824>e)a.va(Z(a.P())),a.Fa(Z(a.aa())),a.eb(Z(a.Aa())),a.vc(Z(a.Ra())),a.Df(Z(a.Ic())),a.P().d[31&b>>5]=a.nb(),a.aa().d[31&b>>10]=a.P(),a.Aa().d[31&b>>15]=a.aa(),a.Ra().d[31&b>>20]=a.Aa(),a.Ic().d[31&b>>25]=a.Ra(),a.vc(ol(a.Ic(),
+31&d>>25)),a.eb(ol(a.Ra(),31&d>>20)),a.Fa(ol(a.Aa(),31&d>>15)),a.va(ol(a.aa(),31&d>>10)),a.Ga(ol(a.P(),31&d>>5));else throw(new Cb).b();else{b=-1+a.Hb()|0;switch(b){case 5:a.Df(Z(a.Ic()));a.vc(ol(a.Ic(),31&d>>25));a.eb(ol(a.Ra(),31&d>>20));a.Fa(ol(a.Aa(),31&d>>15));a.va(ol(a.aa(),31&d>>10));a.Ga(ol(a.P(),31&d>>5));break;case 4:a.vc(Z(a.Ra()));a.eb(ol(a.Ra(),31&d>>20));a.Fa(ol(a.Aa(),31&d>>15));a.va(ol(a.aa(),31&d>>10));a.Ga(ol(a.P(),31&d>>5));break;case 3:a.eb(Z(a.Aa()));a.Fa(ol(a.Aa(),31&d>>15));
+a.va(ol(a.aa(),31&d>>10));a.Ga(ol(a.P(),31&d>>5));break;case 2:a.Fa(Z(a.aa()));a.va(ol(a.aa(),31&d>>10));a.Ga(ol(a.P(),31&d>>5));break;case 1:a.va(Z(a.P()));a.Ga(ol(a.P(),31&d>>5));break;case 0:a.Ga(Z(a.nb()));break;default:throw(new K).w(b);}a.mb=!0}}l.u=function(){if(0===this.pb(0))throw(new xj).h("empty.head");return this.ma(0)};l.ma=function(a){var b=a+this.sb|0;if(0<=a&&b<this.Ib)a=b;else throw(new Rg).h(""+a);return ml(this,a,a^this.wc)};l.Hb=c("ub");l.pb=function(a){return this.q()-a|0};
+l.l=function(a){return this.ma(a|0)};l.Ja=function(){return this};l.k=function(a,b,d){this.sb=a;this.Ib=b;this.wc=d;this.mb=!1;return this};l.Df=da("Nd");l.Dd=function(a,b){return b===(In(),vc().zb)?qy(this,a):Jj(this,a,b)};
+l.ef=function(){if(0===this.pb(0))throw(new xj).h("empty.init");var a;if((this.Ib-1|0)>this.sb){var b=this.Ib-1|0,d=-32&(-1+b|0),e=ry(this.sb^(-1+b|0)),f=this.sb&~(-1+(1<<w(5,e))|0);a=(new Vs).k(this.sb-f|0,b-f|0,d-f|0);pl(a,this,this.ub);a.mb=this.mb;py(a,this.wc,d,this.wc^d);sy(a,e);b=b-f|0;if(32>=b)ty(a.vb,b);else if(1024>=b)ty(a.vb,1+(31&(-1+b|0))|0),a.Db=uy(a.Db,b>>>5|0);else if(32768>=b)ty(a.vb,1+(31&(-1+b|0))|0),a.Db=uy(a.Db,1+(31&((-1+b|0)>>>5|0))|0),a.Yb=uy(a.Yb,b>>>10|0);else if(1048576>=
+b)ty(a.vb,1+(31&(-1+b|0))|0),a.Db=uy(a.Db,1+(31&((-1+b|0)>>>5|0))|0),a.Yb=uy(a.Yb,1+(31&((-1+b|0)>>>10|0))|0),a.uc=uy(a.uc,b>>>15|0);else if(33554432>=b)ty(a.vb,1+(31&(-1+b|0))|0),a.Db=uy(a.Db,1+(31&((-1+b|0)>>>5|0))|0),a.Yb=uy(a.Yb,1+(31&((-1+b|0)>>>10|0))|0),a.uc=uy(a.uc,1+(31&((-1+b|0)>>>15|0))|0),a.Uc=uy(a.Uc,b>>>20|0);else if(1073741824>=b)ty(a.vb,1+(31&(-1+b|0))|0),a.Db=uy(a.Db,1+(31&((-1+b|0)>>>5|0))|0),a.Yb=uy(a.Yb,1+(31&((-1+b|0)>>>10|0))|0),a.uc=uy(a.uc,1+(31&((-1+b|0)>>>15|0))|0),a.Uc=
+uy(a.Uc,1+(31&((-1+b|0)>>>20|0))|0),a.Nd=uy(a.Nd,b>>>25|0);else throw(new Cb).b();}else a=uc().Fh;return a};l.Ab=function(){return uc()};l.nb=c("vb");l.Fa=da("Yb");l.Ra=c("Uc");function vy(a,b,d){var e=-1+a.ub|0;switch(e){case 0:a.vb=rl(a.vb,b,d);break;case 1:a.Db=rl(a.Db,b,d);break;case 2:a.Yb=rl(a.Yb,b,d);break;case 3:a.uc=rl(a.uc,b,d);break;case 4:a.Uc=rl(a.Uc,b,d);break;case 5:a.Nd=rl(a.Nd,b,d);break;default:throw(new K).w(e);}}l.Rc=function(){return this};
+function qy(a,b){if(a.Ib!==a.sb){var d=-32&a.Ib,e=31&a.Ib;if(a.Ib!==d){var f=(new Vs).k(a.sb,1+a.Ib|0,d);pl(f,a,a.ub);f.mb=a.mb;py(f,a.wc,d,a.wc^d);f.vb.d[e]=b;return f}var g=a.sb&~(-1+(1<<w(5,-1+a.ub|0))|0),f=a.sb>>>w(5,-1+a.ub|0)|0;if(0!==g){if(1<a.ub){var d=d-g|0,k=a.wc-g|0,g=(new Vs).k(a.sb-g|0,(1+a.Ib|0)-g|0,d);pl(g,a,a.ub);g.mb=a.mb;vy(g,f,0);wy(g,k,d,k^d);g.vb.d[e]=b;return g}e=-32+d|0;d=a.wc;k=(new Vs).k(a.sb-g|0,(1+a.Ib|0)-g|0,e);pl(k,a,a.ub);k.mb=a.mb;vy(k,f,0);py(k,d,e,d^e);k.vb.d[32-g|
+0]=b;return k}f=a.wc;g=(new Vs).k(a.sb,1+a.Ib|0,d);pl(g,a,a.ub);g.mb=a.mb;wy(g,f,d,f^d);g.vb.d[e]=b;return g}e=p(v(u),[32]);e.d[0]=b;f=(new Vs).k(0,1,0);f.ub=1;f.vb=e;return f}function sy(a,b){a.ub=b;var d=-1+b|0;switch(d){case 0:a.Db=null;a.Yb=null;a.uc=null;a.Uc=null;a.Nd=null;break;case 1:a.Yb=null;a.uc=null;a.Uc=null;a.Nd=null;break;case 2:a.uc=null;a.Uc=null;a.Nd=null;break;case 3:a.Uc=null;a.Nd=null;break;case 4:a.Nd=null;break;case 5:break;default:throw(new K).w(d);}}
+l.Fc=function(a,b){return b===(In(),vc().zb)?xy(this,a):Fj(this,a,b)};l.X=function(){return xd(this)};l.va=da("Db");function ty(a,b){for(var d=b;d<a.d.length;)a.d[d]=null,d=1+d|0}
+l.sf=function(a,b){if(b===(In(),vc().zb)){if(a.m())return this;var d=a.Yc()?a:a.Rc(),e=d.U();switch(e){default:if(2>=e||e<this.q()>>5)return e=(new Hj).w(this),d.R(M(function(a,b){return function(a){b.v=b.v.Dd(a,(uc(),vc().zb))}}(this,e))),e.v;if(this.q()<e>>5&&d&&d.a&&d.a.t.Po){for(e=Ts(this);e.Ca();)var f=e.wa(),d=d.Fc(f,(uc(),vc().zb));return d}return Qj(this,d,b)}}else return Qj(this,a.Ba(),b)};l.q=function(){return this.Ib-this.sb|0};l.Me=function(){return this};l.vc=da("Uc");
+function wy(a,b,d,e){a.mb?(nl(a,b),sl(a,b,d,e)):(sl(a,b,d,e),a.mb=!0)}l.P=c("Db");l.Je=function(){if(0===this.pb(0))throw(new xj).h("empty.last");return this.ma(-1+this.q()|0)};l.Zb=function(a){return yy(this,a)};l.Ic=c("Nd");l.s=function(){if(0===this.pb(0))throw(new xj).h("empty.tail");return yy(this,1)};l.bc=function(){return this};function ry(a){if(32>a)return 1;if(1024>a)return 2;if(32768>a)return 3;if(1048576>a)return 4;if(33554432>a)return 5;if(1073741824>a)return 6;throw(new Cb).b();}
+function xd(a){var b=a.sb,d=a.Ib,e=new Xt;e.lk=d;e.Af=-32&b;e.Yf=31&b;b=d-e.Af|0;e.mk=32>b?b:32;e.Oe=(e.Af+e.Yf|0)<d;pl(e,a,a.ub);a.mb&&nl(e,a.wc);1<e.gk&&ql(e,a.sb,a.sb^a.wc);return e}l.Va=function(a){return Di(this,a|0)};function Ey(a,b){for(var d=0;d<b;)a.d[d]=null,d=1+d|0}l.M=function(){return Nn(wi(),this)};l.Md=da("ub");l.aa=c("Yb");l.Ga=da("vb");
+function xy(a,b){if(a.Ib!==a.sb){var d=-32&(-1+a.sb|0),e=31&(-1+a.sb|0);if(a.sb!==(32+d|0)){var f=(new Vs).k(-1+a.sb|0,a.Ib,d);pl(f,a,a.ub);f.mb=a.mb;py(f,a.wc,d,a.wc^d);f.vb.d[e]=b;return f}var g=(1<<w(5,a.ub))-a.Ib|0,f=g&~(-1+(1<<w(5,-1+a.ub|0))|0),g=g>>>w(5,-1+a.ub|0)|0;if(0!==f){if(1<a.ub){var d=d+f|0,k=a.wc+f|0,f=(new Vs).k((-1+a.sb|0)+f|0,a.Ib+f|0,d);pl(f,a,a.ub);f.mb=a.mb;vy(f,0,g);wy(f,k,d,k^d);f.vb.d[e]=b;return f}e=32+d|0;d=a.wc;k=(new Vs).k((-1+a.sb|0)+f|0,a.Ib+f|0,e);pl(k,a,a.ub);k.mb=
+a.mb;vy(k,0,g);py(k,d,e,d^e);k.vb.d[-1+f|0]=b;return k}if(0>d)return f=(1<<w(5,1+a.ub|0))-(1<<w(5,a.ub))|0,g=d+f|0,d=a.wc+f|0,f=(new Vs).k((-1+a.sb|0)+f|0,a.Ib+f|0,g),pl(f,a,a.ub),f.mb=a.mb,wy(f,d,g,d^g),f.vb.d[e]=b,f;f=a.wc;g=(new Vs).k(-1+a.sb|0,a.Ib,d);pl(g,a,a.ub);g.mb=a.mb;wy(g,f,d,f^d);g.vb.d[e]=b;return g}e=p(v(u),[32]);e.d[31]=b;f=(new Vs).k(31,32,0);f.ub=1;f.vb=e;return f}
+function yy(a,b){var d;if(0>=b)d=a;else if((a.sb+b|0)<a.Ib){var e=a.sb+b|0,f=-32&e,g=ry(e^(-1+a.Ib|0)),k=e&~(-1+(1<<w(5,g))|0);d=(new Vs).k(e-k|0,a.Ib-k|0,f-k|0);pl(d,a,a.ub);d.mb=a.mb;py(d,a.wc,f,a.wc^f);sy(d,g);e=e-k|0;if(32>e)Ey(d.vb,e);else if(1024>e)Ey(d.vb,31&e),d.Db=Uy(d.Db,e>>>5|0);else if(32768>e)Ey(d.vb,31&e),d.Db=Uy(d.Db,31&(e>>>5|0)),d.Yb=Uy(d.Yb,e>>>10|0);else if(1048576>e)Ey(d.vb,31&e),d.Db=Uy(d.Db,31&(e>>>5|0)),d.Yb=Uy(d.Yb,31&(e>>>10|0)),d.uc=Uy(d.uc,e>>>15|0);else if(33554432>e)Ey(d.vb,
+31&e),d.Db=Uy(d.Db,31&(e>>>5|0)),d.Yb=Uy(d.Yb,31&(e>>>10|0)),d.uc=Uy(d.uc,31&(e>>>15|0)),d.Uc=Uy(d.Uc,e>>>20|0);else if(1073741824>e)Ey(d.vb,31&e),d.Db=Uy(d.Db,31&(e>>>5|0)),d.Yb=Uy(d.Yb,31&(e>>>10|0)),d.uc=Uy(d.uc,31&(e>>>15|0)),d.Uc=Uy(d.Uc,31&(e>>>20|0)),d.Nd=Uy(d.Nd,e>>>25|0);else throw(new Cb).b();}else d=uc().Fh;return d}l.kc=aa();function uy(a,b){var d=p(v(u),[a.d.length]);Fa(a,0,d,0,b);return d}function Uy(a,b){var d=p(v(u),[a.d.length]);Fa(a,b,d,b,d.d.length-b|0);return d}l.eb=da("uc");
+l.a=new s({Po:0},!1,"scala.collection.immutable.Vector",{Po:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,gl:1,Mg:1,Na:1,Qa:1,Pa:1,Pc:1,rb:1,Qo:1,g:1,e:1,Sa:1});function wl(){this.Xd=null}wl.prototype=new Lw;l=wl.prototype;l.Ba=function(){return this};l.u=function(){return cj(this)};l.ma=function(a){a=65535&(this.Xd.charCodeAt(a)|0);return(new Re).nc(a)};l.pb=function(a){return Fi(this,a)};
+l.l=function(a){a=65535&(this.Xd.charCodeAt(a|0)|0);return(new Re).nc(a)};l.Qb=function(a){return Ui(this,a)};l.m=function(){return aj(this)};l.Ja=function(){return this};l.o=c("Xd");l.ef=function(){return Yi(this)};l.Ab=function(){return In()};l.R=function(a){Wi(this,a)};l.le=function(a,b){return Ni(this,0,this.Xd.length|0,a,b)};l.Qc=function(a,b){return Vy(this,a,b)};l.pc=function(){return Xi(this)};l.X=function(){return W(new X,this,this.Xd.length|0)};l.Me=function(){return this};
+l.q=function(){return this.Xd.length|0};l.ec=c("Xd");l.Yg=function(a){return Ti(this,a)};l.Je=function(){return Gi(this)};l.Zb=function(a){return Vy(this,a,this.Xd.length|0)};l.bc=function(){return this};l.s=function(){return $i(this)};l.Va=function(a){return Di(this,a|0)};l.M=function(){return Nn(wi(),this)};l.Hc=function(a,b,d){Qi(this,a,b,d)};l.h=function(a){this.Xd=a;return this};
+function Vy(a,b,d){b=0>b?0:b;if(d<=b||b>=(a.Xd.length|0))return(new wl).h("");d=d>(a.Xd.length|0)?a.Xd.length|0:d;Ac();return(new wl).h((null!==a?a.Xd:null).substring(b,d))}l.kc=aa();l.Kb=function(a){return Mi(this,a)};l.na=function(){xl||(xl=(new tl).b());return xl.na()};
+l.a=new s({SC:0},!1,"scala.collection.immutable.WrappedString",{SC:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,gl:1,Mg:1,Na:1,Qa:1,Pa:1,Pc:1,rb:1,No:1,Lb:1,lh:1,Zc:1});function Ub(){this.Cd=this.Jf=null}Ub.prototype=new Ox;l=Ub.prototype;l.jb=h("::");l.u=c("Jf");l.hb=h(2);l.m=h(!1);l.ib=function(a){switch(a){case 0:return this.Jf;case 1:return this.Cd;default:throw(new Rg).h(""+a);}};l.s=c("Cd");
+function Tb(a,b,d){a.Jf=b;a.Cd=d;return a}l.qb=function(){return Fr(new Gr,this)};l.a=new s({el:0},!1,"scala.collection.immutable.$colon$colon",{el:1,Jo:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,hl:1,Mg:1,Na:1,Qa:1,Pa:1,pi:1,Vk:1,xa:1,Wk:1,e:1,g:1});function Wy(){}Wy.prototype=new Ox;l=Wy.prototype;l.u=function(){this.ei()};l.jb=h("Nil");l.hb=h(0);l.K=function(a){return Nr(a)?a.m():!1};
+function $x(){throw(new xj).h("tail of empty list");}l.m=h(!0);l.ib=function(a){throw(new Rg).h(""+a);};l.ei=function(){throw(new uj).h("head of empty list");};l.s=function(){return $x()};l.qb=function(){return Fr(new Gr,this)};l.a=new s({jC:0},!1,"scala.collection.immutable.Nil$",{jC:1,Jo:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,hl:1,Mg:1,Na:1,Qa:1,Pa:1,pi:1,Vk:1,xa:1,Wk:1,e:1,g:1});var Xy=void 0;
+function x(){Xy||(Xy=(new Wy).b());return Xy}function Yy(){}Yy.prototype=new Nw;function Zy(){}l=Zy.prototype=Yy.prototype;l.Ba=function(){return this};l.Ab=function(){Zs||(Zs=(new Ys).b());return Zs};l.hd=function(a,b){Ul(this,a,b)};l.Ta=ba();l.na=function(){return this.Ff()};l.Ka=function(a){return lk(this,a)};function $y(){Bf.call(this);this.Tu=this.yl=null}$y.prototype=new Qw;l=$y.prototype;l.Ba=function(){return this};l.Ja=function(){return this};l.Fj=function(a){return al(this,a)};
+l.Np=function(a,b){return this.Gj((new V).ha(a,b))};function Ix(a,b){var d=new $y;if(null===a)throw G(H(),null);d.yl=a;d.Tu=b;Bf.prototype.Ak.call(d,a,b);return d}l.Ab=function(){return qs()};l.Ff=function(){return Ld(this.ni())};l.dg=function(){return this};l.ni=function(){return this.yl.ni()};l.lc=function(){return this};l.Gj=function(a){return al(this,a)};l.Al=function(a){return cl(this,a)};l.cj=function(a){return Ix(this,a)};l.Yd=function(a){return al(this,a)};l.na=function(){return ok(bl(),this.ni())};
+l.a=new s({yC:0},!1,"scala.collection.immutable.SortedMap$$anon$2",{yC:1,Xk:1,wd:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,fd:1,Oc:1,dd:1,gd:1,la:1,x:1,ab:1,ro:1,CI:1,wC:1,Id:1,Na:1,Qa:1,Pa:1,Jd:1,nB:1,oB:1,AB:1,uI:1});function az(){}az.prototype=new Hw;function bz(){}l=bz.prototype=az.prototype;l.m=function(){return 0===this.U()};l.K=function(a){return Ei(this,a)};l.o=function(){return Lj(this)};l.ol=function(a){var b=Xs(this);return oj(b,a)};
+l.hd=function(a,b){Ul(this,a,b)};l.M=function(){var a=wi();return ti(a,this,a.ml)};l.Ta=ba();l.na=function(){return this.Ab().Ef()};l.Ka=function(a){return lk(this,a)};l.Wb=h("Set");function Af(){this.Cf=null}Af.prototype=new Zy;l=Af.prototype;l.l=function(a){return this.Xj(a)};l.Ja=function(){return this};l.ji=function(a){this.Cf=a;return this};l.tb=function(a){return cz(this,a)};l.Ff=function(){return(new Af).ji(Cg())};l.pa=function(){return this};l.dg=function(){return this};l.X=function(){return(new zr).ji(this.Cf)};
+l.Xc=function(a){var b=this.Cf;return Dg().oh.call(b,a)?(new tg).w(this.Cf[a]):sg()};l.Xj=function(a){var b=this.Cf;if(Dg().oh.call(b,a))return this.Cf[a];throw(new uj).h("key not found: "+a);};function cz(a,b){a.Cf[b.Ua]=b.$a;return a}l.Gb=function(a){var b=this.Cf;return!!Dg().oh.call(b,a)};l.Da=function(a){return cz(this,a)};l.Yd=function(a){var b=(new Af).ji(Cg());return cz(lk(b,this),a)};
+l.a=new s({HD:0},!1,"scala.scalajs.js.WrappedDictionary",{HD:1,EI:1,wd:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,fd:1,Oc:1,dd:1,gd:1,la:1,x:1,ab:1,JI:1,Ad:1,Bd:1,ud:1,KI:1,Vb:1,Ub:1,Tb:1,uj:1,zd:1,td:1,qd:1});function dz(){}dz.prototype=new kx;function ez(){}ez.prototype=dz.prototype;dz.prototype.Ka=function(a){return lk(this,a)};function fz(){}fz.prototype=new kx;function gz(){}l=gz.prototype=fz.prototype;l.Ba=function(){return this};l.u=function(){return cj(this)};
+l.pb=function(a){return Fi(this,a)};l.Qb=function(a){return Ui(this,a)};l.m=function(){return aj(this)};l.Ja=function(){return this};l.ef=function(){return Yi(this)};l.Ab=function(){return Ov()};l.R=function(a){Wi(this,a)};l.le=function(a,b){return Ni(this,0,this.q(),a,b)};l.Qc=function(a,b){return Pi(this,a,b)};l.pc=function(){return Xi(this)};l.ti=function(){return this};l.X=function(){return W(new X,this,this.q())};l.Me=function(){return this};l.Yg=function(a){return Ti(this,a)};l.Je=function(){return Gi(this)};
+l.Zb=function(a){var b=this.q();return Pi(this,a,b)};l.bc=function(){return this};l.s=function(){return $i(this)};l.Va=function(a){return Di(this,a|0)};l.Hc=function(a,b,d){Qi(this,a,b,d)};l.M=function(){return Nn(wi(),this)};l.kc=aa();l.Kb=function(a){return Mi(this,a)};l.na=function(){return(new wr).zk(this.De())};l.Wb=h("WrappedArray");function er(){this.Fi=0;this.Nb=null;this.zj=this.Pg=0;this.eg=null;this.vj=0}er.prototype=new bz;l=er.prototype;l.Ba=function(){return this};
+l.b=function(){er.prototype.Ov.call(this,null);return this};l.l=function(a){return null!==em(this,a)};l.Ja=function(){return this};l.tb=function(a){return hr(this,a)};l.Ab=function(){nw||(nw=(new mw).b());return nw};l.R=function(a){for(var b=0,d=this.Nb.d.length;b<d;){var e=this.Nb.d[b];null!==e&&a.l(e===dm()?null:e);b=1+b|0}};l.U=c("Pg");l.pa=function(){return this};l.X=function(){return Xs(this)};
+l.Ov=function(a){this.Fi=450;this.Nb=p(v(u),[hm()]);this.Pg=0;this.zj=Wl(am(),this.Fi,hm());this.eg=null;this.vj=Nf(Ve(),-1+this.Nb.d.length|0);null!==a&&(this.Fi=a.CH(),this.Nb=a.XI(),this.Pg=a.WI(),this.zj=a.aJ(),this.vj=a.OI(),this.eg=a.PI());return this};l.Da=function(a){return hr(this,a)};l.ze=function(a){var b=(new er).b();return hr(lk(b,this),a)};function hr(a,b){var d=null===b?dm():b;gm(a,d);return a}
+l.a=new s({kD:0},!1,"scala.collection.mutable.HashSet",{kD:1,FI:1,DI:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Ad:1,Bd:1,ud:1,MI:1,de:1,x:1,Sd:1,ce:1,fe:1,ee:1,ab:1,NI:1,Yk:1,Vb:1,Ub:1,Tb:1,uj:1,zd:1,td:1,qd:1,GI:1,HI:1,Sa:1,g:1,e:1});function um(){this.p=null}um.prototype=new gz;l=um.prototype;l.ma=function(a){return this.p.d[a]};l.l=function(a){return this.p.d[a|0]};l.Ne=function(a,b){this.p.d[a]=!!b};l.q=function(){return this.p.d.length};l.De=function(){return tc().Pe};
+l.Rf=function(a){this.p=a;return this};l.a=new s({op:0},!1,"scala.collection.mutable.WrappedArray$ofBoolean",{op:1,pf:1,Ud:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,Vd:1,Ad:1,Bd:1,ud:1,Wd:1,zd:1,td:1,qd:1,ge:1,Pc:1,rb:1,$b:1,qc:1,hc:1,Lb:1,Sa:1,g:1,e:1});function sm(){this.p=null}sm.prototype=new gz;l=sm.prototype;l.ma=function(a){return this.p.d[a]};l.l=function(a){return this.p.d[a|0]};
+l.Ne=function(a,b){this.p.d[a]=b|0};l.q=function(){return this.p.d.length};l.De=function(){return tc().Qe};l.Kf=function(a){this.p=a;return this};l.a=new s({pp:0},!1,"scala.collection.mutable.WrappedArray$ofByte",{pp:1,pf:1,Ud:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,Vd:1,Ad:1,Bd:1,ud:1,Wd:1,zd:1,td:1,qd:1,ge:1,Pc:1,rb:1,$b:1,qc:1,hc:1,Lb:1,Sa:1,g:1,e:1});function rm(){this.p=null}rm.prototype=new gz;l=rm.prototype;
+l.ma=function(a){return(new Re).nc(this.p.d[a])};l.l=function(a){return(new Re).nc(this.p.d[a|0])};l.Ne=function(a,b){this.p.d[a]=null===b?0:b.j};l.Lf=function(a){this.p=a;return this};l.q=function(){return this.p.d.length};l.De=function(){return tc().Re};
+l.a=new s({qp:0},!1,"scala.collection.mutable.WrappedArray$ofChar",{qp:1,pf:1,Ud:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,Vd:1,Ad:1,Bd:1,ud:1,Wd:1,zd:1,td:1,qd:1,ge:1,Pc:1,rb:1,$b:1,qc:1,hc:1,Lb:1,Sa:1,g:1,e:1});function om(){this.p=null}om.prototype=new gz;l=om.prototype;l.ma=function(a){return this.p.d[a]};l.l=function(a){return this.p.d[a|0]};l.Ne=function(a,b){this.p.d[a]=+b};l.Mf=function(a){this.p=a;return this};
+l.q=function(){return this.p.d.length};l.De=function(){return tc().Se};l.a=new s({rp:0},!1,"scala.collection.mutable.WrappedArray$ofDouble",{rp:1,pf:1,Ud:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,Vd:1,Ad:1,Bd:1,ud:1,Wd:1,zd:1,td:1,qd:1,ge:1,Pc:1,rb:1,$b:1,qc:1,hc:1,Lb:1,Sa:1,g:1,e:1});function qm(){this.p=null}qm.prototype=new gz;l=qm.prototype;l.ma=function(a){return this.p.d[a]};l.l=function(a){return this.p.d[a|0]};
+l.Ne=function(a,b){var d=qa(b);this.p.d[a]=d};l.Nf=function(a){this.p=a;return this};l.q=function(){return this.p.d.length};l.De=function(){return tc().Te};l.a=new s({sp:0},!1,"scala.collection.mutable.WrappedArray$ofFloat",{sp:1,pf:1,Ud:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,Vd:1,Ad:1,Bd:1,ud:1,Wd:1,zd:1,td:1,qd:1,ge:1,Pc:1,rb:1,$b:1,qc:1,hc:1,Lb:1,Sa:1,g:1,e:1});function nm(){this.p=null}nm.prototype=new gz;l=nm.prototype;
+l.ma=function(a){return this.Nh(a)};l.l=function(a){return this.Nh(a|0)};l.Ne=function(a,b){this.p.d[a]=b|0};l.Nh=function(a){return this.p.d[a]};l.Of=function(a){this.p=a;return this};l.q=function(){return this.p.d.length};l.De=function(){return tc().Ue};
+l.a=new s({tp:0},!1,"scala.collection.mutable.WrappedArray$ofInt",{tp:1,pf:1,Ud:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,Vd:1,Ad:1,Bd:1,ud:1,Wd:1,zd:1,td:1,qd:1,ge:1,Pc:1,rb:1,$b:1,qc:1,hc:1,Lb:1,Sa:1,g:1,e:1});function pm(){this.p=null}pm.prototype=new gz;l=pm.prototype;l.ma=function(a){return this.p.d[a]};l.l=function(a){return this.p.d[a|0]};l.Pf=function(a){this.p=a;return this};
+l.Ne=function(a,b){var d=Ia(b);this.p.d[a]=d};l.q=function(){return this.p.d.length};l.De=function(){return tc().Ve};l.a=new s({up:0},!1,"scala.collection.mutable.WrappedArray$ofLong",{up:1,pf:1,Ud:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,Vd:1,Ad:1,Bd:1,ud:1,Wd:1,zd:1,td:1,qd:1,ge:1,Pc:1,rb:1,$b:1,qc:1,hc:1,Lb:1,Sa:1,g:1,e:1});function Sb(){this.Km=this.p=null;this.bk=!1}Sb.prototype=new gz;l=Sb.prototype;
+l.l=function(a){return this.ma(a|0)};l.ma=function(a){return this.p.d[a]};l.Ne=function(a,b){this.p.d[a]=b};l.me=function(a){this.p=a;return this};l.q=function(){return this.p.d.length};l.De=function(){this.bk||this.bk||(this.Km=sc(tc(),Mh(U(),la(this.p))),this.bk=!0);return this.Km};
+l.a=new s({vp:0},!1,"scala.collection.mutable.WrappedArray$ofRef",{vp:1,pf:1,Ud:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,Vd:1,Ad:1,Bd:1,ud:1,Wd:1,zd:1,td:1,qd:1,ge:1,Pc:1,rb:1,$b:1,qc:1,hc:1,Lb:1,Sa:1,g:1,e:1});function tm(){this.p=null}tm.prototype=new gz;l=tm.prototype;l.ma=function(a){return this.p.d[a]};l.l=function(a){return this.p.d[a|0]};l.Qf=function(a){this.p=a;return this};l.Ne=function(a,b){this.p.d[a]=b|0};
+l.q=function(){return this.p.d.length};l.De=function(){return tc().Xe};l.a=new s({wp:0},!1,"scala.collection.mutable.WrappedArray$ofShort",{wp:1,pf:1,Ud:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,Vd:1,Ad:1,Bd:1,ud:1,Wd:1,zd:1,td:1,qd:1,ge:1,Pc:1,rb:1,$b:1,qc:1,hc:1,Lb:1,Sa:1,g:1,e:1});function wm(){this.p=null}wm.prototype=new gz;l=wm.prototype;l.ma=function(a){this.p.d[a]};l.l=function(a){this.p.d[a|0]};
+l.Ne=function(a,b){this.p.d[a]=b};l.q=function(){return this.p.d.length};l.Sf=function(a){this.p=a;return this};l.De=function(){return tc().Ye};l.a=new s({xp:0},!1,"scala.collection.mutable.WrappedArray$ofUnit",{xp:1,pf:1,Ud:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,Vd:1,Ad:1,Bd:1,ud:1,Wd:1,zd:1,td:1,qd:1,ge:1,Pc:1,rb:1,$b:1,qc:1,hc:1,Lb:1,Sa:1,g:1,e:1});function zp(){this.Wf=this.Ya=null;this.$h=!1;this.Xf=0}
+zp.prototype=new ez;function Qx(a){if(!a.Ya.m()){var b=a.Ya,d=a.Wf.Cd;a.Ya=x();a.Wf=null;a.$h=!1;for(a.Xf=0;b!==d;)gr(a,b.u()),b=b.s()}}l=zp.prototype;l.b=function(){this.Ya=x();this.$h=!1;this.Xf=0;return this};l.u=function(){return this.Ya.u()};l.ma=function(a){if(0>a||a>=this.Xf)throw(new Rg).h(""+a);return rj(this.Ya,a)};l.pb=function(a){return pj(this.Ya,a)};l.l=function(a){return this.ma(a|0)};l.Qb=function(a){return vj(this.Ya,a)};l.m=function(){return this.Ya.m()};
+l.Fb=function(){this.$h=!this.Ya.m();return this.Ya};l.Ja=function(){return this};l.K=function(a){return a&&a.a&&a.a.t.np?this.Ya.K(a.Ya):Nr(a)?this.Qb(a):!1};l.fc=function(a){return L(this.Ya,"",a,"")};l.Ec=function(a,b,d){return L(this.Ya,a,b,d)};l.tb=function(a){return gr(this,a)};l.Ab=function(){zw||(zw=(new yw).b());return zw};l.R=function(a){for(var b=this.Ya;!b.m();)a.l(b.u()),b=b.s()};l.le=function(a,b){return qj(this.Ya,a,b)};l.U=c("Xf");l.pa=function(){return this.Fb()};
+l.X=function(){var a=new $s;a.Xh=this.Ya.m()?x():this.Ya;return a};l.hd=function(a,b){Ul(this,a,b)};l.ec=function(){return L(this.Ya,"","","")};l.q=c("Xf");l.Me=function(){return this};l.db=function(){return this.Ya.db()};l.Je=function(){return tj(this.Ya)};l.rc=function(a,b,d,e){return Cj(this.Ya,a,b,d,e)};function gr(a,b){a.$h&&Qx(a);if(a.Ya.m())a.Wf=Tb(new Ub,b,x()),a.Ya=a.Wf;else{var d=a.Wf;a.Wf=Tb(new Ub,b,x());d.Cd=a.Wf}a.Xf=1+a.Xf|0;return a}l.Dc=function(a){return ck(this.Ya,a)};
+l.Va=function(a){return 0<=(a|0)&&0<pj(this.Ya,a|0)};l.Ac=function(a,b){return qj(this.Ya,a,b)};l.Da=function(a){return gr(this,a)};l.Ta=ba();l.lc=function(a){return Vj(this.Ya,a)};function Ap(a,b){a:for(;;){var d=b;if(null!==d&&d===a){var e=a,d=a.Xf,f=e.na();if(!(0>=d)){f.hd(d,e);for(var g=0,e=e.X();g<d&&e.Ca();)f.Da(e.wa()),g=1+g|0}b=f.pa();continue a}return lk(a,b)}}l.Kb=function(a){return wj(this.Ya,a)};l.Ka=function(a){return Ap(this,a)};l.Wb=h("ListBuffer");
+l.a=new s({np:0},!1,"scala.collection.mutable.ListBuffer",{np:1,Ro:1,Ud:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,Vd:1,Ad:1,Bd:1,ud:1,Wd:1,zd:1,td:1,qd:1,lp:1,mp:1,Ub:1,Tb:1,uj:1,Yk:1,ab:1,Vb:1,yI:1,wI:1,zI:1,e:1});function dk(){this.Sc=null}dk.prototype=new kx;l=dk.prototype;l.Ba=function(){return this};l.b=function(){dk.prototype.ff.call(this,16,"");return this};l.u=function(){return cj(this)};
+l.ma=function(a){a=65535&(this.Sc.Ob.charCodeAt(a)|0);return(new Re).nc(a)};l.pb=function(a){return Fi(this,a)};l.l=function(a){a=65535&(this.Sc.Ob.charCodeAt(a|0)|0);return(new Re).nc(a)};l.Qb=function(a){return Ui(this,a)};l.m=function(){return aj(this)};l.Ja=function(){return this};l.Dp=function(a,b){return this.Sc.Ob.substring(a,b)};l.tb=function(a){Nq(this.Sc,null===a?0:a.j);return this};l.ef=function(){return Yi(this)};l.Ab=function(){return Ov()};l.o=function(){return this.Sc.Ob};
+l.R=function(a){Wi(this,a)};l.le=function(a,b){return Ni(this,0,this.Sc.Ob.length|0,a,b)};l.Qc=function(a,b){return jl(this,a,b)};l.pc=function(){return(new dk).nn(Oq(Kq(this.Sc)))};l.pa=function(){return this.Sc.Ob};function Zj(a,b){Jq(a.Sc,b);return a}l.ti=function(){return this};l.X=function(){return W(new X,this,this.Sc.Ob.length|0)};l.hd=function(a,b){Ul(this,a,b)};l.ff=function(a,b){dk.prototype.nn.call(this,Jq((new Ao).Oa((b.length|0)+a|0),b));return this};l.Yg=function(a){return Ti(this,a)};
+l.q=function(){return this.Sc.Ob.length|0};l.ec=function(){return this.Sc.Ob};l.Me=function(){return this};l.Je=function(){return Gi(this)};l.Zb=function(a){return jl(this,a,this.Sc.Ob.length|0)};l.bc=function(){return this};l.s=function(){return $i(this)};l.nn=function(a){this.Sc=a;return this};function ak(a,b){Jq(a.Sc,Bj(Ba(),b));return a}l.Va=function(a){return Di(this,a|0)};l.Da=function(a){Nq(this.Sc,null===a?0:a.j);return this};l.Ta=ba();l.Hc=function(a,b,d){Qi(this,a,b,d)};
+l.M=function(){return Nn(wi(),this)};l.kc=aa();l.Kb=function(a){return Mi(this,a)};l.na=function(){return pr(new or,(new dk).b())};l.Ka=function(a){return lk(this,a)};l.a=new s({tD:0},!1,"scala.collection.mutable.StringBuilder",{tD:1,Ud:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,Vd:1,Ad:1,Bd:1,ud:1,Wd:1,zd:1,td:1,qd:1,yn:1,ge:1,Pc:1,rb:1,$b:1,No:1,Lb:1,lh:1,Zc:1,Vb:1,Ub:1,Tb:1,g:1,e:1});function C(){this.p=null}
+C.prototype=new ez;l=C.prototype;l.Ba=function(){return this};l.b=function(){C.prototype.A.call(this,[]);return this};l.u=function(){return cj(this)};l.ma=function(a){return this.p[a]};l.pb=function(a){return Fi(this,a)};l.l=function(a){return this.p[a|0]};l.Qb=function(a){return Ui(this,a)};l.m=function(){return aj(this)};l.Ja=function(){return this};l.tb=function(a){this.p.push(a);return this};l.ef=function(){return Yi(this)};l.Ab=function(){return iq()};l.R=function(a){Wi(this,a)};
+l.le=function(a,b){return Ni(this,0,this.p.length|0,a,b)};l.Qc=function(a,b){return Pi(this,a,b)};l.pc=function(){return Xi(this)};l.pa=function(){return this};l.X=function(){return W(new X,this,this.p.length|0)};l.ti=function(){return this};l.hd=function(a,b){Ul(this,a,b)};l.Yg=function(a){return Ti(this,a)};l.q=function(){return this.p.length|0};l.Me=function(){return this};l.Je=function(){return Gi(this)};l.Zb=function(a){return Pi(this,a,this.p.length|0)};l.s=function(){return $i(this)};
+l.bc=function(){return this};l.Va=function(a){return Di(this,a|0)};l.Da=function(a){this.p.push(a);return this};l.Hc=function(a,b,d){Qi(this,a,b,d)};l.Ta=ba();l.M=function(){return Nn(wi(),this)};l.A=function(a){this.p=a;return this};l.kc=aa();l.Kb=function(a){return Mi(this,a)};l.Wb=h("WrappedArray");
+l.a=new s({FD:0},!1,"scala.scalajs.js.WrappedArray",{FD:1,Ro:1,Ud:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,Vd:1,Ad:1,Bd:1,ud:1,Wd:1,zd:1,td:1,qd:1,lp:1,mp:1,Ub:1,Tb:1,uj:1,Yk:1,ab:1,ge:1,Pc:1,rb:1,$b:1,qc:1,hc:1,Lb:1,Vb:1});function Dj(){this.on=0;this.p=null;this.Mb=0}Dj.prototype=new ez;l=Dj.prototype;l.Ba=function(){return this};function hz(a,b){km(a,1+a.Mb|0);a.p.d[a.Mb]=b;a.Mb=1+a.Mb|0;return a}
+l.b=function(){Dj.prototype.Oa.call(this,16);return this};l.u=function(){return cj(this)};l.ma=function(a){return mm(this,a)};l.pb=function(a){return Fi(this,a)};l.l=function(a){return mm(this,a|0)};l.Qb=function(a){return Ui(this,a)};l.m=function(){return aj(this)};l.Ja=function(){return this};l.tb=function(a){return hz(this,a)};l.ef=function(){return Yi(this)};l.Ab=function(){xw||(xw=(new ww).b());return xw};l.R=function(a){for(var b=0,d=this.Mb;b<d;)a.l(this.p.d[b]),b=1+b|0};
+l.le=function(a,b){return Ni(this,0,this.Mb,a,b)};l.Qc=function(a,b){return Pi(this,a,b)};l.pc=function(){return Xi(this)};l.pa=function(){return this};l.ti=function(){return this};l.X=function(){return W(new X,this,this.Mb)};l.hd=function(a,b){Ul(this,a,b)};l.Oa=function(a){a=this.on=a;this.p=p(v(u),[1<a?a:1]);this.Mb=0;return this};l.Yg=function(a){return Ti(this,a)};l.q=c("Mb");l.Me=function(){return this};l.Je=function(){return Gi(this)};l.Zb=function(a){return Pi(this,a,this.Mb)};l.s=function(){return $i(this)};
+l.bc=function(){return this};function Ej(a,b){if(Ij(b)){var d=b.q();km(a,a.Mb+d|0);b.Hc(a.p,a.Mb,d);a.Mb=a.Mb+d|0;return a}return lk(a,b)}l.Va=function(a){return Di(this,a|0)};l.Da=function(a){return hz(this,a)};l.Hc=function(a,b,d){var e=Ri(U(),a)-b|0;d=d<e?d:e;e=this.Mb;d=d<e?d:e;zl(rc(),this.p,0,a,b,d)};l.Ta=function(a){a>this.Mb&&1<=a&&(a=p(v(u),[a]),Fa(this.p,0,a,0,this.Mb),this.p=a)};l.M=function(){return Nn(wi(),this)};l.kc=aa();l.Kb=function(a){return Mi(this,a)};
+l.Ka=function(a){return Ej(this,a)};l.Wb=h("ArrayBuffer");l.a=new s({UC:0},!1,"scala.collection.mutable.ArrayBuffer",{UC:1,Ro:1,Ud:1,gc:1,ya:1,za:1,c:1,ta:1,fa:1,ga:1,$:1,H:1,G:1,ca:1,ea:1,ra:1,ua:1,sa:1,qa:1,ba:1,da:1,n:1,Sb:1,la:1,x:1,Rb:1,Wa:1,Xa:1,Vd:1,Ad:1,Bd:1,ud:1,Wd:1,zd:1,td:1,qd:1,lp:1,mp:1,Ub:1,Tb:1,uj:1,Yk:1,ab:1,hc:1,$b:1,rb:1,Lb:1,Vb:1,LI:1,ge:1,Pc:1,Sa:1,g:1,e:1});}).call(this);
+//# sourceMappingURL=scrollspy-opt.js.map
+
(function(){'use strict';function ca(){return function(a){return a}}function ea(){return function(){}}function d(a){return function(b){this[a]=b}}function g(a){return function(){return this[a]}}function l(a){return function(){return a}}var m,fa="object"===typeof __ScalaJSEnv&&__ScalaJSEnv?__ScalaJSEnv:{},n="object"===typeof fa.global&&fa.global?fa.global:"object"===typeof global&&global&&global.Object===Object?global:this;fa.global=n;var r="object"===typeof fa.exportsNamespace&&fa.exportsNamespace?fa.exportsNamespace:n;
fa.exportsNamespace=r;n.Object.freeze(fa);var ga=0;function ha(a){return function(b,c){return!(!b||!b.a||b.a.hi!==c||b.a.fi!==a)}}function ia(a){var b,c;for(c in a)b=c;return b}function s(a,b){return ja(a,b,0)}function ja(a,b,c){var e=new a.vk(b[c]);if(c<b.length-1){a=a.ni;c+=1;for(var f=e.d,h=0;h<f.length;h++)f[h]=ja(a,b,c)}return e}function ka(a){return void 0===a?"undefined":a.toString()}
function la(a){switch(typeof a){case "string":return t(ma);case "number":var b=a|0;return b===a?b<<24>>24===b&&1/b!==1/-0?t(na):b<<16>>16===b&&1/b!==1/-0?t(pa):t(sa):a!==a||ta(a)===a?t(ua):t(va);case "boolean":return t(wa);case "undefined":return t(xa);default:if(null===a)throw(new ya).b();return za(a)?t(Aa):a&&a.a?t(a.a):null}}function Ca(a,b){return a&&a.a||null===a?a.M(b):"number"===typeof a?"number"===typeof b&&(a===b?0!==a||1/a===1/b:a!==a&&b!==b):a===b}
diff --git a/styles.css b/styles.css
index 014d2f9..9eb271d 100644
--- a/styles.css
+++ b/styles.css
@@ -1,4 +1,3 @@
-.hljs{display:block;overflow-x:auto;padding:.5em;color:#000;background:#fff;-webkit-text-size-adjust:none}.hljs-subst,.hljs-title,.json .hljs-value{font-weight:normal;color:#000}.hljs-comment,.hljs-template_comment,.hljs-javadoc,.diff .hljs-header{color:#808080;font-style:italic}.hljs-annotation,.hljs-decorator,.hljs-preprocessor,.hljs-pragma,.hljs-doctype,.hljs-pi,.hljs-chunk,.hljs-shebang,.apache .hljs-cbracket,.hljs-prompt,.http .hljs-title{color:#808000}.hljs-tag,.hljs-pi{background:#efefef}.hljs-tag .hljs-title,.hljs-id,.hljs-attr_selector,.hljs-pseudo,.hljs-literal,.hljs-keyword,.hljs-hexcolor,.css .hljs-function,.ini .hljs-title,.css .hljs-class,.hljs-list .hljs-keyword,.nginx .hljs-title,.tex .hljs-command,.hljs-request,.hljs-status{font-weight:bold;color:#000080}.hljs-attribute,.hljs-rules .hljs-keyword,.hljs-number,.hljs-date,.hljs-regexp,.tex .hljs-special{font-weight:bold;color:#00f}.hljs-number,.hljs-regexp{font-weight:normal}.hljs-string,.hljs-value,.hljs-filter .hljs-argument,.css .hljs-function .hljs-params,.apache .hljs-tag{color:#008000;font-weight:bold}.hljs-symbol,.ruby .hljs-symbol .hljs-string,.hljs-char,.tex .hljs-formula{color:#000;background:#d0eded;font-style:italic}.hljs-phpdoc,.hljs-dartdoc,.hljs-yardoctag,.hljs-javadoctag{text-decoration:underline}.hljs-variable,.hljs-envvar,.apache .hljs-sqbracket,.nginx .hljs-built_in{color:#660e7a}.hljs-addition{background:#baeeba}.hljs-deletion{background:#ffc8bd}.diff .hljs-change{background:#bccff9}
/*!
Pure v0.5.0
Copyright 2014 Yahoo! Inc. All rights reserved.
@@ -11,68 +10,7 @@ Copyright (c) Nicolas Gallagher and Jonathan Neal
*/
/*! normalize.css v1.1.3 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-size:100%;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}html,button,input,select,textarea{font-family:sans-serif}body{margin:0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}h2{font-size:1.5em;margin:.83em 0}h3{font-size:1.17em;margin:1em 0}h4{font-size:1em;margin:1.33em 0}h5{font-size:.83em;margin:1.67em 0}h6{font-size:.67em;margin:2.33em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:1em 40px}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}mark{background:#ff0;color:#000}p,pre{margin:1em 0}code,kbd,pre,samp{font-family:monospace,serif;_font-family:'courier new',monospace;font-size:1em}pre{white-space:pre;white-space:pre-wrap;word-wrap:break-word}q{quotes:none}q:before,q:after{content:'';content:none}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,menu,ol,ul{margin:1em 0}dd{margin:0 0 0 40px}menu,ol,ul{padding:0 0 0 40px}nav ul,nav ol{list-style:none;list-style-image:none}img{border:0;-ms-interpolation-mode:bicubic}svg:not(:root){overflow:hidden}figure{margin:0}form{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0;white-space:normal;*margin-left:-7px}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;*overflow:visible}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0;*height:13px;*width:13px}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}[hidden]{display:none!important}.pure-img{max-width:100%;height:auto;display:block}.pure-g{letter-spacing:-.31em;*letter-spacing:normal;*word-spacing:-.43em;text-rendering:optimizespeed;font-family:FreeSans,Arimo,"Droid Sans",Helvetica,Arial,sans-serif;display:-webkit-flex;-webkit-flex-flow:row wrap;display:-ms-flexbox;-ms-flex-flow:row wrap}.opera-only :-o-prefocus,.pure-g{word-spacing:-.43em}.pure-u{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-g [class *="pure-u"]{font-family:sans-serif}.pure-u-1,.pure-u-1-1,.pure-u-1-2,.pure-u-1-3,.pure-u-2-3,.pure-u-1-4,.pure-u-3-4,.pure-u-1-5,.pure-u-2-5,.pure-u-3-5,.pure-u-4-5,.pure-u-5-5,.pure-u-1-6,.pure-u-5-6,.pure-u-1-8,.pure-u-3-8,.pure-u-5-8,.pure-u-7-8,.pure-u-1-12,.pure-u-5-12,.pure-u-7-12,.pure-u-11-12,.pure-u-1-24,.pure-u-2-24,.pure-u-3-24,.pure-u-4-24,.pure-u-5-24,.pure-u-6-24,.pure-u-7-24,.pure-u-8-24,.pure-u-9-24,.pure-u-10-24,.pure-u-11-24,.pure-u-12-24,.pure-u-13-24,.pure-u-14-24,.pure-u-15-24,.pure-u-16-24,.pure-u-17-24,.pure-u-18-24,.pure-u-19-24,.pure-u-20-24,.pure-u-21-24,.pure-u-22-24,.pure-u-23-24,.pure-u-24-24{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-u-1-24{width:4.1667%;*width:4.1357%}.pure-u-1-12,.pure-u-2-24{width:8.3333%;*width:8.3023%}.pure-u-1-8,.pure-u-3-24{width:12.5%;*width:12.469%}.pure-u-1-6,.pure-u-4-24{width:16.6667%;*width:16.6357%}.pure-u-1-5{width:20%;*width:19.969%}.pure-u-5-24{width:20.8333%;*width:20.8023%}.pure-u-1-4,.pure-u-6-24{width:25%;*width:24.969%}.pure-u-7-24{width:29.1667%;*width:29.1357%}.pure-u-1-3,.pure-u-8-24{width:33.3333%;*width:33.3023%}.pure-u-3-8,.pure-u-9-24{width:37.5%;*width:37.469%}.pure-u-2-5{width:40%;*width:39.969%}.pure-u-5-12,.pure-u-10-24{width:41.6667%;*width:41.6357%}.pure-u-11-24{width:45.8333%;*width:45.8023%}.pure-u-1-2,.pure-u-12-24{width:50%;*width:49.969%}.pure-u-13-24{width:54.1667%;*width:54.1357%}.pure-u-7-12,.pure-u-14-24{width:58.3333%;*width:58.3023%}.pure-u-3-5{width:60%;*width:59.969%}.pure-u-5-8,.pure-u-15-24{width:62.5%;*width:62.469%}.pure-u-2-3,.pure-u-16-24{width:66.6667%;*width:66.6357%}.pure-u-17-24{width:70.8333%;*width:70.8023%}.pure-u-3-4,.pure-u-18-24{width:75%;*width:74.969%}.pure-u-19-24{width:79.1667%;*width:79.1357%}.pure-u-4-5{width:80%;*width:79.969%}.pure-u-5-6,.pure-u-20-24{width:83.3333%;*width:83.3023%}.pure-u-7-8,.pure-u-21-24{width:87.5%;*width:87.469%}.pure-u-11-12,.pure-u-22-24{width:91.6667%;*width:91.6357%}.pure-u-23-24{width:95.8333%;*width:95.8023%}.pure-u-1,.pure-u-1-1,.pure-u-5-5,.pure-u-24-24{width:100%}.pure-button{display:inline-block;*display:inline;zoom:1;line-height:normal;white-space:nowrap;vertical-align:baseline;text-align:center;cursor:pointer;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.pure-button::-moz-focus-inner{padding:0;border:0}.pure-button{font-family:inherit;font-size:100%;*font-size:90%;*overflow:visible;padding:.5em 1em;color:#444;color:rgba(0,0,0,.8);*color:#444;border:1px solid #999;border:0 rgba(0,0,0,0);background-color:#E6E6E6;text-decoration:none;border-radius:2px}.pure-button-hover,.pure-button:hover,.pure-button:focus{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#1a000000', GradientType=0);background-image:-webkit-gradient(linear,0 0,0 100%,from(transparent),color-stop(40%,rgba(0,0,0,.05)),to(rgba(0,0,0,.1)));background-image:-webkit-linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1));background-image:-moz-linear-gradient(top,rgba(0,0,0,.05) 0,rgba(0,0,0,.1));background-image:-o-linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1));background-image:linear-gradient(transparent,rgba(0,0,0,.05) 40%,rgba(0,0,0,.1))}.pure-button:focus{outline:0}.pure-button-active,.pure-button:active{box-shadow:0 0 0 1px rgba(0,0,0,.15) inset,0 0 6px rgba(0,0,0,.2) inset}.pure-button[disabled],.pure-button-disabled,.pure-button-disabled:hover,.pure-button-disabled:focus,.pure-button-disabled:active{border:0;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);filter:alpha(opacity=40);-khtml-opacity:.4;-moz-opacity:.4;opacity:.4;cursor:not-allowed;box-shadow:none}.pure-button-hidden{display:none}.pure-button::-moz-focus-inner{padding:0;border:0}.pure-button-primary,.pure-button-selected,a.pure-button-primary,a.pure-button-selected{background-color:#0078e7;color:#fff}.pure-form input[type=text],.pure-form input[type=password],.pure-form input[type=email],.pure-form input[type=url],.pure-form input[type=date],.pure-form input[type=month],.pure-form input[type=time],.pure-form input[type=datetime],.pure-form input[type=datetime-local],.pure-form input[type=week],.pure-form input[type=number],.pure-form input[type=search],.pure-form input[type=tel],.pure-form input[type=color],.pure-form select,.pure-form textarea{padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-form input:not([type]){padding:.5em .6em;display:inline-block;border:1px solid #ccc;box-shadow:inset 0 1px 3px #ddd;border-radius:4px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.pure-form input[type=color]{padding:.2em .5em}.pure-form input[type=text]:focus,.pure-form input[type=password]:focus,.pure-form input[type=email]:focus,.pure-form input[type=url]:focus,.pure-form input[type=date]:focus,.pure-form input[type=month]:focus,.pure-form input[type=time]:focus,.pure-form input[type=datetime]:focus,.pure-form input[type=datetime-local]:focus,.pure-form input[type=week]:focus,.pure-form input[type=number]:focus,.pure-form input[type=search]:focus,.pure-form input[type=tel]:focus,.pure-form input[type=color]:focus,.pure-form select:focus,.pure-form textarea:focus{outline:0;outline:thin dotted \9;border-color:#129FEA}.pure-form input:not([type]):focus{outline:0;outline:thin dotted \9;border-color:#129FEA}.pure-form input[type=file]:focus,.pure-form input[type=radio]:focus,.pure-form input[type=checkbox]:focus{outline:thin dotted #333;outline:1px auto #129FEA}.pure-form .pure-checkbox,.pure-form .pure-radio{margin:.5em 0;display:block}.pure-form input[type=text][disabled],.pure-form input[type=password][disabled],.pure-form input[type=email][disabled],.pure-form input[type=url][disabled],.pure-form input[type=date][disabled],.pure-form input[type=month][disabled],.pure-form input[type=time][disabled],.pure-form input[type=datetime][disabled],.pure-form input[type=datetime-local][disabled],.pure-form input[type=week][disabled],.pure-form input[type=number][disabled],.pure-form input[type=search][disabled],.pure-form input[type=tel][disabled],.pure-form input[type=color][disabled],.pure-form select[disabled],.pure-form textarea[disabled]{cursor:not-allowed;background-color:#eaeded;color:#cad2d3}.pure-form input:not([type])[disabled]{cursor:not-allowed;background-color:#eaeded;color:#cad2d3}.pure-form input[readonly],.pure-form select[readonly],.pure-form textarea[readonly]{background:#eee;color:#777;border-color:#ccc}.pure-form input:focus:invalid,.pure-form textarea:focus:invalid,.pure-form select:focus:invalid{color:#b94a48;border-color:#ee5f5b}.pure-form input:focus:invalid:focus,.pure-form textarea:focus:invalid:focus,.pure-form select:focus:invalid:focus{border-color:#e9322d}.pure-form input[type=file]:focus:invalid:focus,.pure-form input[type=radio]:focus:invalid:focus,.pure-form input[type=checkbox]:focus:invalid:focus{outline-color:#e9322d}.pure-form select{border:1px solid #ccc;background-color:#fff}.pure-form select[multiple]{height:auto}.pure-form label{margin:.5em 0 .2em}.pure-form fieldset{margin:0;padding:.35em 0 .75em;border:0}.pure-form legend{display:block;width:100%;padding:.3em 0;margin-bottom:.3em;color:#333;border-bottom:1px solid #e5e5e5}.pure-form-stacked input[type=text],.pure-form-stacked input[type=password],.pure-form-stacked input[type=email],.pure-form-stacked input[type=url],.pure-form-stacked input[type=date],.pure-form-stacked input[type=month],.pure-form-stacked input[type=time],.pure-form-stacked input[type=datetime],.pure-form-stacked input[type=datetime-local],.pure-form-stacked input[type=week],.pure-form-stacked input[type=number],.pure-form-stacked input[type=search],.pure-form-stacked input[type=tel],.pure-form-stacked input[type=color],.pure-form-stacked select,.pure-form-stacked label,.pure-form-stacked textarea{display:block;margin:.25em 0}.pure-form-stacked input:not([type]){display:block;margin:.25em 0}.pure-form-aligned input,.pure-form-aligned textarea,.pure-form-aligned select,.pure-form-aligned .pure-help-inline,.pure-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.pure-form-aligned textarea{vertical-align:top}.pure-form-aligned .pure-control-group{margin-bottom:.5em}.pure-form-aligned .pure-control-group label{text-align:right;display:inline-block;vertical-align:middle;width:10em;margin:0 1em 0 0}.pure-form-aligned .pure-controls{margin:1.5em 0 0 10em}.pure-form input.pure-input-rounded,.pure-form .pure-input-rounded{border-radius:2em;padding:.5em 1em}.pure-form .pure-group fieldset{margin-bottom:10px}.pure-form .pure-group input{display:block;padding:10px;margin:0;border-radius:0;position:relative;top:-1px}.pure-form .pure-group input:focus{z-index:2}.pure-form .pure-group input:first-child{top:1px;border-radius:4px 4px 0 0}.pure-form .pure-group input:last-child{top:-2px;border-radius:0 0 4px 4px}.pure-form .pure-group button{margin:.35em 0}.pure-form .pure-input-1{width:100%}.pure-form .pure-input-2-3{width:66%}.pure-form .pure-input-1-2{width:50%}.pure-form .pure-input-1-3{width:33%}.pure-form .pure-input-1-4{width:25%}.pure-form .pure-help-inline,.pure-form-message-inline{display:inline-block;padding-left:.3em;color:#666;vertical-align:middle;font-size:.875em}.pure-form-message{display:block;color:#666;font-size:.875em}@media only screen and (max-width :480px){.pure-form button[type=submit]{margin:.7em 0 0}.pure-form input:not([type]),.pure-form input[type=text],.pure-form input[type=password],.pure-form input[type=email],.pure-form input[type=url],.pure-form input[type=date],.pure-form input[type=month],.pure-form input[type=time],.pure-form input[type=datetime],.pure-form input[type=datetime-local],.pure-form input[type=week],.pure-form input[type=number],.pure-form input[type=search],.pure-form input[type=tel],.pure-form input[type=color],.pure-form label{margin-bottom:.3em;display:block}.pure-group input:not([type]),.pure-group input[type=text],.pure-group input[type=password],.pure-group input[type=email],.pure-group input[type=url],.pure-group input[type=date],.pure-group input[type=month],.pure-group input[type=time],.pure-group input[type=datetime],.pure-group input[type=datetime-local],.pure-group input[type=week],.pure-group input[type=number],.pure-group input[type=search],.pure-group input[type=tel],.pure-group input[type=color]{margin-bottom:0}.pure-form-aligned .pure-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.pure-form-aligned .pure-controls{margin:1.5em 0 0}.pure-form .pure-help-inline,.pure-form-message-inline,.pure-form-message{display:block;font-size:.75em;padding:.2em 0 .8em}}.pure-menu ul{position:absolute;visibility:hidden}.pure-menu.pure-menu-open{visibility:visible;z-index:2;width:100%}.pure-menu ul{left:-10000px;list-style:none;margin:0;padding:0;top:-10000px;z-index:1}.pure-menu>ul{position:relative}.pure-menu-open>ul{left:0;top:0;visibility:visible}.pure-menu-open>ul:focus{outline:0}.pure-menu li{position:relative}.pure-menu a,.pure-menu .pure-menu-heading{display:block;color:inherit;line-height:1.5em;padding:5px 20px;text-decoration:none;white-space:nowrap}.pure-menu.pure-menu-horizontal>.pure-menu-heading{display:inline-block;*display:inline;zoom:1;margin:0;vertical-align:middle}.pure-menu.pure-menu-horizontal>ul{display:inline-block;*display:inline;zoom:1;vertical-align:middle}.pure-menu li a{padding:5px 20px}.pure-menu-can-have-children>.pure-menu-label:after{content:'\25B8';float:right;font-family:'Lucida Grande','Lucida Sans Unicode','DejaVu Sans',sans-serif;margin-right:-20px;margin-top:-1px}.pure-menu-can-have-children>.pure-menu-label{padding-right:30px}.pure-menu-separator{background-color:#dfdfdf;display:block;height:1px;font-size:0;margin:7px 2px;overflow:hidden}.pure-menu-hidden{display:none}.pure-menu-fixed{position:fixed;top:0;left:0;width:100%}.pure-menu-horizontal li{display:inline-block;*display:inline;zoom:1;vertical-align:middle}.pure-menu-horizontal li li{display:block}.pure-menu-horizontal>.pure-menu-children>.pure-menu-can-have-children>.pure-menu-label:after{content:"\25BE"}.pure-menu-horizontal>.pure-menu-children>.pure-menu-can-have-children>.pure-menu-label{padding-right:30px}.pure-menu-horizontal li.pure-menu-separator{height:50%;width:1px;margin:0 7px}.pure-menu-horizontal li li.pure-menu-separator{height:1px;width:auto;margin:7px 2px}.pure-menu.pure-menu-open,.pure-menu.pure-menu-horizontal li .pure-menu-children{background:#fff;border:1px solid #b7b7b7}.pure-menu.pure-menu-horizontal,.pure-menu.pure-menu-horizontal .pure-menu-heading{border:0}.pure-menu a{border:1px solid transparent;border-left:0;border-right:0}.pure-menu a,.pure-menu .pure-menu-can-have-children>li:after{color:#777}.pure-menu .pure-menu-can-have-children>li:hover:after{color:#fff}.pure-menu .pure-menu-open{background:#dedede}.pure-menu li a:hover,.pure-menu li a:focus{background:#eee}.pure-menu li.pure-menu-disabled a:hover,.pure-menu li.pure-menu-disabled a:focus{background:#fff;color:#bfbfbf}.pure-menu .pure-menu-disabled>a{background-image:none;border-color:transparent;cursor:default}.pure-menu .pure-menu-disabled>a,.pure-menu .pure-menu-can-have-children.pure-menu-disabled>a:after{color:#bfbfbf}.pure-menu .pure-menu-heading{color:#565d64;text-transform:uppercase;font-size:90%;margin-top:.5em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#dfdfdf}.pure-menu .pure-menu-selected a{color:#000}.pure-menu.pure-menu-open.pure-menu-fixed{border:0;border-bottom:1px solid #b7b7b7}.pure-paginator{letter-spacing:-.31em;*letter-spacing:normal;*word-spacing:-.43em;text-rendering:optimizespeed;list-style:none;margin:0;padding:0}.opera-only :-o-prefocus,.pure-paginator{word-spacing:-.43em}.pure-paginator li{display:inline-block;*display:inline;zoom:1;letter-spacing:normal;word-spacing:normal;vertical-align:top;text-rendering:auto}.pure-paginator .pure-button{border-radius:0;padding:.8em 1.4em;vertical-align:top;height:1.1em}.pure-paginator .pure-button:focus,.pure-paginator .pure-button:active{outline-style:none}.pure-paginator .prev,.pure-paginator .next{color:#C0C1C3;text-shadow:0 -1px 0 rgba(0,0,0,.45)}.pure-paginator .prev{border-radius:2px 0 0 2px}.pure-paginator .next{border-radius:0 2px 2px 0}@media (max-width:480px){.pure-menu-horizontal{width:100%}.pure-menu-children li{display:block;border-bottom:1px solid #000}}.pure-table{border-collapse:collapse;border-spacing:0;empty-cells:show;border:1px solid #cbcbcb}.pure-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.pure-table td,.pure-table th{border-left:1px solid #cbcbcb;border-width:0 0 0 1px;font-size:inherit;margin:0;overflow:visible;padding:.5em 1em}.pure-table td:first-child,.pure-table th:first-child{border-left-width:0}.pure-table thead{background:#e0e0e0;color:#000;text-align:left;vertical-align:bottom}.pure-table td{background-color:transparent}.pure-table-odd td{background-color:#f2f2f2}.pure-table-striped tr:nth-child(2n-1) td{background-color:#f2f2f2}.pure-table-bordered td{border-bottom:1px solid #cbcbcb}.pure-table-bordered tbody>tr:last-child td,.pure-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.pure-table-horizontal td,.pure-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #cbcbcb}.pure-table-horizontal tbody>tr:last-child td{border-bottom-width:0}
-.scalatex-content *{
- position: relative;
-}
-.scalatex-content p{
- text-align: justify;
-}
-
-/*
-The content `<div>` is where all your content goes.
-*/
-.scalatex-content {
- margin: 0 auto;
- padding: 0 1em;
- max-width: 800px;
- padding-bottom: 50px;
- line-height: 1.6em;
- color: #777;
-}
-
-/* Custom Stuff */
-.scalatex-content a:link {
- color: #37a;
- text-decoration: none;
-}
-.scalatex-content a:visited {
- color: #949;
- text-decoration: none;
-}
-.scalatex-content a:hover {
- text-decoration: underline;
-}
-.scalatex-content a:active {
- color: #000;
- text-decoration: underline;
-}
-.scalatex-content code{
- color: #000;
-}
-
-.scalatex-hover-container:hover .scalatex-header-link:hover > i{
- opacity: 1.0;
-}
-
-.scalatex-hover-container:hover .scalatex-header-link > i:active{
- opacity: 0.75;
-}
-
-.scalatex-hover-container:hover .scalatex-header-link > i{
- opacity: 0.5;
-}
-
-.scalatex-header-link > i{
- color: #777;
- opacity: 0.05;
- text-decoration: none;
-}
-
-
-/*Workaround for bug in highlight.js IDEA theme*/
-span.hljs-tag, span.hljs-symbol{
- background: none;
-}
+.hljs{display:block;overflow-x:auto;padding:.5em;color:#000;background:#fff;-webkit-text-size-adjust:none}.hljs-subst,.hljs-title,.json .hljs-value{font-weight:normal;color:#000}.hljs-comment,.hljs-template_comment,.hljs-javadoc,.diff .hljs-header{color:#808080;font-style:italic}.hljs-annotation,.hljs-decorator,.hljs-preprocessor,.hljs-pragma,.hljs-doctype,.hljs-pi,.hljs-chunk,.hljs-shebang,.apache .hljs-cbracket,.hljs-prompt,.http .hljs-title{color:#808000}.hljs-tag,.hljs-pi{background:#efefef}.hljs-tag .hljs-title,.hljs-id,.hljs-attr_selector,.hljs-pseudo,.hljs-literal,.hljs-keyword,.hljs-hexcolor,.css .hljs-function,.ini .hljs-title,.css .hljs-class,.hljs-list .hljs-keyword,.nginx .hljs-title,.tex .hljs-command,.hljs-request,.hljs-status{font-weight:bold;color:#000080}.hljs-attribute,.hljs-rules .hljs-keyword,.hljs-number,.hljs-date,.hljs-regexp,.tex .hljs-special{font-weight:bold;color:#00f}.hljs-number,.hljs-regexp{font-weight:normal}.hljs-string,.hljs-value,.hljs-filter .hljs-argument,.css .hljs-function .hljs-params,.apache .hljs-tag{color:#008000;font-weight:bold}.hljs-symbol,.ruby .hljs-symbol .hljs-string,.hljs-char,.tex .hljs-formula{color:#000;background:#d0eded;font-style:italic}.hljs-phpdoc,.hljs-dartdoc,.hljs-yardoctag,.hljs-javadoctag{text-decoration:underline}.hljs-variable,.hljs-envvar,.apache .hljs-sqbracket,.nginx .hljs-built_in{color:#660e7a}.hljs-addition{background:#baeeba}.hljs-deletion{background:#ffc8bd}.diff .hljs-change{background:#bccff9}
/*!
Pure v0.5.0
Copyright 2014 Yahoo! Inc. All rights reserved.