diff --git a/client/client-monitoring/pom.xml b/client/client-monitoring/pom.xml
new file mode 100644
index 0000000..d94a0ea
--- /dev/null
+++ b/client/client-monitoring/pom.xml
@@ -0,0 +1,159 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2018 Ericsson. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onap.policy.apex-pdp.client</groupId>
+        <artifactId>client</artifactId>
+        <version>2.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>client-monitoring</artifactId>
+    <name>${project.artifactId}</name>
+    <description>Web client for monitoring Apex engines</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onap.policy.apex-pdp.core</groupId>
+            <artifactId>core-deployment</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.containers</groupId>
+            <artifactId>jersey-container-grizzly2-http</artifactId>
+            <version>${version.jersey}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.containers</groupId>
+            <artifactId>jersey-container-servlet-core</artifactId>
+            <version>${version.jersey}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.inject</groupId>
+            <artifactId>jersey-hk2</artifactId>
+            <version>${version.jersey}</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-cli</groupId>
+            <artifactId>commons-cli</artifactId>
+            <version>${version.commons-cli}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <defaultGoal>install</defaultGoal>
+        <outputDirectory>${project.build.directory}/classes</outputDirectory>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <finalName>${project.artifactId}-uber-${project.version}</finalName>
+                    <shadedArtifactAttached>true</shadedArtifactAttached>
+                    <shadedClassifierName>monitoring</shadedClassifierName>
+                    <artifactSet>
+                        <includes>
+                            <include>*:*</include>
+                        </includes>
+                    </artifactSet>
+                    <filters>
+                        <filter>
+                            <artifact>*:*</artifact>
+                            <excludes>
+                                <exclude>META-INF/*.SF</exclude>
+                                <exclude>META-INF/*.DSA</exclude>
+                                <exclude>META-INF/*.RSA</exclude>
+                            </excludes>
+                        </filter>
+                    </filters>
+                    <transformers>
+                        <transformer
+                            implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
+                        <transformer
+                            implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
+                            <resource>reference.conf</resource>
+                        </transformer>
+                        <transformer
+                            implementation="org.apache.maven.plugins.shade.resource.DontIncludeResourceTransformer">
+                            <resource>log4j.properties</resource>
+                        </transformer>
+                        <transformer
+                            implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+                            <mainClass>org.onap.policy.apex.client.monitoring.rest.ApexMonitoringRestMain</mainClass>
+                        </transformer>
+                    </transformers>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-war-plugin</artifactId>
+                <version>2.6</version>
+                <configuration>
+                    <classifier>ui</classifier>
+                    <warSourceDirectory>src/main/resources/webapp</warSourceDirectory>
+                    <webXml>src/main/resources/webapp/WEB-INF/web.xml</webXml>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>prepare-package</phase>
+                        <goals>
+                            <goal>war</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <version>3.0.0</version>
+                <executions>
+                    <execution>
+                        <id>attach-artifacts</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>attach-artifact</goal>
+                        </goals>
+                        <configuration>
+                            <artifacts>
+                                <artifact>
+                                    <file>${project.build.directory}/${project.artifactId}-${project.version}-ui.war</file>
+                                    <type>war</type>
+                                </artifact>
+                                <artifact>
+                                    <file>${project.build.directory}/${project.artifactId}-uber-${project.version}.jar</file>
+                                    <type>uber.jar</type>
+                                </artifact>
+                            </artifacts>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRest.java b/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRest.java
new file mode 100644
index 0000000..d6f7e64
--- /dev/null
+++ b/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRest.java
@@ -0,0 +1,80 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.client.monitoring.rest;
+
+import org.glassfish.grizzly.http.server.HttpServer;
+import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.onap.policy.apex.model.utilities.Assertions;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * This class is used to launch the services. It creates a Grizzly embedded web server and runs the services.
+ */
+public class ApexMonitoringRest {
+    // Logger for this class
+    private static final XLogger logger = XLoggerFactory.getXLogger(ApexMonitoringRest.class);
+
+    // The HTTP server exposing JAX-RS resources defined in this application.
+    private HttpServer server;
+
+    /**
+     * Starts the HTTP server for the Apex services client on the default base URI and with the default REST packages
+     */
+    public ApexMonitoringRest() {
+        this(new ApexMonitoringRestParameters());
+    }
+
+    /**
+     * Starts the HTTP server for the Apex services client
+     *
+     * @param parameters: The Apex parameters to use to start the server
+     */
+    public ApexMonitoringRest(final ApexMonitoringRestParameters parameters) {
+        Assertions.argumentNotNull(parameters, "parameters may not be null");
+
+        logger.debug("Apex services RESTful client starting . . .");
+
+        // Create a resource configuration that scans for JAX-RS resources and providers
+        // in org.onap.policy.apex.services.client.monitoring.rest package
+        final ResourceConfig rc = new ResourceConfig().packages(parameters.getRESTPackages());
+
+        // create and start a new instance of grizzly http server
+        // exposing the Jersey application at BASE_URI
+        server = GrizzlyHttpServerFactory.createHttpServer(parameters.getBaseURI(), rc);
+
+        // Add static content
+        server.getServerConfiguration().addHttpHandler(new org.glassfish.grizzly.http.server.CLStaticHttpHandler(
+                ApexMonitoringRestMain.class.getClassLoader(), "/webapp/"), parameters.getStaticPath());
+
+        logger.debug("Apex services RESTful client started");
+    }
+
+    /**
+     * Shut down the web server
+     */
+    public void shutdown() {
+        logger.debug("Apex services RESTful client shutting down . . .");
+        server.shutdown();
+        logger.debug("Apex services RESTful client shut down");
+    }
+}
diff --git a/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestMain.java b/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestMain.java
new file mode 100644
index 0000000..fcc29ed
--- /dev/null
+++ b/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestMain.java
@@ -0,0 +1,192 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.client.monitoring.rest;
+
+import java.io.PrintStream;
+
+/**
+ * User: ewatkmi Date: 31 Jul 2017
+ */
+public class ApexMonitoringRestMain {
+    // Services state
+    public enum ServicesState {
+        STOPPED, READY, INITIALIZING, RUNNING
+    };
+
+    private ServicesState state = ServicesState.STOPPED;
+
+    // The parameters for the client
+    private ApexMonitoringRestParameters parameters = null;
+
+    // Output and error streams for messages
+    private final PrintStream outStream;
+
+    // The Apex services client this class is running
+    private ApexMonitoringRest apexMonitoringRest = null;
+
+    /**
+     * Main method, main entry point for command
+     *
+     * @param args The command line arguments for the client
+     */
+    public static void main(final String[] args) {
+        try {
+            final ApexMonitoringRestMain restMain = new ApexMonitoringRestMain(args, System.out);
+            restMain.init();
+        } catch (final Exception e) {
+            System.err.println(e.getMessage());
+        }
+    }
+
+    /**
+     * Constructor, kicks off the rest service
+     *
+     * @param args The command line arguments for the RESTful service
+     * @param outStream The stream for output messages
+     */
+    public ApexMonitoringRestMain(final String[] args, final PrintStream outStream) {
+        // Save the streams for output and error
+        this.outStream = outStream;
+
+        // Client parameter parsing
+        final ApexMonitoringRestParameterParser parser = new ApexMonitoringRestParameterParser();
+
+        try {
+            // Get and check the parameters
+            parameters = parser.parse(args);
+        } catch (final ApexMonitoringRestParameterException e) {
+            throw new ApexMonitoringRestParameterException(
+                    "Apex Services REST endpoint (" + this.toString() + ") parameter error, " + e.getMessage() + '\n'
+                            + parser.getHelp(ApexMonitoringRestMain.class.getCanonicalName()));
+        }
+
+        if (parameters.isHelpSet()) {
+            throw new ApexMonitoringRestParameterException(
+                    parser.getHelp(ApexMonitoringRestMain.class.getCanonicalName()));
+        }
+
+        // Validate the parameters
+        final String validationMessage = parameters.validate();
+        if (validationMessage.length() > 0) {
+            throw new ApexMonitoringRestParameterException(
+                    "Apex Services REST endpoint (" + this.toString() + ") parameters invalid, " + validationMessage
+                            + '\n' + parser.getHelp(ApexMonitoringRestMain.class.getCanonicalName()));
+        }
+
+        state = ServicesState.READY;
+    }
+
+    /**
+     * Initialize the rest service
+     */
+    public void init() {
+        outStream.println("Apex Services REST endpoint (" + this.toString() + ") starting at "
+                + parameters.getBaseURI().toString() + " . . .");
+
+        try {
+            state = ServicesState.INITIALIZING;
+
+            // Start the REST service
+            apexMonitoringRest = new ApexMonitoringRest(parameters);
+
+            // Add a shutdown hook to shut down the rest services when the process is exiting
+            Runtime.getRuntime().addShutdownHook(new Thread(new ApexServicesShutdownHook()));
+
+            state = ServicesState.RUNNING;
+
+            if (parameters.getTimeToLive() == ApexMonitoringRestParameters.INFINITY_TIME_TO_LIVE) {
+                outStream.println("Apex Services REST endpoint (" + this.toString() + ") started at "
+                        + parameters.getBaseURI().toString());
+            } else {
+                outStream.println("Apex Services REST endpoint (" + this.toString() + ") started");
+            }
+
+            // Find out how long is left to wait
+            long timeRemaining = parameters.getTimeToLive();
+            while (timeRemaining == ApexMonitoringRestParameters.INFINITY_TIME_TO_LIVE || timeRemaining > 0) {
+                // decrement the time to live in the non-infinity case
+                if (timeRemaining > 0) {
+                    timeRemaining--;
+                }
+
+                // Wait for a second
+                Thread.sleep(1000);
+            }
+        } catch (final Exception e) {
+            outStream.println(
+                    "Apex Services REST endpoint (" + this.toString() + ") failed at with error: " + e.getMessage());
+        } finally {
+            if (apexMonitoringRest != null) {
+                apexMonitoringRest.shutdown();
+                apexMonitoringRest = null;
+            }
+            state = ServicesState.STOPPED;
+        }
+
+    }
+
+    /**
+     * Get services state.
+     *
+     * @return the service state
+     */
+    public ServicesState getState() {
+        return state;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder ret = new StringBuilder();
+        ret.append(this.getClass().getSimpleName()).append(": Config=[").append(this.parameters).append("], State=")
+                .append(this.getState());
+        return ret.toString();
+    }
+
+    /**
+     * Explicitly shut down the services
+     */
+    public void shutdown() {
+        if (apexMonitoringRest != null) {
+            outStream.println("Apex Services REST endpoint (" + this.toString() + ") shutting down");
+            apexMonitoringRest.shutdown();
+        }
+        state = ServicesState.STOPPED;
+        outStream.println("Apex Services REST endpoint (" + this.toString() + ") shut down");
+    }
+
+    /**
+     * This class is a shutdown hook for the Apex services command
+     */
+    private class ApexServicesShutdownHook implements Runnable {
+        /*
+         * (non-Javadoc)
+         *
+         * @see java.lang.Runnable#run()
+         */
+        @Override
+        public void run() {
+            if (apexMonitoringRest != null) {
+                apexMonitoringRest.shutdown();
+            }
+        }
+    }
+
+}
diff --git a/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestParameterException.java b/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestParameterException.java
new file mode 100644
index 0000000..cbbc294
--- /dev/null
+++ b/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestParameterException.java
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.client.monitoring.rest;
+
+/**
+ * A run time exception used to report parsing and parameter input errors
+ *
+ * User: ewatkmi Date: 31 Jul 2017
+ */
+public class ApexMonitoringRestParameterException extends IllegalArgumentException {
+    private static final long serialVersionUID = 6520231162404452427L;
+
+    /**
+     * Create an ApexServicesRestParameterException with a message.
+     *
+     * @param message the message
+     */
+    public ApexMonitoringRestParameterException(final String message) {
+        super(message);
+    }
+
+    /**
+     * Create an ApexServicesRestParameterException with a message and an exception.
+     *
+     * @param message the message
+     * @param throwable The exception that caused the exception
+     */
+    public ApexMonitoringRestParameterException(final String message, final Throwable throwable) {
+        super(message, throwable);
+    }
+}
diff --git a/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestParameterParser.java b/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestParameterParser.java
new file mode 100644
index 0000000..35ee6b4
--- /dev/null
+++ b/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestParameterParser.java
@@ -0,0 +1,116 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.client.monitoring.rest;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Arrays;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+
+/**
+ * This class reads and handles command line parameters to the Apex RESTful services
+ *
+ * User: ewatkmi Date: 31 Jul 2017
+ */
+public class ApexMonitoringRestParameterParser {
+    // Apache Commons CLI options
+    Options options;
+
+    /**
+     * Construct the options for the CLI RESTful services
+     */
+    public ApexMonitoringRestParameterParser() {
+        options = new Options();
+        options.addOption("h", "help", false, "outputs the usage of this command");
+        options.addOption(Option.builder("p").longOpt("port").desc("port to use for the Apex Services REST calls")
+                .hasArg().argName("PORT").required(false).type(Number.class).build());
+        options.addOption(Option.builder("t").longOpt("time-to-live")
+                .desc("the amount of time in seconds that the server will run for before terminating").hasArg()
+                .argName("TIME_TO_LIVE").required(false).type(Number.class).build());
+    }
+
+    /**
+     * Parse the command line options.
+     *
+     * @param args the arguments
+     * @return parsed parameters
+     */
+    public ApexMonitoringRestParameters parse(final String[] args) {
+        CommandLine commandLine = null;
+        try {
+            commandLine = new DefaultParser().parse(options, args);
+        } catch (final ParseException e) {
+            throw new ApexMonitoringRestParameterException(
+                    "invalid command line arguments specified : " + e.getMessage());
+        }
+
+        final ApexMonitoringRestParameters parameters = new ApexMonitoringRestParameters();
+        final String[] remainingArgs = commandLine.getArgs();
+
+        if (commandLine.getArgs().length > 0) {
+            throw new ApexMonitoringRestParameterException(
+                    "too many command line arguments specified : " + Arrays.toString(remainingArgs));
+        }
+
+        if (commandLine.hasOption('h')) {
+            parameters.setHelp(true);
+        }
+        try {
+            if (commandLine.hasOption('p')) {
+                parameters.setRESTPort(((Number) commandLine.getParsedOptionValue("port")).intValue());
+            }
+        } catch (final ParseException e) {
+            throw new ApexMonitoringRestParameterException("error parsing argument \"port\" :" + e.getMessage(), e);
+        }
+        try {
+            if (commandLine.hasOption('t')) {
+                parameters.setTimeToLive(((Number) commandLine.getParsedOptionValue("time-to-live")).longValue());
+            }
+        } catch (final ParseException e) {
+            throw new ApexMonitoringRestParameterException("error parsing argument \"time-to-live\" :" + e.getMessage(),
+                    e);
+        }
+
+        return parameters;
+    }
+
+    /**
+     * Get help information.
+     *
+     * @param mainClassName the main class name for the help output
+     * @return help string
+     */
+    public String getHelp(final String mainClassName) {
+        final StringWriter stringWriter = new StringWriter();
+        final PrintWriter stringPrintWriter = new PrintWriter(stringWriter);
+
+        final HelpFormatter helpFormatter = new HelpFormatter();
+        helpFormatter.printHelp(stringPrintWriter, 120, mainClassName + " [options...] ", "", options, 0, 0, "");
+
+        return stringWriter.toString();
+    }
+}
diff --git a/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestParameters.java b/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestParameters.java
new file mode 100644
index 0000000..a1a8efc
--- /dev/null
+++ b/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestParameters.java
@@ -0,0 +1,115 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.client.monitoring.rest;
+
+import java.net.URI;
+
+/**
+ * This class reads and handles command line parameters to the Apex RESTful services
+ *
+ * User: ewatkmi Date: 31 Jul 2017
+ */
+public class ApexMonitoringRestParameters {
+    public static final int DEFAULT_REST_PORT = 18989;
+    public static final int INFINITY_TIME_TO_LIVE = -1;
+
+    // Base URI the HTTP server will listen on
+    private static final String DEFAULT_SERVER_URI_ROOT = "http://localhost:";
+    private static final String DEFAULT_REST_PATH = "/apexservices/";
+    private static final String DEFAULT_STATIC_PATH = "/";
+
+    // Package that will field REST requests
+    public static final String[] DEFAULT_PACKAGES =
+            new String[] { "org.onap.policy.apex.services.client.monitoring.rest" };
+
+    // The services parameters
+    private boolean helpSet = false;
+    private int restPort = DEFAULT_REST_PORT;
+    private long timeToLive = INFINITY_TIME_TO_LIVE;
+
+    public String validate() {
+        String validationMessage = "";
+        validationMessage += validatePort();
+        validationMessage += validateTimeToLive();
+
+        return validationMessage;
+    }
+
+    public URI getBaseURI() {
+        return URI.create(DEFAULT_SERVER_URI_ROOT + restPort + DEFAULT_REST_PATH);
+    }
+
+    public String[] getRESTPackages() {
+        return DEFAULT_PACKAGES;
+    }
+
+    public String getStaticPath() {
+        return DEFAULT_STATIC_PATH;
+    }
+
+    private String validatePort() {
+        if (restPort < 1024 || restPort > 65535) {
+            return "port must be greater than 1023 and less than 65536\n";
+        } else {
+            return "";
+        }
+    }
+
+    private String validateTimeToLive() {
+        if (timeToLive < -1) {
+            return "time to live must be greater than -1 (set to -1 to wait forever)\n";
+        } else {
+            return "";
+        }
+    }
+
+    public boolean isHelpSet() {
+        return helpSet;
+    }
+
+    public void setHelp(final boolean helpSet) {
+        this.helpSet = helpSet;
+    }
+
+    public int getRESTPort() {
+        return restPort;
+    }
+
+    public void setRESTPort(final int restPort) {
+        this.restPort = restPort;
+    }
+
+    public long getTimeToLive() {
+        return timeToLive;
+    }
+
+    public void setTimeToLive(final long timeToLive) {
+        this.timeToLive = timeToLive;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder ret = new StringBuilder();
+        ret.append(this.getClass().getSimpleName()).append(": URI=").append(this.getBaseURI()).append(", TTL=")
+                .append(this.getTimeToLive()).append("sec");
+        return ret.toString();
+    }
+}
diff --git a/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestResource.java b/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestResource.java
new file mode 100644
index 0000000..84f29df
--- /dev/null
+++ b/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestResource.java
@@ -0,0 +1,346 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.client.monitoring.rest;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.onap.policy.apex.core.deployment.ApexDeploymentException;
+import org.onap.policy.apex.core.deployment.EngineServiceFacade;
+import org.onap.policy.apex.model.basicmodel.concepts.ApexException;
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.onap.policy.apex.model.enginemodel.concepts.AxEngineModel;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * The class represents the root resource exposed at the base URL<br>
+ * The url to access this resource would be in the form {@code <baseURL>/rest/....} <br>
+ * For example: a GET request to the following URL
+ * {@code http://localhost:18989/apexservices/rest/?hostName=localhost&port=12345}
+ *
+ * <b>Note:</b> An allocated {@code hostName} and {@code port} query parameter must be included in all requests.
+ * Datasets for different {@code hostName} are completely isolated from one another.
+ *
+ */
+@Path("monitoring/")
+@Produces({ MediaType.APPLICATION_JSON })
+@Consumes({ MediaType.APPLICATION_JSON })
+
+public class ApexMonitoringRestResource {
+    // Get a reference to the logger
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(ApexMonitoringRestResource.class);
+
+    // Set the maximum number of stored data entries to be stored for each engine
+    private static final int maxCachedEntries = 50;
+
+    // Set up a map separated by host and engine for the data
+    private static final HashMap<String, HashMap<String, List<Counter>>> cache =
+            new HashMap<String, HashMap<String, List<Counter>>>();
+
+    // Set up a map separated by host for storing the state of periodic events
+    private static final HashMap<String, Boolean> periodicEventsStateCache = new HashMap<String, Boolean>();
+
+    /**
+     * Constructor, a new resource director is created for each request.
+     */
+    public ApexMonitoringRestResource() {}
+
+    /**
+     * Query the engine service for data
+     *
+     * @param hostName the host name of the engine service to connect to.
+     * @param port the port number of the engine service to connect to.
+     * @return a Response object containing the engines service, status and context data in JSON
+     */
+    @GET
+    public Response createSession(@QueryParam("hostName") final String hostName, @QueryParam("port") final int port) {
+        final Gson gson = new Gson();
+        final String host = hostName + ":" + port;
+        final EngineServiceFacade engineServiceFacade = new EngineServiceFacade(hostName, port);
+
+        try {
+            engineServiceFacade.init();
+        } catch (final ApexDeploymentException e) {
+            final String errorMessage = "Error connecting to Apex Engine Service at " + host;
+            LOGGER.warn(errorMessage + "<br>", e);
+            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage + "\n" + e.getMessage())
+                    .build();
+        }
+
+        final JsonObject responseObject = new JsonObject();
+
+        // Engine Service data
+        responseObject.addProperty("engine_id", engineServiceFacade.getKey().getID());
+        responseObject.addProperty("model_id",
+                engineServiceFacade.getApexModelKey() != null ? engineServiceFacade.getApexModelKey().getID()
+                        : "Not Set");
+        responseObject.addProperty("server", hostName);
+        responseObject.addProperty("port", Integer.toString(port));
+        responseObject.addProperty("periodic_events", getPeriodicEventsState(host));
+
+        // Engine Status data
+        final JsonArray engineStatusList = new JsonArray();
+
+        for (final AxArtifactKey engineKey : engineServiceFacade.getEngineKeyArray()) {
+            try {
+                final JsonObject engineStatusObject = new JsonObject();
+                final AxEngineModel axEngineModel = engineServiceFacade.getEngineStatus(engineKey);
+                engineStatusObject.addProperty("timestamp", axEngineModel.getTimeStampString());
+                engineStatusObject.addProperty("id", engineKey.getID());
+                engineStatusObject.addProperty("status", axEngineModel.getState().toString());
+                engineStatusObject.addProperty("last_message", axEngineModel.getStats().getTimeStampString());
+                engineStatusObject.addProperty("up_time", axEngineModel.getStats().getUpTime() / 1000L);
+                engineStatusObject.addProperty("policy_executions", axEngineModel.getStats().getEventCount());
+                engineStatusObject.addProperty("last_policy_duration",
+                        gson.toJson(
+                                getValuesFromCache(host, engineKey.getID() + "_last_policy_duration",
+                                        axEngineModel.getTimestamp(), axEngineModel.getStats().getLastExecutionTime()),
+                                List.class));
+                engineStatusObject.addProperty("average_policy_duration",
+                        gson.toJson(getValuesFromCache(host, engineKey.getID() + "_average_policy_duration",
+                                axEngineModel.getTimestamp(),
+                                (long) axEngineModel.getStats().getAverageExecutionTime()), List.class));
+                engineStatusList.add(engineStatusObject);
+            } catch (final ApexException e) {
+                LOGGER.warn("Error getting status of engine with ID " + engineKey.getID() + "<br>", e);
+            }
+        }
+        responseObject.add("status", engineStatusList);
+
+        // Engine context data
+        final JsonArray engineContextList = new JsonArray();
+        for (final AxArtifactKey engineKey : engineServiceFacade.getEngineKeyArray()) {
+            try {
+                final String engineInfo = engineServiceFacade.getEngineInfo(engineKey);
+                if (engineInfo != null && !engineInfo.trim().isEmpty()) {
+                    final JsonObject engineContextObject = new JsonObject();
+                    engineContextObject.addProperty("id", engineKey.getID());
+                    engineContextObject.addProperty("engine_info", engineInfo);
+                    engineContextList.add(engineContextObject);
+                }
+            } catch (final ApexException e) {
+                LOGGER.warn("Error getting runtime information of engine with ID " + engineKey.getID() + "<br>", e);
+            }
+        }
+        responseObject.add("context", engineContextList);
+
+        return Response.ok(responseObject.toString(), MediaType.APPLICATION_JSON).build();
+    }
+
+    /**
+     * Start/Stop and Apex engine
+     *
+     * @param hostName the host name of the engine service to connect to.
+     * @param port the port number of the engine service to connect to.
+     * @param engineId the id of the engine to be started/stopped.
+     * @param startStop the parameter to start/stop the engine. Expects either "Start" or "Stop"
+     * @return a Response object of type 200
+     */
+    @GET
+    @Path("startstop/")
+    public Response startStop(@QueryParam("hostName") final String hostName, @QueryParam("port") final int port,
+            @QueryParam("engineId") final String engineId, @QueryParam("startstop") final String startStop) {
+        final EngineServiceFacade engineServiceFacade = new EngineServiceFacade(hostName, port);
+
+        try {
+            engineServiceFacade.init();
+        } catch (final ApexDeploymentException e) {
+            final String errorMessage = "Error connecting to Apex Engine Service at " + hostName + ":" + port;
+            LOGGER.warn(errorMessage + "<br>", e);
+            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage + "\n" + e.getMessage())
+                    .build();
+        }
+
+        try {
+            final Map<String, String[]> parameterMap = new HashMap<String, String[]>();
+            parameterMap.put("hostname", new String[] { hostName });
+            parameterMap.put("port", new String[] { Integer.toString(port) });
+            parameterMap.put("AxArtifactKey#" + engineId, new String[] { startStop });
+            final AxArtifactKey engineKey = ParameterCheck.getEngineKey(parameterMap);
+            if (startStop.equals("Start")) {
+                engineServiceFacade.startEngine(engineKey);
+            } else if (startStop.equals("Stop")) {
+                engineServiceFacade.stopEngine(engineKey);
+            }
+        } catch (final Exception e) {
+            final String errorMessage = "Error calling " + startStop + " on Apex Engine: " + engineId;
+            LOGGER.warn(errorMessage + "<br>", e);
+            final StringWriter sw = new StringWriter();
+            e.printStackTrace(new PrintWriter(sw));
+            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage + "\n" + sw.toString())
+                    .build();
+        }
+
+        return Response.ok("{}").build();
+    }
+
+    /**
+     * Start/Stop and Apex engine
+     *
+     * @param hostName the host name of the engine service to connect to.
+     * @param port the port number of the engine service to connect to.
+     * @param engineId the id of the engine to be started/stopped.
+     * @param startStop the parameter to start/stop the engine. Expects either "Start" or "Stop"
+     * @param period the time between each event in milliseconds
+     * @return a Response object of type 200
+     */
+    @GET
+    @Path("periodiceventstartstop/")
+    public Response periodiceventStartStop(@QueryParam("hostName") final String hostName,
+            @QueryParam("port") final int port, @QueryParam("engineId") final String engineId,
+            @QueryParam("startstop") final String startStop, @QueryParam("period") final long period) {
+        final EngineServiceFacade engineServiceFacade = new EngineServiceFacade(hostName, port);
+        final String host = hostName + ":" + port;
+        try {
+            engineServiceFacade.init();
+            final Map<String, String[]> parameterMap = new HashMap<String, String[]>();
+            parameterMap.put("hostname", new String[] { hostName });
+            parameterMap.put("port", new String[] { Integer.toString(port) });
+            parameterMap.put("AxArtifactKey#" + engineId, new String[] { startStop });
+            parameterMap.put("period", new String[] { Long.toString(period) });
+            final AxArtifactKey engineKey = ParameterCheck.getEngineKey(parameterMap);
+            if (startStop.equals("Start")) {
+                engineServiceFacade.startPerioidicEvents(engineKey, period);
+                setPeriodicEventsState(host, true);
+            } else if (startStop.equals("Stop")) {
+                engineServiceFacade.stopPerioidicEvents(engineKey);
+                setPeriodicEventsState(host, false);
+            }
+        } catch (final ApexDeploymentException e) {
+            final String errorMessage = "Error connecting to Apex Engine Service at " + host;
+            LOGGER.warn(errorMessage + "<br>", e);
+            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(errorMessage + "\n" + e.getMessage())
+                    .build();
+        }
+
+        return Response.ok("{}").build();
+    }
+
+    /**
+     * Check if periodic events are running
+     *
+     * @param host the engine's host url
+     * @return a boolean stating if periodic events are running for a given host
+     */
+    private Boolean getPeriodicEventsState(final String host) {
+        return periodicEventsStateCache.containsKey(host) ? periodicEventsStateCache.get(host) : false;
+    }
+
+    /**
+     * Sets the state of periodic events for a host
+     *
+     * @param host the engine's host url
+     * @param boolean that states if periodic events have been started or stopped
+     */
+    private void setPeriodicEventsState(final String host, final Boolean isRunning) {
+        periodicEventsStateCache.put(host, isRunning);
+    }
+
+    /**
+     * This method takes in the latest data entry for an engine, adds it to an existing data set and returns the full
+     * map for that host and engine
+     *
+     * @param host the engine's host url
+     * @param id the engines id
+     * @param timestamp the timestamp of the latest data entry
+     * @param latestValue the value of the latest data entry
+     * @return a list of {@code Counter} objects for that engine
+     */
+    private List<Counter> getValuesFromCache(final String host, final String id, final long timestamp,
+            final long latestValue) {
+        SlidingWindowList<Counter> valueList;
+
+        if (!cache.containsKey(host)) {
+            cache.put(host, new HashMap<String, List<Counter>>());
+        }
+
+        if (cache.get(host).containsKey(id)) {
+            valueList = (SlidingWindowList<Counter>) cache.get(host).get(id);
+        } else {
+            valueList = new SlidingWindowList<Counter>(maxCachedEntries);
+        }
+        valueList.add(new Counter(timestamp, latestValue));
+
+        cache.get(host).put(id, valueList);
+
+        return valueList;
+    }
+
+    /**
+     * A list of values that uses a FIFO sliding window of a fixed size.
+     */
+    public class SlidingWindowList<V> extends LinkedList<V> {
+        private static final long serialVersionUID = -7187277916025957447L;
+
+        private final int maxEntries;
+
+        public SlidingWindowList(final int maxEntries) {
+            this.maxEntries = maxEntries;
+        }
+
+        @Override
+        public boolean add(final V e) {
+            if (this.size() > (maxEntries - 1)) {
+                this.removeFirst();
+            }
+            return super.add(e);
+        };
+
+    }
+
+    /**
+     * A class used to storing a single data entry for an engine.
+     */
+    public class Counter {
+        private long timestamp;
+        private long value;
+
+        public Counter(final long timestamp, final long value) {
+            this.timestamp = timestamp;
+            this.value = value;
+        }
+
+        public long getTimestamp() {
+            return timestamp;
+        }
+
+        public long getValue() {
+            return value;
+        }
+    }
+}
diff --git a/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ParameterCheck.java b/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ParameterCheck.java
new file mode 100644
index 0000000..8edeb54
--- /dev/null
+++ b/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ParameterCheck.java
@@ -0,0 +1,211 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.apex.client.monitoring.rest;
+
+import java.util.Map;
+
+import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
+import org.slf4j.ext.XLogger;
+import org.slf4j.ext.XLoggerFactory;
+
+/**
+ * The Class ParameterCheck is used to check parameters passed to the servlet.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+public final class ParameterCheck {
+    private static final int MAX_PORT = 65535;
+
+    /**
+     * private constructor to prevent subclassing of this utility class.
+     */
+    private ParameterCheck() {}
+
+    /**
+     * The Enum StartStop is used to hold .
+     *
+     * @author Liam Fallon (liam.fallon@ericsson.com)
+     */
+    public enum StartStop {
+        /** Start of an Apex engine has been ordered. */
+        START,
+        /** Stop of an Apex engine has been ordered. */
+        STOP
+    };
+
+    private static final XLogger LOGGER = XLoggerFactory.getXLogger(ParameterCheck.class);
+
+    private static final String HOSTNAME_PAR = "hostname";
+    private static final String PORT_PAR = "port";
+    private static final String AXARTIFACTKEY_PAR = "AxArtifactKey";
+
+    /**
+     * Gets the host name.
+     *
+     * @param parameterMap the parameter map
+     * @return the host name
+     */
+    public static String getHostName(final Map<String, String[]> parameterMap) {
+        if (!parameterMap.containsKey(HOSTNAME_PAR)) {
+            LOGGER.warn("parameter \"" + HOSTNAME_PAR + "\" not found");
+            return null;
+        }
+
+        final String[] hostNameValue = parameterMap.get(HOSTNAME_PAR);
+
+        if (hostNameValue.length == 0 || hostNameValue[0].trim().length() == 0) {
+            LOGGER.warn("value of parameter \"" + HOSTNAME_PAR + "\" not found");
+            return null;
+        }
+
+        return hostNameValue[0];
+    }
+
+    /**
+     * Gets the port.
+     *
+     * @param parameterMap the parameter map
+     * @return the port
+     */
+    public static int getPort(final Map<String, String[]> parameterMap) {
+        if (!parameterMap.containsKey(PORT_PAR)) {
+            LOGGER.warn("parameter \"" + PORT_PAR + "\" not found");
+            return -1;
+        }
+
+        final String[] portValue = parameterMap.get(PORT_PAR);
+
+        if (portValue.length == 0 || portValue[0].trim().length() == 0) {
+            LOGGER.warn("value of parameter \"" + PORT_PAR + "\" not found");
+            return -1;
+        }
+
+        int port = -1;
+        try {
+            port = Integer.parseInt(portValue[0]);
+        } catch (final Exception e) {
+            LOGGER.warn("value \"" + portValue[0] + "\"of parameter \"" + PORT_PAR + "\" not a valid integer", e);
+            return -1;
+        }
+
+        if (port <= 0 || port > MAX_PORT) {
+            LOGGER.warn("value \"" + portValue[0] + "\"of parameter \"" + PORT_PAR
+                    + "\" not a valid port between 0 and 65535");
+            return -1;
+        }
+
+        return port;
+    }
+
+    /**
+     * Gets the engine key.
+     *
+     * @param parameterMap the parameter map
+     * @return the engine key
+     */
+    public static AxArtifactKey getEngineKey(final Map<String, String[]> parameterMap) {
+        String artifactKeyParameter = null;
+        for (final String parameter : parameterMap.keySet()) {
+            // Check for an AxArtifactKey parameter
+            if (parameter.startsWith(AXARTIFACTKEY_PAR)) {
+                artifactKeyParameter = parameter;
+                break;
+            }
+        }
+        if (artifactKeyParameter == null) {
+            LOGGER.warn("parameter \"" + AXARTIFACTKEY_PAR + "\" not found");
+            return null;
+        }
+
+        final String[] axArtifactKeyArray = artifactKeyParameter.split("#");
+
+        if (axArtifactKeyArray.length != 2) {
+            LOGGER.warn("value \"" + artifactKeyParameter + "\" of parameter \"" + AXARTIFACTKEY_PAR + "\" not valid");
+            return null;
+        }
+
+        return new AxArtifactKey(axArtifactKeyArray[1]);
+    }
+
+    /**
+     * Gets the start stop.
+     *
+     * @param parameterMap the parameter map
+     * @param engineKey the engine key
+     * @return the start stop
+     */
+    public static ParameterCheck.StartStop getStartStop(final Map<String, String[]> parameterMap,
+            final AxArtifactKey engineKey) {
+        final String startStopPar = AXARTIFACTKEY_PAR + '#' + engineKey.getID();
+        if (!parameterMap.containsKey(startStopPar)) {
+            LOGGER.warn("parameter \"" + startStopPar + "\" not found");
+            return null;
+        }
+
+        final String[] startStopValue = parameterMap.get(startStopPar);
+
+        if (startStopValue.length == 0 || startStopValue[0].trim().length() == 0) {
+            LOGGER.warn("value of parameter \"" + startStopPar + "\" not found");
+            return null;
+        }
+
+        ParameterCheck.StartStop startStop;
+        if (startStopValue[0].equalsIgnoreCase("start")) {
+            startStop = ParameterCheck.StartStop.START;
+        } else if (startStopValue[0].equalsIgnoreCase("stop")) {
+            startStop = ParameterCheck.StartStop.STOP;
+        } else {
+            LOGGER.warn("value \"" + startStopValue[0] + "\"of parameter \"" + startStopPar
+                    + "\" not \"start\" or \"stop\"");
+            return null;
+        }
+
+        return startStop;
+    }
+
+    /**
+     * Find and return a long value with the given name.
+     *
+     * @param parameterMap The parameter map containing the value
+     * @param longName The name of the long parameter
+     * @return The long value
+     */
+    public static long getLong(final Map<String, String[]> parameterMap, final String longName) {
+        if (!parameterMap.containsKey(longName)) {
+            LOGGER.warn("parameter \"" + longName + "\" not found");
+            return -1;
+        }
+
+        final String[] longValue = parameterMap.get(longName);
+
+        if (longValue.length == 0 || longValue[0].trim().length() == 0) {
+            LOGGER.warn("value of parameter \"" + longName + "\" not found");
+            return -1;
+        }
+
+        try {
+            return Long.parseLong(longValue[0]);
+        } catch (final Exception e) {
+            LOGGER.warn("value \"" + longValue[0] + "\"of parameter \"" + longName + "\" not a valid long", e);
+            return -1;
+        }
+    }
+}
diff --git a/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/package-info.java b/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/package-info.java
new file mode 100644
index 0000000..d6c8d3c
--- /dev/null
+++ b/client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/package-info.java
@@ -0,0 +1,27 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/**
+ * Implements the RESTful monitoring client.
+ *
+ * @author Liam Fallon (liam.fallon@ericsson.com)
+ */
+
+package org.onap.policy.apex.client.monitoring.rest;
diff --git a/client/client-monitoring/src/main/resources/webapp/WEB-INF/web.xml b/client/client-monitoring/src/main/resources/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..5906c2c
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/WEB-INF/web.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2016-2018 Ericsson. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
+    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
+    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+    id="WebApp_ID" version="3.0">
+
+    <servlet>
+        <servlet-name>apex-services.rest</servlet-name>
+        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
+        <init-param>
+            <param-name>jersey.config.server.provider.packages</param-name>
+            <param-value>org.onap.policy.apex.client.monitoring.rest</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>apex-services.rest</servlet-name>
+        <url-pattern>/apexservices/*</url-pattern>
+    </servlet-mapping>
+
+</web-app>
\ No newline at end of file
diff --git a/client/client-monitoring/src/main/resources/webapp/css/apexChartLib.css b/client/client-monitoring/src/main/resources/webapp/css/apexChartLib.css
new file mode 100644
index 0000000..628fc0e
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/css/apexChartLib.css
@@ -0,0 +1,74 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+path { //
+	stroke: #5fbadd;
+	stroke-width: 2;
+	fill: none;
+}
+
+.axis path, .axis line {
+	fill: none;
+	stroke: grey;
+	stroke-width: 1;
+	shape-rendering: crispEdges;
+}
+
+.tooltip {
+	position: absolute;
+	text-align: center;
+	width: 90px;
+	height: 42px;
+	padding: 2px;
+	font: 12px sans-serif;
+	background: white;
+	border: 2px solid grey;
+	border-radius: 8px;
+	pointer-events: none;
+}
+
+.apexChart {
+	display: inline-block;
+	position: relative;
+	width: 45%;
+	padding-bottom: 21%;
+	vertical-align: top;
+	overflow: hidden;
+}
+
+.apexChart:nth-child(even) {
+	margin-left: 50px;
+}
+
+.svg-content-responsive {
+	display: inline-block;
+	position: absolute;
+	top: 10px;
+	left: 0;
+}
+
+.apexChart_inline {
+	display: inline-block;
+	position: relative;
+	width: 45%;
+	padding-bottom: 21%;
+	vertical-align: top;
+	overflow: hidden;
+	margin-left: -25px;
+}
\ No newline at end of file
diff --git a/client/client-monitoring/src/main/resources/webapp/css/interfaceAssets.css b/client/client-monitoring/src/main/resources/webapp/css/interfaceAssets.css
new file mode 100644
index 0000000..acb8fe2
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/css/interfaceAssets.css
@@ -0,0 +1,3454 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+@charset "utf-8";
+
+html {
+	position: relative;
+	font-family: Arial, Helvetica, sans-serif;
+	font-size: 10px !important;
+	line-height: 10px !important;
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	height: 100%;
+}
+
+body {
+	font-size: 1.6rem;
+	line-height: 1.2rem;
+	color: #333333;
+	background-color: #ffffff;
+	margin: 0;
+	padding: 0;
+}
+
+*:focus, .ebInput:focus, .ebIcon:focus, .ebCheckbox:focus+.ebCheckbox-inputStatus:after,
+	.ebRadioBtn:focus+.ebRadioBtn-inputStatus:after, textarea:focus, button:focus,
+	i:focus {
+	/**
+     * FF outline do not looks same as Chrome so adding box shadow
+     * FF outline is not working as expected
+     **/
+	/*
+     * one way of outline
+    outline: #4d90fe auto 5px;
+    box-shadow: 0 0 0 1px #4d90fe;
+    -webkit-box-shadow: none;
+    */
+	outline: none; //
+	box-shadow: 0 0 2px 1px #FFFFFF;
+}
+
+h1, h2, h3, h4, h5, h6 {
+	color: #4d4d4d;
+	font-weight: bold;
+}
+
+h1 {
+	line-height: 3.2rem;
+	font-size: 3.2rem;
+	font-weight: normal;
+	padding: 0.6rem 0;
+	margin: 0 0 0.6rem 0;
+}
+
+h2 {
+	border-bottom: #000000 solid 1px;
+	line-height: 2.0rem;
+	font-size: 2.0rem;
+	font-weight: normal;
+	padding: 1.2rem 0 0.7rem 0;
+	margin: 0 0 0.4rem 0;
+}
+
+h3 {
+	border-bottom: #7f7f7f solid 1px;
+	line-height: 1.6rem;
+	font-size: 1.6rem;
+	padding: 1.2rem 0 0.7rem 0;
+	margin: 0 0 0.4rem 0;
+	font-weight: normal;
+	color: #333333;
+}
+
+h4 {
+	border-bottom: #b2b2b2 solid 1px;
+	line-height: 1.2rem;
+	font-size: 1.2rem;
+	padding: 0.6rem 0;
+	margin: 0 0 0.6rem 0;
+	font-weight: bold;
+	color: #333333;
+}
+
+.ebLayout-SectionSubheading h3 {
+	float: left;
+	margin: 0;
+	border-bottom: none;
+}
+
+/* System Bar */
+.ebSystemBar {
+	position: relative;
+	width: 100%;
+	height: 40px;
+	border-top: 4px solid #0066b3;
+	background-image: linear-gradient(180deg, #ffffff 0%, #f4f4f4 100%);
+	box-shadow: 0 1px 2px #D2D2D2;
+}
+
+.ebSystemBar::before {
+	position: absolute;
+	top: -4px;
+	left: 0;
+	width: 100%;
+	height: 4px;
+	content: "";
+	font-size: 0;
+	background: #0066b3;
+	background: -o-linear-gradient(left, #a2c517 10%, #009046 30%, #0082b6 50%, #151f77
+		75%, #db0050 100%);
+	background: -moz-linear-gradient(left, #a2c517 10%, #009046 30%, #0082b6 50%,
+		#151f77 75%, #db0050 100%);
+	background: -webkit-linear-gradient(left, #a2c517 10%, #009046 30%, #0082b6 50%,
+		#151f77 75%, #db0050 100%);
+	background: -ms-linear-gradient(left, #a2c517 10%, #009046 30%, #0082b6 50%, #151f77
+		75%, #db0050 100%);
+	background: -webkit-gradient(linear, left top, right top, color-stop(0.1, #a2c517),
+		color-stop(0.3, #009046), color-stop(0.5, #0082b6),
+		color-stop(0.75, #151f77), color-stop(1, #db0050));
+	background: linear-gradient(left, #a2c517 10%, #009046 30%, #0082b6 50%, #151f77 75%
+		, #db0050 100%);
+}
+
+.ebSystemBar-logo {
+	position: absolute;
+	top: 0;
+	bottom: 0;
+	left: 0;
+	height: 40px;
+	width: 20px;
+	padding: 0 10px;
+	background: url('../resources/systemBar/econ01.svg') no-repeat center
+		center transparent;
+	background-size: 20px;
+}
+
+.ebSystemBar-topMenuName {
+	display: inline-block;
+	padding: 0 5px 0 40px;
+	margin: 0;
+	line-height: 40px;
+	font-size: 16.8px;
+	color: #58585A;
+}
+
+.ebSystemBar-topMenu {
+	position: absolute;
+	top: 0;
+	bottom: 0;
+	left: 50px;
+	list-style: none;
+	height: 40px;
+	margin: 0;
+	padding: 0;
+}
+
+.ebSystemBar-topMenu li {
+	display: inline-block;
+}
+
+.ebSystemBar-topMenu a {
+	padding: 0 5px 0 15px;
+	margin: 0;
+	font-size: 1.6em;
+	line-height: 40px;
+	color: #58585a;
+	cursor: pointer;
+	text-decoration: none;
+}
+
+.ebSystemBar-topMenu a:hover {
+	color: #0066B3;
+}
+
+.ebSystemBar-rightButton {
+	float: right;
+	display: inline-block;
+	line-height: 40px;
+	vertical-align: middle;
+}
+
+.ebSystemBar-rightButton a {
+	display: block;
+	padding: 0 18px 0 18px;
+	font-size: 1.3rem;
+	color: #0066B3;
+	background-color: transparent;
+	background-repeat: no-repeat;
+	background-position: 18px center;
+	border-left: solid 1px #D2D2D2;
+}
+
+.ebSystemBar-rightButton a:hover {
+	text-decoration: underline;
+}
+
+.ebSystemBar-rightButton:hover {
+	background-image: linear-gradient(180deg, #f2f2f2 0%, #e8e8e8 100%);
+}
+
+@media screen and (max-width: 640px) {
+	.ebSystemBar-topBar-rightButton a {
+		width: 0;
+		padding-left: 34px;
+		text-indent: -9999px;
+	}
+}
+
+/* Inline Message */
+.ebInlineMessage {
+	padding: 5px 15px 0px 7px;
+	font-size: 0;
+	position: fixed;
+	bottom: 0;
+	left: 2;
+	width: calc(100% - 30px);
+	height: 66px;
+	border: 3px solid #adadad;
+	background-color: #FFFFFF;
+}
+
+.ebInlineMessage-iconHolder, .ebInlineMessage-contentHolder {
+	display: inline-block;
+	vertical-align: top;
+}
+
+.ebInlineMessage-iconHolder {
+	width: 20px;
+	margin: 0 12px 0 0;
+}
+
+.ebInlineMessage-contentHolder {
+	width: calc(100% - 32px);
+	font-size: 1.2rem;
+}
+
+.ebInlineMessage-header {
+	margin-top: 3px;
+	font-size: 14px;
+	line-height: 14px;
+}
+
+.ebInlineMessage-separator {
+	height: 1px;
+	margin: 12px 0;
+	background-color: #adadad;
+	opacity: 0.3;
+}
+
+.ebInlineMessage-description {
+	color: #666666;
+	white-space: pre;
+}
+
+/* Table */
+.ebTable {
+	margin: 0;
+	padding: 0;
+	table-layout: fixed;
+	border-left: 1px solid #cccccc; //
+	ewatkmi: added for visible border;
+	border-right: 1px solid #cccccc; //
+	ewatkmi: added for visible border;
+	border-bottom: 1px solid #cccccc; //
+	ewatkmi: added for visible border;
+	border-collapse: collapse;
+	border-spacing: 0;
+	color: #1a1a1a;
+}
+
+.ebTable_fullW {
+	width: 100%;
+}
+
+.ebTable-th_resizable, .ebTable-th_sortable {
+	position: relative;
+}
+
+.ebTable-th_resizable .ebTable-headerResize {
+	position: absolute;
+	top: -20px;
+	bottom: -20px;
+	right: -12px;
+	width: 10px;
+	cursor: col-resize;
+	-khtml-user-select: none;
+	-moz-user-select: none;
+	-o-user-select: none;
+	-webkit-user-select: none;
+	user-select: none;
+}
+
+.ebTable-th_sortable {
+	cursor: pointer !important;
+}
+
+.ebTable-th_sortable .ebTable-header {
+	display: flex;
+	flex-wrap: nowrap;
+	flex-direction: row;
+	align-items: center;
+}
+
+.ebTable-th_sortable .ebTable-headerText {
+	flex-shrink: 1;
+	flex-grow: 0;
+	margin-right: 8px;
+	box-sizing: border-box;
+	-khtml-user-select: none;
+	-moz-user-select: none;
+	-o-user-select: none;
+	-webkit-user-select: none;
+	user-select: none;
+}
+
+.ebTable-th_sortable .ebTable-headerSort {
+	flex-grow: 0;
+	flex-shrink: 0;
+	flex-basis: 10px;
+	margin-left: 4px;
+}
+
+.ebTable-th_sortable .ebTable-headerSortOrder {
+	flex-grow: 1;
+	color: #999999;
+	font-weight: normal;
+}
+
+.ebTable-header {
+	position: relative;
+	display: block;
+	width: 100%;
+	-moz-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+.ebTable-headerText {
+	padding: 4px 0;
+	display: inline-block;
+	vertical-align: middle;
+	width: 100%;
+	overflow: hidden;
+	white-space: nowrap;
+	text-overflow: ellipsis;
+}
+
+.ebTable thead tr {
+	height: 3.2rem;
+	font-size: 1.2rem;
+	font-weight: bold;
+	text-align: left;
+}
+
+.ebTable thead tr th {
+	padding-left: 1.2rem;
+	padding-right: 1.2rem;
+	text-align: left;
+	cursor: default;
+	border-top: #cccccc solid 1px;
+	border-bottom: #cccccc solid 1px;
+	border-right: #e6e6e6 solid 1px;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+}
+
+.ebTable thead tr th:last-child {
+	border-right: none;
+}
+
+.ebTable thead tr:hover {
+	background: none;
+}
+
+.ebTable thead tr:active {
+	background: none;
+}
+
+.ebTable tbody tr {
+	height: 3.2rem;
+	font-size: 1.2rem;
+	border-bottom: #e6e6e6 solid 1px;
+}
+
+.ebTable tbody tr td {
+	margin: 0;
+	padding: 0 1.2rem;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+	cursor: default;
+	border-right: #e6e6e6 solid 1px;
+}
+
+.ebTable tbody tr td:last-child {
+	border-right: none;
+}
+
+.ebTable_striped tbody tr {
+	border-bottom: none;
+}
+
+.ebTable_striped tbody tr td {
+	border-right: none;
+}
+
+.ebTable_striped tbody tr:nth-of-type(even) {
+	background-color: #f2f2f2;
+}
+
+.ebTable_striped tbody tr:nth-of-type(odd) { //
+	ewatkmi: added for nested tables;
+	background-color: #ffffff;
+}
+
+.ebTable_compact tbody tr {
+	height: 2.6rem;
+}
+
+.ebTable_expandableStriped {
+	border-collapse: separate;
+}
+
+.ebTable_expandableStriped tbody tr {
+	border-bottom: none;
+}
+
+.ebTable_expandableStriped tbody tr td {
+	border-right: none;
+}
+
+.ebTable_expandableStriped tbody tr:nth-of-type(4n-1),
+	.ebTable_expandableStriped tbody tr:nth-of-type(4n) {
+	background-color: #f2f2f2;
+}
+
+.ebTable_pinstripe tr td {
+	border-bottom: #e6e6e6 solid 1px;
+}
+
+.ebTable_color_paleBlue.ebTable thead tr th {
+	background-color: #99ddee;
+	border-top: none;
+	border-bottom: none;
+}
+
+.ebTable_color_paleBlue.ebTable_striped tbody tr:nth-of-type(even) {
+	background-color: #e6f6fb;
+}
+
+.ebTable_color_purple.ebTable thead tr th {
+	background-color: #ca9bc1;
+	border-top: none;
+	border-bottom: none;
+}
+
+.ebTable_color_purple.ebTable_striped tbody tr:nth-of-type(even) {
+	background-color: #f2e6ef;
+}
+
+.ebTable_color_darkGreen.ebTable thead tr th {
+	background-color: #99c0bf;
+	border-top: none;
+	border-bottom: none;
+}
+
+.ebTable_color_darkGreen.ebTable_striped tbody tr:nth-of-type(even) {
+	background-color: #e6efef;
+}
+
+.ebTable_color_green.ebTable thead tr th {
+	background-color: #d0e3a2;
+	border-top: none;
+	border-bottom: none;
+}
+
+.ebTable_color_green.ebTable_striped tbody tr:nth-of-type(even) {
+	background-color: #f3f8e8;
+}
+
+.ebTable_color_yellow.ebTable thead tr th {
+	background-color: #fde499;
+	border-top: none;
+	border-bottom: none;
+}
+
+.ebTable_color_yellow.ebTable_striped tbody tr:nth-of-type(even) {
+	background-color: #fff8e6;
+}
+
+.ebTable_color_orange.ebTable thead tr th {
+	background-color: #f9d099;
+	border-top: none;
+	border-bottom: none;
+}
+
+.ebTable_color_orange.ebTable_striped tbody tr:nth-of-type(even) {
+	background-color: #fef3e6;
+}
+
+.ebTable_color_red.ebTable thead tr th {
+	background-color: #f4a6a3;
+	border-top: none;
+	border-bottom: none;
+}
+
+.ebTable_color_red.ebTable_striped tbody tr:nth-of-type(even) {
+	background-color: #fce9e8;
+}
+
+.ebTable_borderTop_none thead tr th {
+	border-top: none;
+}
+
+.ebTable_verticalBorders_none thead tr th, .ebTable_verticalBorders_none tr td
+	{
+	border-right: none !important;
+	border-left: none !important;
+}
+
+.ebTable_wrapHeaders th {
+	white-space: normal !important;
+	text-overflow: inherit !important;
+}
+
+.ebTable_wrapHeaders th .ebTable-headerText {
+	white-space: normal !important;
+	text-overflow: inherit !important;
+}
+
+.ebTable-expandableRow {
+	height: inherit !important;
+	display: none;
+}
+
+.ebTable-expandableRow_expanded {
+	display: table-row;
+}
+
+.ebTable-expandableRow>td {
+	padding: 0 !important;
+}
+
+.ebTable-expandableRow>td>div {
+	overflow: hidden;
+	height: 0;
+	transition: height 0.3s ease-in-out;
+}
+/**
+ * Hover/Active/Selected Effects
+ *
+ * Modifiers:
+ *    .ebTable_hoverActive_none (disables native hover and active selectors, primarily for pin columns plugin)
+ */
+.ebTable {
+	/** Hover effect **/
+	
+}
+
+.ebTable.ebTable:not (.ebTable_hoverActive_none ) tbody tr:not (.ebTable-expandableRow
+	):not (.headerRow ):hover>*, .ebTable tbody tr:not (.ebTable-expandableRow
+	):not (.headerRow ).ebTableRow_hover>* {
+	background-image: linear-gradient(0deg, rgba(0, 102, 179, 0.1),
+		rgba(0, 102, 179, 0.1));
+}
+
+.ebTable.ebTable_highlightedEffect_solid tbody tr:not (.ebTable-expandableRow
+	).ebTableRow_highlighted>* {
+	background-color: #ffffff !important;
+}
+
+/* Context Menu */
+.ebContextMenu {
+	position: relative;
+	width: 16px;
+	height: 16px;
+}
+
+.ebContextMenu:focus {
+	outline: none;
+}
+
+.ebContextMenu-ExpandBtn, .ebContextMenu-expandBtn {
+	width: 16px;
+	height: 16px;
+	position: relative;
+	-khtml-user-select: none;
+	-moz-user-select: none;
+	-o-user-select: none;
+	-webkit-user-select: none;
+	user-select: none;
+}
+
+.ebContextMenu-ExpandBtn:focus, .ebContextMenu-expandBtn:focus {
+	outline: none;
+}
+
+.ebContextMenu-Dropdown, .ebContextMenu-body {
+	position: absolute;
+	z-index: 1500;
+	min-width: 60px;
+	width: auto;
+	height: auto;
+	white-space: nowrap;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	-khtml-user-select: none;
+	-moz-user-select: none;
+	-o-user-select: none;
+	-webkit-user-select: none;
+	user-select: none;
+	box-shadow: 5px 5px 5px #87888A;
+}
+
+.ebContextMenu-Dropdown_corner_default,
+	.ebContextMenu-body_corner_default {
+	position: absolute;
+	top: 20px;
+	left: 0px;
+}
+
+.ebContextMenu-Dropdown_corner_topRight,
+	.ebContextMenu-body_corner_topRight {
+	position: absolute;
+	top: 20px;
+	right: 0px;
+}
+
+.ebContextMenu-Dropdown_corner_bottomLeft,
+	.ebContextMenu-body_corner_bottomLeft {
+	position: absolute;
+	bottom: 20px;
+	left: 0px;
+}
+
+.ebContextMenu-Dropdown_corner_bottomRight,
+	.ebContextMenu-body_corner_bottomRight {
+	position: absolute;
+	bottom: 20px;
+	right: 0px;
+}
+
+.ebContextMenu-Dropdown_visible_false, .ebContextMenu-body_visible_false
+	{
+	visibility: hidden;
+}
+
+.ebContextMenu-Dropdown_visible_true, .ebContextMenu-body_visible_true {
+	display: block;
+}
+
+/* Component List */
+.ebComponentList {
+	position: relative;
+	z-index: 1500;
+	padding: 4px 0;
+	margin: 0;
+	color: #333333;
+	list-style: none;
+	background-color: #ffffff;
+	border: #bfbfbf solid 1px;
+	box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.2);
+	border-radius: 3px;
+	-moz-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+.ebComponentList-group, .ebComponentList-item {
+	padding: 0 0.8rem;
+	line-height: 2.4rem;
+	font-size: 1.2rem;
+	background-color: #ffffff;
+}
+
+.ebComponentList-iconHolder {
+	display: inline-block;
+	vertical-align: middle;
+	width: 16px;
+	padding-right: 8px;
+}
+
+.ebComponentList-item {
+	cursor: pointer;
+}
+
+.ebComponentList-item-name {
+	display: inline-block;
+	font-size: 12px;
+	text-overflow: ellipsis;
+	overflow: hidden;
+	width: calc(100% - 24px);
+	vertical-align: middle;
+}
+
+.ebComponentList-item_icon {
+	font-size: 0;
+}
+
+.ebComponentList-link, .ebComponentList-item, .ebComponentList-item>*,
+	.ebComponentList-group-header {
+	white-space: nowrap;
+	text-overflow: ellipsis;
+	overflow: hidden;
+}
+
+.ebComponentList-group {
+	display: block;
+}
+
+.ebComponentList-group_expandable_collapsed>.ebComponentList-group-header,
+	.ebComponentList-group_expandable_expanded>.ebComponentList-group-header
+	{
+	font-size: 0;
+	cursor: pointer;
+	white-space: nowrap;
+	height: 24px;
+	vertical-align: middle;
+}
+
+.ebComponentList-group_expandable_collapsed>.ebComponentList-group-header .ebComponentList-iconHolder+.ebComponentList-group-name,
+	.ebComponentList-group_expandable_expanded>.ebComponentList-group-header .ebComponentList-iconHolder+.ebComponentList-group-name
+	{
+	width: calc(100% - 40px);
+}
+
+.ebComponentList-group_expandable_collapsed>.ebComponentList-inner,
+	.ebComponentList-group_expandable_expanded>.ebComponentList-inner {
+	padding: 0 0 0 24px;
+	margin: 0 -0.8rem;
+}
+
+.ebComponentList-group_expandable_collapsed>.ebComponentList-group-header
+	{
+	border: none;
+}
+
+.ebComponentList-group_expandable_collapsed>.ebComponentList-inner .ebComponentList-item
+	{
+	overflow: hidden;
+	padding: 0;
+	margin: 0;
+	height: 0;
+	opacity: 0;
+	transition: height 0.2s linear, padding 0.075s 0.075s linear, margin
+		0.075s 0.075s linear, opacity 0.075s linear;
+}
+
+.ebComponentList-group_expandable_collapsed>.ebComponentList-inner .ebComponentList-group_expandable_collapsed .ebComponentList-group-header,
+	.ebComponentList-group_expandable_collapsed>.ebComponentList-inner .ebComponentList-group_expandable_expanded .ebComponentList-group-header
+	{
+	overflow: hidden;
+	padding: 0;
+	margin: 0;
+	height: 0;
+	opacity: 0;
+	transition: height 0.2s linear, padding 0.075s 0.075s linear, margin
+		0.075s 0.075s linear, opacity 0.075s linear;
+}
+
+.ebComponentList-group_expandable_collapsed>.ebComponentList-inner .ebComponentList-group>.ebComponentList-inner
+	{
+	padding: 0;
+	margin: 0;
+	transition: padding 0.1s 0.1s linear, margin 0.1s 0.1s linear;
+}
+
+.ebComponentList-group_expandable_expanded>.ebComponentList-group-header
+	{
+	border-bottom: 1px solid #999;
+}
+
+.ebComponentList-group_expandable_expanded>.ebComponentList-inner>.ebComponentList-item
+	{
+	overflow: hidden;
+	height: 24px;
+	transition: height 0.2s linear, padding 0.075s linear, margin 0.075s
+		linear, opacity 0.15s 0.15s linear;
+}
+
+.ebComponentList-group_expandable_expanded>.ebComponentList-inner>.ebComponentList-group_expandable_expanded>.ebComponentList-group-header,
+	.ebComponentList-group_expandable_expanded>.ebComponentList-inner>.ebComponentList-group_expandable_collapsed>.ebComponentList-group-header
+	{
+	overflow: hidden;
+	height: 24px;
+	text-overflow: ellipsis;
+	transition: height 0.2s linear, padding 0.075s linear, margin 0.075s
+		linear, opacity 0.15s 0.15s linear;
+}
+
+.ebComponentList-group:not (.ebComponentList-group_expandable_collapsed
+	):not (.ebComponentList-group_expandable_expanded ) >.ebComponentList-group-header
+	{
+	cursor: default !important;
+	pointer-events: none !important;
+	-ms-touch-action: none !important;
+	touch-action: none !important;
+	-khtml-user-select: none !important;
+	-moz-user-select: none !important;
+	-o-user-select: none !important;
+	-webkit-user-select: none !important;
+	user-select: none;
+}
+
+.ebComponentList-group-header {
+	font-size: 1.2rem;
+	font-weight: bold;
+	line-height: 2.4rem;
+	border-bottom: 1px solid #999;
+	background-color: #ffffff;
+}
+
+.ebComponentList-group-header_icon {
+	font-size: 0;
+}
+
+.ebComponentList-group-header_icon>.ebComponentList-group-name {
+	width: calc(100% - 24px);
+}
+
+.ebComponentList-group-name {
+	display: inline-block;
+	width: calc(100% - 16px);
+	font-size: 1.2rem;
+	line-height: 2.4rem;
+	font-weight: bold;
+	text-overflow: ellipsis;
+	overflow: hidden;
+	white-space: nowrap;
+	vertical-align: middle;
+}
+
+.ebComponentList-inner {
+	margin: 0 -0.8rem;
+	padding: 4px 0 0 0;
+}
+
+.ebComponentList-link {
+	display: block;
+}
+
+.ebComponentList-link:hover {
+	text-decoration: none;
+}
+
+.ebComponentList-separator {
+	height: 1px;
+	margin: 0.4rem;
+	background-color: #E6E6E6;
+}
+
+.ebComponentList_focus_forced .ebComponentList-item:hover {
+	background-color: transparent;
+}
+
+.ebComponentList_focus_forced .ebComponentList-item_focused:hover {
+	background-color: #e6f0f7;
+}
+
+.ebComponentList:not (.ebComponentList_focus_forced ) .ebComponentList-item:hover
+	{
+	background-color: #e6f0f7;
+}
+
+.ebComponentList_focus_forced .ebComponentList-item:active,
+	.ebComponentList:not (.ebComponentList_focus_forced ) .ebComponentList-item:active
+	{
+	background-color: #cce0f0;
+}
+
+.ebComponentList-item {
+	/* Fixes MultiSelectBox ellipsis bug in Firefox */
+	margin: 0px !important;
+	font-size: 1em !important;
+}
+
+.ebComponentList-item_focused {
+	background-color: #e6f0f7;
+}
+
+.ebComponentList-item_disabled {
+	color: #b0b0af;
+	cursor: not-allowed !important;
+}
+
+.ebComponentList-item_disabled:hover, .ebComponentList-item_disabled:active
+	{
+	background-color: inherit !important;
+}
+
+.ebComponentList-item_selected {
+	position: relative;
+	cursor: default;
+}
+
+.ebComponentList-item_selected>.ebComponentList-link {
+	cursor: default;
+	color: #333333;
+	cursor: default !important;
+	pointer-events: none !important;
+	-ms-touch-action: none !important;
+	touch-action: none !important;
+	-khtml-user-select: none !important;
+	-moz-user-select: none !important;
+	-o-user-select: none !important;
+	-webkit-user-select: none !important;
+	user-select: none;
+}
+
+.ebComponentList-item_selected:before {
+	position: absolute;
+	content: "";
+	left: 0;
+	top: 0;
+	bottom: 0;
+	width: 100%;
+	opacity: .2;
+	background-color: #0967b2;
+}
+
+.ebComponentList-item>.ebComponentList-checkboxHolder>.ebCheckbox {
+	margin-left: 1px;
+}
+
+.ebComponentList-item>.ebComponentList-checkboxHolder>.ebCheckbox-label
+	{
+	padding-left: 3px;
+	overflow: hidden;
+	font-size: 12px;
+	line-height: 2.4rem;
+	text-overflow: ellipsis;
+	width: calc(100% - 24px);
+}
+
+.ebComponentList-info {
+	color: #333333;
+	font-style: italic;
+	text-align: center;
+}
+
+.ebComponentList-info:hover {
+	background-color: #ffffff;
+}
+
+.ebComponentList-info:active {
+	background-color: #ffffff;
+}
+
+.ebComponentList-info, .ebComponentList-loader {
+	display: none;
+	margin: 0.6rem;
+	cursor: default;
+}
+
+.ebComponentList_info .ebComponentList-group, .ebComponentList_info .ebComponentList-separator,
+	.ebComponentList_info .ebComponentList-item {
+	display: none;
+}
+
+.ebComponentList_info .ebComponentList-info {
+	display: block;
+}
+
+.ebComponentList_loading {
+	min-height: 34px;
+}
+
+.ebComponentList_loading .ebComponentList-loader {
+	display: block;
+}
+
+.ebComponentList_loading .ebComponentList-item_selected:before {
+	display: none;
+}
+
+.ebComponentList_loading>.ebComponentList-group,
+	.ebComponentList_loading>.ebComponentList-item,
+	.ebComponentList_loading>.ebComponentList-items>.ebComponentList-group,
+	.ebComponentList_loading>.ebComponentList-items>.ebComponentList-item {
+	opacity: 0.4;
+}
+
+/* Scrollbar */
+.eb_scrollbar {
+	-webkit-overflow-scrolling: touch;
+	overflow: auto;
+}
+
+.eb_scrollbar::-webkit-scrollbar {
+	width: 14px;
+	height: 14px;
+}
+
+.eb_scrollbar::-webkit-scrollbar-track {
+	background-color: #f0f0f0;
+	background-clip: content-box;
+}
+
+.eb_scrollbar::-webkit-scrollbar-thumb {
+	background-color: #cccccc;
+	border-radius: 3px;
+	transition: all 0.2s linear;
+	background-clip: content-box;
+}
+
+.eb_scrollbar::-webkit-scrollbar-thumb:hover {
+	background-color: #999999;
+}
+
+.eb_scrollbar::-webkit-scrollbar-button {
+	width: 14px;
+	height: 14px;
+	background-repeat: no-repeat;
+	background-color: #f0f0f0;
+	background-position: center;
+}
+
+.eb_scrollbar::-webkit-scrollbar-button:hover {
+	background-color: #cccccc;
+}
+
+.eb_scrollbar::-webkit-scrollbar-button:vertical:decrement {
+	background-position: center 4px;
+	background-image:
+		url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='8px' height='5px' viewBox='0 0 8 5' enable-background='new 0 0 8 5' xml:space='preserve'><path fill='#333333' d='M0.293,3.293l3-3C3.488,0.098,3.744,0,4,0s0.512,0.098,0.707,0.293l3,3c0.391,0.391,0.391,1.023,0,1.414 s-1.023,0.391-1.414,0L4,2.414L1.707,4.707c-0.391,0.391-1.023,0.391-1.414,0S-0.098,3.684,0.293,3.293z'/></svg>");
+	border-top-left-radius: 2px;
+	border-top-right-radius: 2px;
+}
+
+.eb_scrollbar::-webkit-scrollbar-button:vertical:increment {
+	background-image:
+		url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='8px' height='5px' viewBox='0 0 8 5' enable-background='new 0 0 8 5' xml:space='preserve'><path fill='#333333' d='M7.707,1.707l-3,3C4.512,4.902,4.255,5,4,5S3.488,4.902,3.292,4.707l-3-3c-0.391-0.391-0.391-1.023,0-1.414 s1.023-0.391,1.414,0L4,2.586l2.293-2.293c0.391-0.391,1.023-0.391,1.414,0S8.098,1.316,7.707,1.707z'/></svg>");
+	border-bottom-left-radius: 2px;
+	border-bottom-right-radius: 2px;
+}
+
+.eb_scrollbar::-webkit-scrollbar-button:horizontal:decrement {
+	background-position: 4px center;
+	background-image:
+		url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='5px' height='8px' viewBox='0 0 5 8' enable-background='new 0 0 5 8' xml:space='preserve'><defs></defs><path fill='#333333' d='M4.707,6.293c0.391,0.391,0.391,1.023,0,1.414C4.512,7.902,4.256,8,4,8S3.488,7.902,3.293,7.707l-3-3 C0.105,4.52,0,4.266,0,4s0.105-0.52,0.293-0.707l3-3c0.391-0.391,1.023-0.391,1.414,0c0.391,0.39,0.391,1.023,0,1.414L2.414,4 L4.707,6.293z'/></svg>");
+	border-bottom-left-radius: 2px;
+	border-top-left-radius: 2px;
+}
+
+.eb_scrollbar::-webkit-scrollbar-button:horizontal:increment {
+	background-image:
+		url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='5px' height='8px' viewBox='0 0 5 8' enable-background='new 0 0 5 8' xml:space='preserve'><defs></defs><path fill='#333333' d='M0.293,1.707c-0.391-0.391-0.391-1.023,0-1.414C0.488,0.098,0.744,0,1,0s0.512,0.098,0.707,0.293l3,3 C4.895,3.48,5,3.734,5,4s-0.105,0.52-0.293,0.707l-3,3c-0.391,0.391-1.023,0.391-1.414,0s-0.391-1.023,0-1.414L2.586,4L0.293,1.707z'/></svg>");
+	border-bottom-right-radius: 2px;
+	border-top-right-radius: 2px;
+}
+
+/* Input */
+.ebInput {
+	display: inline-block;
+	vertical-align: middle;
+	text-align: left;
+	font-size: 1.2rem;
+	width: 140px;
+	height: 2.4rem;
+	padding: 0.4rem 0.6rem;
+	border: 1px solid #b3b3b3;
+	-moz-box-sizing: border-box;
+	box-sizing: border-box;
+	border-radius: 3px;
+	box-shadow: inset 1px 1px 0 0 #cccccc;
+	-webkit-appearance: none;
+	-moz-appearance: none;
+	-ms-appearance: none;
+	appearance: none;
+}
+
+.ebInput_wMargin {
+	margin: 6px;
+}
+
+.ebInput_txtCenter {
+	text-align: center;
+}
+
+.ebInput_miniW, .ebInput_width_mini {
+	width: 40px;
+}
+
+.ebInput_smallW, .ebInput_width_small {
+	width: 80px;
+}
+
+.ebInput_longW, .ebInput_width_long {
+	width: 180px;
+}
+
+.ebInput_xLongW, .ebInput_width_xLong {
+	width: 220px;
+}
+
+.ebInput_width_full {
+	min-width: 40px;
+	width: 100%;
+}
+
+.ebInput_noRightSide {
+	border-width: 1px 0 1px 1px;
+	border-radius: 3px 0 0 3px;
+}
+
+.ebInput_noLeftSide {
+	border-width: 1px 1px 1px 0;
+	border-radius: 0 3px 3px 0;
+	box-shadow: inset 0 1px 0 0 #cccccc;
+}
+
+.ebInput:hover {
+	border-color: #666666;
+}
+
+.ebInput[readonly] {
+	cursor: text; //
+	box-shadow: none;
+	border-color: #E3E3E3;
+	background-color: #f0f0f0;
+	color: #b2b2b2;
+}
+
+.ebInput[readonly]:hover { //
+	border-color: #E3E3E3;
+}
+
+.ebInput_disabled, .ebInput:disabled {
+	color: #B2B2B2;
+	border-color: #B2B2B2;
+	background-color: rgba(0, 0, 0, 0.05);
+	-webkit-text-fill-color: #b2b2b2;
+	opacity: 1;
+	-ms-touch-action: none !important;
+	touch-action: none !important;
+	box-shadow: inset 1px 1px 0 0 #cccccc;
+}
+
+.ebInput_borderColor {
+	border-color: #b3b3b3;
+}
+
+.ebInput_borderColor_red {
+	border-color: #e32119;
+}
+
+.ebInput_status_none {
+	border-color: #b3b3b3;
+}
+
+.ebInput_status_warning {
+	border-color: #f08a00;
+}
+
+.ebInput_status_error {
+	border-color: #e32119;
+}
+
+.ebInput.eb_wMargin+.ebInput-status {
+	margin: -0.2rem 0.8rem 0 0.6rem;
+}
+
+.ebInput-status {
+	display: block;
+	margin: 0.4rem 0 0 0;
+	line-height: 1.2rem;
+	min-height: 1.8rem;
+	font-size: 1.2rem;
+	font-weight: normal;
+}
+
+.ebInput-statusOk, .ebInput-statusError {
+	vertical-align: middle;
+}
+
+.ebInput-statusOk:before, .ebInput-statusError:before {
+	display: inline-block;
+	vertical-align: middle;
+	margin: 0 0.6rem 0 0;
+	width: 1.2rem;
+	height: 1.2rem;
+	content: '';
+	background-repeat: no-repeat;
+}
+
+.ebInput-statusInfo {
+	vertical-align: middle;
+	color: #8d8d8d;
+}
+
+.ebInput-statusOk {
+	color: #89ba17;
+	display: none;
+}
+
+.ebInput-statusOk:before {
+	background-image: url('../resources/form/valid_icon.svg');
+}
+
+.ebInput-statusError {
+	color: #e32119;
+	display: none;
+}
+
+.ebInput-statusError:before {
+	background-image: url('../resources/form/invalid_icon.svg');
+}
+
+.ebInput-status_none {
+	display: none;
+}
+
+.ebInput-status_hide .ebInput-statusOk, .ebInput-status_hide .ebInput-statusError,
+	.ebInput-status_hide .ebInput-statusInfo {
+	display: none;
+}
+
+.ebInput-status_info .ebInput-statusInfo {
+	display: inline-block;
+}
+
+.ebInput-status_info .ebInput-statusOk, .ebInput-status_info .ebInput-statusError
+	{
+	display: none;
+}
+
+.ebInput-status_ok .ebInput-statusOk {
+	display: inline-block;
+}
+
+.ebInput-status_ok .ebInput-statusError, .ebInput-status_ok .ebInput-statusInfo
+	{
+	display: none;
+}
+
+.ebInput-status_error .ebInput-statusError {
+	display: inline-block;
+}
+
+.ebInput-status_error .ebInput-statusOk, .ebInput-status_error .ebInput-statusInfo
+	{
+	display: none;
+}
+
+.ebInput:not (.ebInput_validation_focusLost ):valid+.ebInput-status:not
+	(.ebInput-status_hide ):not (.ebInput-status_info ):not (.ebInput-status_ok
+	):not (.ebInput-status_error ) .ebInput-statusOk {
+	display: inline-block;
+}
+
+.ebInput:not (.ebInput_validation_focusLost ):invalid:not (.ebInput_borderColor
+	):not (.ebInput_status_warning ):not (.ebInput_status_none ) {
+	border-color: #e32119;
+}
+
+.ebInput:not (.ebInput_validation_focusLost ):invalid+.ebInput-status:not
+	(.ebInput-status_hide ):not (.ebInput-status_info ):not (.ebInput-status_ok
+	):not (.ebInput-status_error ) .ebInput-statusError {
+	display: inline-block;
+}
+
+.ebInput:not (.ebInput_validation_focusLost ):invalid+.ebInput-status:not
+	(.ebInput-status_hide ):not (.ebInput-status_info ):not (.ebInput-status_ok
+	):not (.ebInput-status_error ) .ebInput-statusInfo {
+	display: none;
+}
+
+.ebInput.ebInput_validation_focusLost:not (:focus ):valid+.ebInput-status:not
+	(.ebInput-status_hide ):not (.ebInput-status_info ):not (.ebInput-status_ok
+	):not (.ebInput-status_error ) .ebInput-statusOk {
+	display: inline-block;
+}
+
+.ebInput.ebInput_validation_focusLost:not (:focus ):invalid:not (.ebInput_borderColor
+	):not (.ebInput_status_warning ):not (.ebInput_status_none ) {
+	border-color: #e32119;
+}
+
+.ebInput.ebInput_validation_focusLost:not (:focus ):invalid+.ebInput-status:not
+	(.ebInput-status_hide ):not (.ebInput-status_info ):not (.ebInput-status_ok
+	):not (.ebInput-status_error ) .ebInput-statusError {
+	display: inline-block;
+}
+
+.ebInput.ebInput_validation_focusLost:not (:focus ):invalid+.ebInput-status:not
+	(.ebInput-status_hide ):not (.ebInput-status_info ):not (.ebInput-status_ok
+	):not (.ebInput-status_error ) .ebInput-statusInfo {
+	display: none;
+}
+
+/* Textarea */
+.ebTextArea {
+	-webkit-overflow-scrolling: touch;
+	overflow: auto;
+	display: inline-block;
+	vertical-align: middle;
+	text-align: left;
+	font-size: 1.2rem;
+	width: 140px;
+	padding: 0.4rem 0.6rem;
+	margin: 0;
+	border: 1px solid #b3b3b3;
+	font-family: arial;
+	-moz-box-sizing: border-box;
+	box-sizing: border-box;
+	border-radius: 3px;
+	box-shadow: inset 1px 1px 0 0 #cccccc;
+	-webkit-appearance: none;
+	-moz-appearance: none;
+	-ms-appearance: none;
+	appearance: none;
+}
+
+.ebTextArea::-webkit-scrollbar {
+	width: 14px;
+	height: 14px;
+}
+
+.ebTextArea::-webkit-scrollbar-track {
+	background-color: #f0f0f0;
+	background-clip: content-box;
+}
+
+.ebTextArea::-webkit-scrollbar-thumb {
+	background-color: #cccccc;
+	border-radius: 3px;
+	transition: all 0.2s linear;
+	background-clip: content-box;
+}
+
+.ebTextArea::-webkit-scrollbar-thumb:hover {
+	background-color: #999999;
+}
+
+.ebTextArea::-webkit-scrollbar-button {
+	width: 14px;
+	height: 14px;
+	background-repeat: no-repeat;
+	background-color: #f0f0f0;
+	background-position: center;
+}
+
+.ebTextArea::-webkit-scrollbar-button:hover {
+	background-color: #cccccc;
+}
+
+.ebTextArea::-webkit-scrollbar-button:vertical:decrement {
+	background-position: center 4px;
+	background-image:
+		url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='8px' height='5px' viewBox='0 0 8 5' enable-background='new 0 0 8 5' xml:space='preserve'><path fill='#333333' d='M0.293,3.293l3-3C3.488,0.098,3.744,0,4,0s0.512,0.098,0.707,0.293l3,3c0.391,0.391,0.391,1.023,0,1.414 s-1.023,0.391-1.414,0L4,2.414L1.707,4.707c-0.391,0.391-1.023,0.391-1.414,0S-0.098,3.684,0.293,3.293z'/></svg>");
+	border-top-left-radius: 2px;
+	border-top-right-radius: 2px;
+}
+
+.ebTextArea::-webkit-scrollbar-button:vertical:increment {
+	background-image:
+		url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='8px' height='5px' viewBox='0 0 8 5' enable-background='new 0 0 8 5' xml:space='preserve'><path fill='#333333' d='M7.707,1.707l-3,3C4.512,4.902,4.255,5,4,5S3.488,4.902,3.292,4.707l-3-3c-0.391-0.391-0.391-1.023,0-1.414 s1.023-0.391,1.414,0L4,2.586l2.293-2.293c0.391-0.391,1.023-0.391,1.414,0S8.098,1.316,7.707,1.707z'/></svg>");
+	border-bottom-left-radius: 2px;
+	border-bottom-right-radius: 2px;
+}
+
+.ebTextArea::-webkit-scrollbar-button:horizontal:decrement {
+	background-position: 4px center;
+	background-image:
+		url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='5px' height='8px' viewBox='0 0 5 8' enable-background='new 0 0 5 8' xml:space='preserve'><defs></defs><path fill='#333333' d='M4.707,6.293c0.391,0.391,0.391,1.023,0,1.414C4.512,7.902,4.256,8,4,8S3.488,7.902,3.293,7.707l-3-3 C0.105,4.52,0,4.266,0,4s0.105-0.52,0.293-0.707l3-3c0.391-0.391,1.023-0.391,1.414,0c0.391,0.39,0.391,1.023,0,1.414L2.414,4 L4.707,6.293z'/></svg>");
+	border-bottom-left-radius: 2px;
+	border-top-left-radius: 2px;
+}
+
+.ebTextArea::-webkit-scrollbar-button:horizontal:increment {
+	background-image:
+		url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='5px' height='8px' viewBox='0 0 5 8' enable-background='new 0 0 5 8' xml:space='preserve'><defs></defs><path fill='#333333' d='M0.293,1.707c-0.391-0.391-0.391-1.023,0-1.414C0.488,0.098,0.744,0,1,0s0.512,0.098,0.707,0.293l3,3 C4.895,3.48,5,3.734,5,4s-0.105,0.52-0.293,0.707l-3,3c-0.391,0.391-1.023,0.391-1.414,0s-0.391-1.023,0-1.414L2.586,4L0.293,1.707z'/></svg>");
+	border-bottom-right-radius: 2px;
+	border-top-right-radius: 2px;
+}
+
+.ebTextArea_noMargin {
+	margin: 0;
+}
+
+.ebTextArea_txtCenter {
+	text-align: center;
+}
+
+.ebTextArea_miniW, .ebTextArea_width_mini {
+	width: 40px;
+}
+
+.ebTextArea_smallW, .ebTextArea_width_small {
+	width: 80px;
+}
+
+.ebTextArea_longW, .ebTextArea_width_long {
+	width: 180px;
+}
+
+.ebTextArea_xLongW, .ebTextArea_width_xLong {
+	width: 220px;
+}
+
+.ebTextArea_width_full {
+	min-width: 40px;
+	width: 100%;
+}
+
+.ebTextArea_noRightSide {
+	border-width: 1px 0 1px 1px;
+	border-radius: 3px 0 0 3px;
+}
+
+.ebTextArea_noLeftSide {
+	border-width: 1px 1px 1px 0;
+	border-radius: 0 3px 3px 0;
+}
+
+.ebTextArea:hover {
+	border-color: #666666;
+}
+
+.ebTextArea[readonly] {
+	cursor: text;
+	border-color: #E3E3E3;
+	background-color: #f0f0f0;
+	color: #b2b2b2;
+}
+
+.ebTextArea[readonly]:hover { //
+	border-color: #E3E3E3;
+}
+
+.ebTextArea_disabled, .ebTextArea:disabled {
+	color: #B2B2B2;
+	border-color: #B2B2B2;
+	background-color: rgba(0, 0, 0, 0.05);
+	-ms-touch-action: none;
+	touch-action: none;
+	-webkit-text-fill-color: #b2b2b2;
+	opacity: 1;
+	box-shadow: inset 1px 1px 0 0 #cccccc;
+}
+
+.ebTextArea_status_none {
+	border-color: #b3b3b3;
+}
+
+.ebTextArea_status_warning {
+	border-color: #f08a00;
+}
+
+.ebTextArea_status_error {
+	border-color: #e32119;
+}
+
+.ebTextArea:invalid:not (.ebTextArea_status_warning ):not (.ebTextArea_status_none
+	) {
+	border-color: #e32119;
+}
+
+/* Button */
+.ebBtn {
+	position: relative;
+	display: inline-block;
+	vertical-align: middle;
+	color: #333333;
+	background-color: #ffffff;
+	border: none;
+	min-width: 60px;
+	box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
+	border-radius: 3px;
+	-moz-box-sizing: border-box;
+	box-sizing: border-box;
+	background-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%,
+		rgba(0, 0, 0, 0.1) 100%);
+	padding: 0 8px;
+	height: 2.4rem;
+	font-size: 1.2rem;
+	white-space: nowrap;
+	text-decoration: none;
+	text-align: center;
+	cursor: pointer;
+}
+
+a.ebBtn:hover {
+	color: #333;
+}
+
+a.ebBtn:focus, a.ebBtn:active, a.ebBtn_active {
+	text-decoration: none;
+}
+
+.ebBtn:focus {
+	outline: none;
+	box-shadow: 0 0 2px 1px #4d90fe, 0 0 0 1px rgba(0, 0, 0, 0.2) inset;
+}
+
+.ebBtn_color_blue, .ebBtn_color_darkBlue, .ebBtn_color_paleBlue,
+	.ebBtn_color_darkGreen, .ebBtn_color_green, .ebBtn_color_orange,
+	.ebBtn_color_red, .ebBtn_color_purple {
+	background-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%,
+		rgba(0, 0, 0, 0.3) 100%);
+	color: #F0F0F0 !important;
+}
+
+.ebBtn_color_blue:hover, .ebBtn_color_darkBlue:hover,
+	.ebBtn_color_paleBlue:hover, .ebBtn_color_darkGreen:hover,
+	.ebBtn_color_green:hover, .ebBtn_color_orange:hover, .ebBtn_color_red:hover,
+	.ebBtn_color_purple:hover {
+	background-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%,
+		rgba(0, 0, 0, 0.1) 100%);
+}
+
+.ebBtn_color_blue {
+	background-color: #0966b3;
+}
+
+.ebBtn_color_darkBlue {
+	background-color: #0066b3;
+}
+
+.ebBtn_color_paleBlue {
+	background-color: #00A9D4;
+}
+
+.ebBtn_color_darkGreen {
+	background-color: #00625F;
+}
+
+.ebBtn_color_green {
+	background-color: #89BA17;
+}
+
+.ebBtn_color_orange {
+	background-color: #F08A00;
+}
+
+.ebBtn_color_red {
+	background-color: #E32119;
+}
+
+.ebBtn_color_purple {
+	background-color: #953882;
+}
+
+.ebBtn_small {
+	font-size: 1.1rem;
+	padding: 0 6px;
+	height: 2rem;
+}
+
+.ebBtn_large {
+	font-size: 1.4rem;
+	padding: 0 10px;
+	height: 3.8rem;
+}
+
+.ebBtn:hover {
+	text-decoration: none;
+	background-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%,
+		rgba(0, 0, 0, 0.15) 100%);
+}
+
+.ebBtn_active, .ebBtn:active, .ebBtn_active:hover {
+	text-decoration: none;
+	box-shadow: inset 2px 2px 2.5px 0 rgba(0, 0, 0, 0.35), inset 0 0 0 1px
+		rgba(0, 0, 0, 0.2);
+	background-image: linear-gradient(180deg, rgba(0, 0, 0, 0.2) 0%,
+		rgba(0, 0, 0, 0.2) 100%);
+}
+
+.ebBtn:disabled, .ebBtn_disabled, .ebBtn:disabled:hover, .ebBtn_disabled:hover,
+	.ebBtn:disabled:active, .ebBtn_disabled:active {
+	-ms-touch-action: none !important;
+	cursor: not-allowed !important;
+	touch-action: none !important;
+	background: rgba(0, 0, 0, 0.1);
+	color: #8d8d8d !important;
+}
+
+.ebBtn:disabled .ebIcon, .ebBtn_disabled .ebIcon {
+	opacity: 0.3;
+}
+
+.ebBtn_subtle {
+	background-image: none;
+	background-color: transparent;
+	box-shadow: none;
+	min-width: auto;
+}
+
+.ebBtn_subtle:hover {
+	background-image: none;
+	box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
+}
+
+.ebBtn_subtle:focus {
+	box-shadow: 0 0 2px 1px #4d90fe, 0 0 0 1px rgba(0, 0, 0, 0.2) inset;
+}
+
+.ebBtn_subtle:active, .ebBtn_subtle.ebBtn_subtle_active {
+	text-decoration: none;
+	box-shadow: inset 2px 2px 2.5px 0 rgba(0, 0, 0, 0.35), inset 0 0 0 1px
+		rgba(0, 0, 0, 0.2);
+	background-image: linear-gradient(180deg, rgba(0, 0, 0, 0.2) 0%,
+		rgba(0, 0, 0, 0.2) 100%);
+}
+
+.ebBtn_subtle:disabled, .ebBtn_subtle.ebBtn_subtle_disabled,
+	.ebBtn_subtle:disabled:hover, .ebBtn_subtle.ebBtn_subtle_disabled:hover,
+	.ebBtn_subtle:disabled:active, .ebBtn_subtle.ebBtn_subtle_disabled:active
+	{
+	background-color: transparent;
+	box-shadow: none;
+}
+
+.ebBtn:active:focus, .ebBtn_active:focus {
+	box-shadow: inset 2px 2px 2.5px 0 rgba(0, 0, 0, 0.35), inset 0 0 0 1px
+		rgba(0, 0, 0, 0.2), 0 0 2px 1px #4d90fe;
+	background-image: linear-gradient(180deg, rgba(0, 0, 0, 0.2) 0%,
+		rgba(0, 0, 0, 0.2) 100%);
+}
+
+/* Combobox */
+.ebCombobox {
+	position: relative;
+	display: inline-block;
+	vertical-align: middle;
+	white-space: nowrap;
+	margin: 0;
+	padding: 0;
+	height: 2.4rem;
+}
+
+.ebCombobox_width_full {
+	min-width: 70px;
+	width: 100%;
+}
+
+.ebCombobox_width_full .ebInput {
+	width: calc(100% - 30px);
+}
+
+.ebCombobox-list, .ebCombobox-body {
+	position: absolute;
+	margin-top: 6px;
+	display: none;
+	width: 100%;
+}
+
+.ebCombobox-list_rightAlign, .ebCombobox-body_rightAlign {
+	right: 0;
+}
+
+.ebCombobox-Helper, .ebCombobox-helper {
+	position: relative;
+	display: inline-block;
+	vertical-align: middle;
+	width: 30px;
+	/*height: 100%; ewwatkmi: replaced with 2.4rem below*/
+	height: 2.4rem;
+	cursor: pointer;
+	border: 1px solid #999999;
+	background-color: #ffffff;
+	-moz-box-sizing: border-box;
+	box-sizing: border-box;
+	border-radius: 0 3px 3px 0;
+	-webkit-appearance: none;
+	-moz-appearance: none;
+	-ms-appearance: none;
+	appearance: none;
+	background-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%,
+		rgba(0, 0, 0, 0.1) 100%);
+}
+
+.ebCombobox-Helper:hover, .ebCombobox-helper:hover {
+	background-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%,
+		rgba(0, 0, 0, 0.15) 100%);
+}
+
+.ebCombobox-Helper:active, .ebCombobox-helper:active {
+	box-shadow: inset 2px 2px 3px 0 rgba(0, 0, 0, 0.35);
+	background-image: linear-gradient(180deg, rgba(0, 0, 0, 0.2) 0%,
+		rgba(0, 0, 0, 0.2) 100%);
+}
+
+.ebCombobox-Helper:disabled, .ebCombobox-helper:disabled {
+	border-color: #b2b2b2;
+}
+
+.ebCombobox-Helper:disabled, .ebCombobox-helper:disabled,
+	.ebCombobox-Helper:disabled:hover, .ebCombobox-helper:disabled:hover,
+	.ebCombobox-Helper:disabled:active, .ebCombobox-helper:disabled:active
+	{
+	-ms-touch-action: none !important;
+	cursor: not-allowed !important;
+	touch-action: none !important;
+	background: #e5e5e5;
+	color: #B2B2B2;
+	cursor: not-allowed;
+	box-shadow: none;
+}
+
+.ebCombobox-Helper .ebCombobox-iconHolder, .ebCombobox-helper .ebCombobox-iconHolder
+	{
+	display: inline-block;
+	opacity: 0.7;
+	cursor: pointer;
+	line-height: 2.2rem;
+}
+
+.ebCombobox-Helper .ebCombobox-iconHolder .ebIcon, .ebCombobox-helper .ebCombobox-iconHolder .ebIcon
+	{
+	position: absolute;
+	top: 0;
+	bottom: 0;
+	left: 0;
+	right: 0;
+	margin: auto;
+}
+
+.ebCombobox:hover>.ebCombobox-Helper, .ebCombobox:hover>.ebCombobox-helper
+	{
+	border-color: #666666;
+}
+
+.ebCombobox
+ 
+.ebInput
+:focus
+ 
+~
+.ebCombobox-list
+, /*.ebCombobox .ebInput:focus ~ .ebCombobox-body,*/
+.ebCombobox
+:active
+>
+.ebCombobox-list
+, /*.ebCombobox:active > .ebCombobox-body*/
+{
+display
+:
+ 
+block
+;
+
+
+}
+.ebCombobox>.ebCombobox-list, .ebCombobox>.ebCombobox-body {
+	display: none;
+}
+
+.ebCombobox_noMargin {
+	margin: 0;
+}
+
+.ebCombobox_disabled, .ebCombobox_disabled *:hover {
+	-ms-touch-action: none !important;
+	cursor: not-allowed !important;
+	touch-action: none !important;
+}
+
+.ebCombobox_disabled .ebCombobox-iconHolder, .ebCombobox_disabled .ebCombobox-iconHolder:hover,
+	.ebCombobox_disabled .ebCombobox-iconHolder:active {
+	-ms-touch-action: none !important;
+	cursor: not-allowed !important;
+	touch-action: none !important;
+	opacity: 0.3;
+}
+
+.ebCombobox_disabled:hover>.ebCombobox-Helper, .ebCombobox_disabled:hover>.ebCombobox-helper
+	{
+	border-color: #b2b2b2;
+}
+
+.ebCombobox_disabled:active>.ebCombobox-list, .ebCombobox_disabled:active>.ebCombobox-body
+	{
+	display: none;
+}
+
+.ebCombobox_disabled .ebInput:focus ~ .ebCombobox-list,
+	.ebCombobox_disabled .ebInput:focus ~ .ebCombobox-body {
+	display: none;
+}
+
+.ebCombobox_status_warning .ebInput {
+	border-color: #f08a00;
+}
+
+.ebCombobox_status_error .ebInput {
+	border-color: #e32119;
+}
+
+/* Switcher */
+.ebSwitcher {
+	position: relative;
+	height: 24px;
+	width: 84px;
+	display: block;
+	overflow: hidden;
+	cursor: pointer;
+	border: 1px solid #ccc;
+	border-radius: 3px;
+	-khtml-user-select: none;
+	-moz-user-select: none;
+	-o-user-select: none;
+	-webkit-user-select: none;
+	user-select: none;
+}
+
+.ebSwitcher-checkbox {
+	display: none;
+}
+
+.ebSwitcher-body {
+	position: relative;
+	font-size: 0;
+	white-space: nowrap;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+	transition: left 0.2s linear;
+}
+
+.ebSwitcher-onLabel, .ebSwitcher-switch, .ebSwitcher-offLabel {
+	display: inline-block;
+	vertical-align: top;
+	overflow: hidden;
+	height: 100%;
+}
+
+.ebSwitcher-onLabel, .ebSwitcher-offLabel {
+	width: calc(100% - 24px);
+	line-height: 2.4rem;
+	color: white;
+	text-align: center;
+	font-size: 1.2rem;
+}
+
+.ebSwitcher-onLabel {
+	background-color: red;
+}
+
+.ebSwitcher-onLabel2 {
+	background-color: #89ba17;
+}
+
+.ebSwitcher-offLabel {
+	background-color: #89ba17;
+}
+
+.ebSwitcher-offLabel2 {
+	background-color: red;
+}
+
+.ebSwitcher-switch {
+	height: 24px;
+	width: 24px;
+	transition: left 0.2s;
+}
+
+.ebSwitcher-switch::after {
+	content: "";
+	position: absolute;
+	margin: -1px;
+	width: 24px;
+	height: 24px;
+	display: inline-block;
+	background: #ffffff;
+	background-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%,
+		rgba(0, 0, 0, 0.1) 100%);
+	border-radius: 3px;
+	border: 1px solid rgba(0, 0, 0, 0.2);
+}
+
+.ebSwitcher-checkbox:not (:checked ) +.ebSwitcher-body {
+	left: calc(-100% + 24px);
+}
+
+.ebSwitcher:focus {
+	/*
+        outline: #4d90fe auto 5px;
+        box-shadow: 0 0 0 1px #4d90fe;
+        -webkit-box-shadow: none;
+        */
+	outline: none;
+	box-shadow: 0 0 2px 1px #4d90fe;
+}
+
+.ebSwitcher_status_warning {
+	border-color: #f08a00;
+}
+
+.ebSwitcher_status_error {
+	border-color: #e32119;
+}
+
+.ebSwitcher_disabled {
+	cursor: not-allowed;
+}
+
+.ebSwitcher_disabled .ebSwitcher-onLabel, .ebSwitcher_disabled .ebSwitcher-offLabel,
+	.ebSwitcher_disabled .ebSwitcher-switch::after {
+	background-color: #e5e5e5;
+	background-image: none;
+	color: #8d8d8d;
+}
+
+/* Dropdown */
+.ebDropdown {
+	position: relative;
+	display: inline-block;
+	height: 2.4rem;
+	padding: 0;
+	margin: 0;
+}
+
+.ebDropdown-list, .ebDropdown-body {
+	position: absolute;
+	margin-top: 6px;
+	display: none;
+	min-width: 100%;
+}
+
+.ebDropdown-list_rightAlign, .ebDropdown-body_rightAlign {
+	right: 0;
+}
+
+.ebDropdown-Header, .ebDropdown-header {
+	position: relative;
+	display: inline-block;
+	vertical-align: middle;
+	height: 100%;
+	min-width: 60px;
+	margin: 0;
+	padding: 6px 8px;
+	line-height: 1.2rem;
+	font-size: 1.2rem;
+	text-align: left;
+	text-decoration: none;
+	white-space: nowrap;
+	color: #333333;
+	background-color: #ffffff;
+	border: none;
+	cursor: pointer;
+	box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
+	border-radius: 3px;
+	-moz-box-sizing: border-box;
+	box-sizing: border-box;
+	background-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%,
+		rgba(0, 0, 0, 0.1) 100%);
+}
+
+.ebDropdown-Header:hover, .ebDropdown-header:hover {
+	background-image: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%,
+		rgba(0, 0, 0, 0.15) 100%);
+}
+
+.ebDropdown-Header:active, .ebDropdown-header:active {
+	box-shadow: inset 2px 2px 2.5px 0 rgba(0, 0, 0, 0.35), inset 0 0 0 1px
+		rgba(0, 0, 0, 0.2);
+	background-image: linear-gradient(180deg, rgba(0, 0, 0, 0.2) 0%,
+		rgba(0, 0, 0, 0.2) 100%);
+}
+
+.ebDropdown-Header .ebDropdown-caption, .ebDropdown-header .ebDropdown-caption
+	{
+	display: inline-block;
+	padding: 0 4px 0 0;
+	vertical-align: middle;
+	min-width: 27px;
+}
+
+.ebDropdown-Header .ebDropdown-iconHolder, .ebDropdown-header .ebDropdown-iconHolder
+	{
+	display: inline-block;
+	cursor: pointer;
+	opacity: 0.7;
+}
+
+.ebDropdown .ebDropdown-Header:focus+.ebDropdown-list, .ebDropdown .ebDropdown-header:focus+.ebDropdown-body,
+	.ebDropdown .ebDropdown-Header:active+.ebDropdown-list, .ebDropdown .ebDropdown-header:active+.ebDropdown-body,
+	.ebDropdown:focus>.ebDropdown-list, .ebDropdown:focus>.ebDropdown-body,
+	.ebDropdown:active>.ebDropdown-list, .ebDropdown:active>.ebDropdown-body
+	{
+	display: block;
+}
+
+.ebDropdown_disabled .ebDropdown-Header, .ebDropdown_disabled .ebDropdown-header
+	{
+	background: rgba(0, 0, 0, 0.1);
+	color: #B2B2B2;
+}
+
+.ebDropdown_disabled .ebDropdown-Header, .ebDropdown_disabled .ebDropdown-header,
+	.ebDropdown_disabled .ebDropdown-Header:hover, .ebDropdown_disabled .ebDropdown-header:hover,
+	.ebDropdown_disabled .ebDropdown-Header:active, .ebDropdown_disabled .ebDropdown-header:active
+	{
+	-ms-touch-action: none !important;
+	cursor: not-allowed !important;
+	touch-action: none !important;
+}
+
+.ebDropdown_disabled .ebDropdown-Header:hover, .ebDropdown_disabled .ebDropdown-header:hover,
+	.ebDropdown_disabled .ebDropdown-Header:active, .ebDropdown_disabled .ebDropdown-header:active
+	{
+	background: rgba(0, 0, 0, 0.1);
+	color: #B2B2B2;
+	box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
+}
+
+.ebDropdown_disabled .ebDropdown-Header .ebDropdown-iconHolder,
+	.ebDropdown_disabled .ebDropdown-header .ebDropdown-iconHolder,
+	.ebDropdown_disabled .ebDropdown-Header .ebDropdown-iconHolder:hover,
+	.ebDropdown_disabled .ebDropdown-header .ebDropdown-iconHolder:hover,
+	.ebDropdown_disabled .ebDropdown-Header .ebDropdown-iconHolder:active,
+	.ebDropdown_disabled .ebDropdown-header .ebDropdown-iconHolder:active {
+	-ms-touch-action: none !important;
+	cursor: not-allowed !important;
+	touch-action: none !important;
+	opacity: 0.3;
+}
+
+.ebDropdown_disabled .ebDropdown-Header:focus+.ebDropdown-list,
+	.ebDropdown_disabled .ebDropdown-header:focus+.ebDropdown-body,
+	.ebDropdown_disabled .ebDropdown-Header:active+.ebDropdown-list,
+	.ebDropdown_disabled .ebDropdown-header:active+.ebDropdown-body,
+	.ebDropdown_disabled:focus>.ebDropdown-list, .ebDropdown_disabled:focus>.ebDropdown-body,
+	.ebDropdown_disabled:active>.ebDropdown-list, .ebDropdown_disabled:active>.ebDropdown-body
+	{
+	display: none;
+}
+
+/* Icons */
+.ebIcon {
+	display: inline-block;
+	vertical-align: middle;
+	border: none;
+	height: 16px;
+	width: 16px;
+	line-height: 1.6rem;
+	background-repeat: no-repeat;
+	background-position: center;
+	background-color: transparent;
+	background-size: 100%;
+	-khtml-user-select: none;
+	-moz-user-select: none;
+	-o-user-select: none;
+	-webkit-user-select: none;
+	user-select: none;
+	/*small icons  */
+	/*16px icons*/
+}
+
+.ebIcon_interactive {
+	opacity: 0.7;
+	cursor: pointer;
+}
+
+.ebIcon_interactive:hover {
+	opacity: 1.0;
+}
+
+.ebIcon_interactive:active {
+	opacity: 0.4;
+}
+
+.ebIcon_button {
+	margin: 10px;
+}
+
+.ebIcon_noVertAlign {
+	vertical-align: inherit;
+}
+
+.ebIcon_disabled {
+	cursor: default;
+}
+
+.ebIcon_disabled, .ebIcon_disabled:hover, .ebIcon_disabled:active {
+	opacity: 0.3;
+}
+
+.ebIcon_small {
+	width: 1rem;
+	height: 1rem;
+	line-height: 1rem;
+}
+
+.ebIcon_big {
+	width: 2rem;
+	height: 2rem;
+	line-height: 2rem;
+}
+
+.ebIcon_large {
+	width: 2.8rem;
+	height: 2.8rem;
+	line-height: 2.8rem;
+}
+
+.ebIcon_wMargin {
+	margin: 4px;
+}
+
+.ebIcon_upArrow {
+	background-image: url('../resources/16px/ArrowUpSmall_black_16px.svg');
+}
+
+.ebIcon_upArrow_white {
+	background-image: url('../resources/16px/arrowUpSmall_white_16px.svg');
+}
+
+.ebIcon_downArrow {
+	background-image: url('../resources/16px/ArrowDownSmall_black_16px.svg');
+}
+
+.ebIcon_downArrow_white {
+	background-image: url('../resources/16px/ArrowDownSmall_white_16px.svg');
+}
+
+.ebIcon_leftArrow {
+	background-image: url('../resources/16px/ArrowLeftSmall_black_16px.svg');
+}
+
+.ebIcon_leftArrow_white {
+	background-image: url('../resources/16px/ArrowLeftSmall_white_16px.svg');
+}
+
+.ebIcon_rightArrow {
+	background-image:
+		url('../resources/16px/ArrowRightSmall_black_16px.svg');
+}
+
+.ebIcon_rightArrow_white {
+	background-image:
+		url('../resources/16px/ArrowRightSmall_white_16px.svg');
+}
+
+.ebIcon_prevArrow {
+	background-image:
+		url('../resources/16px/ArrowDoubleLeftSmall_black_16px.svg');
+}
+
+.ebIcon_nextArrow {
+	background-image:
+		url('../resources/16px/ArrowDoubleRightSmall_black_16px.svg');
+}
+
+.ebIcon_upArrow_10px {
+	background-image: url('../resources/10px/ArrowUpSmall_black_10px.svg');
+}
+
+.ebIcon_downArrow_10px {
+	background-image: url('../resources/10px/ArrowDownSmall_black_10px.svg');
+}
+
+.ebIcon_leftArrow_10px {
+	background-image: url('../resources/10px/ArrowLeftSmall_black_10px.svg');
+}
+
+.ebIcon_rightArrow_10px {
+	background-image:
+		url('../resources/10px/ArrowRightSmall_black_10px.svg');
+}
+
+.ebIcon_prevArrow_10px {
+	background-image:
+		url('../resources/10px/ArrowDoubleLeftSmall_black_10px.svg');
+}
+
+.ebIcon_nextArrow_10px {
+	background-image:
+		url('../resources/10px/ArrowDoubleRightSmall_black_10px.svg');
+}
+
+.ebIcon_errorSmall {
+	background-image: url('../resources/other/errorSmall_red_10px.svg');
+}
+
+.ebIcon_tickSmallBlack {
+	background-image: url('../resources/other/tick_black_10x8px.svg');
+}
+
+.ebIcon_tickSmallGreen {
+	background-image: url('../resources/other/tick_green_10x8px.svg');
+}
+
+.ebIcon_upArrowLarge {
+	background-image: url('../resources/16px/ArrowUp_black_16px.svg');
+}
+
+.ebIcon_upArrowLarge_white {
+	background-image: url('../resources/16px/ArrowUp_white_16px.svg');
+}
+
+.ebIcon_downArrowLarge {
+	background-image: url('../resources/16px/ArrowDown_black_16px.svg');
+}
+
+.ebIcon_downArrowLarge_white {
+	background-image: url('../resources/16px/ArrowDown_white_16px.svg');
+}
+
+.ebIcon_downArrowLarge_blue {
+	background-image: url('../resources/16px/ArrowDown_blue_16px.svg');
+}
+
+.ebIcon_leftArrowLarge {
+	background-image: url('../resources/16px/ArrowLeft_black_16px.svg');
+}
+
+.ebIcon_leftArrowLarge_white {
+	background-image: url('../resources/16px/ArrowLeft_white_16px.svg');
+}
+
+.ebIcon_rightArrowLarge {
+	background-image: url('../resources/16px/ArrowRight_black_16px.svg');
+}
+
+.ebIcon_rightArrowLarge_white {
+	background-image: url('../resources/16px/ArrowRight_white_16px.svg');
+}
+
+.ebIcon_circleArrowDown {
+	background-image:
+		url('../resources/16px/circleArrowDown_black_16px.svg');
+}
+
+.ebIcon_circleArrowDown_white {
+	background-image:
+		url('../resources/16px/circleArrowDown_white_16px.svg');
+}
+
+.ebIcon_circleArrowLeft {
+	background-image:
+		url('../resources/16px/circleArrowLeft_black_16px.svg');
+}
+
+.ebIcon_circleArrowLeft_white {
+	background-image:
+		url('../resources/16px/circleArrowLeft_white_16px.svg');
+}
+
+.ebIcon_circleArrowRight {
+	background-image:
+		url('../resources/16px/circleArrowRight_black_16px.svg');
+}
+
+.ebIcon_circleArrowRight_white {
+	background-image:
+		url('../resources/16px/circleArrowRight_white_16px.svg');
+}
+
+.ebIcon_circleArrowUp {
+	background-image: url('../resources/16px/circleArrowUp_black_16px.svg');
+}
+
+.ebIcon_circleArrowUp_white {
+	background-image: url('../resources/16px/circleArrowUp_white_16px.svg');
+}
+
+.ebIcon_circleCaretDown {
+	background-image:
+		url('../resources/16px/circleCaretDown_black_16px.svg');
+}
+
+.ebIcon_circleCaretDown_white {
+	background-image:
+		url('../resources/16px/circleCaretDown_white_16px.svg');
+}
+
+.ebIcon_circleCaretLeft {
+	background-image:
+		url('../resources/16px/circleCaretLeft_black_16px.svg');
+}
+
+.ebIcon_circleCaretLeft_white {
+	background-image:
+		url('../resources/16px/circleCaretLeft_white_16px.svg');
+}
+
+.ebIcon_circleCaretRight {
+	background-image:
+		url('../resources/16px/circleCaretRight_black_16px.svg');
+}
+
+.ebIcon_circleCaretRight_white {
+	background-image:
+		url('../resources/16px/circleCaretRight_white_16px.svg');
+}
+
+.ebIcon_circleCaretUp {
+	background-image: url('../resources/16px/circleCaretUp_black_16px.svg');
+}
+
+.ebIcon_circleCaretUp_white {
+	background-image: url('../resources/16px/circleCaretUp_white_16px.svg');
+}
+
+.ebIcon_eLogo {
+	background-image: url('../resources/systemBar/econ01.svg');
+}
+
+.ebIcon_comment {
+	background-image: url('../resources/16px/Comment_black_16px.svg');
+}
+
+.ebIcon_comment_white {
+	background-image: url('../resources/16px/comment_white.svg');
+}
+
+.ebIcon_copy {
+	background-image: url('../resources/16px/copy_black_16px.svg');
+}
+
+.ebIcon_copy_white {
+	background-image: url('../resources/16px/copy_white_16px.svg');
+}
+
+.ebIcon_cut {
+	background-image: url('../resources/16px/cut_black.svg');
+}
+
+.ebIcon_cut_white {
+	background-image: url('../resources/16px/cut_white.svg');
+}
+
+.ebIcon_delete {
+	background-image: url('../resources/16px/delete_black_16px.svg');
+}
+
+.ebIcon_delete_white {
+	background-image: url('../resources/16px/delete_white_16px.svg');
+}
+
+.ebIcon_duplicate {
+	background-image: url('../resources/16px/duplicate_black_16px.svg');
+}
+
+.ebIcon_duplicate_white {
+	background-image: url('../resources/16px/duplicate_white_16px.svg');
+}
+
+.ebIcon_edit {
+	background-image: url('../resources/16px/edit_black_16px.svg');
+}
+
+.ebIcon_editWhite {
+	background-image: url('../resources/16px/edit_white_16px.svg');
+}
+
+.ebIcon_newFile {
+	background-image: url('../resources/16px/newFile_black_16px.svg');
+}
+
+.ebIcon_newFile_white {
+	background-image: url('../resources/16px/newFile_white_16px.svg');
+}
+
+.ebIcon_save {
+	background-image: url('../resources/16px/save_black_16px.svg');
+}
+
+.ebIcon_save_white {
+	background-size: contain;
+	background-image: url('../resources/16px/save_white.svg');
+}
+
+.ebIcon_filter {
+	background-image: url('../resources/16px/filter_black_16px.svg');
+}
+
+.ebIcon_filterOn {
+	background-image: url('../resources/16px/filters_on.svg');
+}
+
+.ebIcon_filterOff {
+	background-image: url('../resources/16px/filters_off.svg');
+}
+
+.ebIcon_filter_white {
+	background-image: url('../resources/16px/filter_white_16px.svg');
+}
+
+.ebIcon_folder {
+	background-image: url('../resources/16px/folder_black_16px.svg');
+}
+
+.ebIcon_folder_white {
+	background-image: url('../resources/16px/folder_white_16px.svg');
+}
+
+.ebIcon_folderClosed {
+	background-image: url('../resources/16px/folderClosed_black.svg');
+}
+
+.ebIcon_folderClosed_white {
+	background-image: url('../resources/16px/folderClosed_white.svg');
+}
+
+.ebIcon_detach {
+	background-image: url('../resources/16px/detach_black_16px.svg');
+}
+
+.ebIcon_detach_white {
+	background-size: contain;
+	background-image: url('../resources/16px/detach_white.svg');
+}
+
+.ebIcon_import {
+	background-image: url('../resources/16px/import_black.svg');
+}
+
+.ebIcon_import_white {
+	background-image: url('../resources/16px/import_white.svg');
+}
+
+.ebIcon_export {
+	background-image: url('../resources/16px/export_black_16px.svg');
+}
+
+.ebIcon_export_white {
+	background-image: url('../resources/16px/export_white.svg');
+}
+
+.ebIcon_undo {
+	background-image: url('../resources/16px/undo_black_16px.svg');
+}
+
+.ebIcon_undo_white {
+	background-image: url('../resources/16px/undo_white_16px.svg');
+}
+
+.ebIcon_cancelled {
+	background-image: url('../resources/16px/Cancelled_Black_16px.svg');
+}
+
+.ebIcon_draft {
+	background-size: contain;
+	background-image: url('../resources/16px/draft.svg');
+}
+
+.ebIcon_importExport {
+	background-image: url('../resources/16px/import_export.svg');
+}
+
+.ebIcon_login {
+	background-image: url('../resources/16px/login.svg');
+}
+
+.ebIcon_move {
+	background-image: url('../resources/16px/move.svg');
+}
+
+.ebIcon_remove {
+	background-image: url('../resources/16px/remove.svg');
+}
+
+.ebIcon_valid {
+	background-image: url('../resources/16px/valid_icon.svg');
+}
+
+.ebIcon_invalid {
+	background-image: url('../resources/16px/invalid_icon.svg');
+}
+
+.ebIcon_error {
+	background-image: url('../resources/16px/error_red_16px.svg');
+}
+
+.ebIcon_warning {
+	background-image: url('../resources/16px/warning_yellow_16px.svg');
+}
+
+.ebIcon_warningOrange {
+	background-image: url('../resources/16px/warning_orange_16px.svg');
+}
+
+.ebIcon_warning_white {
+	background-image: url('../resources/16px/warning_white.svg');
+}
+
+.ebIcon_warningShield {
+	background-image: url('../resources/16px/warningShield_black_16px.svg');
+}
+
+.ebIcon_warningShield_white {
+	background-size: contain;
+	background-image: url('../resources/16px/warningShield_white.svg');
+}
+
+.ebIcon_mail {
+	background-image: url('../resources/16px/mail_black_16px.svg');
+}
+
+.ebIcon_mail_white {
+	background-image: url('../resources/16px/mail_white_16px.svg');
+}
+
+.ebIcon_mailRead {
+	background-image: url('../resources/16px/mailRead_black_16px.svg');
+}
+
+.ebIcon_mailRead_white {
+	background-image: url('../resources/16px/mailRead_white_16px.svg');
+}
+
+.ebIcon_link {
+	background-image: url('../resources/16px/Link_black_16px.svg');;
+}
+
+.ebIcon_lock {
+	background-image: url('../resources/16px/lock_black_16px.svg');
+}
+
+.ebIcon_lock_white {
+	background-image: url('../resources/16px/lock_white_16px.svg');
+}
+
+.ebIcon_unlock {
+	background-image: url('../resources/16px/unlock_black_16px.svg');
+}
+
+.ebIcon_unlock_white {
+	background-image: url('../resources/16px/unlock_white_16px.svg');
+}
+
+.ebIcon_logout {
+	background-image: url('../resources/16px/logout_black_16px.svg');
+}
+
+.ebIcon_menu {
+	background-image: url('../resources/16px/menu_black_16px.svg');
+}
+
+.ebIcon_menu_white {
+	background-image: url('../resources/16px/menu_white_16px.svg');
+}
+
+.ebIcon_search {
+	background-image: url('../resources/16px/search_black_16px.svg');
+}
+
+.ebIcon_searchWhite {
+	background-image: url('../resources/16px/search_white_16px.svg');
+}
+
+.ebIcon_advancedSearch {
+	background-image:
+		url('../resources/16px/advanced_search_black_16px.svg');
+}
+
+.ebIcon_advancedSearchWhite {
+	background-image:
+		url('../resources/16px/advanced_search_white_16px.svg');
+}
+
+.ebIcon_share {
+	background-image: url('../resources/16px/share_black_16px.svg');
+}
+
+.ebIcon_share_white {
+	background-image: url('../resources/16px/share_white.svg');
+}
+
+.ebIcon_star {
+	background-image: url('../resources/16px/star_black_16px.svg');
+}
+
+.ebIcon_star_white {
+	background-image: url('../resources/16px/star_white_16px.svg');
+}
+
+.ebIcon_star_yellow {
+	background-image: url('../resources/16px/star_yellow_16px.svg');
+}
+
+.ebIcon_starOutline {
+	background-image: url('../resources/16px/star_outline_black_16px.svg');
+}
+
+.ebIcon_starOutline_white {
+	background-image: url('../resources/16px/star_outline_white_16px.svg');
+}
+
+.ebIcon_starOutline_yellow {
+	background-image: url('../resources/16px/star_outline_yellow_16px.svg');
+}
+
+.ebIcon_tick {
+	background-image: url('../resources/16px/tick_green_16px.svg');
+}
+
+.ebIcon_tick_black {
+	background-image: url('../resources/16px/tick_16px.svg');
+}
+
+.ebIcon_simpleGreenTick {
+	background-image: url('../resources/16px/simple_green_tick.svg');
+}
+
+.ebIcon_simpleTick_black {
+	background-image: url('../resources/16px/simple_tick.svg');
+}
+
+.ebIcon_download {
+	background-image: url('../resources/16px/download_black.svg');
+}
+
+.ebIcon_download_white {
+	background-image: url('../resources/16px/download_white.svg');
+}
+
+.ebIcon_downloadWhite {
+	background-image: url('../resources/16px/download_white_16px.svg');
+}
+
+.ebIcon_documentWhite {
+	background-image: url('../resources/16px/document_white_16px.svg');
+}
+
+.ebIcon_expand {
+	background-image: url('../resources/16px/expand_black_16px.svg');
+}
+
+.ebIcon_rowCollapsed {
+	background-image: url('../resources/16px/rowCollapsed_black_16px.svg');
+}
+
+.ebIcon_rowExpanded {
+	background-image: url('../resources/16px/rowExpanded_black_16px.svg');
+}
+
+.ebIcon_rowView {
+	background-image: url('../resources/16px/rowView_black_16px.svg');
+}
+
+.ebIcon_rowView_white {
+	background-image: url('../resources/16px/rowView_white.svg');
+}
+
+.ebIcon_externalApp {
+	background-image: url('../resources/16px/externalApp_black_16px.svg');
+}
+
+.ebIcon_externalApp_white {
+	background-image: url('../resources/16px/externalApp_white_16px.svg');
+}
+
+.ebIcon_fullscreen {
+	background-image: url('../resources/16px/fullscreen_black_16px.svg');
+}
+
+.ebIcon_fullscreenMinimize {
+	background-image:
+		url('../resources/16px/fullscreenMinimise_black_16px.svg');
+}
+
+.ebIcon_help {
+	background-image: url('../resources/16px/help_black_16px.svg');
+}
+
+.ebIcon_help_white {
+	background-image: url('../resources/16px/help_white.svg');
+}
+
+.ebIcon_info {
+	background-image: url('../resources/16px/info_black.svg');
+}
+
+.ebIcon_info_white {
+	background-image: url('../resources/16px/info_white.svg');
+}
+
+.ebIcon_dialogInfo {
+	background-image: url('../resources/16px/dialogInfo_blue.svg');
+}
+
+.ebIcon_dialogInfo_white {
+	background-image: url('../resources/16px/dialogInfo_white.svg');
+}
+
+.ebIcon_infoMsgIndicator {
+	background-image: url('../resources/16px/infoMsgIndicator_16px.svg');
+}
+
+.ebIcon_exitFullscreen {
+	background-image:
+		url('../resources/16px/minimiseFullscreen_black_16px.svg');
+}
+
+.ebIcon_refresh {
+	background-image: url('../resources/16px/refresh_black_16px.svg');
+}
+
+.ebIcon_refresh_white {
+	background-image: url('../resources/16px/refresh_white_16px.svg');
+}
+
+.ebIcon_settings {
+	background-image: url('../resources/16px/settings_black_16px.svg');
+}
+
+.ebIcon_settings_white {
+	background-image: url('../resources/16px/settings_white_16px.svg');
+}
+
+.ebIcon_user {
+	background-image: url('../resources/16px/user_black_16px.svg');
+}
+
+.ebIcon_user_white {
+	background-image: url('../resources/16px/user_white_16px.svg');
+}
+
+.ebIcon_close {
+	background-image: url('../resources/16px/X_black_16px.svg');
+}
+
+.ebIcon_close_white {
+	background-image: url('../resources/16px/close_white_16px.svg');
+}
+
+.ebIcon_close_blue {
+	background-image: url('../resources/16px/X_blue_16px.svg');
+}
+
+.ebIcon_close_paleBlue {
+	background-image: url('../resources/16px/X_paleBlue_16px.svg');
+}
+
+.ebIcon_close_green {
+	background-image: url('../resources/16px/X_green_16px.svg');
+}
+
+.ebIcon_close_orange {
+	background-image: url('../resources/16px/X_orange_16px.svg');
+}
+
+.ebIcon_close_red {
+	background-image: url('../resources/16px/X_red_16px.svg');
+}
+
+.ebIcon_close_yellow {
+	background-image: url('../resources/16px/X_yellow_16px.svg');
+}
+
+.ebIcon_minus {
+	background-image: url('../resources/16px/minus_black_16px.svg');
+}
+
+.ebIcon_plus {
+	background-image: url('../resources/16px/plus_black_16px.svg');
+}
+
+.ebIcon_add {
+	background-image: url('../resources/16px/add_black_16px.svg');
+}
+
+.ebIcon_add_white {
+	background-image: url('../resources/16px/add_white_16px.svg');
+}
+
+.ebIcon_multiSelect {
+	background-image: url('../resources/16px/multiSelect_black_16px.svg');
+}
+
+.ebIcon_multiSelect_white {
+	background-size: contain;
+	background-image: url('../resources/16px/multiSelect_white.svg');
+}
+
+.ebIcon_multiSort {
+	background-image: url('../resources/16px/multi-sort.svg');
+}
+
+.ebIcon_multiSort_white {
+	background-image: url('../resources/16px/multi-sort_white.svg');
+}
+
+.ebIcon_sort {
+	background-image: url('../resources/16px/sort.svg');
+}
+
+.ebIcon_sort_white {
+	background-image: url('../resources/16px/sort_white.svg');
+}
+
+.ebIcon_stop {
+	background-image: url('../resources/16px/stop_black_16px.svg');
+}
+
+.ebIcon_pause {
+	background-image: url('../resources/16px/pause_black_16px.svg');
+}
+
+.ebIcon_suspend {
+	background-image: url('../resources/16px/suspend_black_16px.svg');
+}
+
+.ebIcon_resume {
+	background-image: url('../resources/16px/resume_black_16px.svg');
+}
+
+.ebIcon_play {
+	background-image: url('../resources/16px/play_black_16px.svg');
+}
+
+.ebIcon_fastForward {
+	background-image: url('../resources/16px/fastForward_black_16px.svg');
+}
+
+.ebIcon_fastRewind {
+	background-image: url('../resources/16px/fastRewind_black_16px.svg');
+}
+
+.ebIcon_print {
+	background-image: url('../resources/16px/print_black_16px.svg');
+}
+
+.ebIcon_print_white {
+	background-image: url('../resources/16px/print_white_16px.svg');
+}
+
+.ebIcon_calendar {
+	background-image: url('../resources/16px/calendar_black_16px.svg');
+}
+
+.ebIcon_calendar_white {
+	background-image: url('../resources/16px/calendar_white_16px.svg');
+}
+
+.ebIcon_addToFolder {
+	background-image: url('../resources/16px/addToFolder_black.svg');
+}
+
+.ebIcon_addToFolder_white {
+	background-image: url('../resources/16px/addToFolder_white.svg');
+}
+
+.ebIcon_alarmCleared {
+	background-image: url('../resources/16px/alarmCleared_16px.svg');
+}
+
+.ebIcon_alarmCleared_white {
+	background-image: url('../resources/16px/alarmCleared_white_16px.svg');
+}
+
+.ebIcon_alarmCritical {
+	background-image: url('../resources/16px/alarmCritical_16px.svg');
+}
+
+.ebIcon_alarmCritical_white {
+	background-image: url('../resources/16px/alarmCritical_white_16px.svg');
+}
+
+.ebIcon_alarmHeartbeat {
+	background-image: url('../resources/16px/alarmHeartbeat_16px.svg');
+}
+
+.ebIcon_alarmIndeterminate {
+	background-image: url('../resources/16px/alarmIndeterminate_16px.svg');
+}
+
+.ebIcon_alarmIndeterminate_white {
+	background-image:
+		url('../resources/16px/alarmIndeterminate_white_16px.svg');
+}
+
+.ebIcon_alarmMajor {
+	background-image: url('../resources/16px/alarmMajor_16px.svg');
+}
+
+.ebIcon_alarmMajor_white {
+	background-image: url('../resources/16px/alarmMajor_white_16px.svg');
+}
+
+.ebIcon_alarmMinor {
+	background-image: url('../resources/16px/alarmMinor_16px.svg');
+}
+
+.ebIcon_alarmMinor_white {
+	background-image: url('../resources/16px/alarmMinor_white_16px.svg');
+}
+
+.ebIcon_alarmWarning {
+	background-image: url('../resources/16px/alarmWarning_16px.svg');
+}
+
+.ebIcon_alarmWarning_white {
+	background-image: url('../resources/16px/alarmWarning_white_16px.svg');
+}
+
+.ebIcon_alarmOtherGrouping {
+	background-image: url('../resources/16px/alarmOtherGrouping_16px.svg');
+}
+
+.ebIcon_alarmUnacknowledged {
+	background-image: url('../resources/16px/alarmUnacknowledged.svg');
+}
+
+.ebIcon_alarmUnacknowledged_white {
+	background-image: url('../resources/16px/alarmUnacknowledged_white.svg');
+}
+
+.ebIcon_alarmUnspecified {
+	background-image: url('../resources/16px/alarmUnspecified_16px.svg');
+}
+
+.ebIcon_acknowledgeAlarm {
+	background-image: url('../resources/16px/acknowledgeAlarm.svg');
+}
+
+.ebIcon_acknowledgeAlarm_white {
+	background-image: url('../resources/16px/acknowledgeAlarm_white.svg');
+}
+
+.ebIcon_clearAlarm {
+	background-image: url('../resources/16px/clearAlarm.svg');
+}
+
+.ebIcon_clearAlarm_white {
+	background-image: url('../resources/16px/clearAlarm_white.svg');
+}
+
+.ebIcon_bsc {
+	background-image: url('../resources/16px/BSC_black_16px.svg');
+}
+
+.ebIcon_bscYellow {
+	background-image: url('../resources/16px/BSC_Yellow_16px.svg');
+}
+
+.ebIcon_bscFunction {
+	background-image: url('../resources/16px/BSCFunction_black_16px.svg');
+}
+
+.ebIcon_bscFunctionYellow {
+	background-image: url('../resources/16px/BSCFunction_Yellow_16px.svg');
+}
+
+.ebIcon_cabinet {
+	background-image: url('../resources/16px/cabinet_black_16px.svg');
+}
+
+.ebIcon_cellGray {
+	background-image: url('../resources/16px/cell_gray_16px.svg');
+}
+
+.ebIcon_cellGreen {
+	background-image: url('../resources/16px/cell_green_16px.svg');
+}
+
+.ebIcon_cellRed {
+	background-image: url('../resources/16px/cell_red_16px.svg');
+}
+
+.ebIcon_cellAdjacent {
+	background-image: url('../resources/16px/cellAdjacent_16px.svg');
+}
+
+.ebIcon_cellExternal {
+	background-image: url('../resources/16px/cellExternal_16px.svg');
+}
+
+.ebIcon_charging {
+	background-image: url('../resources/16px/charging_black.svg');
+}
+
+.ebIcon_charging_white {
+	background-size: contain;
+	background-image: url('../resources/16px/charging_white.svg');
+}
+
+.ebIcon_connected {
+	background-image: url('../resources/16px/connected_black_16px.svg');
+}
+
+.ebIcon_disconnected {
+	background-image: url('../resources/16px/disconnected_black_16px.svg');
+}
+
+.ebIcon_connectionError {
+	background-image:
+		url('../resources/16px/connectionError_black_16px.svg');
+}
+
+.ebIcon_core {
+	background-image: url('../resources/16px/core_black_16px.svg');
+}
+
+.ebIcon_coreSubscriber {
+	background-image: url('../resources/16px/coreSubscriber_black_16px.svg');
+}
+
+.ebIcon_database {
+	background-image: url('../resources/16px/database_black_16px.svg');
+}
+
+.ebIcon_ftpServer {
+	background-image: url('../resources/16px/ftpServer_black_16px.svg');
+}
+
+.ebIcon_ftpServerFunction {
+	background-image:
+		url('../resources/16px/ftpServerFunction_black_16px.svg');
+}
+
+.ebIcon_gatewayFunction {
+	background-image:
+		url('../resources/16px/gatewayFunction_black_16px.svg');
+}
+
+.ebIcon_grabHandle {
+	background-image: url('../resources/16px/grabHandle_black_16px.svg');
+}
+
+.ebIcon_grabHandle_white {
+	background-size: contain;
+	background-image: url('../resources/16px/grabHandle_white.svg');
+}
+
+.ebIcon_managedFunction {
+	background-image:
+		url('../resources/16px/managedFunction_black_16px.svg');
+}
+
+.ebIcon_managedGroup {
+	background-image: url('../resources/16px/managedGroup_black_16px.svg');
+}
+
+.ebIcon_managementNode {
+	background-image: url('../resources/16px/managementNode_black_16px.svg');
+}
+
+.ebIcon_network {
+	background-image: url('../resources/16px/network_black_16px.svg');
+}
+
+.ebIcon_networkElement {
+	background-image: url('../resources/16px/networkElement_black_16px.svg');
+}
+
+.ebIcon_networkElement_white {
+	background-image: url('../resources/16px/networkElement_white_16px.svg');
+}
+
+.ebIcon_rbs {
+	background-image: url('../resources/16px/RBS_black_16px.svg');
+}
+
+.ebIcon_rbs_white {
+	background-image: url('../resources/16px/RBS_white_16px.svg');
+}
+
+.ebIcon_routeSwitch {
+	background-image: url('../resources/16px/routeSwitch.svg');
+}
+
+.ebIcon_rxi {
+	background-image: url('../resources/16px/rxi_black_16px.svg');
+}
+
+.ebIcon_switchFunction {
+	background-image: url('../resources/16px/switchFunction_black_16px.svg');
+}
+
+.ebIcon_technicianPresent {
+	background-image: url('../resources/16px/technicianPresent_16px.svg');
+}
+
+.ebIcon_terminal {
+	background-image: url('../resources/16px/terminal_black_16px.svg');
+}
+
+.ebIcon_topology {
+	background-image: url('../resources/16px/topology_black_16px.svg');
+}
+
+.ebIcon_access {
+	background-image: url('../resources/16px/access_black_16px.svg');
+}
+
+.ebIcon_access_white {
+	background-image: url('../resources/16px/access_white_16px.svg');
+}
+
+.ebIcon_accessSettings {
+	background-image: url('../resources/16px/accessSettings_black_16px.svg');
+}
+
+.ebIcon_accessSettings_white {
+	background-image: url('../resources/16px/accessSettings_white_16px.svg');
+}
+
+.ebIcon_alignCenter {
+	background-image: url('../resources/16px/alignCenter_black_16px.svg');
+}
+
+.ebIcon_alignCenter_white {
+	background-image: url('../resources/16px/alignCenter_white.svg');
+}
+
+.ebIcon_alignLeft {
+	background-image: url('../resources/16px/alignLeft_black_16px.svg');
+}
+
+.ebIcon_alignLeft_white {
+	background-image: url('../resources/16px/alignLeft_white.svg');
+}
+
+.ebIcon_alignRight {
+	background-image: url('../resources/16px/alignRight_black_16px.svg');
+}
+
+.ebIcon_alignRight_white {
+	background-image: url('../resources/16px/alignRight_white.svg');
+}
+
+.ebIcon_cli {
+	background-image:
+		url('../resources/16px/CommandLineInterface_black_16px.svg');
+}
+
+.ebIcon_cli_white {
+	background-image:
+		url('../resources/16px/CommandLineInterface_white_16px.svg');
+}
+
+.ebIcon_controllingNode {
+	background-image: url('../resources/16px/controllingNode.svg');
+}
+
+.ebIcon_grid3x3 {
+	background-image: url('../resources/16px/grid3X3_black_16px.svg');
+}
+
+.ebIcon_grid3x3_white {
+	background-image: url('../resources/16px/grid3x3_white.svg');
+}
+
+.ebIcon_grid4x4 {
+	background-image: url('../resources/16px/grid4X4_black_16px.svg');
+}
+
+.ebIcon_grid4x4_white {
+	background-image: url('../resources/16px/grid4x4_white.svg');
+}
+
+.ebIcon_gridView {
+	background-image: url('../resources/16px/gridView_black_16px.svg');
+}
+
+.ebIcon_gridView_white {
+	background-image: url('../resources/16px/gridView_white.svg');
+}
+
+.ebIcon_jumpTo {
+	background-image: url('../resources/16px/jumpTo_black_16px.svg');
+}
+
+.ebIcon_microwave {
+	background-image: url('../resources/16px/microwave.svg');
+}
+
+.ebIcon_mo {
+	background-image: url('../resources/16px/mo.svg');
+}
+
+.ebIcon_security {
+	background-image: url('../resources/16px/security_black_16px.svg');
+}
+
+.ebIcon_security_white {
+	background-image: url('../resources/16px/security_white_16px.svg');
+}
+
+.ebIcon_site {
+	background-image: url('../resources/16px/site_black_16px.svg');
+}
+
+.ebIcon_siteManager {
+	background-image: url('../resources/16px/siteManager_black_16px.svg');
+}
+
+.ebIcon_subnetwork {
+	background-image: url('../resources/16px/subnetwork.svg');
+}
+
+.ebIcon_gateway, .ebIcon_switch {
+	background-image: url('../resources/16px/switch.svg');
+}
+
+.ebIcon_tip {
+	background-image: url('../resources/16px/tip_black_16px.svg');
+}
+
+.ebIcon_tip_white {
+	background-image: url('../resources/16px/tip_white_16px.svg');
+}
+
+.ebIcon_attach {
+	background-image: url('../resources/16px/attach_black_16px.svg');
+}
+
+.ebIcon_attach_white {
+	background-size: contain;
+	background-image: url('../resources/16px/attach_white.svg');
+}
+
+.ebIcon_clock {
+	background-image: url('../resources/16px/clock_black_16px.svg');
+}
+
+.ebIcon_clock_white {
+	background-image: url('../resources/16px/clock_white_16px.svg');
+}
+
+.ebIcon_windowMaximize {
+	background-image: url('../resources/16px/WindowMaximize_black_16px.svg');
+}
+
+.ebIcon_windowMinimize {
+	background-image: url('../resources/16px/WindowMinimize_black_16px.svg');
+}
+
+.ebIcon_deprecated {
+	background-image: url('../resources/16px/deprecated_16px.svg');
+}
+
+.ebIcon_obsolete {
+	background-image: url('../resources/16px/obsolete_16px.svg');
+}
+
+.ebIcon_newStatus_blue {
+	background-image: url('../resources/16px/newStatus_blue_16px.svg');
+}
+
+.ebIcon_newStatus_green {
+	background-image: url('../resources/16px/newStatus_green_16px.svg');
+}
+
+.ebIcon_upload {
+	background-image: url('../resources/16px/upload_black_16px.svg');
+}
+
+.ebIcon_activate {
+	background-image: url('../resources/16px/activate_black_16px.svg');
+}
+
+.ebIcon_activate_white {
+	background-size: contain;
+	background-image: url('../resources/16px/activate_white.svg');
+}
+
+.ebIcon_deactivate {
+	background-image: url('../resources/16px/deactivate_black_16px.svg');
+}
+
+.ebIcon_deactivate_white {
+	background-size: contain;
+	background-image: url('../resources/16px/deactivate_white.svg');
+}
+
+.ebIcon_switchBetween {
+	background-image: url('../resources/16px/switchBetween_black_16px.svg');
+}
+
+.ebIcon_switchBetween_white {
+	background-image: url('../resources/16px/switchBetween_white_16px.svg');
+}
+
+.ebIcon_eye {
+	background-image: url('../resources/16px/eye_black_16px.svg');
+}
+
+.ebIcon_eye_white {
+	background-image: url('../resources/16px/eye_white_16px.svg');
+}
+
+.ebIcon_eyeLine {
+	background-image: url('../resources/16px/eyeLine_black_16px.svg');
+}
+
+.ebIcon_eyeLine_white {
+	background-image: url('../resources/16px/eyeLine_white.svg');
+}
+
+.ebIcon_activityTray {
+	background-image: url('../resources/16px/activity_16px_black.svg');
+}
+
+.ebIcon_note {
+	background-image: url('../resources/16px/note_black_16px.svg');
+	background-size: contain;
+}
+
+.ebIcon_note_white {
+	background-image: url('../resources/16px/note_white_16px.svg');
+}
+
+.ebIcon_tableView {
+	background-image: url('../resources/16px/tableView_black_16px.svg');
+}
+
+.ebIcon_tableView_white {
+	background-image: url('../resources/16px/tableView_white_16px.svg');
+}
+
+.ebIcon_synced {
+	background-image: url('../resources/16px/Syncd_16px.svg');
+}
+
+.ebIcon_syncError {
+	background-image: url('../resources/16px/SyncError_16px.svg');
+}
+
+.ebIcon_syncing {
+	background-image: url('../resources/16px/Syncing_Static_16px.svg');
+}
+
+.ebIcon_syncing_animated {
+	background-image: url('../resources/16px/Syncing_Animated_16px.svg');
+}
+
+/* Breadcrumb */
+.ebBreadcrumbs {
+	position: relative;
+	display: block;
+	font-size: 0;
+	margin-top: 12px;
+	margin-bottom: 4px;
+}
+
+.ebBreadcrumbs-link {
+	font-size: 1.2rem;
+	vertical-align: middle;
+	display: inline-block
+}
+
+.ebBreadcrumbs-list {
+	position: absolute;
+	left: 0;
+	margin-top: 6px;
+	display: none;
+	min-width: calc(100% - 16px);
+	max-width: 250px;
+	z-index: 1500
+}
+
+.ebBreadcrumbs-arrow {
+	margin-left: .6rem;
+	vertical-align: middle;
+	outline: none;
+	display: inline-block;
+	line-height: 12px
+}
+
+.ebBreadcrumbs-arrow:focus>* {
+	opacity: 1
+}
+
+.ebBreadcrumbs-arrow_hidden {
+	display: none
+}
+
+.ebBreadcrumbs-arrow:focus+.ebBreadcrumbs-list {
+	display: block
+}
+
+.ebBreadcrumbs-item {
+	position: relative;
+	font-size: 0;
+	white-space: nowrap;
+	display: inline-block;
+	margin-bottom: .8rem
+}
+
+.ebBreadcrumbs-item:after {
+	vertical-align: middle;
+	display: inline-block;
+	width: 20px;
+	content: "/";
+	font-size: 1.6rem;
+	text-align: center;
+	color: #999;
+	cursor: default !important;
+	pointer-events: none !important;
+	-ms-touch-action: none !important;
+	touch-action: none !important;
+	-khtml-user-select: none !important;
+	-moz-user-select: none !important;
+	-o-user-select: none !important;
+	-webkit-user-select: none !important;
+	user-select: none
+}
+
+.ebBreadcrumbs-item:last-child {
+	margin-right: 0
+}
+
+.ebBreadcrumbs-item:last-child>.ebBreadcrumbs-link {
+	-ms-touch-action: none !important;
+	touch-action: none !important;
+	-khtml-user-select: none !important;
+	-moz-user-select: none !important;
+	-o-user-select: none !important;
+	-webkit-user-select: none !important;
+	user-select: none
+}
+
+.ebBreadcrumbs-item:last-child:after {
+	content: "";
+	padding: 0;
+	font-size: 0;
+	width: 0;
+}
+
+.ebBreadcrumbs a {
+	font-size: 1.2rem;
+	color: #0066b3;
+	text-decoration: none;
+}
+
+.ebBreadcrumbs a:hover {
+	text-decoration: underline;
+	outline: none;
+}
+
+.ebBreadcrumbs a:active {
+	text-decoration: underline
+}
+
+.ebBreadcrumbs a:focus {
+	outline: none;
+	text-decoration: underline;
+	box-shadow: none;
+}
\ No newline at end of file
diff --git a/client/client-monitoring/src/main/resources/webapp/css/styles.css b/client/client-monitoring/src/main/resources/webapp/css/styles.css
new file mode 100644
index 0000000..fcb78fb
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/css/styles.css
@@ -0,0 +1,441 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+.ebSystemBar-config {
+	position: absolute;
+	top: 0;
+	bottom: 0;
+	right: 0;
+	height: 40px;
+	width: 20px;
+	padding: 0 10px;
+	background: url('../resources/16px/settings_black_16px.svg') no-repeat
+		center center transparent;
+	background-size: 20px;
+	cursor: pointer;
+}
+
+.content {
+	display: none;
+	padding: 10px;
+}
+
+.context {
+	margin-left: 5px;
+}
+
+.wrapper {
+	border: 1px dashed #ddd;
+	box-shadow: 0 0 0 3px #fff, 0 0 0 5px #ddd, 0 0 0 10px #fff, 0 0 2px
+		10px #eee;
+	padding: 10px;
+	margin: 10px;
+	min-width: 1287px;
+}
+
+.wrapper_borderless {
+	margin-left: 5px;
+	min-width: 1287px;
+}
+
+.engineService {
+	margin-left: 5px;
+	padding-bottom: 10px;
+}
+
+.apexDialogDiv {
+	background-color: white;
+	position: fixed;
+	top: 50%;
+	left: 50%;
+	transform: translate(-50%, -50%);
+	min-width: 310px;
+	min-height: 140px;
+	resize: both;
+	overflow: auto;
+	padding: 10px 10px 10px 10px;
+	border: 1px solid #c0c0c0;
+	border-radius: 3px;
+	box-shadow: 3px 7px 5px #555555;
+}
+
+.apexDialogDiv {
+	background-color: white;
+	position: fixed;
+	top: 50%;
+	left: 50%;
+	transform: translate(-50%, -50%);
+	min-width: 310px;
+	min-height: 140px;
+	resize: both;
+	overflow: auto;
+	padding: 10px 10px 10px 10px;
+	border: 1px solid #c0c0c0;
+	border-radius: 3px;
+	box-shadow: 3px 7px 5px #555555;
+}
+
+.apexErrorDialogDiv {
+	max-width: 80%;
+	max-height: 80%;
+	overflow: hidden;
+}
+
+/* Dialog */
+.apexDialogDiv .headingSpan {
+	width: 100%;
+	height: 30px;
+	display: inline-block;
+	text-align: center;
+	font-weight: bold;
+	font-size: 20px;
+	padding: 5px 0px 0px 0px;
+	border-bottom: #c0c0c0 solid 1px;
+}
+
+.apexDialogDivBackground {
+	position: fixed;
+	height: 100%;
+	width: 100%;
+	background-color: rgba(0, 0, 0, 0.5);
+	top: 0px;
+	left: 0px;
+}
+
+.dialogMessage {
+	white-space: pre-wrap;
+	font: 14px "Lucida Sans Unicode", "Lucida Grande", sans-serif;
+	overflow-y: auto;
+	max-height: 480px;
+	overflow-x: hidden;
+	word-wrap: break-word;
+}
+
+/* Form */
+.resultFormDiv .form-style-1 .field-textarea {
+	height: 480px;
+	font-size: 15px;
+}
+
+.form-style-1 {
+	margin: 10px auto;
+	font: 16px "Lucida Sans Unicode", "Lucida Grande", sans-serif;
+}
+
+.form-style-1 li {
+	padding: 0;
+	display: block;
+	list-style: none;
+	margin: 10px 0 0 0;
+}
+
+.form-style-1 label {
+	margin: 0 0 3px 0;
+	padding: 0px;
+	display: block;
+	font-weight: bold;
+}
+
+.form-style-1 input[type=text], .form-style-1 input[type=date],
+	.form-style-1 input[type=datetime], .form-style-1 input[type=number],
+	.form-style-1 input[type=search], .form-style-1 input[type=time],
+	.form-style-1 input[type=url], .form-style-1 input[type=email],
+	textarea, select {
+	box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+	-moz-box-sizing: border-box;
+	border: 1px solid #BEBEBE;
+	padding: 0px 7px;
+	margin: 0px;
+	-webkit-transition: all 0.30s ease-in-out;
+	-moz-transition: all 0.30s ease-in-out;
+	-ms-transition: all 0.30s ease-in-out;
+	-o-transition: all 0.30s ease-in-out;
+	outline: none;
+}
+
+.form-style-1 input[type=text]:focus, .form-style-1 input[type=date]:focus,
+	.form-style-1 input[type=datetime]:focus, .form-style-1 input[type=number]:focus,
+	.form-style-1 input[type=search]:focus, .form-style-1 input[type=time]:focus,
+	.form-style-1 input[type=url]:focus, .form-style-1 input[type=email]:focus,
+	.form-style-1 textarea:focus, .form-style-1 select:focus {
+	-moz-box-shadow: 0 0 8px #88D5E9;
+	-webkit-box-shadow: 0 0 8px #88D5E9;
+	box-shadow: 0 0 8px #88D5E9;
+	border: 1px solid #88D5E9;
+}
+
+.form-style-1 input:focus::-webkit-input-placeholder {
+	color: transparent;
+}
+
+.form-style-1 input:focus:-moz-placeholder {
+	color: transparent;
+}
+
+.form-style-1 .field {
+	font-size: 15px;
+}
+
+.form-style-1 .field-divided {
+	width: 49%;
+	font-size: 15px;
+}
+
+.form-style-1 .field-long {
+	width: 100%;
+	font-size: 15px;
+}
+
+.form-style-1 .field-medium {
+	width: 50%;
+	font-size: 15px;
+}
+
+.form-style-1 .field-select {
+	width: 100%;
+	font-size: 15px;
+}
+
+.form-style-1 .field-textarea {
+	height: 100px;
+	font-size: 15px;
+}
+
+.form-style-1 .field-javaType {
+	width: 100%;
+	font-size: 15px;
+}
+
+.form-style-1 .field-schemaFlavour {
+	width: 100%;
+	font-size: 15px;
+}
+
+.form-style-1 .field-taskSelLogic {
+	width: 100%;
+	font-size: 15px;
+	height: 300px;
+}
+
+.form-style-1 .field-taskLogic {
+	width: 100%;
+	font-size: 15px;
+	height: 300px;
+}
+
+.form-style-1 .field-finalizerLogic {
+	width: 100%;
+	font-size: 15px;
+	height: 300px;
+}
+
+.form-style-1 .field-schemaDefinition {
+	width: 100%;
+	font-size: 15px;
+	height: 100px;
+}
+
+.form-style-1 .required {
+	color: red;
+}
+
+.form-style-1 .button {
+	font-size: 15px;
+}
+
+.form-style-1 .delete_ex {
+	height: 30px;
+	width: 30px;
+	opacity: 1;
+	font-size: 30px;
+	line-height: 30px;
+	transition: all 0.8s;
+	border: 1px solid transparent;
+	text-align: center;
+}
+
+.form-style-1 .delete_ex:hover {
+	border-radius: 50%;
+	background: tomato;
+	border: 1px solid black;
+}
+
+.form-style-1 .delete_ex_disabled {
+	width: 0px;
+	opacity: 0;
+}
+
+/* Icons */
+.expandIcon {
+	float: right;
+}
+
+.ignoreConflictsLabel {
+	font-size: 1.4rem;
+	padding-right: 15px;
+}
+
+#engineServicesTable_periodic_events {
+	align-items: center;
+	display: flex;
+	height: 30px;
+}
+
+.modelLoading {
+	margin-left: 5px;
+	display: none;
+}
+
+.layoutWrapper {
+	margin: 0 40px;
+}
+
+.appHeading {
+	color: rgb(51, 51, 51);
+	display: block;
+	font-family: Arial, Helvetica, sans-serif;
+	font-size: 12px;
+	height: 32px;
+	line-height: 12px;
+	position: relative;
+}
+
+.ebQuickActionBar {
+	margin-top: 1.2rem;
+	font-size: 0;
+	height: 32px;
+	padding: 0.4rem 0;
+	background-color: #e8e8e8;
+	position: relative;
+	width: 100%;
+	overflow: hidden;
+	line-height: 0;
+	box-sizing: border-box;
+	-webkit-transition: background-color 0.1s ease-in;
+	transition: background-color 0.1s ease-in;
+	-webkit-border-radius: 3px;
+	-moz-border-radius: 3px;
+	-ms-border-radius: 3px;
+	border-radius: 3px;
+}
+
+.ebQuickActionBar_context {
+	background-color: #f3f3f3;
+	border-bottom: 2px solid #65cbe5;
+	box-sizing: border-box;
+	height: 32px;
+}
+
+.ebQuickActionBar>* {
+	margin-left: 0.4rem;
+	margin-right: 0.4rem;
+	vertical-align: middle;
+}
+
+.ebQuickActionBar-iconHolder {
+	display: inline-block;
+	vertical-align: middle;
+	height: 1.6rem;
+}
+
+.ebQuickActionBar-separator {
+	display: inline-block;
+	vertical-align: middle;
+	border-left: 1px solid #CCCCCC;
+	margin: 0 8px;
+	height: 2.4rem;
+}
+
+.ebQuickActionBar-Commands, .ebQuickActionBar-commands {
+	display: inline-block;
+	margin: 0;
+	font-size: 0;
+	line-height: 2.4rem;
+}
+
+.ebQuickActionBar-Commands-iconHolder,
+	.ebQuickActionBar-commands-iconHolder {
+	display: inline-block;
+	vertical-align: middle;
+	height: 1.6rem;
+}
+
+.ebQuickActionBar-Commands-separator,
+	.ebQuickActionBar-commands-separator {
+	display: inline-block;
+	vertical-align: middle;
+	border-left: 1px solid #CCCCCC;
+	margin: 0 8px;
+	height: 2.4rem;
+}
+
+.ebQuickActionBar-Commands>*, .ebQuickActionBar-commands>* {
+	margin-left: 0.4rem;
+	margin-right: 0.4rem;
+	vertical-align: middle;
+}
+
+.ebQuickActionBar-Commands-block, .ebQuickActionBar-commands-block,
+	.ebQuickActionBar-CommandsBlock, .ebQuickActionBar-commandsBlock {
+	margin: 0 0.8rem;
+	display: inline-block;
+}
+
+.ebQuickActionBar-Commands-block>*, .ebQuickActionBar-commands-block>*,
+	.ebQuickActionBar-CommandsBlock>*, .ebQuickActionBar-commandsBlock>* {
+	margin-left: 0.4rem;
+	margin-right: 0.4rem;
+	vertical-align: middle;
+}
+
+.ebQuickActionBar-Commands-block :last-child,
+	.ebQuickActionBar-commands-block :last-child,
+	.ebQuickActionBar-CommandsBlock :last-child,
+	.ebQuickActionBar-commandsBlock :last-child {
+	margin-right: 0;
+}
+
+.title {
+	padding: 0px;
+}
+
+.dataTd {
+	max-width: 1000px;
+	word-wrap: break-word;
+	white-space: normal !important;
+}
+
+.dataTd_wordwrap {
+	max-width: 1000px;
+	word-wrap: break-word;
+	white-space: pre-wrap !important;
+}
+
+.engineContextTitle {
+	padding: 1.2rem 0 .7rem 0;
+	font-weight: normal;
+}
+
+.engineContextWrapper {
+	display: inline-block;
+	float: left;
+	padding-right: 10px;
+	padding-bottom: 10px;
+}
\ No newline at end of file
diff --git a/client/client-monitoring/src/main/resources/webapp/index.html b/client/client-monitoring/src/main/resources/webapp/index.html
new file mode 100644
index 0000000..bd5ce0f
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/index.html
@@ -0,0 +1,103 @@
+<!--
+  ============LICENSE_START=======================================================
+   Copyright (C) 2016-2018 Ericsson. All rights reserved.
+  ================================================================================
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  
+  SPDX-License-Identifier: Apache-2.0
+  ============LICENSE_END=========================================================
+-->
+
+<html>
+<head>
+<meta charset="UTF-8">
+
+<title>Apex Deployment and Monitoring</title>
+
+<!-- interface style -->
+<link rel="stylesheet" type="text/css" href="css/interfaceAssets.css">
+<!-- ApexChartLib style -->
+<link rel="stylesheet" type="text/css" href="css/apexChartLib.css">
+<!-- Apex services client style -->
+<link rel="stylesheet" type="text/css" href="css/styles.css">
+
+<script type="text/javascript" src="js/ApexUtils.js"></script>
+
+</head>
+
+<body>
+
+	<!-- interface styled System Bar -->
+	<div class="ebSystemBar">
+		<div class="ebSystemBar-topMenuName">Apex</div>
+		<div class="ebSystemBar-config"></div>
+	</div>
+
+	<div class="layoutWrapper">
+
+		<div class="ebBreadcrumbs">
+			<div class="ebBreadcrumbs-item">
+				<a href="javascript:getHomepageURL();" class="ebBreadcrumbs-link">Apex</a>
+			</div>
+			<div class="ebBreadcrumbs-item">
+				<a href="" class="ebBreadcrumbs-link">Monitoring</a>
+			</div>
+		</div>
+
+		<div class="appHeading">
+			<h1 class="title">Apex Monitoring</h1>
+		</div>
+
+		<div class="search ebQuickActionBar"></div>
+
+		<!-- Main content div -->
+		<div id="content" class="content">
+			<!-- Engine Service -->
+			<h2>Engine Service</h2>
+			<div class="engineService"></div>
+
+			<!-- Apex Engine Summary -->
+			<h2>Apex Engine Service aggregated status</h2>
+			<div class="engineSummary"></div>
+
+			<!-- Apex Engine Status -->
+			<h2>Apex Engine status per engine</h2>
+			<div class="engineStatus"></div>
+
+			<!-- Apex Context -->
+			<h2>Apex Context</h2>
+			<div class="context"></div>
+		</div>
+	</div>
+
+	<!-- jQuery -->
+	<script src="js/jquery/jquery-1.12.4.js"></script>
+
+	<!-- D3 -->
+	<script type="text/javascript" src="js/d3/d3.min.js"></script>
+
+	<!-- AVCS -->
+	<script type="text/javascript" src="js/avsc/avsc.js"></script>
+
+	<!-- Apex services client JS files -->
+	<script type="text/javascript" src="js/ApexAjax.js"></script>
+	<script type="text/javascript" src="js/ApexTable.js"></script>
+	<script type="text/javascript" src="js/ApexChart.js"></script>
+	<script type="text/javascript" src="js/ApexEngineService.js"></script>
+	<script type="text/javascript" src="js/ApexEngineSummary.js"></script>
+	<script type="text/javascript" src="js/ApexEngineStatus.js"></script>
+	<script type="text/javascript" src="js/ApexContext.js"></script>
+	<script type="text/javascript" src="js/ApexServicesMain.js"></script>
+
+</body>
+</html>
diff --git a/client/client-monitoring/src/main/resources/webapp/js/ApexAjax.js b/client/client-monitoring/src/main/resources/webapp/js/ApexAjax.js
new file mode 100644
index 0000000..e62489f
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/js/ApexAjax.js
@@ -0,0 +1,89 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * Send a GET request
+ */
+function ajax_get(requestURL, callback, hostName, port, params, errorCallback) {
+	var data = {
+		hostName : hostName,
+		port : port
+	};
+	for ( var p in params) {
+		data[p] = params[p];
+	}
+	return $
+			.ajax({
+				type : 'GET',
+				url : requestURL,
+				dataType : "json",
+				data : data,
+				success : function(data, textStatus, jqXHR) {
+					if (callback) {
+						callback(data);
+					}
+				},
+				error : function(jqXHR, textStatus, errorThrown) {
+					if (jqXHR.status == 500 || jqXHR.status == 404) {
+						if (jqXHR.responseText
+								.indexOf("cound not handshake with server") !== -1
+								|| jqXHR.status == 404) {
+							clearEngineURL();
+							getEngineURL(jqXHR.responseText);
+						} else {
+							apexErrorDialog_activate(document.body,
+									jqXHR.responseText);
+						}
+					}
+					if (errorCallback) {
+						errorCallback(jqXHR, textStatus, errorThrown);
+					}
+				}
+			});
+}
+
+/*
+ * Send a POST request and add a file to its payload
+ */
+function ajax_upload(requestURL, callback, hostName, port, fileUrl,
+		ignoreConflicts, forceUpdate) {
+	var formData = new FormData();
+	formData.append("hostName", hostName);
+	formData.append("port", port);
+	formData.append("file", fileUrl);
+	formData.append("ignoreConflicts", ignoreConflicts);
+	formData.append("forceUpdate", forceUpdate);
+	return $.ajax({
+		url : requestURL,
+		type : "POST",
+		contentType : false,
+		dataType : "text",
+		processData : false,
+		data : formData,
+		success : function(data, textStatus, jqXHR) {
+			callback(data);
+		},
+		error : function(jqXHR, textStatus, errorThrown) {
+			if (jqXHR.status == 500) {
+				apexErrorDialog_activate(document.body, jqXHR.responseText);
+			}
+		}
+	});
+}
diff --git a/client/client-monitoring/src/main/resources/webapp/js/ApexChart.js b/client/client-monitoring/src/main/resources/webapp/js/ApexChart.js
new file mode 100644
index 0000000..438a3e5
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/js/ApexChart.js
@@ -0,0 +1,256 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * Create a chart and append it to a container
+ */
+function createChart(data, container, title, unit, lineStroke, nodeColour) {
+	// Set the dimensions of the canvas
+	var margin = {
+		top : 30,
+		right : 20,
+		bottom : 30,
+		left : 50
+	}, width = 600 - margin.left - margin.right, height = 270 - margin.top
+			- margin.bottom;
+
+	// Set the ranges
+	var x = d3.time.scale().range([ 0, width ]);
+	var y = d3.scale.linear().range([ height, 0 ]);
+
+	// Define the axes
+	var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(5).innerTickSize(
+			-height).outerTickSize(0).tickPadding(10);
+
+	var yAxis = d3.svg.axis().scale(y).orient("left").ticks(10).innerTickSize(
+			-width).outerTickSize(0).tickPadding(10);
+
+	// Define the line
+	var valueline = d3.svg.line().x(function(d) {
+		return x(d.timestamp);
+	}).y(function(d) {
+		return y(d.value);
+	});
+
+	// Add the svg canvas to the container
+	var svg = d3.select(container).append("svg").attr("preserveAspectRatio",
+			"xMinYMin meet").attr("viewBox", "0 0 600 400").classed(
+			"svg-content-responsive", true).append("g").attr("transform",
+			"translate(" + margin.left + "," + margin.top + ")");
+
+	// Set the unit for the value
+	svg.attr("unit", unit);
+
+	// Format the data for the chart
+	data.forEach(function(d) {
+		d.timestamp = d.timestamp;
+		d.value = +d.value;
+	});
+
+	// Scale the range of the data
+	x.domain(d3.extent(data, function(d) {
+		return d.timestamp;
+	}));
+	y.domain([ 0, d3.max(data, function(d) {
+		return Math.ceil((d.value + 1) / 10) * 10;
+	}) ]);
+
+	// Set the colour of the line
+	if (!lineStroke) {
+		lineStroke = "#5fbadd"
+	}
+
+	// Set the colour of the circles
+	if (!nodeColour) {
+		nodeColour = "#00A9D4"
+	}
+
+	// Add the valueline path
+	svg.append("path").attr("class", "line").data(data).attr("unit", unit)
+			.attr("stroke", lineStroke).attr("d", valueline(data));
+
+	// Add the scatterplot
+	svg.selectAll("circle").data(data).enter().append("circle").attr("r", 3.5)
+			.attr("class", "circle").attr("fill", nodeColour).attr("cx",
+					function(d) {
+						return x(d.timestamp);
+					}).attr("cy", function(d) {
+				return y(d.value);
+			})
+
+			// Apply the tooltip to each node
+			.on(
+					"mouseover",
+					function(d) {
+						d3.select("body").select(".tooltip").transition()
+								.duration(50).style("opacity", 1);
+						d3.select("body").select(".tooltip").html(
+								formatDate(new Date(d.timestamp)) + "<br/>"
+										+ d.value + (unit ? " " + unit : ""))
+								.style("left", (d3.event.pageX) + "px").style(
+										"top", (d3.event.pageY - 28) + "px");
+					}).on(
+					"mouseout",
+					function(d) {
+						d3.select("body").select(".tooltip").transition()
+								.duration(500).style("opacity", 0);
+					});
+
+	// Add the X Axis
+	svg.append("g").attr("class", "x axis").attr("transform",
+			"translate(0," + height + ")").call(xAxis);
+
+	// Add the Y Axis
+	svg.append("g").attr("class", "y axis").call(yAxis);
+
+	// Add the title
+	svg.append("text").attr("x", (width / 2)).attr("y", 0 - (margin.top / 2))
+			.attr("text-anchor", "middle").style("font-size", "16px").style(
+					"text-decoration", "underline").text(title);
+
+	// Add the background
+	svg.selectAll(".tick:not(:first-of-type) line").attr("stroke", "#777")
+			.attr("stroke-dasharray", "2,2");
+}
+
+/*
+ * Generates random chart data. Used when initializing the charts so that they
+ * are not empty on load
+ */
+function generateRandomData() {
+	var data = [];
+	for (var i = 0; i < 30; i++) {
+		data.push({
+			timestamp : new Date().getTime() - (i * 5000),
+			value : Math.floor(Math.random() * 100) + 1
+		});
+	}
+	return data;
+}
+
+/*
+ * Update a chart belonging to a specific container
+ */
+function updateChart(container, data, nodeColour) {
+	var margin = {
+		top : 30,
+		right : 20,
+		bottom : 30,
+		left : 50
+	}, width = 600 - margin.left - margin.right, height = 270 - margin.top
+			- margin.bottom;
+	var parseDate = d3.time.format("%d-%b-%y").parse;
+
+	// Format the data for the chart
+	data.forEach(function(d) {
+		d.timestamp = d.timestamp;
+		d.value = +d.value;
+	});
+
+	// Select the chart
+	var svg = d3.select(container);
+
+	// Set the ranges
+	var x = d3.time.scale().range([ 0, width ]);
+	var y = d3.scale.linear().range([ height, 0 ]);
+
+	// Define the axes
+	var xAxis = d3.svg.axis().scale(x).orient("bottom").ticks(5).innerTickSize(
+			-height).outerTickSize(0).tickPadding(10);
+
+	var yAxis = d3.svg.axis().scale(y).orient("left").ticks(10).innerTickSize(
+			-width).outerTickSize(0).tickPadding(10);
+
+	// Scale the range of the data
+	x.domain(d3.extent(data, function(d) {
+		return d.timestamp;
+	}));
+	y.domain([ 0, d3.max(data, function(d) {
+		return Math.ceil((d.value + 1) / 10) * 10;
+	}) ]);
+
+	// Update the valueline path
+	var valueline = d3.svg.line().x(function(d) {
+		return x(d.timestamp);
+	}).y(function(d) {
+		return y(d.value);
+	});
+
+	var unit = svg.select(".line").attr("unit");
+
+	// Remove all nodes
+	svg.selectAll("circle").remove();
+
+	// Set the node colour if one is passed in
+	if (!nodeColour) {
+		nodeColour = "#00A9D4"
+	}
+
+	// Make the changes
+	svg.select(".line").data(data) // change the line
+	.transition().duration(750).attr("d", valueline(data));
+	svg.select(".x.axis") // change the x axis
+	.transition().duration(750).call(xAxis.ticks(5));
+	svg.select(".y.axis") // change the y axis
+	.transition().duration(750).call(yAxis);
+
+	// Redraw the nodes based on the new data
+	svg.select("svg").select("g").selectAll("circle").data(data).enter()
+			.append("circle").attr("r", 3.5).attr("class", "circle").attr(
+					"fill", nodeColour).attr("cx", function(d) {
+				return x(d.timestamp);
+			}).attr("cy", function(d) {
+				return y(d.value);
+			})
+
+			// Apply the tooltip to each node
+			.on(
+					"mouseover",
+					function(d) {
+						d3.select("body").select(".tooltip").transition()
+								.duration(50).style("opacity", 1);
+						d3.select("body").select(".tooltip").html(
+								formatDate(new Date(d.timestamp)) + "<br/>"
+										+ d.value + (unit ? " " + unit : ""))
+								.style("left", (d3.event.pageX) + "px").style(
+										"top", (d3.event.pageY - 28) + "px");
+					}).on(
+					"mouseout",
+					function(d) {
+						d3.select("body").select(".tooltip").transition()
+								.duration(500).style("opacity", 0);
+					});
+
+}
+
+/*
+ * Initialize a singleton div used as a floating tooltip for all charts
+ */
+function initTooltip() {
+	d3.select("body").append("div").attr("class", "tooltip").attr("id",
+			"tooltip").style("opacity", 0);
+}
+
+/*
+ * Format a date object to string
+ */
+function formatDate(date) {
+	return date.toLocaleString().replace(',', '');
+}
\ No newline at end of file
diff --git a/client/client-monitoring/src/main/resources/webapp/js/ApexContext.js b/client/client-monitoring/src/main/resources/webapp/js/ApexContext.js
new file mode 100644
index 0000000..437d817
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/js/ApexContext.js
@@ -0,0 +1,94 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * Create a Context Table
+ */
+function createEngineContextTable(wrapper) {
+	var tableId = config.engineContext.tableId;
+	var headers = config.engineContext.headers.map(function(a) {
+		return a.title;
+	});
+	return createEngineTable($(wrapper), tableId, headers);
+}
+
+/*
+ * Update each Context Table with the latest data
+ */
+function setEngineContextData(engineContextData) {
+	var tableId = config.engineContext.tableId;
+	for ( var ecd in engineContextData) {
+		var id = tableId + "_" + engineContextData[ecd].id;
+		var existingTable = undefined;
+		for ( var ect in this.engineContextTables) {
+			if (id === this.engineContextTables[ect].getAttribute("id")) {
+				existingTable = this.engineContextTables[ect];
+			}
+		}
+		var engineInfo = JSON.parse(engineContextData[ecd].engine_info);
+		var contextAlbums = engineInfo.ContextAlbums;
+		var data = [];
+
+		for ( var ca in contextAlbums) {
+			var cAlbumn = contextAlbums[ca];
+			data.push([ cAlbumn.AlbumKey.name, cAlbumn.AlbumKey.version,
+					JSON.stringify(cAlbumn.AlbumContent, undefined, 50) ]);
+		}
+
+		var table = existingTable;
+		// If no table already exists for the context, add one
+		if (!table) {
+			var wrapper = document.createElement("div");
+			wrapper.setAttribute("class", "engineContextWrapper");
+			var title = document.createElement("div");
+			title.setAttribute("class", "engineContextTitle");
+			title.innerHTML = engineContextData[ecd].id;
+			$(wrapper).append(title);
+			$("." + config.engineContext.parent).append(wrapper);
+			table = createEngineContextTable(wrapper);
+			table.setAttribute("id", id);
+			table.style["margin-bottom"] = "10px";
+			this.engineContextTables.push(table);
+		}
+
+		var old_data = $(table).data(tableId);
+		if (!deepCompare(old_data, data)) {
+			$(table).find("tbody").remove();
+			var tbody = document.createElement("tbody");
+
+			for ( var d in data) {
+				var rowData = data[d];
+				var row = document.createElement("tr");
+				var rowContent = "<tr>";
+				for ( var rd in rowData) {
+					var tdClass = (rd == 2 ? "dataTd_wordwrap" : "dataTd");
+					rowContent += "<td class=" + tdClass + ">" + rowData[rd]
+							+ "</td>";
+				}
+				rowContent += "</tr>";
+				row.innerHTML = rowContent;
+				$(tbody).append(row);
+			}
+			$(table).data(tableId, data);
+			$(table).append(tbody);
+		}
+
+	}
+}
\ No newline at end of file
diff --git a/client/client-monitoring/src/main/resources/webapp/js/ApexEngineService.js b/client/client-monitoring/src/main/resources/webapp/js/ApexEngineService.js
new file mode 100644
index 0000000..0573dd8
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/js/ApexEngineService.js
@@ -0,0 +1,104 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * Create the Engine Service Table 
+ */
+function createEngineServiceTable() {
+	var tableId = config.engineService.tableId;
+	var headers = config.engineService.headers;
+	var table = createEngineTable($("." + config.engineService.parent),
+			tableId, headers.map(function(a) {
+				return a.title;
+			}));
+	var tableRow = document.createElement("tr");
+	var tableData = "";
+	for ( var h in headers) {
+		tableData += "<td id=" + tableId + "_" + headers[h].id + "></td>";
+	}
+	tableRow.innerHTML = tableData;
+	var actionTD = $(tableRow).find("#" + tableId + "_periodic_events");
+	actionTD
+			.html('<input type="text" name="period" id="period" style="display:inline-block"><label class="ebSwitcher"><input type="checkbox" class="ebSwitcher-checkbox" /><div class="ebSwitcher-body"><div class="ebSwitcher-onLabel">Stopped</div><div class="ebSwitcher-switch"></div><div class="ebSwitcher-offLabel">Started</div></div></label>');
+	var period = actionTD.find("#period");
+	var switcher = actionTD.find(".ebSwitcher");
+	switcher.css('display', 'inline-block');
+	switcher.css('margin-left', '5px');
+	switcher.css('vertical-align', 'middle');
+	var checkbox = $(actionTD).find('input:checkbox:first');
+	checkbox.change(function(event) {
+		var startstop;
+		if (checkbox.prop('checked')) {
+			startstop = "Stop";
+		} else {
+			startstop = "Start";
+		}
+		this.servicesCall.abort();
+		ajax_get(restRootURL + "periodiceventstartstop", startStopCallback,
+				this.engineURL.hostname, this.engineURL.port, {
+					engineId : this.engineId,
+					startstop : startstop,
+					period : period.val()
+				}, resetPeriodicEvents);
+	}.bind(this));
+	$(table).children("#engineTableBody").append(tableRow);
+}
+
+/*
+ * Check for any changes in the Engine Service Table data and update only where
+ * necessary
+ */
+function setEngineServiceData(engineId, modelId, server, port, periodicEvents) {
+	this.engineId = engineId;
+	var tableId = config.engineService.tableId;
+	var headers = config.engineService.headers.map(function(a) {
+		return a.id;
+	});
+	var data = [ engineId, server + ":" + port, modelId ];
+
+	var engineServiceTable = $("#engineServicesTable");
+
+	for ( var h in headers) {
+		var td = engineServiceTable.find("#" + tableId + "_" + headers[h]);
+		if (td.html() !== data[h]) {
+			engineServiceTable.find("#" + tableId + "_" + headers[h]).html(
+					data[h]);
+		}
+	}
+
+	var actionTD = engineServiceTable.find("#" + tableId + "_periodic_events");
+	var checkbox = $(actionTD).find('input:checkbox:first');
+	if (checkbox.is(":checked") === periodicEvents) {
+		checkbox.prop("checked", !checkbox.prop("checked"));
+	}
+}
+
+/*
+ * Resets the switcher for Periodic Events in the Engine Service Table
+ */
+function resetPeriodicEvents() {
+	var engineServiceTable = $("#engineServicesTable");
+	var periodicEventsTD = $(engineServiceTable).find(
+			"#engineServicesTable_periodic_events");
+	var checkbox = $(periodicEventsTD).find('input:checkbox:first');
+	if (checkbox.is(":checked")) {
+		checkbox.prop("checked", false);
+	}
+}
diff --git a/client/client-monitoring/src/main/resources/webapp/js/ApexEngineStatus.js b/client/client-monitoring/src/main/resources/webapp/js/ApexEngineStatus.js
new file mode 100644
index 0000000..832a704
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/js/ApexEngineStatus.js
@@ -0,0 +1,184 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * Create an Engine Status Table and its charts
+ */
+function createEngineStatusTable(id, startStopStatus) {
+	var tableId = config.engineStatus.tableId;
+	var headers = config.engineStatus.headers;
+
+	// Create a wrapper div for both the table and the charts
+	var wrapper = document.createElement("div");
+	wrapper.setAttribute("id", id + "_wrapper");
+	wrapper.setAttribute("class", "wrapper");
+	$("." + config.engineStatus.parent).append(wrapper);
+
+	// Create the table
+	var table = createEngineTable($(wrapper), id, headers.map(function(a) {
+		return a.title;
+	}));
+	var tableRow = document.createElement("tr");
+	var tableData = "";
+	for ( var h in headers) {
+		tableData += "<td id=" + tableId + "_" + headers[h].id + "></td>";
+	}
+	tableRow.innerHTML = tableData;
+	var actionTD = $(tableRow).find("#" + tableId + "_action");
+	var checked = (startStopStatus === "STOPPED") ? "checked" : "";
+	var chartWrapper = document.createElement("div");
+	chartWrapper.setAttribute("id", "chartWrapper");
+	actionTD
+			.html('<label class="ebSwitcher"><input type="checkbox" '
+					+ checked
+					+ ' class="ebSwitcher-checkbox" /><div class="ebSwitcher-body"><div class="ebSwitcher-onLabel">Stopped</div><div class="ebSwitcher-switch"></div><div class="ebSwitcher-offLabel">Started</div></div></label>');
+
+	var checkbox = $(actionTD).find('input:checkbox:first');
+	checkbox.change(function(event) {
+		var startstop;
+		if (checkbox.prop('checked')) {
+			startstop = "Stop";
+		} else {
+			startstop = "Start";
+		}
+		this.servicesCall.abort();
+		ajax_get(restRootURL + "startstop", startStopCallback,
+				this.engineURL.hostname, this.engineURL.port, {
+					engineId : id.split("_")[1],
+					startstop : startstop
+				});
+	}.bind(this));
+
+	$(table).children("#engineTableBody").append(tableRow);
+
+	var expand = document.createElement("i");
+	expand
+			.setAttribute("class",
+					"ebIcon ebIcon_rowExpanded ebIcon_large ebIcon_interactive expandIcon");
+	$(expand)
+			.click(
+					function() {
+						if ($(chartWrapper).is(":visible")) {
+							expand
+									.setAttribute("class",
+											"ebIcon ebIcon_rowCollapsed ebIcon_large ebIcon_interactive expandIcon");
+						} else {
+							expand
+									.setAttribute("class",
+											"ebIcon ebIcon_rowExpanded ebIcon_large ebIcon_interactive expandIcon");
+						}
+						$(chartWrapper).slideToggle();
+					}.bind(this));
+	$(wrapper).append(expand);
+	$(wrapper).append(chartWrapper);
+	return table;
+}
+
+/*
+ * Check for any changes in the Engine Status Table data and its charts and
+ * update only where necessary
+ */
+function setEngineStatusData(engineStatusData) {
+	var tableId = config.engineStatus.tableId;
+	var headers = config.engineStatus.headers.map(function(a) {
+		return a.id;
+	});
+	for ( var esd in engineStatusData) {
+		var id = tableId + "_" + engineStatusData[esd].id;
+		var existingTable = undefined;
+		for ( var est in this.engineStatusTables) {
+			if (id === this.engineStatusTables[est].getAttribute("id")) {
+				existingTable = this.engineStatusTables[est];
+			}
+		}
+
+		var data = [ engineStatusData[esd].timestamp, id.split("_")[1],
+				engineStatusData[esd].status,
+				engineStatusData[esd].last_message,
+				engineStatusData[esd].up_time,
+				engineStatusData[esd].policy_executions ];
+
+		var table = existingTable;
+		// If no table already exists for the engine, add one
+		if (!table) {
+			table = createEngineStatusTable(id, engineStatusData[esd].status);
+			table.setAttribute("id", id);
+			table.style["margin-bottom"] = "10px";
+			table.style.display = "inline-block";
+			this.engineStatusTables.push(table);
+		}
+
+		// Update data in table
+		for ( var h in headers) {
+			var td = $(table).find("#" + tableId + "_" + headers[h]);
+			if (td.html() !== data[h]) {
+				$(table).find("#" + tableId + "_" + headers[h]).html(data[h]);
+			}
+		}
+
+		var checked = (engineStatusData[esd].status === "STOPPED");
+		var actionTD = $(table).find("#engineStatusTable_action");
+		var checkbox = $(actionTD).find('input:checkbox:first');
+		if (checkbox.is(":checked") !== checked) {
+			checkbox.prop("checked", !checkbox.prop("checked"));
+		}
+
+		// Update charts
+		var wrapper = $(table).parent();
+		var chartWrapper = $(wrapper).find("#chartWrapper")
+
+		var chartConfig = this.config.engineChart.lastPolicyDurationChart;
+		var lastPolicyDurationChart = wrapper.find("#" + chartConfig.parent)[0];
+		if (lastPolicyDurationChart) {
+			updateChart(lastPolicyDurationChart, JSON
+					.parse(engineStatusData[esd].last_policy_duration),
+					chartConfig.nodeColour);
+		} else {
+			chartConfig = this.config.engineChart.lastPolicyDurationChart;
+			var lastPolicyDurationDiv = document.createElement("div");
+			lastPolicyDurationDiv.setAttribute("id", chartConfig.parent);
+			lastPolicyDurationDiv.setAttribute("class", "apexChart");
+			createChart(JSON.parse(engineStatusData[esd].last_policy_duration),
+					lastPolicyDurationDiv, chartConfig.title, chartConfig.unit,
+					chartConfig.lineStroke, chartConfig.nodeColour);
+			$(chartWrapper).append(lastPolicyDurationDiv);
+		}
+
+		chartConfig = this.config.engineChart.averagePolicyDurationChart;
+		var averagePolicyDurationChart = wrapper.find("#" + chartConfig.parent)[0];
+		if (averagePolicyDurationChart) {
+			updateChart(averagePolicyDurationChart, JSON
+					.parse(engineStatusData[esd].average_policy_duration),
+					chartConfig.nodeColour);
+		} else {
+			chartConfig = this.config.engineChart.averagePolicyDurationChart;
+			var averagePolicyDurationDiv = document.createElement("div");
+			averagePolicyDurationDiv.setAttribute("id", chartConfig.parent);
+			averagePolicyDurationDiv.setAttribute("class", "apexChart");
+			createChart(JSON
+					.parse(engineStatusData[esd].average_policy_duration),
+					averagePolicyDurationDiv, chartConfig.title,
+					chartConfig.unit, chartConfig.lineStroke,
+					chartConfig.nodeColour);
+			$(chartWrapper).append(averagePolicyDurationDiv);
+		}
+
+	}
+}
\ No newline at end of file
diff --git a/client/client-monitoring/src/main/resources/webapp/js/ApexEngineSummary.js b/client/client-monitoring/src/main/resources/webapp/js/ApexEngineSummary.js
new file mode 100644
index 0000000..8b40514
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/js/ApexEngineSummary.js
@@ -0,0 +1,152 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * Create the Engine Service Table 
+ */
+function createEngineSummaryTable() {
+	var tableId = config.engineSummary.tableId;
+	var headers = config.engineSummary.headers;
+
+	// Create a wrapper div for both the table and the charts
+	var wrapper = document.createElement("div");
+	wrapper.setAttribute("id", "engineSummary_wrapper");
+	wrapper.setAttribute("class", "wrapper_borderless");
+	$("." + config.engineSummary.parent).append(wrapper);
+
+	var table = createEngineTable($(wrapper), tableId, headers.map(function(a) {
+		return a.title;
+	}));
+	var tableRow = document.createElement("tr");
+	var tableData = "";
+	for ( var h in headers) {
+		tableData += "<td id=" + tableId + "_" + headers[h].id + "></td>";
+	}
+	tableRow.innerHTML = tableData;
+
+	$(table).children("#engineTableBody").append(tableRow);
+
+}
+
+function setEngineSummaryData(data) {
+	this._setEngineSummaryData(getLatestTimestamp(data),
+			getUptimeOfOldestEngine(data), getSumOfPolicyExecutions(data),
+			getAvgPolicyDuration(data));
+}
+
+/*
+ * Check for any changes in the Engine Summary Table data and update only where
+ * necessary
+ */
+function _setEngineSummaryData(timestamp, upTime, policyExecutions,
+		avgPolicyDuration) {
+
+	var tableId = config.engineSummary.tableId;
+	var headers = config.engineSummary.headers.map(function(a) {
+		return a.id;
+	});
+	var data = [ timestamp, upTime, policyExecutions ];
+
+	var engineSummaryTable = $("#engineSummaryTable");
+
+	for ( var h in headers) {
+		var td = engineSummaryTable.find("#" + tableId + "_" + headers[h]);
+		if (td.html() !== data[h]) {
+			engineSummaryTable.find("#" + tableId + "_" + headers[h]).html(
+					data[h]);
+		}
+	}
+
+	// Update charts
+	var wrapper = engineSummaryTable.parent();
+	var chartConfig = this.config.engineSummary.chart.avgPolicyDurationChart;
+	var avgPolicyDurationChart = wrapper.find("#" + chartConfig.parent)[0];
+	if (avgPolicyDurationChart) {
+		updateChart(avgPolicyDurationChart, avgPolicyDuration,
+				chartConfig.nodeColour);
+	} else {
+		var avgPolicyDurationDiv = document.createElement("div");
+		avgPolicyDurationDiv.setAttribute("id", chartConfig.parent);
+		avgPolicyDurationDiv.setAttribute("class", "apexChart_inline");
+		createChart(avgPolicyDuration, avgPolicyDurationDiv, chartConfig.title,
+				chartConfig.unit, chartConfig.lineStroke,
+				chartConfig.nodeColour);
+		$(wrapper).append(avgPolicyDurationDiv);
+	}
+}
+
+function getLatestTimestamp(data) {
+	var latestTimestamp = {
+		displayText : "-1",
+		value : -1
+	};
+	for ( var d in data) {
+		var currentDateInMillis = new Date(data[d].timestamp.replace(/-/g, '/')
+				.split('.')[0]).getTime();
+		if (currentDateInMillis > latestTimestamp.value) {
+			latestTimestamp.displayText = data[d].timestamp;
+			latestTimestamp.value = currentDateInMillis;
+		}
+	}
+	return latestTimestamp.displayText;
+}
+
+function getUptimeOfOldestEngine(data) {
+	var oldestUpTime = -1;
+	for ( var d in data) {
+		if (data[d].up_time > oldestUpTime) {
+			oldestUpTime = data[d].up_time;
+		}
+	}
+	return oldestUpTime;
+}
+
+function getSumOfPolicyExecutions(data) {
+	var totalPolicyExecutions = 0;
+	for ( var d in data) {
+		totalPolicyExecutions += data[d].policy_executions;
+	}
+	return totalPolicyExecutions;
+}
+
+function getAvgPolicyDuration(data) {
+	var chartData = [];
+	var avgPolicyDurations = [];
+	for ( var d in data) {
+		var avgPolicyDuration = JSON.parse(data[d].average_policy_duration);
+		avgPolicyDurations.push(avgPolicyDuration);
+	}
+
+	if (avgPolicyDurations.length > 0) {
+		chartData = avgPolicyDurations[0];
+		for (var i = 1; i < avgPolicyDurations.length; i++) {
+			var engineData = avgPolicyDurations[i];
+			for ( var c in chartData) {
+				chartData[c].value += engineData[c].value;
+			}
+		}
+	}
+
+	for ( var c2 in chartData) {
+		chartData[c2].value = Math.round(chartData[c2].value / data.length);
+	}
+
+	return chartData;
+}
\ No newline at end of file
diff --git a/client/client-monitoring/src/main/resources/webapp/js/ApexServicesMain.js b/client/client-monitoring/src/main/resources/webapp/js/ApexServicesMain.js
new file mode 100644
index 0000000..f22b307
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/js/ApexServicesMain.js
@@ -0,0 +1,253 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+var restRootURL;
+
+// Configuration used for page layout and charts
+var config = {
+	refresh : 5000,
+	engineService : {
+		parent : "engineService",
+		tableId : "engineServicesTable",
+		headers : [ {
+			title : "Engine Service ID",
+			id : "engine_id"
+		}, {
+			title : "server:port",
+			id : "server_port"
+		}, {
+			title : "Model ID",
+			id : "model_id"
+		}, {
+			title : "Periodic Events",
+			id : "periodic_events"
+		} ]
+	},
+	engineSummary : {
+		parent : "engineSummary",
+		tableId : "engineSummaryTable",
+		headers : [ {
+			title : "Timestamp",
+			id : "timestamp"
+		}, {
+			title : "Up Time of oldest engine (ms)",
+			id : "up_time"
+		}, {
+			title : "Sum of policy executions",
+			id : "policy_executions"
+		} ],
+		chart : {
+			avgPolicyDurationChart : {
+				parent : "avgPolicyDuration",
+				title : "Average Policy Duration (ms)",
+				unit : "ms",
+				lineStroke : "#5FBADD",
+				nodeColour : "#00A9D4"
+			},
+		}
+	},
+	engineStatus : {
+		parent : "engineStatus",
+		tableId : "engineStatusTable",
+		headers : [ {
+			title : "Timestamp",
+			id : "timestamp"
+		}, {
+			title : "Engine ID",
+			id : "engine_id"
+		}, {
+			title : "Engine Status",
+			id : "engine_status"
+		}, {
+			title : "Last Message",
+			id : "last_message"
+		}, {
+			title : "Up Time (ms)",
+			id : "up_time"
+		}, {
+			title : "Policy Executions",
+			id : "policy_executions"
+		}, {
+			title : "Action",
+			id : "action"
+		} ]
+	},
+	engineContext : {
+		parent : "context",
+		tableId : "engineContextTable",
+		headers : [ {
+			title : "Name",
+			id : "name"
+		}, {
+			title : "Version",
+			id : "version"
+		}, {
+			title : "Info",
+			id : "schema"
+		} ]
+	},
+	engineChart : {
+		lastPolicyDurationChart : {
+			parent : "lastPolicyDurationChart",
+			title : "Last Policy Duration (ms)",
+			unit : "ms",
+			lineStroke : "#F5A241",
+			nodeColour : "#F08A00"
+		},
+		averagePolicyDurationChart : {
+			parent : "averagePolicyDurationChart",
+			title : "Average Policy Duration (ms)",
+			unit : "ms",
+			lineStroke : "#00625F",
+			nodeColour : "#007B78"
+		}
+	}
+};
+
+function servicesCallback(data) {
+	// If engine url in cookie has not been cleared
+	if (localStorage.getItem("apex-monitor-services")) {
+		setEngineServiceData(data.engine_id, data.model_id, data.server,
+				data.port, data.periodic_events);
+		setEngineSummaryData(data.status);
+		setEngineStatusData(data.status);
+		setEngineContextData(data.context);
+
+		// Make content visible after data has been returned for the first time
+		if (!$(".content").is(':visible')) {
+			$(".content").fadeIn();
+		}
+
+		// Repeat the same request
+		setTimeout(function() {
+			this.servicesCall = ajax_get(restRootURL, servicesCallback,
+					this.engineURL.hostname, this.engineURL.port);
+		}, config.refresh);
+	}
+}
+
+/*
+ * Callback for starting/stopping an engine/events
+ */
+function startStopCallback() {
+	this.servicesCall = ajax_get(restRootURL, servicesCallback,
+			this.engineURL.hostname, this.engineURL.port);
+}
+
+/*
+ * Callback for uploading a model
+ */
+function uploadCallback(response) {
+	// Open a dialog showing the response
+	apexSuccessDialog_activate(document.body, response);
+}
+
+/*
+ * Clears and resets all content on the page
+ */
+function setUpPage() {
+	// Hide all content
+	$('#content').hide();
+
+	// Clear each div
+	$('#content > div').each(function() {
+		$(this).empty();
+	});
+
+	// Reset trackers for tables
+	this.engineStatusTables = [];
+	this.engineContextTables = [];
+
+	// Set up content div's
+	createEngineServiceTable();
+	createEngineSummaryTable();
+}
+
+/*
+ * Retrieves the engine URL from the cookie. If it has not been set yet, then a
+ * dialog is shown asking for it
+ */
+function getEngineURL(message) {
+	// The engine URL is stored in a cookie using the key
+	// "apex-monitor-services"
+	var engineURL = localStorage.getItem("apex-monitor-services");
+
+	// This url is used to store the last known engine URL so that the user
+	// doesn't have to retype it every time
+	var oldEngineURL = localStorage.getItem("apex-monitor-services_old");
+
+	// If an engine URL is stored in the cookie
+	if (engineURL) {
+		// Parse the engine URL
+		this.engineURL = JSON.parse(engineURL);
+
+		// Send a request with that engine URL
+		this.servicesCall = ajax_get(restRootURL, servicesCallback,
+				this.engineURL.hostname, this.engineURL.port);
+	} else {
+		// Prompt for engine URL
+		apexDialogForm_activate(document.body, message);
+	}
+}
+
+/*
+ * Clears the cookie and reset the page
+ */
+function clearEngineURL() {
+	// Remove engine URL from cookie
+	localStorage.removeItem("apex-monitor-services");
+
+	// Reset the page
+	setUpPage();
+}
+
+/*
+ * Called after the DOM is ready
+ */
+$(document)
+		.ready(
+				function() {
+					restRootURL = location.protocol
+							+ "//"
+							+ window.location.hostname
+							+ (location.port ? ':' + location.port : '')
+							+ (location.pathname.endsWith("/monitoring/") ? location.pathname
+									.substring(0, location.pathname
+											.indexOf("monitoring/"))
+									: location.pathname)
+							+ "apexservices/monitoring/";
+					// Initialize tooltip for the charts
+					initTooltip();
+
+					// Set up the structure of the page
+					setUpPage();
+
+					// Check cookies for engine URL
+					getEngineURL();
+
+					// Add click event to config icon for clearing engine URL
+					$(".ebSystemBar-config").click(function() {
+						// Clear the engine URL
+						clearEngineURL();
+
+						// Request the engine URL
+						getEngineURL();
+					});
+				});
\ No newline at end of file
diff --git a/client/client-monitoring/src/main/resources/webapp/js/ApexTable.js b/client/client-monitoring/src/main/resources/webapp/js/ApexTable.js
new file mode 100644
index 0000000..95e9ec1
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/js/ApexTable.js
@@ -0,0 +1,60 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * Create a table with given headers
+ */
+function createEngineTable(parent, id, tableHeaders) {
+	var table = createTable(id);
+
+	var tableHead = document.createElement("thead");
+	table.appendChild(tableHead);
+	tableHead.setAttribute("id", "engineTableHeader");
+
+	var tableHeaderRow = document.createElement("tr");
+	tableHead.appendChild(tableHeaderRow);
+	tableHeaderRow.setAttribute("id", "engineTableHeaderRow");
+
+	for ( var t in tableHeaders) {
+		var tableHeader = document.createElement("th");
+		tableHeaderRow.appendChild(tableHeader);
+		tableHeader.setAttribute("id", "engineTableHeader");
+		tableHeader.appendChild(document.createTextNode(tableHeaders[t]));
+	}
+
+	var tableBody = document.createElement("tbody");
+	tableBody.setAttribute("id", "engineTableBody");
+	table.appendChild(tableBody);
+
+	parent.append(table);
+
+	return table;
+}
+
+/*
+ * Create a table and apply UISDK styles to it
+ */
+function createTable(id) {
+	var table = document.createElement("table");
+	table.setAttribute("id", id);
+	table.setAttribute("class",
+			"apexTable ebTable elTablelib-Table-table ebTable_striped");
+	return table;
+}
\ No newline at end of file
diff --git a/client/client-monitoring/src/main/resources/webapp/js/ApexUtils.js b/client/client-monitoring/src/main/resources/webapp/js/ApexUtils.js
new file mode 100644
index 0000000..732fbfd
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/js/ApexUtils.js
@@ -0,0 +1,332 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+/*
+ * Crate a dialog with input, attach it to a given parent and show an optional message
+ */
+function apexDialogForm_activate(formParent, message) {
+	apexUtils_removeElement("apexDialogDiv");
+
+	var contentelement = document.createElement("apexDialogDiv");
+	var formDiv = document.createElement("div");
+	var backgroundDiv = document.createElement("div");
+	backgroundDiv.setAttribute("id", "apexDialogDivBackground");
+	backgroundDiv.setAttribute("class", "apexDialogDivBackground");
+
+	backgroundDiv.appendChild(formDiv);
+	contentelement.appendChild(backgroundDiv);
+	formParent.appendChild(contentelement);
+
+	formDiv.setAttribute("id", "apexDialogDiv");
+	formDiv.setAttribute("class", "apexDialogDiv");
+
+	var headingSpan = document.createElement("span");
+	formDiv.appendChild(headingSpan);
+
+	headingSpan.setAttribute("class", "headingSpan");
+	headingSpan.innerHTML = "Apex Engine Configuration";
+
+	var form = document.createElement("apexDialog");
+	formDiv.appendChild(form);
+
+	form.setAttribute("id", "apexDialog");
+	form.setAttribute("class", "form-style-1");
+	form.setAttribute("method", "post");
+
+	if (message) {
+		var messageLI = document.createElement("li");
+		messageLI.setAttribute("class", "dialogMessage");
+		messageLI.innerHTML = message;
+		form.appendChild(messageLI);
+	}
+
+	var urlLI = document.createElement("li");
+	form.appendChild(urlLI);
+
+	var urlLabel = document.createElement("label");
+	urlLI.appendChild(urlLabel);
+
+	urlLabel.setAttribute("for", "apexDialogUrlInput");
+	urlLabel.innerHTML = "Apex Engine rest URL:";
+
+	var urlLabelSpan = document.createElement("span");
+	urlLabel.appendChild(urlLabelSpan);
+
+	urlLabelSpan.setAttribute("class", "required");
+	urlLabelSpan.innerHTML = "*";
+
+	var engineUrl = localStorage.getItem("apex-monitor-services_old");
+
+	var urlInput = document.createElement("input");
+	urlInput.setAttribute("id", "services_url_input");
+	urlInput.setAttribute("placeholder", "localhost:12345");
+	urlInput.value = (engineUrl && engineUrl !== "null") ? JSON
+			.parse(engineUrl).hostname
+			+ ":" + JSON.parse(engineUrl).port : "";
+	urlLI.appendChild(urlInput);
+
+	var inputLI = document.createElement("li");
+	form.appendChild(inputLI);
+
+	var submitInput = document.createElement("input");
+	submitInput.setAttribute("id", "submit");
+	submitInput.setAttribute("class", "button ebBtn");
+	submitInput.setAttribute("type", "submit");
+	submitInput.setAttribute("value", "Submit");
+	submitInput.onclick = apexDialogForm_submitPressed;
+	inputLI.appendChild(submitInput);
+
+	// Enter key press triggers submit
+	$(urlInput).keyup(function(event) {
+		if (event.keyCode == 13) {
+			$(submitInput).click();
+		}
+	});
+
+	urlInput.focus();
+}
+
+/*
+ * Create a dialog for displaying text
+ */
+function apexTextDialog_activate(formParent, message, title) {
+	apexUtils_removeElement("apexDialogDiv");
+
+	var contentelement = document.createElement("div");
+	contentelement.setAttribute("id", "apexDialogDiv")
+	var formDiv = document.createElement("div");
+	var backgroundDiv = document.createElement("div");
+	backgroundDiv.setAttribute("id", "apexDialogDivBackground");
+	backgroundDiv.setAttribute("class", "apexDialogDivBackground");
+
+	backgroundDiv.appendChild(formDiv);
+	contentelement.appendChild(backgroundDiv);
+	formParent.appendChild(contentelement);
+
+	formDiv.setAttribute("id", "apexErrorDialogDiv");
+	formDiv.setAttribute("class", "apexDialogDiv apexErrorDialogDiv");
+
+	var headingSpan = document.createElement("span");
+	formDiv.appendChild(headingSpan);
+
+	headingSpan.setAttribute("class", "headingSpan");
+	headingSpan.innerHTML = title;
+
+	var form = document.createElement("div");
+	formDiv.appendChild(form);
+
+	form.setAttribute("id", "apexDialog");
+	form.setAttribute("class", "form-style-1");
+	form.setAttribute("method", "post");
+
+	if (message) {
+		var messageLI = document.createElement("li");
+		messageLI.setAttribute("class", "dialogMessage");
+		messageLI.innerHTML = message;
+		form.appendChild(messageLI);
+	}
+
+	var inputLI = document.createElement("li");
+	form.appendChild(inputLI);
+
+	var cancelInput = document.createElement("input");
+	cancelInput.setAttribute("class", "button ebBtn");
+	cancelInput.setAttribute("type", "submit");
+	cancelInput.setAttribute("value", "Close");
+	cancelInput.onclick = newModelForm_cancelPressed;
+	form.appendChild(cancelInput);
+}
+
+/*
+ * Create a Success dialog
+ */
+function apexSuccessDialog_activate(formParent, message) {
+	apexTextDialog_activate(formParent, message, "Success");
+}
+
+/*
+ * Create an Error dialog
+ */
+function apexErrorDialog_activate(formParent, message) {
+	apexTextDialog_activate(formParent, message, "Error");
+}
+
+/*
+ * Dialog cancel callback
+ */
+function newModelForm_cancelPressed() {
+	apexUtils_removeElement("apexDialogDivBackground");
+}
+
+/*
+ * Dialog submit callback
+ */
+function apexDialogForm_submitPressed() {
+	var url = $('#services_url_input').val();
+	if (url && url.length > 0) {
+		var engineConfig = {
+			hostname : url.split(":")[0],
+			port : url.split(":")[1]
+		};
+		localStorage.setItem("apex-monitor-services_old", JSON
+				.stringify(engineConfig));
+		localStorage.setItem("apex-monitor-services", JSON
+				.stringify(engineConfig));
+		apexUtils_removeElement("apexDialogDivBackground");
+		getEngineURL();
+	}
+}
+
+/*
+ * Remove an element from the page
+ */
+function apexUtils_removeElement(elementname) {
+	var element = document.getElementById(elementname);
+	if (element != null) {
+		element.parentNode.removeChild(element);
+	}
+}
+
+/*
+ * Compare two objects
+ */
+function deepCompare() {
+	var i, l, leftChain, rightChain;
+
+	function compare2Objects(x, y) {
+		var p;
+
+		// remember that NaN === NaN returns false
+		// and isNaN(undefined) returns true
+		if (isNaN(x) && isNaN(y) && typeof x === 'number'
+				&& typeof y === 'number') {
+			return true;
+		}
+
+		// Compare primitives and functions.
+		// Check if both arguments link to the same object.
+		// Especially useful on the step where we compare prototypes
+		if (x === y) {
+			return true;
+		}
+
+		// Works in case when functions are created in constructor.
+		// Comparing dates is a common scenario. Another built-ins?
+		// We can even handle functions passed across iframes
+		if ((typeof x === 'function' && typeof y === 'function')
+				|| (x instanceof Date && y instanceof Date)
+				|| (x instanceof RegExp && y instanceof RegExp)
+				|| (x instanceof String && y instanceof String)
+				|| (x instanceof Number && y instanceof Number)) {
+			return x.toString() === y.toString();
+		}
+
+		// At last checking prototypes as good as we can
+		if (!(x instanceof Object && y instanceof Object)) {
+			return false;
+		}
+
+		if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) {
+			return false;
+		}
+
+		if (x.constructor !== y.constructor) {
+			return false;
+		}
+
+		if (x.prototype !== y.prototype) {
+			return false;
+		}
+
+		// Check for infinitive linking loops
+		if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) {
+			return false;
+		}
+
+		// Quick checking of one object being a subset of another.
+		// todo: cache the structure of arguments[0] for performance
+		for (p in y) {
+			if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
+				return false;
+			} else if (typeof y[p] !== typeof x[p]) {
+				return false;
+			}
+		}
+
+		for (p in x) {
+			if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
+				return false;
+			} else if (typeof y[p] !== typeof x[p]) {
+				return false;
+			}
+
+			switch (typeof (x[p])) {
+			case 'object':
+			case 'function':
+
+				leftChain.push(x);
+				rightChain.push(y);
+
+				if (!compare2Objects(x[p], y[p])) {
+					return false;
+				}
+
+				leftChain.pop();
+				rightChain.pop();
+				break;
+
+			default:
+				if (x[p] !== y[p]) {
+					return false;
+				}
+				break;
+			}
+		}
+
+		return true;
+	}
+
+	if (arguments.length < 1) {
+		return true;
+	}
+
+	for (i = 1, l = arguments.length; i < l; i++) {
+
+		leftChain = []; // Todo: this can be cached
+		rightChain = [];
+
+		if (!compare2Objects(arguments[0], arguments[i])) {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+function getHomepageURL() {
+	var homepageURL = location.protocol
+			+ "//"
+			+ window.location.hostname
+			+ (location.port ? ':' + location.port : '')
+			+ (location.pathname.endsWith("/monitoring/") ? location.pathname
+					.substring(0, location.pathname.indexOf("monitoring/"))
+					: location.pathname);
+	location.href = homepageURL;
+}
\ No newline at end of file
diff --git a/client/client-monitoring/src/main/resources/webapp/js/avsc/avsc.js b/client/client-monitoring/src/main/resources/webapp/js/avsc/avsc.js
new file mode 100644
index 0000000..7177943
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/js/avsc/avsc.js
@@ -0,0 +1,21605 @@
+/*
+ * Copyright (c) 2015-2017, Matthieu Monsch.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
+(function (global){
+'use strict';
+
+// compare and isBuffer taken from
+// https://github.com/feross/buffer/blob/680e9e5e488f22aac27599a57dc844a6315928dd/index.js
+// original notice:
+
+/*
+ * ! The buffer module from node.js, for the browser.
+ * 
+ * @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org> @license
+ * MIT
+ */
+function compare(a, b) {
+  if (a === b) {
+    return 0;
+  }
+
+  var x = a.length;
+  var y = b.length;
+
+  for (var i = 0, len = Math.min(x, y); i < len; ++i) {
+    if (a[i] !== b[i]) {
+      x = a[i];
+      y = b[i];
+      break;
+    }
+  }
+
+  if (x < y) {
+    return -1;
+  }
+  if (y < x) {
+    return 1;
+  }
+  return 0;
+}
+function isBuffer(b) {
+  if (global.Buffer && typeof global.Buffer.isBuffer === 'function') {
+    return global.Buffer.isBuffer(b);
+  }
+  return !!(b != null && b._isBuffer);
+}
+
+// based on node assert, original notice:
+
+// http://wiki.commonjs.org/wiki/Unit_Testing/1.0
+//
+// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8!
+//
+// Originally from narwhal.js (http://narwhaljs.org)
+// Copyright (c) 2009 Thomas Robinson <280north.com>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the 'Software'), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var util = require('util/');
+var hasOwn = Object.prototype.hasOwnProperty;
+var pSlice = Array.prototype.slice;
+var functionsHaveNames = (function () {
+  return function foo() {}.name === 'foo';
+}());
+function pToString (obj) {
+  return Object.prototype.toString.call(obj);
+}
+function isView(arrbuf) {
+  if (isBuffer(arrbuf)) {
+    return false;
+  }
+  if (typeof global.ArrayBuffer !== 'function') {
+    return false;
+  }
+  if (typeof ArrayBuffer.isView === 'function') {
+    return ArrayBuffer.isView(arrbuf);
+  }
+  if (!arrbuf) {
+    return false;
+  }
+  if (arrbuf instanceof DataView) {
+    return true;
+  }
+  if (arrbuf.buffer && arrbuf.buffer instanceof ArrayBuffer) {
+    return true;
+  }
+  return false;
+}
+// 1. The assert module provides functions that throw
+// AssertionError's when particular conditions are not met. The
+// assert module must conform to the following interface.
+
+var assert = module.exports = ok;
+
+// 2. The AssertionError is defined in assert.
+// new assert.AssertionError({ message: message,
+// actual: actual,
+// expected: expected })
+
+var regex = /\s*function\s+([^\(\s]*)\s*/;
+// based on
+// https://github.com/ljharb/function.prototype.name/blob/adeeeec8bfcc6068b187d7d9fb3d5bb1d3a30899/implementation.js
+function getName(func) {
+  if (!util.isFunction(func)) {
+    return;
+  }
+  if (functionsHaveNames) {
+    return func.name;
+  }
+  var str = func.toString();
+  var match = str.match(regex);
+  return match && match[1];
+}
+assert.AssertionError = function AssertionError(options) {
+  this.name = 'AssertionError';
+  this.actual = options.actual;
+  this.expected = options.expected;
+  this.operator = options.operator;
+  if (options.message) {
+    this.message = options.message;
+    this.generatedMessage = false;
+  } else {
+    this.message = getMessage(this);
+    this.generatedMessage = true;
+  }
+  var stackStartFunction = options.stackStartFunction || fail;
+  if (Error.captureStackTrace) {
+    Error.captureStackTrace(this, stackStartFunction);
+  } else {
+    // non v8 browsers so we can have a stacktrace
+    var err = new Error();
+    if (err.stack) {
+      var out = err.stack;
+
+      // try to strip useless frames
+      var fn_name = getName(stackStartFunction);
+      var idx = out.indexOf('\n' + fn_name);
+      if (idx >= 0) {
+        // once we have located the function frame
+        // we need to strip out everything before it (and its line)
+        var next_line = out.indexOf('\n', idx + 1);
+        out = out.substring(next_line + 1);
+      }
+
+      this.stack = out;
+    }
+  }
+};
+
+// assert.AssertionError instanceof Error
+util.inherits(assert.AssertionError, Error);
+
+function truncate(s, n) {
+  if (typeof s === 'string') {
+    return s.length < n ? s : s.slice(0, n);
+  } else {
+    return s;
+  }
+}
+function inspect(something) {
+  if (functionsHaveNames || !util.isFunction(something)) {
+    return util.inspect(something);
+  }
+  var rawname = getName(something);
+  var name = rawname ? ': ' + rawname : '';
+  return '[Function' +  name + ']';
+}
+function getMessage(self) {
+  return truncate(inspect(self.actual), 128) + ' ' +
+         self.operator + ' ' +
+         truncate(inspect(self.expected), 128);
+}
+
+// At present only the three keys mentioned above are used and
+// understood by the spec. Implementations or sub modules can pass
+// other keys to the AssertionError's constructor - they will be
+// ignored.
+
+// 3. All of the following functions must throw an AssertionError
+// when a corresponding condition is not met, with a message that
+// may be undefined if not provided. All assertion methods provide
+// both the actual and expected values to the assertion error for
+// display purposes.
+
+function fail(actual, expected, message, operator, stackStartFunction) {
+  throw new assert.AssertionError({
+    message: message,
+    actual: actual,
+    expected: expected,
+    operator: operator,
+    stackStartFunction: stackStartFunction
+  });
+}
+
+// EXTENSION! allows for well behaved errors defined elsewhere.
+assert.fail = fail;
+
+// 4. Pure assertion tests whether a value is truthy, as determined
+// by !!guard.
+// assert.ok(guard, message_opt);
+// This statement is equivalent to assert.equal(true, !!guard,
+// message_opt);. To test strictly for the value true, use
+// assert.strictEqual(true, guard, message_opt);.
+
+function ok(value, message) {
+  if (!value) fail(value, true, message, '==', assert.ok);
+}
+assert.ok = ok;
+
+// 5. The equality assertion tests shallow, coercive equality with
+// ==.
+// assert.equal(actual, expected, message_opt);
+
+assert.equal = function equal(actual, expected, message) {
+  if (actual != expected) fail(actual, expected, message, '==', assert.equal);
+};
+
+// 6. The non-equality assertion tests for whether two objects are not equal
+// with != assert.notEqual(actual, expected, message_opt);
+
+assert.notEqual = function notEqual(actual, expected, message) {
+  if (actual == expected) {
+    fail(actual, expected, message, '!=', assert.notEqual);
+  }
+};
+
+// 7. The equivalence assertion tests a deep equality relation.
+// assert.deepEqual(actual, expected, message_opt);
+
+assert.deepEqual = function deepEqual(actual, expected, message) {
+  if (!_deepEqual(actual, expected, false)) {
+    fail(actual, expected, message, 'deepEqual', assert.deepEqual);
+  }
+};
+
+assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) {
+  if (!_deepEqual(actual, expected, true)) {
+    fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual);
+  }
+};
+
+function _deepEqual(actual, expected, strict, memos) {
+  // 7.1. All identical values are equivalent, as determined by ===.
+  if (actual === expected) {
+    return true;
+  } else if (isBuffer(actual) && isBuffer(expected)) {
+    return compare(actual, expected) === 0;
+
+  // 7.2. If the expected value is a Date object, the actual value is
+  // equivalent if it is also a Date object that refers to the same time.
+  } else if (util.isDate(actual) && util.isDate(expected)) {
+    return actual.getTime() === expected.getTime();
+
+  // 7.3 If the expected value is a RegExp object, the actual value is
+  // equivalent if it is also a RegExp object with the same source and
+  // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`).
+  } else if (util.isRegExp(actual) && util.isRegExp(expected)) {
+    return actual.source === expected.source &&
+           actual.global === expected.global &&
+           actual.multiline === expected.multiline &&
+           actual.lastIndex === expected.lastIndex &&
+           actual.ignoreCase === expected.ignoreCase;
+
+  // 7.4. Other pairs that do not both pass typeof value == 'object',
+  // equivalence is determined by ==.
+  } else if ((actual === null || typeof actual !== 'object') &&
+             (expected === null || typeof expected !== 'object')) {
+    return strict ? actual === expected : actual == expected;
+
+  // If both values are instances of typed arrays, wrap their underlying
+  // ArrayBuffers in a Buffer each to increase performance
+  // This optimization requires the arrays to have the same type as checked by
+  // Object.prototype.toString (aka pToString). Never perform binary
+  // comparisons for Float*Arrays, though, since e.g. +0 === -0 but their
+  // bit patterns are not identical.
+  } else if (isView(actual) && isView(expected) &&
+             pToString(actual) === pToString(expected) &&
+             !(actual instanceof Float32Array ||
+               actual instanceof Float64Array)) {
+    return compare(new Uint8Array(actual.buffer),
+                   new Uint8Array(expected.buffer)) === 0;
+
+  // 7.5 For all other Object pairs, including Array objects, equivalence is
+  // determined by having the same number of owned properties (as verified
+  // with Object.prototype.hasOwnProperty.call), the same set of keys
+  // (although not necessarily the same order), equivalent values for every
+  // corresponding key, and an identical 'prototype' property. Note: this
+  // accounts for both named and indexed properties on Arrays.
+  } else if (isBuffer(actual) !== isBuffer(expected)) {
+    return false;
+  } else {
+    memos = memos || {actual: [], expected: []};
+
+    var actualIndex = memos.actual.indexOf(actual);
+    if (actualIndex !== -1) {
+      if (actualIndex === memos.expected.indexOf(expected)) {
+        return true;
+      }
+    }
+
+    memos.actual.push(actual);
+    memos.expected.push(expected);
+
+    return objEquiv(actual, expected, strict, memos);
+  }
+}
+
+function isArguments(object) {
+  return Object.prototype.toString.call(object) == '[object Arguments]';
+}
+
+function objEquiv(a, b, strict, actualVisitedObjects) {
+  if (a === null || a === undefined || b === null || b === undefined)
+    return false;
+  // if one is a primitive, the other must be same
+  if (util.isPrimitive(a) || util.isPrimitive(b))
+    return a === b;
+  if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b))
+    return false;
+  var aIsArgs = isArguments(a);
+  var bIsArgs = isArguments(b);
+  if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
+    return false;
+  if (aIsArgs) {
+    a = pSlice.call(a);
+    b = pSlice.call(b);
+    return _deepEqual(a, b, strict);
+  }
+  var ka = objectKeys(a);
+  var kb = objectKeys(b);
+  var key, i;
+  // having the same number of owned properties (keys incorporates
+  // hasOwnProperty)
+  if (ka.length !== kb.length)
+    return false;
+  // the same set of keys (although not necessarily the same order),
+  ka.sort();
+  kb.sort();
+  // ~~~cheap key test
+  for (i = ka.length - 1; i >= 0; i--) {
+    if (ka[i] !== kb[i])
+      return false;
+  }
+  // equivalent values for every corresponding key, and
+  // ~~~possibly expensive deep test
+  for (i = ka.length - 1; i >= 0; i--) {
+    key = ka[i];
+    if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects))
+      return false;
+  }
+  return true;
+}
+
+// 8. The non-equivalence assertion tests for any deep inequality.
+// assert.notDeepEqual(actual, expected, message_opt);
+
+assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
+  if (_deepEqual(actual, expected, false)) {
+    fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
+  }
+};
+
+assert.notDeepStrictEqual = notDeepStrictEqual;
+function notDeepStrictEqual(actual, expected, message) {
+  if (_deepEqual(actual, expected, true)) {
+    fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual);
+  }
+}
+
+
+// 9. The strict equality assertion tests strict equality, as determined by ===.
+// assert.strictEqual(actual, expected, message_opt);
+
+assert.strictEqual = function strictEqual(actual, expected, message) {
+  if (actual !== expected) {
+    fail(actual, expected, message, '===', assert.strictEqual);
+  }
+};
+
+// 10. The strict non-equality assertion tests for strict inequality, as
+// determined by !==. assert.notStrictEqual(actual, expected, message_opt);
+
+assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
+  if (actual === expected) {
+    fail(actual, expected, message, '!==', assert.notStrictEqual);
+  }
+};
+
+function expectedException(actual, expected) {
+  if (!actual || !expected) {
+    return false;
+  }
+
+  if (Object.prototype.toString.call(expected) == '[object RegExp]') {
+    return expected.test(actual);
+  }
+
+  try {
+    if (actual instanceof expected) {
+      return true;
+    }
+  } catch (e) {
+    // Ignore. The instanceof check doesn't work for arrow functions.
+  }
+
+  if (Error.isPrototypeOf(expected)) {
+    return false;
+  }
+
+  return expected.call({}, actual) === true;
+}
+
+function _tryBlock(block) {
+  var error;
+  try {
+    block();
+  } catch (e) {
+    error = e;
+  }
+  return error;
+}
+
+function _throws(shouldThrow, block, expected, message) {
+  var actual;
+
+  if (typeof block !== 'function') {
+    throw new TypeError('"block" argument must be a function');
+  }
+
+  if (typeof expected === 'string') {
+    message = expected;
+    expected = null;
+  }
+
+  actual = _tryBlock(block);
+
+  message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
+            (message ? ' ' + message : '.');
+
+  if (shouldThrow && !actual) {
+    fail(actual, expected, 'Missing expected exception' + message);
+  }
+
+  var userProvidedMessage = typeof message === 'string';
+  var isUnwantedException = !shouldThrow && util.isError(actual);
+  var isUnexpectedException = !shouldThrow && actual && !expected;
+
+  if ((isUnwantedException &&
+      userProvidedMessage &&
+      expectedException(actual, expected)) ||
+      isUnexpectedException) {
+    fail(actual, expected, 'Got unwanted exception' + message);
+  }
+
+  if ((shouldThrow && actual && expected &&
+      !expectedException(actual, expected)) || (!shouldThrow && actual)) {
+    throw actual;
+  }
+}
+
+// 11. Expected to throw an error:
+// assert.throws(block, Error_opt, message_opt);
+
+assert.throws = function(block, /* optional */error, /* optional */message) {
+  _throws(true, block, error, message);
+};
+
+// EXTENSION! This is annoying to write outside this module.
+assert.doesNotThrow = function(block, /* optional */error, /* optional */message) {
+  _throws(false, block, error, message);
+};
+
+assert.ifError = function(err) { if (err) throw err; };
+
+var objectKeys = Object.keys || function (obj) {
+  var keys = [];
+  for (var key in obj) {
+    if (hasOwn.call(obj, key)) keys.push(key);
+  }
+  return keys;
+};
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"util/":47}],2:[function(require,module,exports){
+
+},{}],3:[function(require,module,exports){
+'use strict';
+
+
+var TYPED_OK =  (typeof Uint8Array !== 'undefined') &&
+                (typeof Uint16Array !== 'undefined') &&
+                (typeof Int32Array !== 'undefined');
+
+
+exports.assign = function (obj /* from1, from2, from3, ... */) {
+  var sources = Array.prototype.slice.call(arguments, 1);
+  while (sources.length) {
+    var source = sources.shift();
+    if (!source) { continue; }
+
+    if (typeof source !== 'object') {
+      throw new TypeError(source + 'must be non-object');
+    }
+
+    for (var p in source) {
+      if (source.hasOwnProperty(p)) {
+        obj[p] = source[p];
+      }
+    }
+  }
+
+  return obj;
+};
+
+
+// reduce buffer size, avoiding mem copy
+exports.shrinkBuf = function (buf, size) {
+  if (buf.length === size) { return buf; }
+  if (buf.subarray) { return buf.subarray(0, size); }
+  buf.length = size;
+  return buf;
+};
+
+
+var fnTyped = {
+  arraySet: function (dest, src, src_offs, len, dest_offs) {
+    if (src.subarray && dest.subarray) {
+      dest.set(src.subarray(src_offs, src_offs + len), dest_offs);
+      return;
+    }
+    // Fallback to ordinary array
+    for (var i = 0; i < len; i++) {
+      dest[dest_offs + i] = src[src_offs + i];
+    }
+  },
+  // Join array of chunks to single array.
+  flattenChunks: function (chunks) {
+    var i, l, len, pos, chunk, result;
+
+    // calculate data length
+    len = 0;
+    for (i = 0, l = chunks.length; i < l; i++) {
+      len += chunks[i].length;
+    }
+
+    // join chunks
+    result = new Uint8Array(len);
+    pos = 0;
+    for (i = 0, l = chunks.length; i < l; i++) {
+      chunk = chunks[i];
+      result.set(chunk, pos);
+      pos += chunk.length;
+    }
+
+    return result;
+  }
+};
+
+var fnUntyped = {
+  arraySet: function (dest, src, src_offs, len, dest_offs) {
+    for (var i = 0; i < len; i++) {
+      dest[dest_offs + i] = src[src_offs + i];
+    }
+  },
+  // Join array of chunks to single array.
+  flattenChunks: function (chunks) {
+    return [].concat.apply([], chunks);
+  }
+};
+
+
+// Enable/Disable typed arrays use, for testing
+//
+exports.setTyped = function (on) {
+  if (on) {
+    exports.Buf8  = Uint8Array;
+    exports.Buf16 = Uint16Array;
+    exports.Buf32 = Int32Array;
+    exports.assign(exports, fnTyped);
+  } else {
+    exports.Buf8  = Array;
+    exports.Buf16 = Array;
+    exports.Buf32 = Array;
+    exports.assign(exports, fnUntyped);
+  }
+};
+
+exports.setTyped(TYPED_OK);
+
+},{}],4:[function(require,module,exports){
+'use strict';
+
+// Note: adler32 takes 12% for level 0 and 2% for level 6.
+// It doesn't worth to make additional optimizationa as in original.
+// Small size is preferable.
+
+function adler32(adler, buf, len, pos) {
+  var s1 = (adler & 0xffff) |0,
+      s2 = ((adler >>> 16) & 0xffff) |0,
+      n = 0;
+
+  while (len !== 0) {
+    // Set limit ~ twice less than 5552, to keep
+    // s2 in 31-bits, because we force signed ints.
+    // in other case %= will fail.
+    n = len > 2000 ? 2000 : len;
+    len -= n;
+
+    do {
+      s1 = (s1 + buf[pos++]) |0;
+      s2 = (s2 + s1) |0;
+    } while (--n);
+
+    s1 %= 65521;
+    s2 %= 65521;
+  }
+
+  return (s1 | (s2 << 16)) |0;
+}
+
+
+module.exports = adler32;
+
+},{}],5:[function(require,module,exports){
+'use strict';
+
+
+module.exports = {
+
+  /* Allowed flush values; see deflate() and inflate() below for details */
+  Z_NO_FLUSH:         0,
+  Z_PARTIAL_FLUSH:    1,
+  Z_SYNC_FLUSH:       2,
+  Z_FULL_FLUSH:       3,
+  Z_FINISH:           4,
+  Z_BLOCK:            5,
+  Z_TREES:            6,
+
+  /*
+	 * Return codes for the compression/decompression functions. Negative values
+	 * are errors, positive values are used for special but normal events.
+	 */
+  Z_OK:               0,
+  Z_STREAM_END:       1,
+  Z_NEED_DICT:        2,
+  Z_ERRNO:           -1,
+  Z_STREAM_ERROR:    -2,
+  Z_DATA_ERROR:      -3,
+  // Z_MEM_ERROR: -4,
+  Z_BUF_ERROR:       -5,
+  // Z_VERSION_ERROR: -6,
+
+  /* compression levels */
+  Z_NO_COMPRESSION:         0,
+  Z_BEST_SPEED:             1,
+  Z_BEST_COMPRESSION:       9,
+  Z_DEFAULT_COMPRESSION:   -1,
+
+
+  Z_FILTERED:               1,
+  Z_HUFFMAN_ONLY:           2,
+  Z_RLE:                    3,
+  Z_FIXED:                  4,
+  Z_DEFAULT_STRATEGY:       0,
+
+  /* Possible values of the data_type field (though see inflate()) */
+  Z_BINARY:                 0,
+  Z_TEXT:                   1,
+  // Z_ASCII: 1, // = Z_TEXT (deprecated)
+  Z_UNKNOWN:                2,
+
+  /* The deflate compression method */
+  Z_DEFLATED:               8
+  // Z_NULL: null // Use -1 or null inline, depending on var type
+};
+
+},{}],6:[function(require,module,exports){
+'use strict';
+
+// Note: we can't get significant speed boost here.
+// So write code to minimize size - no pregenerated tables
+// and array tools dependencies.
+
+
+// Use ordinary array, since untyped makes no boost here
+function makeTable() {
+  var c, table = [];
+
+  for (var n = 0; n < 256; n++) {
+    c = n;
+    for (var k = 0; k < 8; k++) {
+      c = ((c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1));
+    }
+    table[n] = c;
+  }
+
+  return table;
+}
+
+// Create table on load. Just 255 signed longs. Not a problem.
+var crcTable = makeTable();
+
+
+function crc32(crc, buf, len, pos) {
+  var t = crcTable,
+      end = pos + len;
+
+  crc ^= -1;
+
+  for (var i = pos; i < end; i++) {
+    crc = (crc >>> 8) ^ t[(crc ^ buf[i]) & 0xFF];
+  }
+
+  return (crc ^ (-1)); // >>> 0;
+}
+
+
+module.exports = crc32;
+
+},{}],7:[function(require,module,exports){
+'use strict';
+
+var utils   = require('../utils/common');
+var trees   = require('./trees');
+var adler32 = require('./adler32');
+var crc32   = require('./crc32');
+var msg     = require('./messages');
+
+/* Public constants ========================================================== */
+/* =========================================================================== */
+
+
+/* Allowed flush values; see deflate() and inflate() below for details */
+var Z_NO_FLUSH      = 0;
+var Z_PARTIAL_FLUSH = 1;
+// var Z_SYNC_FLUSH = 2;
+var Z_FULL_FLUSH    = 3;
+var Z_FINISH        = 4;
+var Z_BLOCK         = 5;
+// var Z_TREES = 6;
+
+
+/*
+ * Return codes for the compression/decompression functions. Negative values are
+ * errors, positive values are used for special but normal events.
+ */
+var Z_OK            = 0;
+var Z_STREAM_END    = 1;
+// var Z_NEED_DICT = 2;
+// var Z_ERRNO = -1;
+var Z_STREAM_ERROR  = -2;
+var Z_DATA_ERROR    = -3;
+// var Z_MEM_ERROR = -4;
+var Z_BUF_ERROR     = -5;
+// var Z_VERSION_ERROR = -6;
+
+
+/* compression levels */
+// var Z_NO_COMPRESSION = 0;
+// var Z_BEST_SPEED = 1;
+// var Z_BEST_COMPRESSION = 9;
+var Z_DEFAULT_COMPRESSION = -1;
+
+
+var Z_FILTERED            = 1;
+var Z_HUFFMAN_ONLY        = 2;
+var Z_RLE                 = 3;
+var Z_FIXED               = 4;
+var Z_DEFAULT_STRATEGY    = 0;
+
+/* Possible values of the data_type field (though see inflate()) */
+// var Z_BINARY = 0;
+// var Z_TEXT = 1;
+// var Z_ASCII = 1; // = Z_TEXT
+var Z_UNKNOWN             = 2;
+
+
+/* The deflate compression method */
+var Z_DEFLATED  = 8;
+
+/* ============================================================================ */
+
+
+var MAX_MEM_LEVEL = 9;
+/* Maximum value for memLevel in deflateInit2 */
+var MAX_WBITS = 15;
+/* 32K LZ77 window */
+var DEF_MEM_LEVEL = 8;
+
+
+var LENGTH_CODES  = 29;
+/* number of length codes, not counting the special END_BLOCK code */
+var LITERALS      = 256;
+/* number of literal bytes 0..255 */
+var L_CODES       = LITERALS + 1 + LENGTH_CODES;
+/* number of Literal or Length codes, including the END_BLOCK code */
+var D_CODES       = 30;
+/* number of distance codes */
+var BL_CODES      = 19;
+/* number of codes used to transfer the bit lengths */
+var HEAP_SIZE     = 2 * L_CODES + 1;
+/* maximum heap size */
+var MAX_BITS  = 15;
+/* All codes must not exceed MAX_BITS bits */
+
+var MIN_MATCH = 3;
+var MAX_MATCH = 258;
+var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);
+
+var PRESET_DICT = 0x20;
+
+var INIT_STATE = 42;
+var EXTRA_STATE = 69;
+var NAME_STATE = 73;
+var COMMENT_STATE = 91;
+var HCRC_STATE = 103;
+var BUSY_STATE = 113;
+var FINISH_STATE = 666;
+
+var BS_NEED_MORE      = 1; /*
+							 * block not completed, need more input or more
+							 * output
+							 */
+var BS_BLOCK_DONE     = 2; /* block flush performed */
+var BS_FINISH_STARTED = 3; /*
+							 * finish started, need only more output at next
+							 * deflate
+							 */
+var BS_FINISH_DONE    = 4; /* finish done, accept no more input or output */
+
+var OS_CODE = 0x03; // Unix :) . Don't detect, use this default.
+
+function err(strm, errorCode) {
+  strm.msg = msg[errorCode];
+  return errorCode;
+}
+
+function rank(f) {
+  return ((f) << 1) - ((f) > 4 ? 9 : 0);
+}
+
+function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } }
+
+
+/*
+ * =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes through
+ * this function so some applications may wish to modify it to avoid allocating
+ * a large strm->output buffer and copying into it. (See also read_buf()).
+ */
+function flush_pending(strm) {
+  var s = strm.state;
+
+  // _tr_flush_bits(s);
+  var len = s.pending;
+  if (len > strm.avail_out) {
+    len = strm.avail_out;
+  }
+  if (len === 0) { return; }
+
+  utils.arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out);
+  strm.next_out += len;
+  s.pending_out += len;
+  strm.total_out += len;
+  strm.avail_out -= len;
+  s.pending -= len;
+  if (s.pending === 0) {
+    s.pending_out = 0;
+  }
+}
+
+
+function flush_block_only(s, last) {
+  trees._tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last);
+  s.block_start = s.strstart;
+  flush_pending(s.strm);
+}
+
+
+function put_byte(s, b) {
+  s.pending_buf[s.pending++] = b;
+}
+
+
+/*
+ * ========================================================================= Put
+ * a short in the pending buffer. The 16-bit value is put in MSB order. IN
+ * assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+function putShortMSB(s, b) {
+// put_byte(s, (Byte)(b >> 8));
+// put_byte(s, (Byte)(b & 0xff));
+  s.pending_buf[s.pending++] = (b >>> 8) & 0xff;
+  s.pending_buf[s.pending++] = b & 0xff;
+}
+
+
+/*
+ * ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32 and total
+ * number of bytes read. All deflate() input goes through this function so some
+ * applications may wish to modify it to avoid allocating a large strm->input
+ * buffer and copying from it. (See also flush_pending()).
+ */
+function read_buf(strm, buf, start, size) {
+  var len = strm.avail_in;
+
+  if (len > size) { len = size; }
+  if (len === 0) { return 0; }
+
+  strm.avail_in -= len;
+
+  // zmemcpy(buf, strm->next_in, len);
+  utils.arraySet(buf, strm.input, strm.next_in, len, start);
+  if (strm.state.wrap === 1) {
+    strm.adler = adler32(strm.adler, buf, len, start);
+  }
+
+  else if (strm.state.wrap === 2) {
+    strm.adler = crc32(strm.adler, buf, len, start);
+  }
+
+  strm.next_in += len;
+  strm.total_in += len;
+
+  return len;
+}
+
+
+/*
+ * ===========================================================================
+ * Set match_start to the longest match starting at the given string and return
+ * its length. Matches shorter or equal to prev_length are discarded, in which
+ * case the result is equal to prev_length and match_start is garbage. IN
+ * assertions: cur_match is the head of the hash chain for the current string
+ * (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 OUT
+ * assertion: the match length is not greater than s->lookahead.
+ */
+function longest_match(s, cur_match) {
+  var chain_length = s.max_chain_length;      /* max hash chain length */
+  var scan = s.strstart; /* current string */
+  var match;                       /* matched string */
+  var len;                           /* length of current match */
+  var best_len = s.prev_length;              /* best match length so far */
+  var nice_match = s.nice_match;             /* stop if match long enough */
+  var limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ?
+      s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/* NIL */;
+
+  var _win = s.window; // shortcut
+
+  var wmask = s.w_mask;
+  var prev  = s.prev;
+
+  /*
+	 * Stop when cur_match becomes <= limit. To simplify the code, we prevent
+	 * matches with the string of window index 0.
+	 */
+
+  var strend = s.strstart + MAX_MATCH;
+  var scan_end1  = _win[scan + best_len - 1];
+  var scan_end   = _win[scan + best_len];
+
+  /*
+	 * The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+	 * It is easy to get rid of this optimization if necessary.
+	 */
+  // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+  /* Do not waste too much time if we already have a good match: */
+  if (s.prev_length >= s.good_match) {
+    chain_length >>= 2;
+  }
+  /*
+	 * Do not look for matches beyond the end of the input. This is necessary to
+	 * make deflate deterministic.
+	 */
+  if (nice_match > s.lookahead) { nice_match = s.lookahead; }
+
+  // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need
+	// lookahead");
+
+  do {
+    // Assert(cur_match < s->strstart, "no future");
+    match = cur_match;
+
+    /*
+	 * Skip to next match if the match length cannot increase or if the match
+	 * length is less than 2. Note that the checks below for insufficient
+	 * lookahead only occur occasionally for performance reasons. Therefore
+	 * uninitialized memory will be accessed, and conditional jumps will be made
+	 * that depend on those values. However the length of the match is limited
+	 * to the lookahead, so the output of deflate is not affected by the
+	 * uninitialized values.
+	 */
+
+    if (_win[match + best_len]     !== scan_end  ||
+        _win[match + best_len - 1] !== scan_end1 ||
+        _win[match]                !== _win[scan] ||
+        _win[++match]              !== _win[scan + 1]) {
+      continue;
+    }
+
+    /*
+	 * The check at best_len-1 can be removed because it will be made again
+	 * later. (This heuristic is not always a win.) It is not necessary to
+	 * compare scan[2] and match[2] since they are always equal when the other
+	 * bytes match, given that the hash keys are equal and that HASH_BITS >= 8.
+	 */
+    scan += 2;
+    match++;
+    // Assert(*scan == *match, "match[2]?");
+
+    /*
+	 * We check for insufficient lookahead only every 8th comparison; the 256th
+	 * check will be made at strstart+258.
+	 */
+    do {
+      /* jshint noempty:false */
+    } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
+             _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
+             _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
+             _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
+             scan < strend);
+
+    // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+    len = MAX_MATCH - (strend - scan);
+    scan = strend - MAX_MATCH;
+
+    if (len > best_len) {
+      s.match_start = cur_match;
+      best_len = len;
+      if (len >= nice_match) {
+        break;
+      }
+      scan_end1  = _win[scan + best_len - 1];
+      scan_end   = _win[scan + best_len];
+    }
+  } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0);
+
+  if (best_len <= s.lookahead) {
+    return best_len;
+  }
+  return s.lookahead;
+}
+
+
+/*
+ * ===========================================================================
+ * Fill the window when the lookahead becomes insufficient. Updates strstart and
+ * lookahead.
+ * 
+ * IN assertion: lookahead < MIN_LOOKAHEAD OUT assertions: strstart <=
+ * window_size-MIN_LOOKAHEAD At least one byte has been read, or avail_in == 0;
+ * reads are performed for at least two bytes (required for the zip
+ * translate_eol option -- not supported here).
+ */
+function fill_window(s) {
+  var _w_size = s.w_size;
+  var p, n, m, more, str;
+
+  // Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
+
+  do {
+    more = s.window_size - s.lookahead - s.strstart;
+
+    // JS ints have 32 bit, block below not needed
+    /* Deal with !@#$% 64K limit: */
+    // if (sizeof(int) <= 2) {
+    // if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+    // more = wsize;
+    //
+    // } else if (more == (unsigned)(-1)) {
+    // /* Very unlikely, but possible on 16 bit machine if
+    // * strstart == 0 && lookahead == 1 (input done a byte at time)
+    // */
+    // more--;
+    // }
+    // }
+
+
+    /*
+	 * If the window is almost full and there is insufficient lookahead, move
+	 * the upper half to the lower one to make room in the upper half.
+	 */
+    if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) {
+
+      utils.arraySet(s.window, s.window, _w_size, _w_size, 0);
+      s.match_start -= _w_size;
+      s.strstart -= _w_size;
+      /* we now have strstart >= MAX_DIST */
+      s.block_start -= _w_size;
+
+      /*
+		 * Slide the hash table (could be avoided with 32 bit values at the
+		 * expense of memory usage). We slide even when level == 0 to keep the
+		 * hash table consistent if we switch back to level > 0 later. (Using
+		 * level 0 permanently is not an optimal usage of zlib, so we don't care
+		 * about this pathological case.)
+		 */
+
+      n = s.hash_size;
+      p = n;
+      do {
+        m = s.head[--p];
+        s.head[p] = (m >= _w_size ? m - _w_size : 0);
+      } while (--n);
+
+      n = _w_size;
+      p = n;
+      do {
+        m = s.prev[--p];
+        s.prev[p] = (m >= _w_size ? m - _w_size : 0);
+        /*
+		 * If n is not on any hash chain, prev[n] is garbage but its value will
+		 * never be used.
+		 */
+      } while (--n);
+
+      more += _w_size;
+    }
+    if (s.strm.avail_in === 0) {
+      break;
+    }
+
+    /*
+	 * If there was no sliding: strstart <= WSIZE+MAX_DIST-1 && lookahead <=
+	 * MIN_LOOKAHEAD - 1 && more == window_size - lookahead - strstart => more >=
+	 * window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) => more >=
+	 * window_size - 2*WSIZE + 2 In the BIG_MEM or MMAP case (not yet
+	 * supported), window_size == input_size + MIN_LOOKAHEAD && strstart +
+	 * s->lookahead <= input_size => more >= MIN_LOOKAHEAD. Otherwise,
+	 * window_size == 2*WSIZE so more >= 2. If there was sliding, more >= WSIZE.
+	 * So in all cases, more >= 2.
+	 */
+    // Assert(more >= 2, "more < 2");
+    n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more);
+    s.lookahead += n;
+
+    /* Initialize the hash value now that we have some input: */
+    if (s.lookahead + s.insert >= MIN_MATCH) {
+      str = s.strstart - s.insert;
+      s.ins_h = s.window[str];
+
+      /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */
+      s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask;
+// #if MIN_MATCH != 3
+// Call update_hash() MIN_MATCH-3 more times
+// #endif
+      while (s.insert) {
+        /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */
+        s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;
+
+        s.prev[str & s.w_mask] = s.head[s.ins_h];
+        s.head[s.ins_h] = str;
+        str++;
+        s.insert--;
+        if (s.lookahead + s.insert < MIN_MATCH) {
+          break;
+        }
+      }
+    }
+    /*
+	 * If the whole input has less than MIN_MATCH bytes, ins_h is garbage, but
+	 * this is not important since only literal bytes will be emitted.
+	 */
+
+  } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0);
+
+  /*
+	 * If the WIN_INIT bytes after the end of the current data have never been
+	 * written, then zero those bytes in order to avoid memory check reports of
+	 * the use of uninitialized (or uninitialised as Julian writes) bytes by the
+	 * longest match routines. Update the high water mark for the next time
+	 * through here. WIN_INIT is set to MAX_MATCH since the longest match
+	 * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
+	 */
+// if (s.high_water < s.window_size) {
+// var curr = s.strstart + s.lookahead;
+// var init = 0;
+//
+// if (s.high_water < curr) {
+// /* Previous high water mark below current data -- zero WIN_INIT
+// * bytes or up to end of window, whichever is less.
+// */
+// init = s.window_size - curr;
+// if (init > WIN_INIT)
+// init = WIN_INIT;
+// zmemzero(s->window + curr, (unsigned)init);
+// s->high_water = curr + init;
+// }
+// else if (s->high_water < (ulg)curr + WIN_INIT) {
+// /* High water mark at or above current data, but below current data
+// * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
+// * to end of window, whichever is less.
+// */
+// init = (ulg)curr + WIN_INIT - s->high_water;
+// if (init > s->window_size - s->high_water)
+// init = s->window_size - s->high_water;
+// zmemzero(s->window + s->high_water, (unsigned)init);
+// s->high_water += init;
+// }
+// }
+//
+// Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
+// "not enough room for search");
+}
+
+/*
+ * ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state. This function does not insert new strings in the
+ * dictionary since uncompressible data is probably not useful. This function is
+ * used only for the level=0 compression option. NOTE: this function should be
+ * optimized to avoid extra copying from window to pending_buf.
+ */
+function deflate_stored(s, flush) {
+  /*
+	 * Stored blocks are limited to 0xffff bytes, pending_buf is limited to
+	 * pending_buf_size, and each stored block has a 5 byte header:
+	 */
+  var max_block_size = 0xffff;
+
+  if (max_block_size > s.pending_buf_size - 5) {
+    max_block_size = s.pending_buf_size - 5;
+  }
+
+  /* Copy as much as possible from input to output: */
+  for (;;) {
+    /* Fill the window as much as possible: */
+    if (s.lookahead <= 1) {
+
+      // Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+      // s->block_start >= (long)s->w_size, "slide too late");
+// if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) ||
+// s.block_start >= s.w_size)) {
+// throw new Error("slide too late");
+// }
+
+      fill_window(s);
+      if (s.lookahead === 0 && flush === Z_NO_FLUSH) {
+        return BS_NEED_MORE;
+      }
+
+      if (s.lookahead === 0) {
+        break;
+      }
+      /* flush the current block */
+    }
+    // Assert(s->block_start >= 0L, "block gone");
+// if (s.block_start < 0) throw new Error("block gone");
+
+    s.strstart += s.lookahead;
+    s.lookahead = 0;
+
+    /* Emit a stored block if pending_buf will be full: */
+    var max_start = s.block_start + max_block_size;
+
+    if (s.strstart === 0 || s.strstart >= max_start) {
+      /* strstart == 0 is possible when wraparound on 16-bit machine */
+      s.lookahead = s.strstart - max_start;
+      s.strstart = max_start;
+      /** * FLUSH_BLOCK(s, 0); ** */
+      flush_block_only(s, false);
+      if (s.strm.avail_out === 0) {
+        return BS_NEED_MORE;
+      }
+      /***/
+
+
+    }
+    /*
+	 * Flush if we may have to slide, otherwise block_start may become negative
+	 * and the data will be gone:
+	 */
+    if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) {
+      /** * FLUSH_BLOCK(s, 0); ** */
+      flush_block_only(s, false);
+      if (s.strm.avail_out === 0) {
+        return BS_NEED_MORE;
+      }
+      /***/
+    }
+  }
+
+  s.insert = 0;
+
+  if (flush === Z_FINISH) {
+    /** * FLUSH_BLOCK(s, 1); ** */
+    flush_block_only(s, true);
+    if (s.strm.avail_out === 0) {
+      return BS_FINISH_STARTED;
+    }
+    /***/
+    return BS_FINISH_DONE;
+  }
+
+  if (s.strstart > s.block_start) {
+    /** * FLUSH_BLOCK(s, 0); ** */
+    flush_block_only(s, false);
+    if (s.strm.avail_out === 0) {
+      return BS_NEED_MORE;
+    }
+    /***/
+  }
+
+  return BS_NEED_MORE;
+}
+
+/*
+ * ===========================================================================
+ * Compress as much as possible from the input stream, return the current block
+ * state. This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+function deflate_fast(s, flush) {
+  var hash_head;        /* head of the hash chain */
+  var bflush;           /* set if current block must be flushed */
+
+  for (;;) {
+    /*
+	 * Make sure that we always have enough lookahead, except at the end of the
+	 * input file. We need MAX_MATCH bytes for the next match, plus MIN_MATCH
+	 * bytes to insert the string following the next match.
+	 */
+    if (s.lookahead < MIN_LOOKAHEAD) {
+      fill_window(s);
+      if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
+        return BS_NEED_MORE;
+      }
+      if (s.lookahead === 0) {
+        break; /* flush the current block */
+      }
+    }
+
+    /*
+	 * Insert the string window[strstart .. strstart+2] in the dictionary, and
+	 * set hash_head to the head of the hash chain:
+	 */
+    hash_head = 0/* NIL */;
+    if (s.lookahead >= MIN_MATCH) {
+      /** * INSERT_STRING(s, s.strstart, hash_head); ** */
+      s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
+      hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
+      s.head[s.ins_h] = s.strstart;
+      /***/
+    }
+
+    /*
+	 * Find the longest match, discarding those <= prev_length. At this point we
+	 * have always match_length < MIN_MATCH
+	 */
+    if (hash_head !== 0/* NIL */ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) {
+      /*
+		 * To simplify the code, we prevent matches with the string of window
+		 * index 0 (in particular we have to avoid a match of the string with
+		 * itself at the start of the input file).
+		 */
+      s.match_length = longest_match(s, hash_head);
+      /* longest_match() sets match_start */
+    }
+    if (s.match_length >= MIN_MATCH) {
+      // check_match(s, s.strstart, s.match_start, s.match_length); // for
+		// debug only
+
+      /***********************************************************************
+		 * * _tr_tally_dist(s, s.strstart - s.match_start, s.match_length -
+		 * MIN_MATCH, bflush);
+		 **********************************************************************/
+      bflush = trees._tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH);
+
+      s.lookahead -= s.match_length;
+
+      /*
+		 * Insert new strings in the hash table only if the match length is not
+		 * too large. This saves time but degrades compression.
+		 */
+      if (s.match_length <= s.max_lazy_match/* max_insert_length */ && s.lookahead >= MIN_MATCH) {
+        s.match_length--; /* string at strstart already in table */
+        do {
+          s.strstart++;
+          /** * INSERT_STRING(s, s.strstart, hash_head); ** */
+          s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
+          hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
+          s.head[s.ins_h] = s.strstart;
+          /***/
+          /*
+			 * strstart never exceeds WSIZE-MAX_MATCH, so there are always
+			 * MIN_MATCH bytes ahead.
+			 */
+        } while (--s.match_length !== 0);
+        s.strstart++;
+      } else
+      {
+        s.strstart += s.match_length;
+        s.match_length = 0;
+        s.ins_h = s.window[s.strstart];
+        /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */
+        s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask;
+
+// #if MIN_MATCH != 3
+// Call UPDATE_HASH() MIN_MATCH-3 more times
+// #endif
+        /*
+		 * If lookahead < MIN_MATCH, ins_h is garbage, but it does not matter
+		 * since it will be recomputed at next deflate call.
+		 */
+      }
+    } else {
+      /* No match, output a literal byte */
+      // Tracevv((stderr,"%c", s.window[s.strstart]));
+      /** * _tr_tally_lit(s, s.window[s.strstart], bflush); ** */
+      bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
+
+      s.lookahead--;
+      s.strstart++;
+    }
+    if (bflush) {
+      /** * FLUSH_BLOCK(s, 0); ** */
+      flush_block_only(s, false);
+      if (s.strm.avail_out === 0) {
+        return BS_NEED_MORE;
+      }
+      /***/
+    }
+  }
+  s.insert = ((s.strstart < (MIN_MATCH - 1)) ? s.strstart : MIN_MATCH - 1);
+  if (flush === Z_FINISH) {
+    /** * FLUSH_BLOCK(s, 1); ** */
+    flush_block_only(s, true);
+    if (s.strm.avail_out === 0) {
+      return BS_FINISH_STARTED;
+    }
+    /***/
+    return BS_FINISH_DONE;
+  }
+  if (s.last_lit) {
+    /** * FLUSH_BLOCK(s, 0); ** */
+    flush_block_only(s, false);
+    if (s.strm.avail_out === 0) {
+      return BS_NEED_MORE;
+    }
+    /***/
+  }
+  return BS_BLOCK_DONE;
+}
+
+/*
+ * ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy evaluation for
+ * matches: a match is finally adopted only if there is no better match at the
+ * next window position.
+ */
+function deflate_slow(s, flush) {
+  var hash_head;          /* head of hash chain */
+  var bflush;              /* set if current block must be flushed */
+
+  var max_insert;
+
+  /* Process the input block. */
+  for (;;) {
+    /*
+	 * Make sure that we always have enough lookahead, except at the end of the
+	 * input file. We need MAX_MATCH bytes for the next match, plus MIN_MATCH
+	 * bytes to insert the string following the next match.
+	 */
+    if (s.lookahead < MIN_LOOKAHEAD) {
+      fill_window(s);
+      if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
+        return BS_NEED_MORE;
+      }
+      if (s.lookahead === 0) { break; } /* flush the current block */
+    }
+
+    /*
+	 * Insert the string window[strstart .. strstart+2] in the dictionary, and
+	 * set hash_head to the head of the hash chain:
+	 */
+    hash_head = 0/* NIL */;
+    if (s.lookahead >= MIN_MATCH) {
+      /** * INSERT_STRING(s, s.strstart, hash_head); ** */
+      s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
+      hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
+      s.head[s.ins_h] = s.strstart;
+      /***/
+    }
+
+    /*
+	 * Find the longest match, discarding those <= prev_length.
+	 */
+    s.prev_length = s.match_length;
+    s.prev_match = s.match_start;
+    s.match_length = MIN_MATCH - 1;
+
+    if (hash_head !== 0/* NIL */ && s.prev_length < s.max_lazy_match &&
+        s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/* MAX_DIST(s) */) {
+      /*
+		 * To simplify the code, we prevent matches with the string of window
+		 * index 0 (in particular we have to avoid a match of the string with
+		 * itself at the start of the input file).
+		 */
+      s.match_length = longest_match(s, hash_head);
+      /* longest_match() sets match_start */
+
+      if (s.match_length <= 5 &&
+         (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH && s.strstart - s.match_start > 4096/* TOO_FAR */))) {
+
+        /*
+		 * If prev_match is also MIN_MATCH, match_start is garbage but we will
+		 * ignore the current match anyway.
+		 */
+        s.match_length = MIN_MATCH - 1;
+      }
+    }
+    /*
+	 * If there was a match at the previous step and the current match is not
+	 * better, output the previous match:
+	 */
+    if (s.prev_length >= MIN_MATCH && s.match_length <= s.prev_length) {
+      max_insert = s.strstart + s.lookahead - MIN_MATCH;
+      /* Do not insert strings in hash table beyond this. */
+
+      // check_match(s, s.strstart-1, s.prev_match, s.prev_length);
+
+      /***********************************************************************
+		 * *_tr_tally_dist(s, s.strstart - 1 - s.prev_match, s.prev_length -
+		 * MIN_MATCH, bflush);
+		 **********************************************************************/
+      bflush = trees._tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH);
+      /*
+		 * Insert in hash table all strings up to the end of the match.
+		 * strstart-1 and strstart are already inserted. If there is not enough
+		 * lookahead, the last two strings are not inserted in the hash table.
+		 */
+      s.lookahead -= s.prev_length - 1;
+      s.prev_length -= 2;
+      do {
+        if (++s.strstart <= max_insert) {
+          /** * INSERT_STRING(s, s.strstart, hash_head); ** */
+          s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH - 1]) & s.hash_mask;
+          hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
+          s.head[s.ins_h] = s.strstart;
+          /***/
+        }
+      } while (--s.prev_length !== 0);
+      s.match_available = 0;
+      s.match_length = MIN_MATCH - 1;
+      s.strstart++;
+
+      if (bflush) {
+        /** * FLUSH_BLOCK(s, 0); ** */
+        flush_block_only(s, false);
+        if (s.strm.avail_out === 0) {
+          return BS_NEED_MORE;
+        }
+        /***/
+      }
+
+    } else if (s.match_available) {
+      /*
+		 * If there was no match at the previous position, output a single
+		 * literal. If there was a match but the current match is longer,
+		 * truncate the previous match to a single literal.
+		 */
+      // Tracevv((stderr,"%c", s->window[s->strstart-1]));
+      /** * _tr_tally_lit(s, s.window[s.strstart-1], bflush); ** */
+      bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]);
+
+      if (bflush) {
+        /** * FLUSH_BLOCK_ONLY(s, 0) ** */
+        flush_block_only(s, false);
+        /***/
+      }
+      s.strstart++;
+      s.lookahead--;
+      if (s.strm.avail_out === 0) {
+        return BS_NEED_MORE;
+      }
+    } else {
+      /*
+		 * There is no previous match to compare with, wait for the next step to
+		 * decide.
+		 */
+      s.match_available = 1;
+      s.strstart++;
+      s.lookahead--;
+    }
+  }
+  // Assert (flush != Z_NO_FLUSH, "no flush?");
+  if (s.match_available) {
+    // Tracevv((stderr,"%c", s->window[s->strstart-1]));
+    /** * _tr_tally_lit(s, s.window[s.strstart-1], bflush); ** */
+    bflush = trees._tr_tally(s, 0, s.window[s.strstart - 1]);
+
+    s.match_available = 0;
+  }
+  s.insert = s.strstart < MIN_MATCH - 1 ? s.strstart : MIN_MATCH - 1;
+  if (flush === Z_FINISH) {
+    /** * FLUSH_BLOCK(s, 1); ** */
+    flush_block_only(s, true);
+    if (s.strm.avail_out === 0) {
+      return BS_FINISH_STARTED;
+    }
+    /***/
+    return BS_FINISH_DONE;
+  }
+  if (s.last_lit) {
+    /** * FLUSH_BLOCK(s, 0); ** */
+    flush_block_only(s, false);
+    if (s.strm.avail_out === 0) {
+      return BS_NEED_MORE;
+    }
+    /***/
+  }
+
+  return BS_BLOCK_DONE;
+}
+
+
+/*
+ * ===========================================================================
+ * For Z_RLE, simply look for runs of bytes, generate matches only of distance
+ * one. Do not maintain a hash table. (It will be regenerated if this run of
+ * deflate switches away from Z_RLE.)
+ */
+function deflate_rle(s, flush) {
+  var bflush;            /* set if current block must be flushed */
+  var prev;              /* byte at distance one to match */
+  var scan, strend;      /* scan goes up to strend for length of run */
+
+  var _win = s.window;
+
+  for (;;) {
+    /*
+	 * Make sure that we always have enough lookahead, except at the end of the
+	 * input file. We need MAX_MATCH bytes for the longest run, plus one for the
+	 * unrolled loop.
+	 */
+    if (s.lookahead <= MAX_MATCH) {
+      fill_window(s);
+      if (s.lookahead <= MAX_MATCH && flush === Z_NO_FLUSH) {
+        return BS_NEED_MORE;
+      }
+      if (s.lookahead === 0) { break; } /* flush the current block */
+    }
+
+    /* See how many times the previous byte repeats */
+    s.match_length = 0;
+    if (s.lookahead >= MIN_MATCH && s.strstart > 0) {
+      scan = s.strstart - 1;
+      prev = _win[scan];
+      if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) {
+        strend = s.strstart + MAX_MATCH;
+        do {
+          /* jshint noempty:false */
+        } while (prev === _win[++scan] && prev === _win[++scan] &&
+                 prev === _win[++scan] && prev === _win[++scan] &&
+                 prev === _win[++scan] && prev === _win[++scan] &&
+                 prev === _win[++scan] && prev === _win[++scan] &&
+                 scan < strend);
+        s.match_length = MAX_MATCH - (strend - scan);
+        if (s.match_length > s.lookahead) {
+          s.match_length = s.lookahead;
+        }
+      }
+      // Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
+    }
+
+    /* Emit match if have run of MIN_MATCH or longer, else emit literal */
+    if (s.match_length >= MIN_MATCH) {
+      // check_match(s, s.strstart, s.strstart - 1, s.match_length);
+
+      /** * _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ** */
+      bflush = trees._tr_tally(s, 1, s.match_length - MIN_MATCH);
+
+      s.lookahead -= s.match_length;
+      s.strstart += s.match_length;
+      s.match_length = 0;
+    } else {
+      /* No match, output a literal byte */
+      // Tracevv((stderr,"%c", s->window[s->strstart]));
+      /** * _tr_tally_lit(s, s.window[s.strstart], bflush); ** */
+      bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
+
+      s.lookahead--;
+      s.strstart++;
+    }
+    if (bflush) {
+      /** * FLUSH_BLOCK(s, 0); ** */
+      flush_block_only(s, false);
+      if (s.strm.avail_out === 0) {
+        return BS_NEED_MORE;
+      }
+      /***/
+    }
+  }
+  s.insert = 0;
+  if (flush === Z_FINISH) {
+    /** * FLUSH_BLOCK(s, 1); ** */
+    flush_block_only(s, true);
+    if (s.strm.avail_out === 0) {
+      return BS_FINISH_STARTED;
+    }
+    /***/
+    return BS_FINISH_DONE;
+  }
+  if (s.last_lit) {
+    /** * FLUSH_BLOCK(s, 0); ** */
+    flush_block_only(s, false);
+    if (s.strm.avail_out === 0) {
+      return BS_NEED_MORE;
+    }
+    /***/
+  }
+  return BS_BLOCK_DONE;
+}
+
+/*
+ * ===========================================================================
+ * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table.
+ * (It will be regenerated if this run of deflate switches away from Huffman.)
+ */
+function deflate_huff(s, flush) {
+  var bflush;             /* set if current block must be flushed */
+
+  for (;;) {
+    /* Make sure that we have a literal to write. */
+    if (s.lookahead === 0) {
+      fill_window(s);
+      if (s.lookahead === 0) {
+        if (flush === Z_NO_FLUSH) {
+          return BS_NEED_MORE;
+        }
+        break;      /* flush the current block */
+      }
+    }
+
+    /* Output a literal byte */
+    s.match_length = 0;
+    // Tracevv((stderr,"%c", s->window[s->strstart]));
+    /** * _tr_tally_lit(s, s.window[s.strstart], bflush); ** */
+    bflush = trees._tr_tally(s, 0, s.window[s.strstart]);
+    s.lookahead--;
+    s.strstart++;
+    if (bflush) {
+      /** * FLUSH_BLOCK(s, 0); ** */
+      flush_block_only(s, false);
+      if (s.strm.avail_out === 0) {
+        return BS_NEED_MORE;
+      }
+      /***/
+    }
+  }
+  s.insert = 0;
+  if (flush === Z_FINISH) {
+    /** * FLUSH_BLOCK(s, 1); ** */
+    flush_block_only(s, true);
+    if (s.strm.avail_out === 0) {
+      return BS_FINISH_STARTED;
+    }
+    /***/
+    return BS_FINISH_DONE;
+  }
+  if (s.last_lit) {
+    /** * FLUSH_BLOCK(s, 0); ** */
+    flush_block_only(s, false);
+    if (s.strm.avail_out === 0) {
+      return BS_NEED_MORE;
+    }
+    /***/
+  }
+  return BS_BLOCK_DONE;
+}
+
+/*
+ * Values for max_lazy_match, good_match and max_chain_length, depending on the
+ * desired pack level (0..9). The values given below have been tuned to exclude
+ * worst case performance for pathological files. Better values may be found for
+ * specific files.
+ */
+function Config(good_length, max_lazy, nice_length, max_chain, func) {
+  this.good_length = good_length;
+  this.max_lazy = max_lazy;
+  this.nice_length = nice_length;
+  this.max_chain = max_chain;
+  this.func = func;
+}
+
+var configuration_table;
+
+configuration_table = [
+  /* good lazy nice chain */
+  new Config(0, 0, 0, 0, deflate_stored),          /* 0 store only */
+  new Config(4, 4, 8, 4, deflate_fast),            /*
+													 * 1 max speed, no lazy
+													 * matches
+													 */
+  new Config(4, 5, 16, 8, deflate_fast),           /* 2 */
+  new Config(4, 6, 32, 32, deflate_fast),          /* 3 */
+
+  new Config(4, 4, 16, 16, deflate_slow),          /* 4 lazy matches */
+  new Config(8, 16, 32, 32, deflate_slow),         /* 5 */
+  new Config(8, 16, 128, 128, deflate_slow),       /* 6 */
+  new Config(8, 32, 128, 256, deflate_slow),       /* 7 */
+  new Config(32, 128, 258, 1024, deflate_slow),    /* 8 */
+  new Config(32, 258, 258, 4096, deflate_slow)     /* 9 max compression */
+];
+
+
+/*
+ * ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+function lm_init(s) {
+  s.window_size = 2 * s.w_size;
+
+  /** * CLEAR_HASH(s); ** */
+  zero(s.head); // Fill with NIL (= 0);
+
+  /*
+	 * Set the default configuration parameters:
+	 */
+  s.max_lazy_match = configuration_table[s.level].max_lazy;
+  s.good_match = configuration_table[s.level].good_length;
+  s.nice_match = configuration_table[s.level].nice_length;
+  s.max_chain_length = configuration_table[s.level].max_chain;
+
+  s.strstart = 0;
+  s.block_start = 0;
+  s.lookahead = 0;
+  s.insert = 0;
+  s.match_length = s.prev_length = MIN_MATCH - 1;
+  s.match_available = 0;
+  s.ins_h = 0;
+}
+
+
+function DeflateState() {
+  this.strm = null;            /* pointer back to this zlib stream */
+  this.status = 0;            /* as the name implies */
+  this.pending_buf = null;      /* output still pending */
+  this.pending_buf_size = 0;  /* size of pending_buf */
+  this.pending_out = 0;       /* next pending byte to output to the stream */
+  this.pending = 0;           /* nb of bytes in the pending buffer */
+  this.wrap = 0;              /* bit 0 true for zlib, bit 1 true for gzip */
+  this.gzhead = null;         /* gzip header information to write */
+  this.gzindex = 0;           /* where in extra, name, or comment */
+  this.method = Z_DEFLATED; /* can only be DEFLATED */
+  this.last_flush = -1;   /* value of flush param for previous deflate call */
+
+  this.w_size = 0;  /* LZ77 window size (32K by default) */
+  this.w_bits = 0;  /* log2(w_size) (8..16) */
+  this.w_mask = 0;  /* w_size - 1 */
+
+  this.window = null;
+  /*
+	 * Sliding window. Input bytes are read into the second half of the window,
+	 * and move to the first half later to keep a dictionary of at least wSize
+	 * bytes. With this organization, matches are limited to a distance of
+	 * wSize-MAX_MATCH bytes, but this ensures that IO is always performed with
+	 * a length multiple of the block size.
+	 */
+
+  this.window_size = 0;
+  /*
+	 * Actual size of window: 2*wSize, except when the user input buffer is
+	 * directly used as sliding window.
+	 */
+
+  this.prev = null;
+  /*
+	 * Link to older string with same hash index. To limit the size of this
+	 * array to 64K, this link is maintained only for the last 32K strings. An
+	 * index in this array is thus a window index modulo 32K.
+	 */
+
+  this.head = null;   /* Heads of the hash chains or NIL. */
+
+  this.ins_h = 0;       /* hash index of string to be inserted */
+  this.hash_size = 0;   /* number of elements in hash table */
+  this.hash_bits = 0;   /* log2(hash_size) */
+  this.hash_mask = 0;   /* hash_size-1 */
+
+  this.hash_shift = 0;
+  /*
+	 * Number of bits by which ins_h must be shifted at each input step. It must
+	 * be such that after MIN_MATCH steps, the oldest byte no longer takes part
+	 * in the hash key, that is: hash_shift * MIN_MATCH >= hash_bits
+	 */
+
+  this.block_start = 0;
+  /*
+	 * Window position at the beginning of the current output block. Gets
+	 * negative when the window is moved backwards.
+	 */
+
+  this.match_length = 0;      /* length of best match */
+  this.prev_match = 0;        /* previous match */
+  this.match_available = 0;   /* set if previous match exists */
+  this.strstart = 0;          /* start of string to insert */
+  this.match_start = 0;       /* start of matching string */
+  this.lookahead = 0;         /* number of valid bytes ahead in window */
+
+  this.prev_length = 0;
+  /*
+	 * Length of the best match at previous step. Matches not greater than this
+	 * are discarded. This is used in the lazy match evaluation.
+	 */
+
+  this.max_chain_length = 0;
+  /*
+	 * To speed up deflation, hash chains are never searched beyond this length.
+	 * A higher limit improves compression ratio but degrades the speed.
+	 */
+
+  this.max_lazy_match = 0;
+  /*
+	 * Attempt to find a better match only when the current match is strictly
+	 * smaller than this value. This mechanism is used only for compression
+	 * levels >= 4.
+	 */
+  // That's alias to max_lazy_match, don't use directly
+  // this.max_insert_length = 0;
+  /*
+	 * Insert new strings in the hash table only if the match length is not
+	 * greater than this length. This saves time but degrades compression.
+	 * max_insert_length is used only for compression levels <= 3.
+	 */
+
+  this.level = 0;     /* compression level (1..9) */
+  this.strategy = 0;  /* favor or force Huffman coding */
+
+  this.good_match = 0;
+  /* Use a faster search when the previous match is longer than this */
+
+  this.nice_match = 0; /* Stop searching when current match exceeds this */
+
+              /* used by trees.c: */
+
+  /* Didn't use ct_data typedef below to suppress compiler warning */
+
+  // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
+  // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+  // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths
+	// */
+
+  // Use flat array of DOUBLE size, with interleaved fata,
+  // because JS does not support effective
+  this.dyn_ltree  = new utils.Buf16(HEAP_SIZE * 2);
+  this.dyn_dtree  = new utils.Buf16((2 * D_CODES + 1) * 2);
+  this.bl_tree    = new utils.Buf16((2 * BL_CODES + 1) * 2);
+  zero(this.dyn_ltree);
+  zero(this.dyn_dtree);
+  zero(this.bl_tree);
+
+  this.l_desc   = null;         /* desc. for literal tree */
+  this.d_desc   = null;         /* desc. for distance tree */
+  this.bl_desc  = null;         /* desc. for bit length tree */
+
+  // ush bl_count[MAX_BITS+1];
+  this.bl_count = new utils.Buf16(MAX_BITS + 1);
+  /* number of codes at each bit length for an optimal tree */
+
+  // int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
+  this.heap = new utils.Buf16(2 * L_CODES + 1);  /*
+													 * heap used to build the
+													 * Huffman trees
+													 */
+  zero(this.heap);
+
+  this.heap_len = 0;               /* number of elements in the heap */
+  this.heap_max = 0;               /* element of largest frequency */
+  /*
+	 * The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+	 * The same heap array is used to build all trees.
+	 */
+
+  this.depth = new utils.Buf16(2 * L_CODES + 1); // uch depth[2*L_CODES+1];
+  zero(this.depth);
+  /*
+	 * Depth of each subtree used as tie breaker for trees of equal frequency
+	 */
+
+  this.l_buf = 0;          /* buffer index for literals or lengths */
+
+  this.lit_bufsize = 0;
+  /*
+	 * Size of match buffer for literals/lengths. There are 4 reasons for
+	 * limiting lit_bufsize to 64K: - frequencies can be kept in 16 bit counters -
+	 * if compression is not successful for the first block, all input data is
+	 * still in the window so we can still emit a stored block even when input
+	 * comes from standard input. (This can also be done for all blocks if
+	 * lit_bufsize is not greater than 32K.) - if compression is not successful
+	 * for a file smaller than 64K, we can even emit a stored file instead of a
+	 * stored block (saving 5 bytes). This is applicable only for zip (not gzip
+	 * or zlib). - creating new Huffman trees less frequently may not provide
+	 * fast adaptation to changes in the input data statistics. (Take for
+	 * example a binary file with poorly compressible code followed by a highly
+	 * compressible string table.) Smaller buffer sizes give fast adaptation but
+	 * have of course the overhead of transmitting trees more frequently. - I
+	 * can't count above 4
+	 */
+
+  this.last_lit = 0;      /* running index in l_buf */
+
+  this.d_buf = 0;
+  /*
+	 * Buffer index for distances. To simplify the code, d_buf and l_buf have
+	 * the same number of elements. To use different lengths, an extra flag
+	 * array would be necessary.
+	 */
+
+  this.opt_len = 0;       /* bit length of current block with optimal trees */
+  this.static_len = 0;    /* bit length of current block with static trees */
+  this.matches = 0;       /* number of string matches in current block */
+  this.insert = 0;        /* bytes at end of window left to insert */
+
+
+  this.bi_buf = 0;
+  /*
+	 * Output buffer. bits are inserted starting at the bottom (least
+	 * significant bits).
+	 */
+  this.bi_valid = 0;
+  /*
+	 * Number of valid bits in bi_buf. All bits above the last valid bit are
+	 * always zero.
+	 */
+
+  // Used for window memory init. We safely ignore it for JS. That makes
+  // sense only for pointers and memory check tools.
+  // this.high_water = 0;
+  /*
+	 * High water mark offset in window for initialized bytes -- bytes above
+	 * this are set to zero in order to avoid memory check warnings when longest
+	 * match routines access bytes past the input. This is then updated to the
+	 * new high water mark.
+	 */
+}
+
+
+function deflateResetKeep(strm) {
+  var s;
+
+  if (!strm || !strm.state) {
+    return err(strm, Z_STREAM_ERROR);
+  }
+
+  strm.total_in = strm.total_out = 0;
+  strm.data_type = Z_UNKNOWN;
+
+  s = strm.state;
+  s.pending = 0;
+  s.pending_out = 0;
+
+  if (s.wrap < 0) {
+    s.wrap = -s.wrap;
+    /* was made negative by deflate(..., Z_FINISH); */
+  }
+  s.status = (s.wrap ? INIT_STATE : BUSY_STATE);
+  strm.adler = (s.wrap === 2) ?
+    0  // crc32(0, Z_NULL, 0)
+  :
+    1; // adler32(0, Z_NULL, 0)
+  s.last_flush = Z_NO_FLUSH;
+  trees._tr_init(s);
+  return Z_OK;
+}
+
+
+function deflateReset(strm) {
+  var ret = deflateResetKeep(strm);
+  if (ret === Z_OK) {
+    lm_init(strm.state);
+  }
+  return ret;
+}
+
+
+function deflateSetHeader(strm, head) {
+  if (!strm || !strm.state) { return Z_STREAM_ERROR; }
+  if (strm.state.wrap !== 2) { return Z_STREAM_ERROR; }
+  strm.state.gzhead = head;
+  return Z_OK;
+}
+
+
+function deflateInit2(strm, level, method, windowBits, memLevel, strategy) {
+  if (!strm) { // === Z_NULL
+    return Z_STREAM_ERROR;
+  }
+  var wrap = 1;
+
+  if (level === Z_DEFAULT_COMPRESSION) {
+    level = 6;
+  }
+
+  if (windowBits < 0) { /* suppress zlib wrapper */
+    wrap = 0;
+    windowBits = -windowBits;
+  }
+
+  else if (windowBits > 15) {
+    wrap = 2;           /* write gzip wrapper instead */
+    windowBits -= 16;
+  }
+
+
+  if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED ||
+    windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+    strategy < 0 || strategy > Z_FIXED) {
+    return err(strm, Z_STREAM_ERROR);
+  }
+
+
+  if (windowBits === 8) {
+    windowBits = 9;
+  }
+  /* until 256-byte window bug fixed */
+
+  var s = new DeflateState();
+
+  strm.state = s;
+  s.strm = strm;
+
+  s.wrap = wrap;
+  s.gzhead = null;
+  s.w_bits = windowBits;
+  s.w_size = 1 << s.w_bits;
+  s.w_mask = s.w_size - 1;
+
+  s.hash_bits = memLevel + 7;
+  s.hash_size = 1 << s.hash_bits;
+  s.hash_mask = s.hash_size - 1;
+  s.hash_shift = ~~((s.hash_bits + MIN_MATCH - 1) / MIN_MATCH);
+
+  s.window = new utils.Buf8(s.w_size * 2);
+  s.head = new utils.Buf16(s.hash_size);
+  s.prev = new utils.Buf16(s.w_size);
+
+  // Don't need mem init magic for JS.
+  // s.high_water = 0; /* nothing written to s->window yet */
+
+  s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+  s.pending_buf_size = s.lit_bufsize * 4;
+
+  // overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+  // s->pending_buf = (uchf *) overlay;
+  s.pending_buf = new utils.Buf8(s.pending_buf_size);
+
+  // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`)
+  // s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+  s.d_buf = 1 * s.lit_bufsize;
+
+  // s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+  s.l_buf = (1 + 2) * s.lit_bufsize;
+
+  s.level = level;
+  s.strategy = strategy;
+  s.method = method;
+
+  return deflateReset(strm);
+}
+
+function deflateInit(strm, level) {
+  return deflateInit2(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
+}
+
+
+function deflate(strm, flush) {
+  var old_flush, s;
+  var beg, val; // for gzip header write only
+
+  if (!strm || !strm.state ||
+    flush > Z_BLOCK || flush < 0) {
+    return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR;
+  }
+
+  s = strm.state;
+
+  if (!strm.output ||
+      (!strm.input && strm.avail_in !== 0) ||
+      (s.status === FINISH_STATE && flush !== Z_FINISH)) {
+    return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR : Z_STREAM_ERROR);
+  }
+
+  s.strm = strm; /* just in case */
+  old_flush = s.last_flush;
+  s.last_flush = flush;
+
+  /* Write the header */
+  if (s.status === INIT_STATE) {
+
+    if (s.wrap === 2) { // GZIP header
+      strm.adler = 0;  // crc32(0L, Z_NULL, 0);
+      put_byte(s, 31);
+      put_byte(s, 139);
+      put_byte(s, 8);
+      if (!s.gzhead) { // s->gzhead == Z_NULL
+        put_byte(s, 0);
+        put_byte(s, 0);
+        put_byte(s, 0);
+        put_byte(s, 0);
+        put_byte(s, 0);
+        put_byte(s, s.level === 9 ? 2 :
+                    (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?
+                     4 : 0));
+        put_byte(s, OS_CODE);
+        s.status = BUSY_STATE;
+      }
+      else {
+        put_byte(s, (s.gzhead.text ? 1 : 0) +
+                    (s.gzhead.hcrc ? 2 : 0) +
+                    (!s.gzhead.extra ? 0 : 4) +
+                    (!s.gzhead.name ? 0 : 8) +
+                    (!s.gzhead.comment ? 0 : 16)
+                );
+        put_byte(s, s.gzhead.time & 0xff);
+        put_byte(s, (s.gzhead.time >> 8) & 0xff);
+        put_byte(s, (s.gzhead.time >> 16) & 0xff);
+        put_byte(s, (s.gzhead.time >> 24) & 0xff);
+        put_byte(s, s.level === 9 ? 2 :
+                    (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?
+                     4 : 0));
+        put_byte(s, s.gzhead.os & 0xff);
+        if (s.gzhead.extra && s.gzhead.extra.length) {
+          put_byte(s, s.gzhead.extra.length & 0xff);
+          put_byte(s, (s.gzhead.extra.length >> 8) & 0xff);
+        }
+        if (s.gzhead.hcrc) {
+          strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0);
+        }
+        s.gzindex = 0;
+        s.status = EXTRA_STATE;
+      }
+    }
+    else // DEFLATE header
+    {
+      var header = (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8;
+      var level_flags = -1;
+
+      if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) {
+        level_flags = 0;
+      } else if (s.level < 6) {
+        level_flags = 1;
+      } else if (s.level === 6) {
+        level_flags = 2;
+      } else {
+        level_flags = 3;
+      }
+      header |= (level_flags << 6);
+      if (s.strstart !== 0) { header |= PRESET_DICT; }
+      header += 31 - (header % 31);
+
+      s.status = BUSY_STATE;
+      putShortMSB(s, header);
+
+      /* Save the adler32 of the preset dictionary: */
+      if (s.strstart !== 0) {
+        putShortMSB(s, strm.adler >>> 16);
+        putShortMSB(s, strm.adler & 0xffff);
+      }
+      strm.adler = 1; // adler32(0L, Z_NULL, 0);
+    }
+  }
+
+// #ifdef GZIP
+  if (s.status === EXTRA_STATE) {
+    if (s.gzhead.extra/* != Z_NULL */) {
+      beg = s.pending;  /* start of bytes to update crc */
+
+      while (s.gzindex < (s.gzhead.extra.length & 0xffff)) {
+        if (s.pending === s.pending_buf_size) {
+          if (s.gzhead.hcrc && s.pending > beg) {
+            strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
+          }
+          flush_pending(strm);
+          beg = s.pending;
+          if (s.pending === s.pending_buf_size) {
+            break;
+          }
+        }
+        put_byte(s, s.gzhead.extra[s.gzindex] & 0xff);
+        s.gzindex++;
+      }
+      if (s.gzhead.hcrc && s.pending > beg) {
+        strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
+      }
+      if (s.gzindex === s.gzhead.extra.length) {
+        s.gzindex = 0;
+        s.status = NAME_STATE;
+      }
+    }
+    else {
+      s.status = NAME_STATE;
+    }
+  }
+  if (s.status === NAME_STATE) {
+    if (s.gzhead.name/* != Z_NULL */) {
+      beg = s.pending;  /* start of bytes to update crc */
+      // int val;
+
+      do {
+        if (s.pending === s.pending_buf_size) {
+          if (s.gzhead.hcrc && s.pending > beg) {
+            strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
+          }
+          flush_pending(strm);
+          beg = s.pending;
+          if (s.pending === s.pending_buf_size) {
+            val = 1;
+            break;
+          }
+        }
+        // JS specific: little magic to add zero terminator to end of string
+        if (s.gzindex < s.gzhead.name.length) {
+          val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff;
+        } else {
+          val = 0;
+        }
+        put_byte(s, val);
+      } while (val !== 0);
+
+      if (s.gzhead.hcrc && s.pending > beg) {
+        strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
+      }
+      if (val === 0) {
+        s.gzindex = 0;
+        s.status = COMMENT_STATE;
+      }
+    }
+    else {
+      s.status = COMMENT_STATE;
+    }
+  }
+  if (s.status === COMMENT_STATE) {
+    if (s.gzhead.comment/* != Z_NULL */) {
+      beg = s.pending;  /* start of bytes to update crc */
+      // int val;
+
+      do {
+        if (s.pending === s.pending_buf_size) {
+          if (s.gzhead.hcrc && s.pending > beg) {
+            strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
+          }
+          flush_pending(strm);
+          beg = s.pending;
+          if (s.pending === s.pending_buf_size) {
+            val = 1;
+            break;
+          }
+        }
+        // JS specific: little magic to add zero terminator to end of string
+        if (s.gzindex < s.gzhead.comment.length) {
+          val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff;
+        } else {
+          val = 0;
+        }
+        put_byte(s, val);
+      } while (val !== 0);
+
+      if (s.gzhead.hcrc && s.pending > beg) {
+        strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
+      }
+      if (val === 0) {
+        s.status = HCRC_STATE;
+      }
+    }
+    else {
+      s.status = HCRC_STATE;
+    }
+  }
+  if (s.status === HCRC_STATE) {
+    if (s.gzhead.hcrc) {
+      if (s.pending + 2 > s.pending_buf_size) {
+        flush_pending(strm);
+      }
+      if (s.pending + 2 <= s.pending_buf_size) {
+        put_byte(s, strm.adler & 0xff);
+        put_byte(s, (strm.adler >> 8) & 0xff);
+        strm.adler = 0; // crc32(0L, Z_NULL, 0);
+        s.status = BUSY_STATE;
+      }
+    }
+    else {
+      s.status = BUSY_STATE;
+    }
+  }
+// #endif
+
+  /* Flush as much pending output as possible */
+  if (s.pending !== 0) {
+    flush_pending(strm);
+    if (strm.avail_out === 0) {
+      /*
+		 * Since avail_out is 0, deflate will be called again with more output
+		 * space, but possibly with both pending and avail_in equal to zero.
+		 * There won't be anything to do, but this is not an error situation so
+		 * make sure we return OK instead of BUF_ERROR at next call of deflate:
+		 */
+      s.last_flush = -1;
+      return Z_OK;
+    }
+
+    /*
+	 * Make sure there is something to do and avoid duplicate consecutive
+	 * flushes. For repeated and useless calls with Z_FINISH, we keep returning
+	 * Z_STREAM_END instead of Z_BUF_ERROR.
+	 */
+  } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) &&
+    flush !== Z_FINISH) {
+    return err(strm, Z_BUF_ERROR);
+  }
+
+  /* User must not provide more input after the first FINISH: */
+  if (s.status === FINISH_STATE && strm.avail_in !== 0) {
+    return err(strm, Z_BUF_ERROR);
+  }
+
+  /*
+	 * Start a new block or continue the current one.
+	 */
+  if (strm.avail_in !== 0 || s.lookahead !== 0 ||
+    (flush !== Z_NO_FLUSH && s.status !== FINISH_STATE)) {
+    var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) :
+      (s.strategy === Z_RLE ? deflate_rle(s, flush) :
+        configuration_table[s.level].func(s, flush));
+
+    if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) {
+      s.status = FINISH_STATE;
+    }
+    if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) {
+      if (strm.avail_out === 0) {
+        s.last_flush = -1;
+        /* avoid BUF_ERROR next call, see above */
+      }
+      return Z_OK;
+      /*
+		 * If flush != Z_NO_FLUSH && avail_out == 0, the next call of deflate
+		 * should use the same flush parameter to make sure that the flush is
+		 * complete. So we don't have to output an empty block here, this will
+		 * be done at next call. This also ensures that for a very small output
+		 * buffer, we emit at most one empty block.
+		 */
+    }
+    if (bstate === BS_BLOCK_DONE) {
+      if (flush === Z_PARTIAL_FLUSH) {
+        trees._tr_align(s);
+      }
+      else if (flush !== Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
+
+        trees._tr_stored_block(s, 0, 0, false);
+        /*
+		 * For a full flush, this empty block will be recognized as a special
+		 * marker by inflate_sync().
+		 */
+        if (flush === Z_FULL_FLUSH) {
+          /** * CLEAR_HASH(s); ** */             /* forget history */
+          zero(s.head); // Fill with NIL (= 0);
+
+          if (s.lookahead === 0) {
+            s.strstart = 0;
+            s.block_start = 0;
+            s.insert = 0;
+          }
+        }
+      }
+      flush_pending(strm);
+      if (strm.avail_out === 0) {
+        s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+        return Z_OK;
+      }
+    }
+  }
+  // Assert(strm->avail_out > 0, "bug2");
+  // if (strm.avail_out <= 0) { throw new Error("bug2");}
+
+  if (flush !== Z_FINISH) { return Z_OK; }
+  if (s.wrap <= 0) { return Z_STREAM_END; }
+
+  /* Write the trailer */
+  if (s.wrap === 2) {
+    put_byte(s, strm.adler & 0xff);
+    put_byte(s, (strm.adler >> 8) & 0xff);
+    put_byte(s, (strm.adler >> 16) & 0xff);
+    put_byte(s, (strm.adler >> 24) & 0xff);
+    put_byte(s, strm.total_in & 0xff);
+    put_byte(s, (strm.total_in >> 8) & 0xff);
+    put_byte(s, (strm.total_in >> 16) & 0xff);
+    put_byte(s, (strm.total_in >> 24) & 0xff);
+  }
+  else
+  {
+    putShortMSB(s, strm.adler >>> 16);
+    putShortMSB(s, strm.adler & 0xffff);
+  }
+
+  flush_pending(strm);
+  /*
+	 * If avail_out is zero, the application will call deflate again to flush
+	 * the rest.
+	 */
+  if (s.wrap > 0) { s.wrap = -s.wrap; }
+  /* write the trailer only once! */
+  return s.pending !== 0 ? Z_OK : Z_STREAM_END;
+}
+
+function deflateEnd(strm) {
+  var status;
+
+  if (!strm/* == Z_NULL */ || !strm.state/* == Z_NULL */) {
+    return Z_STREAM_ERROR;
+  }
+
+  status = strm.state.status;
+  if (status !== INIT_STATE &&
+    status !== EXTRA_STATE &&
+    status !== NAME_STATE &&
+    status !== COMMENT_STATE &&
+    status !== HCRC_STATE &&
+    status !== BUSY_STATE &&
+    status !== FINISH_STATE
+  ) {
+    return err(strm, Z_STREAM_ERROR);
+  }
+
+  strm.state = null;
+
+  return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK;
+}
+
+
+/*
+ * =========================================================================
+ * Initializes the compression dictionary from the given byte sequence without
+ * producing any compressed output.
+ */
+function deflateSetDictionary(strm, dictionary) {
+  var dictLength = dictionary.length;
+
+  var s;
+  var str, n;
+  var wrap;
+  var avail;
+  var next;
+  var input;
+  var tmpDict;
+
+  if (!strm/* == Z_NULL */ || !strm.state/* == Z_NULL */) {
+    return Z_STREAM_ERROR;
+  }
+
+  s = strm.state;
+  wrap = s.wrap;
+
+  if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) {
+    return Z_STREAM_ERROR;
+  }
+
+  /* when using zlib wrappers, compute Adler-32 for provided dictionary */
+  if (wrap === 1) {
+    /* adler32(strm->adler, dictionary, dictLength); */
+    strm.adler = adler32(strm.adler, dictionary, dictLength, 0);
+  }
+
+  s.wrap = 0;   /* avoid computing Adler-32 in read_buf */
+
+  /* if dictionary would fill window, just replace the history */
+  if (dictLength >= s.w_size) {
+    if (wrap === 0) {            /* already empty otherwise */
+      /** * CLEAR_HASH(s); ** */
+      zero(s.head); // Fill with NIL (= 0);
+      s.strstart = 0;
+      s.block_start = 0;
+      s.insert = 0;
+    }
+    /* use the tail */
+    // dictionary = dictionary.slice(dictLength - s.w_size);
+    tmpDict = new utils.Buf8(s.w_size);
+    utils.arraySet(tmpDict, dictionary, dictLength - s.w_size, s.w_size, 0);
+    dictionary = tmpDict;
+    dictLength = s.w_size;
+  }
+  /* insert dictionary into window and hash */
+  avail = strm.avail_in;
+  next = strm.next_in;
+  input = strm.input;
+  strm.avail_in = dictLength;
+  strm.next_in = 0;
+  strm.input = dictionary;
+  fill_window(s);
+  while (s.lookahead >= MIN_MATCH) {
+    str = s.strstart;
+    n = s.lookahead - (MIN_MATCH - 1);
+    do {
+      /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */
+      s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH - 1]) & s.hash_mask;
+
+      s.prev[str & s.w_mask] = s.head[s.ins_h];
+
+      s.head[s.ins_h] = str;
+      str++;
+    } while (--n);
+    s.strstart = str;
+    s.lookahead = MIN_MATCH - 1;
+    fill_window(s);
+  }
+  s.strstart += s.lookahead;
+  s.block_start = s.strstart;
+  s.insert = s.lookahead;
+  s.lookahead = 0;
+  s.match_length = s.prev_length = MIN_MATCH - 1;
+  s.match_available = 0;
+  strm.next_in = next;
+  strm.input = input;
+  strm.avail_in = avail;
+  s.wrap = wrap;
+  return Z_OK;
+}
+
+
+exports.deflateInit = deflateInit;
+exports.deflateInit2 = deflateInit2;
+exports.deflateReset = deflateReset;
+exports.deflateResetKeep = deflateResetKeep;
+exports.deflateSetHeader = deflateSetHeader;
+exports.deflate = deflate;
+exports.deflateEnd = deflateEnd;
+exports.deflateSetDictionary = deflateSetDictionary;
+exports.deflateInfo = 'pako deflate (from Nodeca project)';
+
+/*
+ * Not implemented exports.deflateBound = deflateBound; exports.deflateCopy =
+ * deflateCopy; exports.deflateParams = deflateParams; exports.deflatePending =
+ * deflatePending; exports.deflatePrime = deflatePrime; exports.deflateTune =
+ * deflateTune;
+ */
+
+},{"../utils/common":3,"./adler32":4,"./crc32":6,"./messages":11,"./trees":12}],8:[function(require,module,exports){
+'use strict';
+
+// See state defs from inflate.js
+var BAD = 30;       /* got a data error -- remain here until reset */
+var TYPE = 12;      /* i: waiting for type bits, including last-flag bit */
+
+/*
+ * Decode literal, length, and distance codes and write out the resulting
+ * literal and match bytes until either not enough input or output is available,
+ * an end-of-block is encountered, or a data error is encountered. When large
+ * enough input and output buffers are supplied to inflate(), for example, a 16K
+ * input buffer and a 64K output buffer, more than 95% of the inflate execution
+ * time is spent in this routine.
+ * 
+ * Entry assumptions:
+ * 
+ * state.mode === LEN strm.avail_in >= 6 strm.avail_out >= 258 start >=
+ * strm.avail_out state.bits < 8
+ * 
+ * On return, state.mode is one of:
+ * 
+ * LEN -- ran out of enough output space or enough available input TYPE --
+ * reached end of block code, inflate() to interpret next block BAD -- error in
+ * block data
+ * 
+ * Notes:
+ *  - The maximum input bits used by a length/distance pair is 15 bits for the
+ * length code, 5 bits for the length extra, 15 bits for the distance code, and
+ * 13 bits for the distance extra. This totals 48 bits, or six bytes. Therefore
+ * if strm.avail_in >= 6, then there is enough input to avoid checking for
+ * available input while decoding.
+ *  - The maximum bytes that a single length/distance pair can output is 258
+ * bytes, which is the maximum length that can be coded. inflate_fast() requires
+ * strm.avail_out >= 258 for each loop to avoid checking for output space.
+ */
+module.exports = function inflate_fast(strm, start) {
+  var state;
+  var _in;                    /* local strm.input */
+  var last;                   /* have enough input while in < last */
+  var _out;                   /* local strm.output */
+  var beg;                    /* inflate()'s initial strm.output */
+  var end;                    /* while out < end, enough space available */
+// #ifdef INFLATE_STRICT
+  var dmax;                   /* maximum distance from zlib header */
+// #endif
+  var wsize;                  /* window size or zero if not using window */
+  var whave;                  /* valid bytes in the window */
+  var wnext;                  /* window write index */
+  // Use `s_window` instead `window`, avoid conflict with instrumentation
+	// tools
+  var s_window;               /* allocated sliding window, if wsize != 0 */
+  var hold;                   /* local strm.hold */
+  var bits;                   /* local strm.bits */
+  var lcode;                  /* local strm.lencode */
+  var dcode;                  /* local strm.distcode */
+  var lmask;                  /* mask for first level of length codes */
+  var dmask;                  /* mask for first level of distance codes */
+  var here;                   /* retrieved table entry */
+  var op;                     /* code bits, operation, extra bits, or */
+                              /* window position, window bytes to copy */
+  var len;                    /* match length, unused bytes */
+  var dist;                   /* match distance */
+  var from;                   /* where to copy match from */
+  var from_source;
+
+
+  var input, output; // JS specific, because we have no pointers
+
+  /* copy state to local variables */
+  state = strm.state;
+  // here = state.here;
+  _in = strm.next_in;
+  input = strm.input;
+  last = _in + (strm.avail_in - 5);
+  _out = strm.next_out;
+  output = strm.output;
+  beg = _out - (start - strm.avail_out);
+  end = _out + (strm.avail_out - 257);
+// #ifdef INFLATE_STRICT
+  dmax = state.dmax;
+// #endif
+  wsize = state.wsize;
+  whave = state.whave;
+  wnext = state.wnext;
+  s_window = state.window;
+  hold = state.hold;
+  bits = state.bits;
+  lcode = state.lencode;
+  dcode = state.distcode;
+  lmask = (1 << state.lenbits) - 1;
+  dmask = (1 << state.distbits) - 1;
+
+
+  /*
+	 * decode literals and length/distances until end-of-block or not enough
+	 * input data or output space
+	 */
+
+  top:
+  do {
+    if (bits < 15) {
+      hold += input[_in++] << bits;
+      bits += 8;
+      hold += input[_in++] << bits;
+      bits += 8;
+    }
+
+    here = lcode[hold & lmask];
+
+    dolen:
+    for (;;) { // Goto emulation
+      op = here >>> 24/* here.bits */;
+      hold >>>= op;
+      bits -= op;
+      op = (here >>> 16) & 0xff/* here.op */;
+      if (op === 0) {                          /* literal */
+        // Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+        // "inflate: literal '%c'\n" :
+        // "inflate: literal 0x%02x\n", here.val));
+        output[_out++] = here & 0xffff/* here.val */;
+      }
+      else if (op & 16) {                     /* length base */
+        len = here & 0xffff/* here.val */;
+        op &= 15;                           /* number of extra bits */
+        if (op) {
+          if (bits < op) {
+            hold += input[_in++] << bits;
+            bits += 8;
+          }
+          len += hold & ((1 << op) - 1);
+          hold >>>= op;
+          bits -= op;
+        }
+        // Tracevv((stderr, "inflate: length %u\n", len));
+        if (bits < 15) {
+          hold += input[_in++] << bits;
+          bits += 8;
+          hold += input[_in++] << bits;
+          bits += 8;
+        }
+        here = dcode[hold & dmask];
+
+        dodist:
+        for (;;) { // goto emulation
+          op = here >>> 24/* here.bits */;
+          hold >>>= op;
+          bits -= op;
+          op = (here >>> 16) & 0xff/* here.op */;
+
+          if (op & 16) {                      /* distance base */
+            dist = here & 0xffff/* here.val */;
+            op &= 15;                       /* number of extra bits */
+            if (bits < op) {
+              hold += input[_in++] << bits;
+              bits += 8;
+              if (bits < op) {
+                hold += input[_in++] << bits;
+                bits += 8;
+              }
+            }
+            dist += hold & ((1 << op) - 1);
+// #ifdef INFLATE_STRICT
+            if (dist > dmax) {
+              strm.msg = 'invalid distance too far back';
+              state.mode = BAD;
+              break top;
+            }
+// #endif
+            hold >>>= op;
+            bits -= op;
+            // Tracevv((stderr, "inflate: distance %u\n", dist));
+            op = _out - beg;                /* max distance in output */
+            if (dist > op) {                /* see if copy from window */
+              op = dist - op;               /* distance back in window */
+              if (op > whave) {
+                if (state.sane) {
+                  strm.msg = 'invalid distance too far back';
+                  state.mode = BAD;
+                  break top;
+                }
+
+// (!) This block is disabled in zlib defailts,
+// don't enable it for binary compatibility
+// #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+// if (len <= op - whave) {
+// do {
+// output[_out++] = 0;
+// } while (--len);
+// continue top;
+// }
+// len -= op - whave;
+// do {
+// output[_out++] = 0;
+// } while (--op > whave);
+// if (op === 0) {
+// from = _out - dist;
+// do {
+// output[_out++] = output[from++];
+// } while (--len);
+// continue top;
+// }
+// #endif
+              }
+              from = 0; // window index
+              from_source = s_window;
+              if (wnext === 0) {           /* very common case */
+                from += wsize - op;
+                if (op < len) {         /* some from window */
+                  len -= op;
+                  do {
+                    output[_out++] = s_window[from++];
+                  } while (--op);
+                  from = _out - dist;  /* rest from output */
+                  from_source = output;
+                }
+              }
+              else if (wnext < op) {      /* wrap around window */
+                from += wsize + wnext - op;
+                op -= wnext;
+                if (op < len) {         /* some from end of window */
+                  len -= op;
+                  do {
+                    output[_out++] = s_window[from++];
+                  } while (--op);
+                  from = 0;
+                  if (wnext < len) {  /* some from start of window */
+                    op = wnext;
+                    len -= op;
+                    do {
+                      output[_out++] = s_window[from++];
+                    } while (--op);
+                    from = _out - dist;      /* rest from output */
+                    from_source = output;
+                  }
+                }
+              }
+              else {                      /* contiguous in window */
+                from += wnext - op;
+                if (op < len) {         /* some from window */
+                  len -= op;
+                  do {
+                    output[_out++] = s_window[from++];
+                  } while (--op);
+                  from = _out - dist;  /* rest from output */
+                  from_source = output;
+                }
+              }
+              while (len > 2) {
+                output[_out++] = from_source[from++];
+                output[_out++] = from_source[from++];
+                output[_out++] = from_source[from++];
+                len -= 3;
+              }
+              if (len) {
+                output[_out++] = from_source[from++];
+                if (len > 1) {
+                  output[_out++] = from_source[from++];
+                }
+              }
+            }
+            else {
+              from = _out - dist;          /* copy direct from output */
+              do {                        /* minimum length is three */
+                output[_out++] = output[from++];
+                output[_out++] = output[from++];
+                output[_out++] = output[from++];
+                len -= 3;
+              } while (len > 2);
+              if (len) {
+                output[_out++] = output[from++];
+                if (len > 1) {
+                  output[_out++] = output[from++];
+                }
+              }
+            }
+          }
+          else if ((op & 64) === 0) {          /* 2nd level distance code */
+            here = dcode[(here & 0xffff)/* here.val */ + (hold & ((1 << op) - 1))];
+            continue dodist;
+          }
+          else {
+            strm.msg = 'invalid distance code';
+            state.mode = BAD;
+            break top;
+          }
+
+          break; // need to emulate goto via "continue"
+        }
+      }
+      else if ((op & 64) === 0) {              /* 2nd level length code */
+        here = lcode[(here & 0xffff)/* here.val */ + (hold & ((1 << op) - 1))];
+        continue dolen;
+      }
+      else if (op & 32) {                     /* end-of-block */
+        // Tracevv((stderr, "inflate: end of block\n"));
+        state.mode = TYPE;
+        break top;
+      }
+      else {
+        strm.msg = 'invalid literal/length code';
+        state.mode = BAD;
+        break top;
+      }
+
+      break; // need to emulate goto via "continue"
+    }
+  } while (_in < last && _out < end);
+
+  /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+  len = bits >> 3;
+  _in -= len;
+  bits -= len << 3;
+  hold &= (1 << bits) - 1;
+
+  /* update state and return */
+  strm.next_in = _in;
+  strm.next_out = _out;
+  strm.avail_in = (_in < last ? 5 + (last - _in) : 5 - (_in - last));
+  strm.avail_out = (_out < end ? 257 + (end - _out) : 257 - (_out - end));
+  state.hold = hold;
+  state.bits = bits;
+  return;
+};
+
+},{}],9:[function(require,module,exports){
+'use strict';
+
+
+var utils         = require('../utils/common');
+var adler32       = require('./adler32');
+var crc32         = require('./crc32');
+var inflate_fast  = require('./inffast');
+var inflate_table = require('./inftrees');
+
+var CODES = 0;
+var LENS = 1;
+var DISTS = 2;
+
+/* Public constants ========================================================== */
+/* =========================================================================== */
+
+
+/* Allowed flush values; see deflate() and inflate() below for details */
+// var Z_NO_FLUSH = 0;
+// var Z_PARTIAL_FLUSH = 1;
+// var Z_SYNC_FLUSH = 2;
+// var Z_FULL_FLUSH = 3;
+var Z_FINISH        = 4;
+var Z_BLOCK         = 5;
+var Z_TREES         = 6;
+
+
+/*
+ * Return codes for the compression/decompression functions. Negative values are
+ * errors, positive values are used for special but normal events.
+ */
+var Z_OK            = 0;
+var Z_STREAM_END    = 1;
+var Z_NEED_DICT     = 2;
+// var Z_ERRNO = -1;
+var Z_STREAM_ERROR  = -2;
+var Z_DATA_ERROR    = -3;
+var Z_MEM_ERROR     = -4;
+var Z_BUF_ERROR     = -5;
+// var Z_VERSION_ERROR = -6;
+
+/* The deflate compression method */
+var Z_DEFLATED  = 8;
+
+
+/* STATES ==================================================================== */
+/* =========================================================================== */
+
+
+var    HEAD = 1;       /* i: waiting for magic header */
+var    FLAGS = 2;      /* i: waiting for method and flags (gzip) */
+var    TIME = 3;       /* i: waiting for modification time (gzip) */
+var    OS = 4;         /*
+						 * i: waiting for extra flags and operating system
+						 * (gzip)
+						 */
+var    EXLEN = 5;      /* i: waiting for extra length (gzip) */
+var    EXTRA = 6;      /* i: waiting for extra bytes (gzip) */
+var    NAME = 7;       /* i: waiting for end of file name (gzip) */
+var    COMMENT = 8;    /* i: waiting for end of comment (gzip) */
+var    HCRC = 9;       /* i: waiting for header crc (gzip) */
+var    DICTID = 10;    /* i: waiting for dictionary check value */
+var    DICT = 11;      /* waiting for inflateSetDictionary() call */
+var        TYPE = 12;      /* i: waiting for type bits, including last-flag bit */
+var        TYPEDO = 13;    /*
+							 * i: same, but skip check to exit inflate on new
+							 * block
+							 */
+var        STORED = 14;    /*
+							 * i: waiting for stored size (length and
+							 * complement)
+							 */
+var        COPY_ = 15;     /* i/o: same as COPY below, but only first time in */
+var        COPY = 16;      /*
+							 * i/o: waiting for input or output to copy stored
+							 * block
+							 */
+var        TABLE = 17;     /* i: waiting for dynamic block table lengths */
+var        LENLENS = 18;   /* i: waiting for code length code lengths */
+var        CODELENS = 19;  /*
+							 * i: waiting for length/lit and distance code
+							 * lengths
+							 */
+var            LEN_ = 20;      /* i: same as LEN below, but only first time in */
+var            LEN = 21;       /* i: waiting for length/lit/eob code */
+var            LENEXT = 22;    /* i: waiting for length extra bits */
+var            DIST = 23;      /* i: waiting for distance code */
+var            DISTEXT = 24;   /* i: waiting for distance extra bits */
+var            MATCH = 25;     /* o: waiting for output space to copy string */
+var            LIT = 26;       /* o: waiting for output space to write literal */
+var    CHECK = 27;     /* i: waiting for 32-bit check value */
+var    LENGTH = 28;    /* i: waiting for 32-bit length (gzip) */
+var    DONE = 29;      /* finished check, done -- remain here until reset */
+var    BAD = 30;       /* got a data error -- remain here until reset */
+var    MEM = 31;       /*
+						 * got an inflate() memory error -- remain here until
+						 * reset
+						 */
+var    SYNC = 32;      /*
+						 * looking for synchronization bytes to restart
+						 * inflate()
+						 */
+
+/* =========================================================================== */
+
+
+
+var ENOUGH_LENS = 852;
+var ENOUGH_DISTS = 592;
+// var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);
+
+var MAX_WBITS = 15;
+/* 32K LZ77 window */
+var DEF_WBITS = MAX_WBITS;
+
+
+function zswap32(q) {
+  return  (((q >>> 24) & 0xff) +
+          ((q >>> 8) & 0xff00) +
+          ((q & 0xff00) << 8) +
+          ((q & 0xff) << 24));
+}
+
+
+function InflateState() {
+  this.mode = 0;             /* current inflate mode */
+  this.last = false;          /* true if processing last block */
+  this.wrap = 0;              /* bit 0 true for zlib, bit 1 true for gzip */
+  this.havedict = false;      /* true if dictionary provided */
+  this.flags = 0;             /* gzip header method and flags (0 if zlib) */
+  this.dmax = 0;              /* zlib header max distance (INFLATE_STRICT) */
+  this.check = 0;             /* protected copy of check value */
+  this.total = 0;             /* protected copy of output count */
+  // TODO: may be {}
+  this.head = null;           /* where to save gzip header information */
+
+  /* sliding window */
+  this.wbits = 0;             /* log base 2 of requested window size */
+  this.wsize = 0;             /* window size or zero if not using window */
+  this.whave = 0;             /* valid bytes in the window */
+  this.wnext = 0;             /* window write index */
+  this.window = null;         /* allocated sliding window, if needed */
+
+  /* bit accumulator */
+  this.hold = 0;              /* input bit accumulator */
+  this.bits = 0;              /* number of bits in "in" */
+
+  /* for string and stored block copying */
+  this.length = 0;            /* literal or length of data to copy */
+  this.offset = 0;            /* distance back to copy string from */
+
+  /* for table and code decoding */
+  this.extra = 0;             /* extra bits needed */
+
+  /* fixed and dynamic code tables */
+  this.lencode = null;          /* starting table for length/literal codes */
+  this.distcode = null;         /* starting table for distance codes */
+  this.lenbits = 0;           /* index bits for lencode */
+  this.distbits = 0;          /* index bits for distcode */
+
+  /* dynamic table building */
+  this.ncode = 0;             /* number of code length code lengths */
+  this.nlen = 0;              /* number of length code lengths */
+  this.ndist = 0;             /* number of distance code lengths */
+  this.have = 0;              /* number of code lengths in lens[] */
+  this.next = null;              /* next available space in codes[] */
+
+  this.lens = new utils.Buf16(320); /* temporary storage for code lengths */
+  this.work = new utils.Buf16(288); /* work area for code table building */
+
+  /*
+	 * because we don't have pointers in js, we use lencode and distcode
+	 * directly as buffers so we don't need codes
+	 */
+  // this.codes = new utils.Buf32(ENOUGH); /* space for code tables */
+  this.lendyn = null;              /*
+									 * dynamic table for length/literal codes
+									 * (JS specific)
+									 */
+  this.distdyn = null;             /*
+									 * dynamic table for distance codes (JS
+									 * specific)
+									 */
+  this.sane = 0;                   /* if false, allow invalid distance too far */
+  this.back = 0;                   /* bits back of last unprocessed length/lit */
+  this.was = 0;                    /* initial length of match */
+}
+
+function inflateResetKeep(strm) {
+  var state;
+
+  if (!strm || !strm.state) { return Z_STREAM_ERROR; }
+  state = strm.state;
+  strm.total_in = strm.total_out = state.total = 0;
+  strm.msg = ''; /* Z_NULL */
+  if (state.wrap) {       /* to support ill-conceived Java test suite */
+    strm.adler = state.wrap & 1;
+  }
+  state.mode = HEAD;
+  state.last = 0;
+  state.havedict = 0;
+  state.dmax = 32768;
+  state.head = null/* Z_NULL */;
+  state.hold = 0;
+  state.bits = 0;
+  // state.lencode = state.distcode = state.next = state.codes;
+  state.lencode = state.lendyn = new utils.Buf32(ENOUGH_LENS);
+  state.distcode = state.distdyn = new utils.Buf32(ENOUGH_DISTS);
+
+  state.sane = 1;
+  state.back = -1;
+  // Tracev((stderr, "inflate: reset\n"));
+  return Z_OK;
+}
+
+function inflateReset(strm) {
+  var state;
+
+  if (!strm || !strm.state) { return Z_STREAM_ERROR; }
+  state = strm.state;
+  state.wsize = 0;
+  state.whave = 0;
+  state.wnext = 0;
+  return inflateResetKeep(strm);
+
+}
+
+function inflateReset2(strm, windowBits) {
+  var wrap;
+  var state;
+
+  /* get the state */
+  if (!strm || !strm.state) { return Z_STREAM_ERROR; }
+  state = strm.state;
+
+  /* extract wrap request from windowBits parameter */
+  if (windowBits < 0) {
+    wrap = 0;
+    windowBits = -windowBits;
+  }
+  else {
+    wrap = (windowBits >> 4) + 1;
+    if (windowBits < 48) {
+      windowBits &= 15;
+    }
+  }
+
+  /* set number of window bits, free window if different */
+  if (windowBits && (windowBits < 8 || windowBits > 15)) {
+    return Z_STREAM_ERROR;
+  }
+  if (state.window !== null && state.wbits !== windowBits) {
+    state.window = null;
+  }
+
+  /* update state and reset the rest of it */
+  state.wrap = wrap;
+  state.wbits = windowBits;
+  return inflateReset(strm);
+}
+
+function inflateInit2(strm, windowBits) {
+  var ret;
+  var state;
+
+  if (!strm) { return Z_STREAM_ERROR; }
+  // strm.msg = Z_NULL; /* in case we return an error */
+
+  state = new InflateState();
+
+  // if (state === Z_NULL) return Z_MEM_ERROR;
+  // Tracev((stderr, "inflate: allocated\n"));
+  strm.state = state;
+  state.window = null/* Z_NULL */;
+  ret = inflateReset2(strm, windowBits);
+  if (ret !== Z_OK) {
+    strm.state = null/* Z_NULL */;
+  }
+  return ret;
+}
+
+function inflateInit(strm) {
+  return inflateInit2(strm, DEF_WBITS);
+}
+
+
+/*
+ * Return state with length and distance decoding tables and index sizes set to
+ * fixed code decoding. Normally this returns fixed tables from inffixed.h. If
+ * BUILDFIXED is defined, then instead this routine builds the tables the first
+ * time it's called, and returns those tables the first time and thereafter.
+ * This reduces the size of the code by about 2K bytes, in exchange for a little
+ * execution time. However, BUILDFIXED should not be used for threaded
+ * applications, since the rewriting of the tables and virgin may not be
+ * thread-safe.
+ */
+var virgin = true;
+
+var lenfix, distfix; // We have no pointers in JS, so keep tables separate
+
+function fixedtables(state) {
+  /* build fixed huffman tables if first call (may not be thread safe) */
+  if (virgin) {
+    var sym;
+
+    lenfix = new utils.Buf32(512);
+    distfix = new utils.Buf32(32);
+
+    /* literal/length table */
+    sym = 0;
+    while (sym < 144) { state.lens[sym++] = 8; }
+    while (sym < 256) { state.lens[sym++] = 9; }
+    while (sym < 280) { state.lens[sym++] = 7; }
+    while (sym < 288) { state.lens[sym++] = 8; }
+
+    inflate_table(LENS,  state.lens, 0, 288, lenfix,   0, state.work, { bits: 9 });
+
+    /* distance table */
+    sym = 0;
+    while (sym < 32) { state.lens[sym++] = 5; }
+
+    inflate_table(DISTS, state.lens, 0, 32,   distfix, 0, state.work, { bits: 5 });
+
+    /* do this just once */
+    virgin = false;
+  }
+
+  state.lencode = lenfix;
+  state.lenbits = 9;
+  state.distcode = distfix;
+  state.distbits = 5;
+}
+
+
+/*
+ * Update the window with the last wsize (normally 32K) bytes written before
+ * returning. If window does not exist yet, create it. This is only called when
+ * a window is already in use, or when output has been written during this
+ * inflate call, but the end of the deflate stream has not been reached yet. It
+ * is also called to create a window for dictionary data when a dictionary is
+ * loaded.
+ * 
+ * Providing output buffers larger than 32K to inflate() should provide a speed
+ * advantage, since only the last 32K of output is copied to the sliding window
+ * upon return from inflate(), and since all distances after the first 32K of
+ * output will fall in the output data, making match copies simpler and faster.
+ * The advantage may be dependent on the size of the processor's data caches.
+ */
+function updatewindow(strm, src, end, copy) {
+  var dist;
+  var state = strm.state;
+
+  /* if it hasn't been done already, allocate space for the window */
+  if (state.window === null) {
+    state.wsize = 1 << state.wbits;
+    state.wnext = 0;
+    state.whave = 0;
+
+    state.window = new utils.Buf8(state.wsize);
+  }
+
+  /* copy state->wsize or less output bytes into the circular window */
+  if (copy >= state.wsize) {
+    utils.arraySet(state.window, src, end - state.wsize, state.wsize, 0);
+    state.wnext = 0;
+    state.whave = state.wsize;
+  }
+  else {
+    dist = state.wsize - state.wnext;
+    if (dist > copy) {
+      dist = copy;
+    }
+    // zmemcpy(state->window + state->wnext, end - copy, dist);
+    utils.arraySet(state.window, src, end - copy, dist, state.wnext);
+    copy -= dist;
+    if (copy) {
+      // zmemcpy(state->window, end - copy, copy);
+      utils.arraySet(state.window, src, end - copy, copy, 0);
+      state.wnext = copy;
+      state.whave = state.wsize;
+    }
+    else {
+      state.wnext += dist;
+      if (state.wnext === state.wsize) { state.wnext = 0; }
+      if (state.whave < state.wsize) { state.whave += dist; }
+    }
+  }
+  return 0;
+}
+
+function inflate(strm, flush) {
+  var state;
+  var input, output;          // input/output buffers
+  var next;                   /* next input INDEX */
+  var put;                    /* next output INDEX */
+  var have, left;             /* available input and output */
+  var hold;                   /* bit buffer */
+  var bits;                   /* bits in bit buffer */
+  var _in, _out;              /* save starting available input and output */
+  var copy;                   /* number of stored or match bytes to copy */
+  var from;                   /* where to copy match bytes from */
+  var from_source;
+  var here = 0;               /* current decoding table entry */
+  var here_bits, here_op, here_val; // paked "here" denormalized (JS specific)
+  // var last; /* parent table entry */
+  var last_bits, last_op, last_val; // paked "last" denormalized (JS specific)
+  var len;                    /* length to copy for repeats, bits to drop */
+  var ret;                    /* return code */
+  var hbuf = new utils.Buf8(4);    /* buffer for gzip header crc calculation */
+  var opts;
+
+  var n; // temporary var for NEED_BITS
+
+  var order = /* permutation of code lengths */
+    [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
+
+
+  if (!strm || !strm.state || !strm.output ||
+      (!strm.input && strm.avail_in !== 0)) {
+    return Z_STREAM_ERROR;
+  }
+
+  state = strm.state;
+  if (state.mode === TYPE) { state.mode = TYPEDO; }    /* skip check */
+
+
+  // --- LOAD() ---
+  put = strm.next_out;
+  output = strm.output;
+  left = strm.avail_out;
+  next = strm.next_in;
+  input = strm.input;
+  have = strm.avail_in;
+  hold = state.hold;
+  bits = state.bits;
+  // ---
+
+  _in = have;
+  _out = left;
+  ret = Z_OK;
+
+  inf_leave: // goto emulation
+  for (;;) {
+    switch (state.mode) {
+    case HEAD:
+      if (state.wrap === 0) {
+        state.mode = TYPEDO;
+        break;
+      }
+      // === NEEDBITS(16);
+      while (bits < 16) {
+        if (have === 0) { break inf_leave; }
+        have--;
+        hold += input[next++] << bits;
+        bits += 8;
+      }
+      // ===//
+      if ((state.wrap & 2) && hold === 0x8b1f) {  /* gzip header */
+        state.check = 0/* crc32(0L, Z_NULL, 0) */;
+        // === CRC2(state.check, hold);
+        hbuf[0] = hold & 0xff;
+        hbuf[1] = (hold >>> 8) & 0xff;
+        state.check = crc32(state.check, hbuf, 2, 0);
+        // ===//
+
+        // === INITBITS();
+        hold = 0;
+        bits = 0;
+        // ===//
+        state.mode = FLAGS;
+        break;
+      }
+      state.flags = 0;           /* expect zlib header */
+      if (state.head) {
+        state.head.done = false;
+      }
+      if (!(state.wrap & 1) ||   /* check if zlib header allowed */
+        (((hold & 0xff)/* BITS(8) */ << 8) + (hold >> 8)) % 31) {
+        strm.msg = 'incorrect header check';
+        state.mode = BAD;
+        break;
+      }
+      if ((hold & 0x0f)/* BITS(4) */ !== Z_DEFLATED) {
+        strm.msg = 'unknown compression method';
+        state.mode = BAD;
+        break;
+      }
+      // --- DROPBITS(4) ---//
+      hold >>>= 4;
+      bits -= 4;
+      // ---//
+      len = (hold & 0x0f)/* BITS(4) */ + 8;
+      if (state.wbits === 0) {
+        state.wbits = len;
+      }
+      else if (len > state.wbits) {
+        strm.msg = 'invalid window size';
+        state.mode = BAD;
+        break;
+      }
+      state.dmax = 1 << len;
+      // Tracev((stderr, "inflate: zlib header ok\n"));
+      strm.adler = state.check = 1/* adler32(0L, Z_NULL, 0) */;
+      state.mode = hold & 0x200 ? DICTID : TYPE;
+      // === INITBITS();
+      hold = 0;
+      bits = 0;
+      // ===//
+      break;
+    case FLAGS:
+      // === NEEDBITS(16); */
+      while (bits < 16) {
+        if (have === 0) { break inf_leave; }
+        have--;
+        hold += input[next++] << bits;
+        bits += 8;
+      }
+      // ===//
+      state.flags = hold;
+      if ((state.flags & 0xff) !== Z_DEFLATED) {
+        strm.msg = 'unknown compression method';
+        state.mode = BAD;
+        break;
+      }
+      if (state.flags & 0xe000) {
+        strm.msg = 'unknown header flags set';
+        state.mode = BAD;
+        break;
+      }
+      if (state.head) {
+        state.head.text = ((hold >> 8) & 1);
+      }
+      if (state.flags & 0x0200) {
+        // === CRC2(state.check, hold);
+        hbuf[0] = hold & 0xff;
+        hbuf[1] = (hold >>> 8) & 0xff;
+        state.check = crc32(state.check, hbuf, 2, 0);
+        // ===//
+      }
+      // === INITBITS();
+      hold = 0;
+      bits = 0;
+      // ===//
+      state.mode = TIME;
+      /* falls through */
+    case TIME:
+      // === NEEDBITS(32); */
+      while (bits < 32) {
+        if (have === 0) { break inf_leave; }
+        have--;
+        hold += input[next++] << bits;
+        bits += 8;
+      }
+      // ===//
+      if (state.head) {
+        state.head.time = hold;
+      }
+      if (state.flags & 0x0200) {
+        // === CRC4(state.check, hold)
+        hbuf[0] = hold & 0xff;
+        hbuf[1] = (hold >>> 8) & 0xff;
+        hbuf[2] = (hold >>> 16) & 0xff;
+        hbuf[3] = (hold >>> 24) & 0xff;
+        state.check = crc32(state.check, hbuf, 4, 0);
+        // ===
+      }
+      // === INITBITS();
+      hold = 0;
+      bits = 0;
+      // ===//
+      state.mode = OS;
+      /* falls through */
+    case OS:
+      // === NEEDBITS(16); */
+      while (bits < 16) {
+        if (have === 0) { break inf_leave; }
+        have--;
+        hold += input[next++] << bits;
+        bits += 8;
+      }
+      // ===//
+      if (state.head) {
+        state.head.xflags = (hold & 0xff);
+        state.head.os = (hold >> 8);
+      }
+      if (state.flags & 0x0200) {
+        // === CRC2(state.check, hold);
+        hbuf[0] = hold & 0xff;
+        hbuf[1] = (hold >>> 8) & 0xff;
+        state.check = crc32(state.check, hbuf, 2, 0);
+        // ===//
+      }
+      // === INITBITS();
+      hold = 0;
+      bits = 0;
+      // ===//
+      state.mode = EXLEN;
+      /* falls through */
+    case EXLEN:
+      if (state.flags & 0x0400) {
+        // === NEEDBITS(16); */
+        while (bits < 16) {
+          if (have === 0) { break inf_leave; }
+          have--;
+          hold += input[next++] << bits;
+          bits += 8;
+        }
+        // ===//
+        state.length = hold;
+        if (state.head) {
+          state.head.extra_len = hold;
+        }
+        if (state.flags & 0x0200) {
+          // === CRC2(state.check, hold);
+          hbuf[0] = hold & 0xff;
+          hbuf[1] = (hold >>> 8) & 0xff;
+          state.check = crc32(state.check, hbuf, 2, 0);
+          // ===//
+        }
+        // === INITBITS();
+        hold = 0;
+        bits = 0;
+        // ===//
+      }
+      else if (state.head) {
+        state.head.extra = null/* Z_NULL */;
+      }
+      state.mode = EXTRA;
+      /* falls through */
+    case EXTRA:
+      if (state.flags & 0x0400) {
+        copy = state.length;
+        if (copy > have) { copy = have; }
+        if (copy) {
+          if (state.head) {
+            len = state.head.extra_len - state.length;
+            if (!state.head.extra) {
+              // Use untyped array for more conveniend processing later
+              state.head.extra = new Array(state.head.extra_len);
+            }
+            utils.arraySet(
+              state.head.extra,
+              input,
+              next,
+              // extra field is limited to 65536 bytes
+              // - no need for additional size check
+              copy,
+              /*
+				 * len + copy > state.head.extra_max - len ?
+				 * state.head.extra_max : copy,
+				 */
+              len
+            );
+            // zmemcpy(state.head.extra + len, next,
+            // len + copy > state.head.extra_max ?
+            // state.head.extra_max - len : copy);
+          }
+          if (state.flags & 0x0200) {
+            state.check = crc32(state.check, input, copy, next);
+          }
+          have -= copy;
+          next += copy;
+          state.length -= copy;
+        }
+        if (state.length) { break inf_leave; }
+      }
+      state.length = 0;
+      state.mode = NAME;
+      /* falls through */
+    case NAME:
+      if (state.flags & 0x0800) {
+        if (have === 0) { break inf_leave; }
+        copy = 0;
+        do {
+          // TODO: 2 or 1 bytes?
+          len = input[next + copy++];
+          /* use constant limit because in js we should not preallocate memory */
+          if (state.head && len &&
+              (state.length < 65536 /* state.head.name_max */)) {
+            state.head.name += String.fromCharCode(len);
+          }
+        } while (len && copy < have);
+
+        if (state.flags & 0x0200) {
+          state.check = crc32(state.check, input, copy, next);
+        }
+        have -= copy;
+        next += copy;
+        if (len) { break inf_leave; }
+      }
+      else if (state.head) {
+        state.head.name = null;
+      }
+      state.length = 0;
+      state.mode = COMMENT;
+      /* falls through */
+    case COMMENT:
+      if (state.flags & 0x1000) {
+        if (have === 0) { break inf_leave; }
+        copy = 0;
+        do {
+          len = input[next + copy++];
+          /* use constant limit because in js we should not preallocate memory */
+          if (state.head && len &&
+              (state.length < 65536 /* state.head.comm_max */)) {
+            state.head.comment += String.fromCharCode(len);
+          }
+        } while (len && copy < have);
+        if (state.flags & 0x0200) {
+          state.check = crc32(state.check, input, copy, next);
+        }
+        have -= copy;
+        next += copy;
+        if (len) { break inf_leave; }
+      }
+      else if (state.head) {
+        state.head.comment = null;
+      }
+      state.mode = HCRC;
+      /* falls through */
+    case HCRC:
+      if (state.flags & 0x0200) {
+        // === NEEDBITS(16); */
+        while (bits < 16) {
+          if (have === 0) { break inf_leave; }
+          have--;
+          hold += input[next++] << bits;
+          bits += 8;
+        }
+        // ===//
+        if (hold !== (state.check & 0xffff)) {
+          strm.msg = 'header crc mismatch';
+          state.mode = BAD;
+          break;
+        }
+        // === INITBITS();
+        hold = 0;
+        bits = 0;
+        // ===//
+      }
+      if (state.head) {
+        state.head.hcrc = ((state.flags >> 9) & 1);
+        state.head.done = true;
+      }
+      strm.adler = state.check = 0;
+      state.mode = TYPE;
+      break;
+    case DICTID:
+      // === NEEDBITS(32); */
+      while (bits < 32) {
+        if (have === 0) { break inf_leave; }
+        have--;
+        hold += input[next++] << bits;
+        bits += 8;
+      }
+      // ===//
+      strm.adler = state.check = zswap32(hold);
+      // === INITBITS();
+      hold = 0;
+      bits = 0;
+      // ===//
+      state.mode = DICT;
+      /* falls through */
+    case DICT:
+      if (state.havedict === 0) {
+        // --- RESTORE() ---
+        strm.next_out = put;
+        strm.avail_out = left;
+        strm.next_in = next;
+        strm.avail_in = have;
+        state.hold = hold;
+        state.bits = bits;
+        // ---
+        return Z_NEED_DICT;
+      }
+      strm.adler = state.check = 1/* adler32(0L, Z_NULL, 0) */;
+      state.mode = TYPE;
+      /* falls through */
+    case TYPE:
+      if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; }
+      /* falls through */
+    case TYPEDO:
+      if (state.last) {
+        // --- BYTEBITS() ---//
+        hold >>>= bits & 7;
+        bits -= bits & 7;
+        // ---//
+        state.mode = CHECK;
+        break;
+      }
+      // === NEEDBITS(3); */
+      while (bits < 3) {
+        if (have === 0) { break inf_leave; }
+        have--;
+        hold += input[next++] << bits;
+        bits += 8;
+      }
+      // ===//
+      state.last = (hold & 0x01)/* BITS(1) */;
+      // --- DROPBITS(1) ---//
+      hold >>>= 1;
+      bits -= 1;
+      // ---//
+
+      switch ((hold & 0x03)/* BITS(2) */) {
+      case 0:                             /* stored block */
+        // Tracev((stderr, "inflate: stored block%s\n",
+        // state.last ? " (last)" : ""));
+        state.mode = STORED;
+        break;
+      case 1:                             /* fixed block */
+        fixedtables(state);
+        // Tracev((stderr, "inflate: fixed codes block%s\n",
+        // state.last ? " (last)" : ""));
+        state.mode = LEN_;             /* decode codes */
+        if (flush === Z_TREES) {
+          // --- DROPBITS(2) ---//
+          hold >>>= 2;
+          bits -= 2;
+          // ---//
+          break inf_leave;
+        }
+        break;
+      case 2:                             /* dynamic block */
+        // Tracev((stderr, "inflate: dynamic codes block%s\n",
+        // state.last ? " (last)" : ""));
+        state.mode = TABLE;
+        break;
+      case 3:
+        strm.msg = 'invalid block type';
+        state.mode = BAD;
+      }
+      // --- DROPBITS(2) ---//
+      hold >>>= 2;
+      bits -= 2;
+      // ---//
+      break;
+    case STORED:
+      // --- BYTEBITS() ---// /* go to byte boundary */
+      hold >>>= bits & 7;
+      bits -= bits & 7;
+      // ---//
+      // === NEEDBITS(32); */
+      while (bits < 32) {
+        if (have === 0) { break inf_leave; }
+        have--;
+        hold += input[next++] << bits;
+        bits += 8;
+      }
+      // ===//
+      if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) {
+        strm.msg = 'invalid stored block lengths';
+        state.mode = BAD;
+        break;
+      }
+      state.length = hold & 0xffff;
+      // Tracev((stderr, "inflate: stored length %u\n",
+      // state.length));
+      // === INITBITS();
+      hold = 0;
+      bits = 0;
+      // ===//
+      state.mode = COPY_;
+      if (flush === Z_TREES) { break inf_leave; }
+      /* falls through */
+    case COPY_:
+      state.mode = COPY;
+      /* falls through */
+    case COPY:
+      copy = state.length;
+      if (copy) {
+        if (copy > have) { copy = have; }
+        if (copy > left) { copy = left; }
+        if (copy === 0) { break inf_leave; }
+        // --- zmemcpy(put, next, copy); ---
+        utils.arraySet(output, input, next, copy, put);
+        // ---//
+        have -= copy;
+        next += copy;
+        left -= copy;
+        put += copy;
+        state.length -= copy;
+        break;
+      }
+      // Tracev((stderr, "inflate: stored end\n"));
+      state.mode = TYPE;
+      break;
+    case TABLE:
+      // === NEEDBITS(14); */
+      while (bits < 14) {
+        if (have === 0) { break inf_leave; }
+        have--;
+        hold += input[next++] << bits;
+        bits += 8;
+      }
+      // ===//
+      state.nlen = (hold & 0x1f)/* BITS(5) */ + 257;
+      // --- DROPBITS(5) ---//
+      hold >>>= 5;
+      bits -= 5;
+      // ---//
+      state.ndist = (hold & 0x1f)/* BITS(5) */ + 1;
+      // --- DROPBITS(5) ---//
+      hold >>>= 5;
+      bits -= 5;
+      // ---//
+      state.ncode = (hold & 0x0f)/* BITS(4) */ + 4;
+      // --- DROPBITS(4) ---//
+      hold >>>= 4;
+      bits -= 4;
+      // ---//
+// #ifndef PKZIP_BUG_WORKAROUND
+      if (state.nlen > 286 || state.ndist > 30) {
+        strm.msg = 'too many length or distance symbols';
+        state.mode = BAD;
+        break;
+      }
+// #endif
+      // Tracev((stderr, "inflate: table sizes ok\n"));
+      state.have = 0;
+      state.mode = LENLENS;
+      /* falls through */
+    case LENLENS:
+      while (state.have < state.ncode) {
+        // === NEEDBITS(3);
+        while (bits < 3) {
+          if (have === 0) { break inf_leave; }
+          have--;
+          hold += input[next++] << bits;
+          bits += 8;
+        }
+        // ===//
+        state.lens[order[state.have++]] = (hold & 0x07);// BITS(3);
+        // --- DROPBITS(3) ---//
+        hold >>>= 3;
+        bits -= 3;
+        // ---//
+      }
+      while (state.have < 19) {
+        state.lens[order[state.have++]] = 0;
+      }
+      // We have separate tables & no pointers. 2 commented lines below not
+		// needed.
+      // state.next = state.codes;
+      // state.lencode = state.next;
+      // Switch to use dynamic table
+      state.lencode = state.lendyn;
+      state.lenbits = 7;
+
+      opts = { bits: state.lenbits };
+      ret = inflate_table(CODES, state.lens, 0, 19, state.lencode, 0, state.work, opts);
+      state.lenbits = opts.bits;
+
+      if (ret) {
+        strm.msg = 'invalid code lengths set';
+        state.mode = BAD;
+        break;
+      }
+      // Tracev((stderr, "inflate: code lengths ok\n"));
+      state.have = 0;
+      state.mode = CODELENS;
+      /* falls through */
+    case CODELENS:
+      while (state.have < state.nlen + state.ndist) {
+        for (;;) {
+          here = state.lencode[hold & ((1 << state.lenbits) - 1)];/* BITS(state.lenbits) */
+          here_bits = here >>> 24;
+          here_op = (here >>> 16) & 0xff;
+          here_val = here & 0xffff;
+
+          if ((here_bits) <= bits) { break; }
+          // --- PULLBYTE() ---//
+          if (have === 0) { break inf_leave; }
+          have--;
+          hold += input[next++] << bits;
+          bits += 8;
+          // ---//
+        }
+        if (here_val < 16) {
+          // --- DROPBITS(here.bits) ---//
+          hold >>>= here_bits;
+          bits -= here_bits;
+          // ---//
+          state.lens[state.have++] = here_val;
+        }
+        else {
+          if (here_val === 16) {
+            // === NEEDBITS(here.bits + 2);
+            n = here_bits + 2;
+            while (bits < n) {
+              if (have === 0) { break inf_leave; }
+              have--;
+              hold += input[next++] << bits;
+              bits += 8;
+            }
+            // ===//
+            // --- DROPBITS(here.bits) ---//
+            hold >>>= here_bits;
+            bits -= here_bits;
+            // ---//
+            if (state.have === 0) {
+              strm.msg = 'invalid bit length repeat';
+              state.mode = BAD;
+              break;
+            }
+            len = state.lens[state.have - 1];
+            copy = 3 + (hold & 0x03);// BITS(2);
+            // --- DROPBITS(2) ---//
+            hold >>>= 2;
+            bits -= 2;
+            // ---//
+          }
+          else if (here_val === 17) {
+            // === NEEDBITS(here.bits + 3);
+            n = here_bits + 3;
+            while (bits < n) {
+              if (have === 0) { break inf_leave; }
+              have--;
+              hold += input[next++] << bits;
+              bits += 8;
+            }
+            // ===//
+            // --- DROPBITS(here.bits) ---//
+            hold >>>= here_bits;
+            bits -= here_bits;
+            // ---//
+            len = 0;
+            copy = 3 + (hold & 0x07);// BITS(3);
+            // --- DROPBITS(3) ---//
+            hold >>>= 3;
+            bits -= 3;
+            // ---//
+          }
+          else {
+            // === NEEDBITS(here.bits + 7);
+            n = here_bits + 7;
+            while (bits < n) {
+              if (have === 0) { break inf_leave; }
+              have--;
+              hold += input[next++] << bits;
+              bits += 8;
+            }
+            // ===//
+            // --- DROPBITS(here.bits) ---//
+            hold >>>= here_bits;
+            bits -= here_bits;
+            // ---//
+            len = 0;
+            copy = 11 + (hold & 0x7f);// BITS(7);
+            // --- DROPBITS(7) ---//
+            hold >>>= 7;
+            bits -= 7;
+            // ---//
+          }
+          if (state.have + copy > state.nlen + state.ndist) {
+            strm.msg = 'invalid bit length repeat';
+            state.mode = BAD;
+            break;
+          }
+          while (copy--) {
+            state.lens[state.have++] = len;
+          }
+        }
+      }
+
+      /* handle error breaks in while */
+      if (state.mode === BAD) { break; }
+
+      /* check for end-of-block code (better have one) */
+      if (state.lens[256] === 0) {
+        strm.msg = 'invalid code -- missing end-of-block';
+        state.mode = BAD;
+        break;
+      }
+
+      /*
+		 * build code tables -- note: do not change the lenbits or distbits
+		 * values here (9 and 6) without reading the comments in inftrees.h
+		 * concerning the ENOUGH constants, which depend on those values
+		 */
+      state.lenbits = 9;
+
+      opts = { bits: state.lenbits };
+      ret = inflate_table(LENS, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts);
+      // We have separate tables & no pointers. 2 commented lines below not
+		// needed.
+      // state.next_index = opts.table_index;
+      state.lenbits = opts.bits;
+      // state.lencode = state.next;
+
+      if (ret) {
+        strm.msg = 'invalid literal/lengths set';
+        state.mode = BAD;
+        break;
+      }
+
+      state.distbits = 6;
+      // state.distcode.copy(state.codes);
+      // Switch to use dynamic table
+      state.distcode = state.distdyn;
+      opts = { bits: state.distbits };
+      ret = inflate_table(DISTS, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts);
+      // We have separate tables & no pointers. 2 commented lines below not
+		// needed.
+      // state.next_index = opts.table_index;
+      state.distbits = opts.bits;
+      // state.distcode = state.next;
+
+      if (ret) {
+        strm.msg = 'invalid distances set';
+        state.mode = BAD;
+        break;
+      }
+      // Tracev((stderr, 'inflate: codes ok\n'));
+      state.mode = LEN_;
+      if (flush === Z_TREES) { break inf_leave; }
+      /* falls through */
+    case LEN_:
+      state.mode = LEN;
+      /* falls through */
+    case LEN:
+      if (have >= 6 && left >= 258) {
+        // --- RESTORE() ---
+        strm.next_out = put;
+        strm.avail_out = left;
+        strm.next_in = next;
+        strm.avail_in = have;
+        state.hold = hold;
+        state.bits = bits;
+        // ---
+        inflate_fast(strm, _out);
+        // --- LOAD() ---
+        put = strm.next_out;
+        output = strm.output;
+        left = strm.avail_out;
+        next = strm.next_in;
+        input = strm.input;
+        have = strm.avail_in;
+        hold = state.hold;
+        bits = state.bits;
+        // ---
+
+        if (state.mode === TYPE) {
+          state.back = -1;
+        }
+        break;
+      }
+      state.back = 0;
+      for (;;) {
+        here = state.lencode[hold & ((1 << state.lenbits) - 1)];  /* BITS(state.lenbits) */
+        here_bits = here >>> 24;
+        here_op = (here >>> 16) & 0xff;
+        here_val = here & 0xffff;
+
+        if (here_bits <= bits) { break; }
+        // --- PULLBYTE() ---//
+        if (have === 0) { break inf_leave; }
+        have--;
+        hold += input[next++] << bits;
+        bits += 8;
+        // ---//
+      }
+      if (here_op && (here_op & 0xf0) === 0) {
+        last_bits = here_bits;
+        last_op = here_op;
+        last_val = here_val;
+        for (;;) {
+          here = state.lencode[last_val +
+                  ((hold & ((1 << (last_bits + last_op)) - 1))/*
+																 * BITS(last.bits +
+																 * last.op)
+																 */ >> last_bits)];
+          here_bits = here >>> 24;
+          here_op = (here >>> 16) & 0xff;
+          here_val = here & 0xffff;
+
+          if ((last_bits + here_bits) <= bits) { break; }
+          // --- PULLBYTE() ---//
+          if (have === 0) { break inf_leave; }
+          have--;
+          hold += input[next++] << bits;
+          bits += 8;
+          // ---//
+        }
+        // --- DROPBITS(last.bits) ---//
+        hold >>>= last_bits;
+        bits -= last_bits;
+        // ---//
+        state.back += last_bits;
+      }
+      // --- DROPBITS(here.bits) ---//
+      hold >>>= here_bits;
+      bits -= here_bits;
+      // ---//
+      state.back += here_bits;
+      state.length = here_val;
+      if (here_op === 0) {
+        // Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+        // "inflate: literal '%c'\n" :
+        // "inflate: literal 0x%02x\n", here.val));
+        state.mode = LIT;
+        break;
+      }
+      if (here_op & 32) {
+        // Tracevv((stderr, "inflate: end of block\n"));
+        state.back = -1;
+        state.mode = TYPE;
+        break;
+      }
+      if (here_op & 64) {
+        strm.msg = 'invalid literal/length code';
+        state.mode = BAD;
+        break;
+      }
+      state.extra = here_op & 15;
+      state.mode = LENEXT;
+      /* falls through */
+    case LENEXT:
+      if (state.extra) {
+        // === NEEDBITS(state.extra);
+        n = state.extra;
+        while (bits < n) {
+          if (have === 0) { break inf_leave; }
+          have--;
+          hold += input[next++] << bits;
+          bits += 8;
+        }
+        // ===//
+        state.length += hold & ((1 << state.extra) - 1)/* BITS(state.extra) */;
+        // --- DROPBITS(state.extra) ---//
+        hold >>>= state.extra;
+        bits -= state.extra;
+        // ---//
+        state.back += state.extra;
+      }
+      // Tracevv((stderr, "inflate: length %u\n", state.length));
+      state.was = state.length;
+      state.mode = DIST;
+      /* falls through */
+    case DIST:
+      for (;;) {
+        here = state.distcode[hold & ((1 << state.distbits) - 1)];/* BITS(state.distbits) */
+        here_bits = here >>> 24;
+        here_op = (here >>> 16) & 0xff;
+        here_val = here & 0xffff;
+
+        if ((here_bits) <= bits) { break; }
+        // --- PULLBYTE() ---//
+        if (have === 0) { break inf_leave; }
+        have--;
+        hold += input[next++] << bits;
+        bits += 8;
+        // ---//
+      }
+      if ((here_op & 0xf0) === 0) {
+        last_bits = here_bits;
+        last_op = here_op;
+        last_val = here_val;
+        for (;;) {
+          here = state.distcode[last_val +
+                  ((hold & ((1 << (last_bits + last_op)) - 1))/*
+																 * BITS(last.bits +
+																 * last.op)
+																 */ >> last_bits)];
+          here_bits = here >>> 24;
+          here_op = (here >>> 16) & 0xff;
+          here_val = here & 0xffff;
+
+          if ((last_bits + here_bits) <= bits) { break; }
+          // --- PULLBYTE() ---//
+          if (have === 0) { break inf_leave; }
+          have--;
+          hold += input[next++] << bits;
+          bits += 8;
+          // ---//
+        }
+        // --- DROPBITS(last.bits) ---//
+        hold >>>= last_bits;
+        bits -= last_bits;
+        // ---//
+        state.back += last_bits;
+      }
+      // --- DROPBITS(here.bits) ---//
+      hold >>>= here_bits;
+      bits -= here_bits;
+      // ---//
+      state.back += here_bits;
+      if (here_op & 64) {
+        strm.msg = 'invalid distance code';
+        state.mode = BAD;
+        break;
+      }
+      state.offset = here_val;
+      state.extra = (here_op) & 15;
+      state.mode = DISTEXT;
+      /* falls through */
+    case DISTEXT:
+      if (state.extra) {
+        // === NEEDBITS(state.extra);
+        n = state.extra;
+        while (bits < n) {
+          if (have === 0) { break inf_leave; }
+          have--;
+          hold += input[next++] << bits;
+          bits += 8;
+        }
+        // ===//
+        state.offset += hold & ((1 << state.extra) - 1)/* BITS(state.extra) */;
+        // --- DROPBITS(state.extra) ---//
+        hold >>>= state.extra;
+        bits -= state.extra;
+        // ---//
+        state.back += state.extra;
+      }
+// #ifdef INFLATE_STRICT
+      if (state.offset > state.dmax) {
+        strm.msg = 'invalid distance too far back';
+        state.mode = BAD;
+        break;
+      }
+// #endif
+      // Tracevv((stderr, "inflate: distance %u\n", state.offset));
+      state.mode = MATCH;
+      /* falls through */
+    case MATCH:
+      if (left === 0) { break inf_leave; }
+      copy = _out - left;
+      if (state.offset > copy) {         /* copy from window */
+        copy = state.offset - copy;
+        if (copy > state.whave) {
+          if (state.sane) {
+            strm.msg = 'invalid distance too far back';
+            state.mode = BAD;
+            break;
+          }
+// (!) This block is disabled in zlib defailts,
+// don't enable it for binary compatibility
+// #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+// Trace((stderr, "inflate.c too far\n"));
+// copy -= state.whave;
+// if (copy > state.length) { copy = state.length; }
+// if (copy > left) { copy = left; }
+// left -= copy;
+// state.length -= copy;
+// do {
+// output[put++] = 0;
+// } while (--copy);
+// if (state.length === 0) { state.mode = LEN; }
+// break;
+// #endif
+        }
+        if (copy > state.wnext) {
+          copy -= state.wnext;
+          from = state.wsize - copy;
+        }
+        else {
+          from = state.wnext - copy;
+        }
+        if (copy > state.length) { copy = state.length; }
+        from_source = state.window;
+      }
+      else {                              /* copy from output */
+        from_source = output;
+        from = put - state.offset;
+        copy = state.length;
+      }
+      if (copy > left) { copy = left; }
+      left -= copy;
+      state.length -= copy;
+      do {
+        output[put++] = from_source[from++];
+      } while (--copy);
+      if (state.length === 0) { state.mode = LEN; }
+      break;
+    case LIT:
+      if (left === 0) { break inf_leave; }
+      output[put++] = state.length;
+      left--;
+      state.mode = LEN;
+      break;
+    case CHECK:
+      if (state.wrap) {
+        // === NEEDBITS(32);
+        while (bits < 32) {
+          if (have === 0) { break inf_leave; }
+          have--;
+          // Use '|' insdead of '+' to make sure that result is signed
+          hold |= input[next++] << bits;
+          bits += 8;
+        }
+        // ===//
+        _out -= left;
+        strm.total_out += _out;
+        state.total += _out;
+        if (_out) {
+          strm.adler = state.check =
+              /* UPDATE(state.check, put - _out, _out); */
+              (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out));
+
+        }
+        _out = left;
+        // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too
+        if ((state.flags ? hold : zswap32(hold)) !== state.check) {
+          strm.msg = 'incorrect data check';
+          state.mode = BAD;
+          break;
+        }
+        // === INITBITS();
+        hold = 0;
+        bits = 0;
+        // ===//
+        // Tracev((stderr, "inflate: check matches trailer\n"));
+      }
+      state.mode = LENGTH;
+      /* falls through */
+    case LENGTH:
+      if (state.wrap && state.flags) {
+        // === NEEDBITS(32);
+        while (bits < 32) {
+          if (have === 0) { break inf_leave; }
+          have--;
+          hold += input[next++] << bits;
+          bits += 8;
+        }
+        // ===//
+        if (hold !== (state.total & 0xffffffff)) {
+          strm.msg = 'incorrect length check';
+          state.mode = BAD;
+          break;
+        }
+        // === INITBITS();
+        hold = 0;
+        bits = 0;
+        // ===//
+        // Tracev((stderr, "inflate: length matches trailer\n"));
+      }
+      state.mode = DONE;
+      /* falls through */
+    case DONE:
+      ret = Z_STREAM_END;
+      break inf_leave;
+    case BAD:
+      ret = Z_DATA_ERROR;
+      break inf_leave;
+    case MEM:
+      return Z_MEM_ERROR;
+    case SYNC:
+      /* falls through */
+    default:
+      return Z_STREAM_ERROR;
+    }
+  }
+
+  // inf_leave <- here is real place for "goto inf_leave", emulated via "break
+	// inf_leave"
+
+  /*
+	 * Return from inflate(), updating the total counts and the check value. If
+	 * there was no progress during the inflate() call, return a buffer error.
+	 * Call updatewindow() to create and/or update the window state. Note: a
+	 * memory error from inflate() is non-recoverable.
+	 */
+
+  // --- RESTORE() ---
+  strm.next_out = put;
+  strm.avail_out = left;
+  strm.next_in = next;
+  strm.avail_in = have;
+  state.hold = hold;
+  state.bits = bits;
+  // ---
+
+  if (state.wsize || (_out !== strm.avail_out && state.mode < BAD &&
+                      (state.mode < CHECK || flush !== Z_FINISH))) {
+    if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) {
+      state.mode = MEM;
+      return Z_MEM_ERROR;
+    }
+  }
+  _in -= strm.avail_in;
+  _out -= strm.avail_out;
+  strm.total_in += _in;
+  strm.total_out += _out;
+  state.total += _out;
+  if (state.wrap && _out) {
+    strm.adler = state.check = /*
+								 * UPDATE(state.check, strm.next_out - _out,
+								 * _out);
+								 */
+      (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out));
+  }
+  strm.data_type = state.bits + (state.last ? 64 : 0) +
+                    (state.mode === TYPE ? 128 : 0) +
+                    (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0);
+  if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) {
+    ret = Z_BUF_ERROR;
+  }
+  return ret;
+}
+
+function inflateEnd(strm) {
+
+  if (!strm || !strm.state /* || strm->zfree == (free_func)0 */) {
+    return Z_STREAM_ERROR;
+  }
+
+  var state = strm.state;
+  if (state.window) {
+    state.window = null;
+  }
+  strm.state = null;
+  return Z_OK;
+}
+
+function inflateGetHeader(strm, head) {
+  var state;
+
+  /* check state */
+  if (!strm || !strm.state) { return Z_STREAM_ERROR; }
+  state = strm.state;
+  if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; }
+
+  /* save header structure */
+  state.head = head;
+  head.done = false;
+  return Z_OK;
+}
+
+function inflateSetDictionary(strm, dictionary) {
+  var dictLength = dictionary.length;
+
+  var state;
+  var dictid;
+  var ret;
+
+  /* check state */
+  if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) { return Z_STREAM_ERROR; }
+  state = strm.state;
+
+  if (state.wrap !== 0 && state.mode !== DICT) {
+    return Z_STREAM_ERROR;
+  }
+
+  /* check for correct dictionary identifier */
+  if (state.mode === DICT) {
+    dictid = 1; /* adler32(0, null, 0) */
+    /* dictid = adler32(dictid, dictionary, dictLength); */
+    dictid = adler32(dictid, dictionary, dictLength, 0);
+    if (dictid !== state.check) {
+      return Z_DATA_ERROR;
+    }
+  }
+  /*
+	 * copy dictionary to window using updatewindow(), which will amend the
+	 * existing dictionary if appropriate
+	 */
+  ret = updatewindow(strm, dictionary, dictLength, dictLength);
+  if (ret) {
+    state.mode = MEM;
+    return Z_MEM_ERROR;
+  }
+  state.havedict = 1;
+  // Tracev((stderr, "inflate: dictionary set\n"));
+  return Z_OK;
+}
+
+exports.inflateReset = inflateReset;
+exports.inflateReset2 = inflateReset2;
+exports.inflateResetKeep = inflateResetKeep;
+exports.inflateInit = inflateInit;
+exports.inflateInit2 = inflateInit2;
+exports.inflate = inflate;
+exports.inflateEnd = inflateEnd;
+exports.inflateGetHeader = inflateGetHeader;
+exports.inflateSetDictionary = inflateSetDictionary;
+exports.inflateInfo = 'pako inflate (from Nodeca project)';
+
+/*
+ * Not implemented exports.inflateCopy = inflateCopy;
+ * exports.inflateGetDictionary = inflateGetDictionary; exports.inflateMark =
+ * inflateMark; exports.inflatePrime = inflatePrime; exports.inflateSync =
+ * inflateSync; exports.inflateSyncPoint = inflateSyncPoint;
+ * exports.inflateUndermine = inflateUndermine;
+ */
+
+},{"../utils/common":3,"./adler32":4,"./crc32":6,"./inffast":8,"./inftrees":10}],10:[function(require,module,exports){
+'use strict';
+
+
+var utils = require('../utils/common');
+
+var MAXBITS = 15;
+var ENOUGH_LENS = 852;
+var ENOUGH_DISTS = 592;
+// var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);
+
+var CODES = 0;
+var LENS = 1;
+var DISTS = 2;
+
+var lbase = [ /* Length codes 257..285 base */
+  3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+  35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
+];
+
+var lext = [ /* Length codes 257..285 extra */
+  16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+  19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78
+];
+
+var dbase = [ /* Distance codes 0..29 base */
+  1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+  257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+  8193, 12289, 16385, 24577, 0, 0
+];
+
+var dext = [ /* Distance codes 0..29 extra */
+  16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+  23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+  28, 28, 29, 29, 64, 64
+];
+
+module.exports = function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts)
+{
+  var bits = opts.bits;
+      // here = opts.here; /* table entry for duplication */
+
+  var len = 0;               /* a code's length in bits */
+  var sym = 0;               /* index of code symbols */
+  var min = 0, max = 0;          /* minimum and maximum code lengths */
+  var root = 0;              /* number of index bits for root table */
+  var curr = 0;              /* number of index bits for current table */
+  var drop = 0;              /* code bits to drop for sub-table */
+  var left = 0;                   /* number of prefix codes available */
+  var used = 0;              /* code entries in table used */
+  var huff = 0;              /* Huffman code */
+  var incr;              /* for incrementing code, index */
+  var fill;              /* index for replicating entries */
+  var low;               /* low bits for current root entry */
+  var mask;              /* mask for low root bits */
+  var next;             /* next available space in table */
+  var base = null;     /* base value table to use */
+  var base_index = 0;
+// var shoextra; /* extra bits table to use */
+  var end;                    /* use base and extra for symbol > end */
+  var count = new utils.Buf16(MAXBITS + 1); // [MAXBITS+1]; /* number of codes
+											// of each length */
+  var offs = new utils.Buf16(MAXBITS + 1); // [MAXBITS+1]; /* offsets in table
+											// for each length */
+  var extra = null;
+  var extra_index = 0;
+
+  var here_bits, here_op, here_val;
+
+  /*
+	 * Process a set of code lengths to create a canonical Huffman code. The
+	 * code lengths are lens[0..codes-1]. Each length corresponds to the symbols
+	 * 0..codes-1. The Huffman code is generated by first sorting the symbols by
+	 * length from short to long, and retaining the symbol order for codes with
+	 * equal lengths. Then the code starts with all zero bits for the first code
+	 * of the shortest length, and the codes are integer increments for the same
+	 * length, and zeros are appended as the length increases. For the deflate
+	 * format, these bits are stored backwards from their more natural integer
+	 * increment ordering, and so when the decoding tables are built in the
+	 * large loop below, the integer codes are incremented backwards.
+	 * 
+	 * This routine assumes, but does not check, that all of the entries in
+	 * lens[] are in the range 0..MAXBITS. The caller must assure this.
+	 * 1..MAXBITS is interpreted as that code length. zero means that that
+	 * symbol does not occur in this code.
+	 * 
+	 * The codes are sorted by computing a count of codes for each length,
+	 * creating from that a table of starting indices for each length in the
+	 * sorted table, and then entering the symbols in order in the sorted table.
+	 * The sorted table is work[], with that space being provided by the caller.
+	 * 
+	 * The length counts are used for other purposes as well, i.e. finding the
+	 * minimum and maximum length codes, determining if there are any codes at
+	 * all, checking for a valid set of lengths, and looking ahead at length
+	 * counts to determine sub-table sizes when building the decoding tables.
+	 */
+
+  /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+  for (len = 0; len <= MAXBITS; len++) {
+    count[len] = 0;
+  }
+  for (sym = 0; sym < codes; sym++) {
+    count[lens[lens_index + sym]]++;
+  }
+
+  /* bound code lengths, force root to be within code lengths */
+  root = bits;
+  for (max = MAXBITS; max >= 1; max--) {
+    if (count[max] !== 0) { break; }
+  }
+  if (root > max) {
+    root = max;
+  }
+  if (max === 0) {                     /* no symbols to code at all */
+    // table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid
+	// code marker */
+    // table.bits[opts.table_index] = 1; //here.bits = (var char)1;
+    // table.val[opts.table_index++] = 0; //here.val = (var short)0;
+    table[table_index++] = (1 << 24) | (64 << 16) | 0;
+
+
+    // table.op[opts.table_index] = 64;
+    // table.bits[opts.table_index] = 1;
+    // table.val[opts.table_index++] = 0;
+    table[table_index++] = (1 << 24) | (64 << 16) | 0;
+
+    opts.bits = 1;
+    return 0;     /* no symbols, but wait for decoding to report error */
+  }
+  for (min = 1; min < max; min++) {
+    if (count[min] !== 0) { break; }
+  }
+  if (root < min) {
+    root = min;
+  }
+
+  /* check for an over-subscribed or incomplete set of lengths */
+  left = 1;
+  for (len = 1; len <= MAXBITS; len++) {
+    left <<= 1;
+    left -= count[len];
+    if (left < 0) {
+      return -1;
+    }        /* over-subscribed */
+  }
+  if (left > 0 && (type === CODES || max !== 1)) {
+    return -1;                      /* incomplete set */
+  }
+
+  /* generate offsets into symbol table for each length for sorting */
+  offs[1] = 0;
+  for (len = 1; len < MAXBITS; len++) {
+    offs[len + 1] = offs[len] + count[len];
+  }
+
+  /* sort symbols by length, by symbol order within each length */
+  for (sym = 0; sym < codes; sym++) {
+    if (lens[lens_index + sym] !== 0) {
+      work[offs[lens[lens_index + sym]]++] = sym;
+    }
+  }
+
+  /*
+	 * Create and fill in decoding tables. In this loop, the table being filled
+	 * is at next and has curr index bits. The code being used is huff with
+	 * length len. That code is converted to an index by dropping drop bits off
+	 * of the bottom. For codes where len is less than drop + curr, those top
+	 * drop + curr - len bits are incremented through all values to fill the
+	 * table with replicated entries.
+	 * 
+	 * root is the number of index bits for the root table. When len exceeds
+	 * root, sub-tables are created pointed to by the root entry with an index
+	 * of the low root bits of huff. This is saved in low to check for when a
+	 * new sub-table should be started. drop is zero when the root table is
+	 * being filled, and drop is root when sub-tables are being filled.
+	 * 
+	 * When a new sub-table is needed, it is necessary to look ahead in the code
+	 * lengths to determine what size sub-table is needed. The length counts are
+	 * used for this, and so count[] is decremented as codes are entered in the
+	 * tables.
+	 * 
+	 * used keeps track of how many table entries have been allocated from the
+	 * provided *table space. It is checked for LENS and DIST tables against the
+	 * constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in the
+	 * initial root table size constants. See the comments in inftrees.h for
+	 * more information.
+	 * 
+	 * sym increments through all symbols, and the loop terminates when all
+	 * codes of length max, i.e. all codes, have been processed. This routine
+	 * permits incomplete codes, so another loop after this one fills in the
+	 * rest of the decoding tables with invalid code markers.
+	 */
+
+  /* set up for code type */
+  // poor man optimization - use if-else instead of switch,
+  // to avoid deopts in old v8
+  if (type === CODES) {
+    base = extra = work;    /* dummy value--not used */
+    end = 19;
+
+  } else if (type === LENS) {
+    base = lbase;
+    base_index -= 257;
+    extra = lext;
+    extra_index -= 257;
+    end = 256;
+
+  } else {                    /* DISTS */
+    base = dbase;
+    extra = dext;
+    end = -1;
+  }
+
+  /* initialize opts for loop */
+  huff = 0;                   /* starting code */
+  sym = 0;                    /* starting code symbol */
+  len = min;                  /* starting code length */
+  next = table_index;              /* current table to fill in */
+  curr = root;                /* current table index bits */
+  drop = 0;                   /* current bits to drop from code for index */
+  low = -1;                   /* trigger new sub-table when len > root */
+  used = 1 << root;          /* use root table entries */
+  mask = used - 1;            /* mask for comparing low */
+
+  /* check available table space */
+  if ((type === LENS && used > ENOUGH_LENS) ||
+    (type === DISTS && used > ENOUGH_DISTS)) {
+    return 1;
+  }
+
+  var i = 0;
+  /* process all codes and make table entries */
+  for (;;) {
+    i++;
+    /* create table entry */
+    here_bits = len - drop;
+    if (work[sym] < end) {
+      here_op = 0;
+      here_val = work[sym];
+    }
+    else if (work[sym] > end) {
+      here_op = extra[extra_index + work[sym]];
+      here_val = base[base_index + work[sym]];
+    }
+    else {
+      here_op = 32 + 64;         /* end of block */
+      here_val = 0;
+    }
+
+    /* replicate for those indices with low len bits equal to huff */
+    incr = 1 << (len - drop);
+    fill = 1 << curr;
+    min = fill;                 /* save offset to next table */
+    do {
+      fill -= incr;
+      table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0;
+    } while (fill !== 0);
+
+    /* backwards increment the len-bit code huff */
+    incr = 1 << (len - 1);
+    while (huff & incr) {
+      incr >>= 1;
+    }
+    if (incr !== 0) {
+      huff &= incr - 1;
+      huff += incr;
+    } else {
+      huff = 0;
+    }
+
+    /* go to next symbol, update count, len */
+    sym++;
+    if (--count[len] === 0) {
+      if (len === max) { break; }
+      len = lens[lens_index + work[sym]];
+    }
+
+    /* create new sub-table if needed */
+    if (len > root && (huff & mask) !== low) {
+      /* if first time, transition to sub-tables */
+      if (drop === 0) {
+        drop = root;
+      }
+
+      /* increment past last table */
+      next += min;            /* here min is 1 << curr */
+
+      /* determine length of next table */
+      curr = len - drop;
+      left = 1 << curr;
+      while (curr + drop < max) {
+        left -= count[curr + drop];
+        if (left <= 0) { break; }
+        curr++;
+        left <<= 1;
+      }
+
+      /* check for enough space */
+      used += 1 << curr;
+      if ((type === LENS && used > ENOUGH_LENS) ||
+        (type === DISTS && used > ENOUGH_DISTS)) {
+        return 1;
+      }
+
+      /* point entry in root table to sub-table */
+      low = huff & mask;
+      /*
+		 * table.op[low] = curr; table.bits[low] = root; table.val[low] = next -
+		 * opts.table_index;
+		 */
+      table[low] = (root << 24) | (curr << 16) | (next - table_index) |0;
+    }
+  }
+
+  /*
+	 * fill in remaining table entry if code is incomplete (guaranteed to have
+	 * at most one remaining entry, since if the code is incomplete, the maximum
+	 * code length that was allowed to get this far is one bit)
+	 */
+  if (huff !== 0) {
+    // table.op[next + huff] = 64; /* invalid code marker */
+    // table.bits[next + huff] = len - drop;
+    // table.val[next + huff] = 0;
+    table[next + huff] = ((len - drop) << 24) | (64 << 16) |0;
+  }
+
+  /* set return parameters */
+  // opts.table_index += used;
+  opts.bits = root;
+  return 0;
+};
+
+},{"../utils/common":3}],11:[function(require,module,exports){
+'use strict';
+
+module.exports = {
+  2:      'need dictionary',     /* Z_NEED_DICT 2 */
+  1:      'stream end',          /* Z_STREAM_END 1 */
+  0:      '',                    /* Z_OK 0 */
+  '-1':   'file error',          /* Z_ERRNO (-1) */
+  '-2':   'stream error',        /* Z_STREAM_ERROR (-2) */
+  '-3':   'data error',          /* Z_DATA_ERROR (-3) */
+  '-4':   'insufficient memory', /* Z_MEM_ERROR (-4) */
+  '-5':   'buffer error',        /* Z_BUF_ERROR (-5) */
+  '-6':   'incompatible version' /* Z_VERSION_ERROR (-6) */
+};
+
+},{}],12:[function(require,module,exports){
+'use strict';
+
+
+var utils = require('../utils/common');
+
+/* Public constants ========================================================== */
+/* =========================================================================== */
+
+
+// var Z_FILTERED = 1;
+// var Z_HUFFMAN_ONLY = 2;
+// var Z_RLE = 3;
+var Z_FIXED               = 4;
+// var Z_DEFAULT_STRATEGY = 0;
+
+/* Possible values of the data_type field (though see inflate()) */
+var Z_BINARY              = 0;
+var Z_TEXT                = 1;
+// var Z_ASCII = 1; // = Z_TEXT
+var Z_UNKNOWN             = 2;
+
+/* ============================================================================ */
+
+
+function zero(buf) { var len = buf.length; while (--len >= 0) { buf[len] = 0; } }
+
+// From zutil.h
+
+var STORED_BLOCK = 0;
+var STATIC_TREES = 1;
+var DYN_TREES    = 2;
+/* The three kinds of block type */
+
+var MIN_MATCH    = 3;
+var MAX_MATCH    = 258;
+/* The minimum and maximum match lengths */
+
+// From deflate.h
+/*
+ * ===========================================================================
+ * Internal compression state.
+ */
+
+var LENGTH_CODES  = 29;
+/* number of length codes, not counting the special END_BLOCK code */
+
+var LITERALS      = 256;
+/* number of literal bytes 0..255 */
+
+var L_CODES       = LITERALS + 1 + LENGTH_CODES;
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+var D_CODES       = 30;
+/* number of distance codes */
+
+var BL_CODES      = 19;
+/* number of codes used to transfer the bit lengths */
+
+var HEAP_SIZE     = 2 * L_CODES + 1;
+/* maximum heap size */
+
+var MAX_BITS      = 15;
+/* All codes must not exceed MAX_BITS bits */
+
+var Buf_size      = 16;
+/* size of bit buffer in bi_buf */
+
+
+/*
+ * ===========================================================================
+ * Constants
+ */
+
+var MAX_BL_BITS = 7;
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+var END_BLOCK   = 256;
+/* end of block literal code */
+
+var REP_3_6     = 16;
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+var REPZ_3_10   = 17;
+/* repeat a zero length 3-10 times (3 bits of repeat count) */
+
+var REPZ_11_138 = 18;
+/* repeat a zero length 11-138 times (7 bits of repeat count) */
+
+/* eslint-disable comma-spacing,array-bracket-spacing */
+var extra_lbits =   /* extra bits for each length code */
+  [0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0];
+
+var extra_dbits =   /* extra bits for each distance code */
+  [0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13];
+
+var extra_blbits =  /* extra bits for each bit length code */
+  [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7];
+
+var bl_order =
+  [16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];
+/* eslint-enable comma-spacing,array-bracket-spacing */
+
+/*
+ * The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+/*
+ * ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+// We pre-fill arrays with 0 to avoid uninitialized gaps
+
+var DIST_CODE_LEN = 512; /* see definition of array dist_code below */
+
+// !!!! Use flat array insdead of structure, Freq = i*2, Len = i*2+1
+var static_ltree  = new Array((L_CODES + 2) * 2);
+zero(static_ltree);
+/*
+ * The static literal tree. Since the bit lengths are imposed, there is no need
+ * for the L_CODES extra codes used during heap construction. However The codes
+ * 286 and 287 are needed to build a canonical tree (see _tr_init below).
+ */
+
+var static_dtree  = new Array(D_CODES * 2);
+zero(static_dtree);
+/*
+ * The static distance tree. (Actually a trivial tree since all codes use 5
+ * bits.)
+ */
+
+var _dist_code    = new Array(DIST_CODE_LEN);
+zero(_dist_code);
+/*
+ * Distance codes. The first 256 values correspond to the distances 3 .. 258,
+ * the last 256 values correspond to the top 8 bits of the 15 bit distances.
+ */
+
+var _length_code  = new Array(MAX_MATCH - MIN_MATCH + 1);
+zero(_length_code);
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+var base_length   = new Array(LENGTH_CODES);
+zero(base_length);
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+var base_dist     = new Array(D_CODES);
+zero(base_dist);
+/* First normalized distance for each code (0 = distance of 1) */
+
+
+function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) {
+
+  this.static_tree  = static_tree;  /* static tree or NULL */
+  this.extra_bits   = extra_bits;   /* extra bits for each code or NULL */
+  this.extra_base   = extra_base;   /* base index for extra_bits */
+  this.elems        = elems;        /* max number of elements in the tree */
+  this.max_length   = max_length;   /* max bit length for the codes */
+
+  // show if `static_tree` has data or dummy - needed for monomorphic objects
+  this.has_stree    = static_tree && static_tree.length;
+}
+
+
+var static_l_desc;
+var static_d_desc;
+var static_bl_desc;
+
+
+function TreeDesc(dyn_tree, stat_desc) {
+  this.dyn_tree = dyn_tree;     /* the dynamic tree */
+  this.max_code = 0;            /* largest code with non zero frequency */
+  this.stat_desc = stat_desc;   /* the corresponding static tree */
+}
+
+
+
+function d_code(dist) {
+  return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)];
+}
+
+
+/*
+ * ===========================================================================
+ * Output a short LSB first on the stream. IN assertion: there is enough room in
+ * pendingBuf.
+ */
+function put_short(s, w) {
+// put_byte(s, (uch)((w) & 0xff));
+// put_byte(s, (uch)((ush)(w) >> 8));
+  s.pending_buf[s.pending++] = (w) & 0xff;
+  s.pending_buf[s.pending++] = (w >>> 8) & 0xff;
+}
+
+
+/*
+ * ===========================================================================
+ * Send a value on a given number of bits. IN assertion: length <= 16 and value
+ * fits in length bits.
+ */
+function send_bits(s, value, length) {
+  if (s.bi_valid > (Buf_size - length)) {
+    s.bi_buf |= (value << s.bi_valid) & 0xffff;
+    put_short(s, s.bi_buf);
+    s.bi_buf = value >> (Buf_size - s.bi_valid);
+    s.bi_valid += length - Buf_size;
+  } else {
+    s.bi_buf |= (value << s.bi_valid) & 0xffff;
+    s.bi_valid += length;
+  }
+}
+
+
+function send_code(s, c, tree) {
+  send_bits(s, tree[c * 2]/* .Code */, tree[c * 2 + 1]/* .Len */);
+}
+
+
+/*
+ * ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table) IN assertion: 1 <= len <= 15
+ */
+function bi_reverse(code, len) {
+  var res = 0;
+  do {
+    res |= code & 1;
+    code >>>= 1;
+    res <<= 1;
+  } while (--len > 0);
+  return res >>> 1;
+}
+
+
+/*
+ * ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+function bi_flush(s) {
+  if (s.bi_valid === 16) {
+    put_short(s, s.bi_buf);
+    s.bi_buf = 0;
+    s.bi_valid = 0;
+
+  } else if (s.bi_valid >= 8) {
+    s.pending_buf[s.pending++] = s.bi_buf & 0xff;
+    s.bi_buf >>= 8;
+    s.bi_valid -= 8;
+  }
+}
+
+
+/*
+ * ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block. IN assertion: the fields freq and dad are set,
+ * heap[heap_max] and above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the array
+ * bl_count contains the frequencies for each bit length. The length opt_len is
+ * updated; static_len is also updated if stree is not null.
+ */
+function gen_bitlen(s, desc)
+// deflate_state *s;
+// tree_desc *desc; /* the tree descriptor */
+{
+  var tree            = desc.dyn_tree;
+  var max_code        = desc.max_code;
+  var stree           = desc.stat_desc.static_tree;
+  var has_stree       = desc.stat_desc.has_stree;
+  var extra           = desc.stat_desc.extra_bits;
+  var base            = desc.stat_desc.extra_base;
+  var max_length      = desc.stat_desc.max_length;
+  var h;              /* heap index */
+  var n, m;           /* iterate over the tree elements */
+  var bits;           /* bit length */
+  var xbits;          /* extra bits */
+  var f;              /* frequency */
+  var overflow = 0;   /* number of elements with bit length too large */
+
+  for (bits = 0; bits <= MAX_BITS; bits++) {
+    s.bl_count[bits] = 0;
+  }
+
+  /*
+	 * In a first pass, compute the optimal bit lengths (which may overflow in
+	 * the case of the bit length tree).
+	 */
+  tree[s.heap[s.heap_max] * 2 + 1]/* .Len */ = 0; /* root of the heap */
+
+  for (h = s.heap_max + 1; h < HEAP_SIZE; h++) {
+    n = s.heap[h];
+    bits = tree[tree[n * 2 + 1]/* .Dad */ * 2 + 1]/* .Len */ + 1;
+    if (bits > max_length) {
+      bits = max_length;
+      overflow++;
+    }
+    tree[n * 2 + 1]/* .Len */ = bits;
+    /* We overwrite tree[n].Dad which is no longer needed */
+
+    if (n > max_code) { continue; } /* not a leaf node */
+
+    s.bl_count[bits]++;
+    xbits = 0;
+    if (n >= base) {
+      xbits = extra[n - base];
+    }
+    f = tree[n * 2]/* .Freq */;
+    s.opt_len += f * (bits + xbits);
+    if (has_stree) {
+      s.static_len += f * (stree[n * 2 + 1]/* .Len */ + xbits);
+    }
+  }
+  if (overflow === 0) { return; }
+
+  // Trace((stderr,"\nbit length overflow\n"));
+  /* This happens for example on obj2 and pic of the Calgary corpus */
+
+  /* Find the first bit length which could increase: */
+  do {
+    bits = max_length - 1;
+    while (s.bl_count[bits] === 0) { bits--; }
+    s.bl_count[bits]--;      /* move one leaf down the tree */
+    s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */
+    s.bl_count[max_length]--;
+    /*
+	 * The brother of the overflow item also moves one step up, but this does
+	 * not affect bl_count[max_length]
+	 */
+    overflow -= 2;
+  } while (overflow > 0);
+
+  /*
+	 * Now recompute all bit lengths, scanning in increasing frequency. h is
+	 * still equal to HEAP_SIZE. (It is simpler to reconstruct all lengths
+	 * instead of fixing only the wrong ones. This idea is taken from 'ar'
+	 * written by Haruhiko Okumura.)
+	 */
+  for (bits = max_length; bits !== 0; bits--) {
+    n = s.bl_count[bits];
+    while (n !== 0) {
+      m = s.heap[--h];
+      if (m > max_code) { continue; }
+      if (tree[m * 2 + 1]/* .Len */ !== bits) {
+        // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+        s.opt_len += (bits - tree[m * 2 + 1]/* .Len */) * tree[m * 2]/* .Freq */;
+        tree[m * 2 + 1]/* .Len */ = bits;
+      }
+      n--;
+    }
+  }
+}
+
+
+/*
+ * ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal). IN assertion: the array bl_count contains the bit length statistics
+ * for the given tree and the field len is set for all tree elements. OUT
+ * assertion: the field code is set for all tree elements of non zero code
+ * length.
+ */
+function gen_codes(tree, max_code, bl_count)
+// ct_data *tree; /* the tree to decorate */
+// int max_code; /* largest code with non zero frequency */
+// ushf *bl_count; /* number of codes at each bit length */
+{
+  var next_code = new Array(MAX_BITS + 1); /*
+											 * next code value for each bit
+											 * length
+											 */
+  var code = 0;              /* running code value */
+  var bits;                  /* bit index */
+  var n;                     /* code index */
+
+  /*
+	 * The distribution counts are first used to generate the code values
+	 * without bit reversal.
+	 */
+  for (bits = 1; bits <= MAX_BITS; bits++) {
+    next_code[bits] = code = (code + bl_count[bits - 1]) << 1;
+  }
+  /*
+	 * Check that the bit counts in bl_count are consistent. The last code must
+	 * be all ones.
+	 */
+  // Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+  // "inconsistent bit counts");
+  // Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+  for (n = 0;  n <= max_code; n++) {
+    var len = tree[n * 2 + 1]/* .Len */;
+    if (len === 0) { continue; }
+    /* Now reverse the bits */
+    tree[n * 2]/* .Code */ = bi_reverse(next_code[len]++, len);
+
+    // Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+    // n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+  }
+}
+
+
+/*
+ * ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+function tr_static_init() {
+  var n;        /* iterates over tree elements */
+  var bits;     /* bit counter */
+  var length;   /* length value */
+  var code;     /* code value */
+  var dist;     /* distance index */
+  var bl_count = new Array(MAX_BITS + 1);
+  /* number of codes at each bit length for an optimal tree */
+
+  // do check in _tr_init()
+  // if (static_init_done) return;
+
+  /* For some embedded targets, global variables are not initialized: */
+/*
+ * #ifdef NO_INIT_GLOBAL_POINTERS static_l_desc.static_tree = static_ltree;
+ * static_l_desc.extra_bits = extra_lbits; static_d_desc.static_tree =
+ * static_dtree; static_d_desc.extra_bits = extra_dbits;
+ * static_bl_desc.extra_bits = extra_blbits; #endif
+ */
+
+  /* Initialize the mapping length (0..255) -> length code (0..28) */
+  length = 0;
+  for (code = 0; code < LENGTH_CODES - 1; code++) {
+    base_length[code] = length;
+    for (n = 0; n < (1 << extra_lbits[code]); n++) {
+      _length_code[length++] = code;
+    }
+  }
+  // Assert (length == 256, "tr_static_init: length != 256");
+  /*
+	 * Note that the length 255 (match length 258) can be represented in two
+	 * different ways: code 284 + 5 bits or code 285, so we overwrite
+	 * length_code[255] to use the best encoding:
+	 */
+  _length_code[length - 1] = code;
+
+  /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+  dist = 0;
+  for (code = 0; code < 16; code++) {
+    base_dist[code] = dist;
+    for (n = 0; n < (1 << extra_dbits[code]); n++) {
+      _dist_code[dist++] = code;
+    }
+  }
+  // Assert (dist == 256, "tr_static_init: dist != 256");
+  dist >>= 7; /* from now on, all distances are divided by 128 */
+  for (; code < D_CODES; code++) {
+    base_dist[code] = dist << 7;
+    for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) {
+      _dist_code[256 + dist++] = code;
+    }
+  }
+  // Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+  /* Construct the codes of the static literal tree */
+  for (bits = 0; bits <= MAX_BITS; bits++) {
+    bl_count[bits] = 0;
+  }
+
+  n = 0;
+  while (n <= 143) {
+    static_ltree[n * 2 + 1]/* .Len */ = 8;
+    n++;
+    bl_count[8]++;
+  }
+  while (n <= 255) {
+    static_ltree[n * 2 + 1]/* .Len */ = 9;
+    n++;
+    bl_count[9]++;
+  }
+  while (n <= 279) {
+    static_ltree[n * 2 + 1]/* .Len */ = 7;
+    n++;
+    bl_count[7]++;
+  }
+  while (n <= 287) {
+    static_ltree[n * 2 + 1]/* .Len */ = 8;
+    n++;
+    bl_count[8]++;
+  }
+  /*
+	 * Codes 286 and 287 do not exist, but we must include them in the tree
+	 * construction to get a canonical Huffman tree (longest code all ones)
+	 */
+  gen_codes(static_ltree, L_CODES + 1, bl_count);
+
+  /* The static distance tree is trivial: */
+  for (n = 0; n < D_CODES; n++) {
+    static_dtree[n * 2 + 1]/* .Len */ = 5;
+    static_dtree[n * 2]/* .Code */ = bi_reverse(n, 5);
+  }
+
+  // Now data ready and we can init static trees
+  static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS + 1, L_CODES, MAX_BITS);
+  static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS);
+  static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0,         BL_CODES, MAX_BL_BITS);
+
+  // static_init_done = true;
+}
+
+
+/*
+ * ===========================================================================
+ * Initialize a new block.
+ */
+function init_block(s) {
+  var n; /* iterates over tree elements */
+
+  /* Initialize the trees. */
+  for (n = 0; n < L_CODES;  n++) { s.dyn_ltree[n * 2]/* .Freq */ = 0; }
+  for (n = 0; n < D_CODES;  n++) { s.dyn_dtree[n * 2]/* .Freq */ = 0; }
+  for (n = 0; n < BL_CODES; n++) { s.bl_tree[n * 2]/* .Freq */ = 0; }
+
+  s.dyn_ltree[END_BLOCK * 2]/* .Freq */ = 1;
+  s.opt_len = s.static_len = 0;
+  s.last_lit = s.matches = 0;
+}
+
+
+/*
+ * ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+function bi_windup(s)
+{
+  if (s.bi_valid > 8) {
+    put_short(s, s.bi_buf);
+  } else if (s.bi_valid > 0) {
+    // put_byte(s, (Byte)s->bi_buf);
+    s.pending_buf[s.pending++] = s.bi_buf;
+  }
+  s.bi_buf = 0;
+  s.bi_valid = 0;
+}
+
+/*
+ * ===========================================================================
+ * Copy a stored block, storing first the length and its one's complement if
+ * requested.
+ */
+function copy_block(s, buf, len, header)
+// DeflateState *s;
+// charf *buf; /* the input data */
+// unsigned len; /* its length */
+// int header; /* true if block header must be written */
+{
+  bi_windup(s);        /* align on byte boundary */
+
+  if (header) {
+    put_short(s, len);
+    put_short(s, ~len);
+  }
+// while (len--) {
+// put_byte(s, *buf++);
+// }
+  utils.arraySet(s.pending_buf, s.window, buf, len, s.pending);
+  s.pending += len;
+}
+
+/*
+ * ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when the subtrees
+ * have equal frequency. This minimizes the worst case length.
+ */
+function smaller(tree, n, m, depth) {
+  var _n2 = n * 2;
+  var _m2 = m * 2;
+  return (tree[_n2]/* .Freq */ < tree[_m2]/* .Freq */ ||
+         (tree[_n2]/* .Freq */ === tree[_m2]/* .Freq */ && depth[n] <= depth[m]));
+}
+
+/*
+ * ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its two
+ * sons).
+ */
+function pqdownheap(s, tree, k)
+// deflate_state *s;
+// ct_data *tree; /* the tree to restore */
+// int k; /* node to move down */
+{
+  var v = s.heap[k];
+  var j = k << 1;  /* left son of k */
+  while (j <= s.heap_len) {
+    /* Set j to the smallest of the two sons: */
+    if (j < s.heap_len &&
+      smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) {
+      j++;
+    }
+    /* Exit if v is smaller than both sons */
+    if (smaller(tree, v, s.heap[j], s.depth)) { break; }
+
+    /* Exchange v with the smallest son */
+    s.heap[k] = s.heap[j];
+    k = j;
+
+    /* And continue down the tree, setting j to the left son of k */
+    j <<= 1;
+  }
+  s.heap[k] = v;
+}
+
+
+// inlined manually
+// var SMALLEST = 1;
+
+/*
+ * ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+function compress_block(s, ltree, dtree)
+// deflate_state *s;
+// const ct_data *ltree; /* literal tree */
+// const ct_data *dtree; /* distance tree */
+{
+  var dist;           /* distance of matched string */
+  var lc;             /* match length or unmatched char (if dist == 0) */
+  var lx = 0;         /* running index in l_buf */
+  var code;           /* the code to send */
+  var extra;          /* number of extra bits to send */
+
+  if (s.last_lit !== 0) {
+    do {
+      dist = (s.pending_buf[s.d_buf + lx * 2] << 8) | (s.pending_buf[s.d_buf + lx * 2 + 1]);
+      lc = s.pending_buf[s.l_buf + lx];
+      lx++;
+
+      if (dist === 0) {
+        send_code(s, lc, ltree); /* send a literal byte */
+        // Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+      } else {
+        /* Here, lc is the match length - MIN_MATCH */
+        code = _length_code[lc];
+        send_code(s, code + LITERALS + 1, ltree); /* send the length code */
+        extra = extra_lbits[code];
+        if (extra !== 0) {
+          lc -= base_length[code];
+          send_bits(s, lc, extra);       /* send the extra length bits */
+        }
+        dist--; /* dist is now the match distance - 1 */
+        code = d_code(dist);
+        // Assert (code < D_CODES, "bad d_code");
+
+        send_code(s, code, dtree);       /* send the distance code */
+        extra = extra_dbits[code];
+        if (extra !== 0) {
+          dist -= base_dist[code];
+          send_bits(s, dist, extra);   /* send the extra distance bits */
+        }
+      } /* literal or match pair ? */
+
+      /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+      // Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
+      // "pendingBuf overflow");
+
+    } while (lx < s.last_lit);
+  }
+
+  send_code(s, END_BLOCK, ltree);
+}
+
+
+/*
+ * ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block. IN assertion: the field
+ * freq is set for all tree elements. OUT assertions: the fields len and code
+ * are set to the optimal bit length and corresponding code. The length opt_len
+ * is updated; static_len is also updated if stree is not null. The field
+ * max_code is set.
+ */
+function build_tree(s, desc)
+// deflate_state *s;
+// tree_desc *desc; /* the tree descriptor */
+{
+  var tree     = desc.dyn_tree;
+  var stree    = desc.stat_desc.static_tree;
+  var has_stree = desc.stat_desc.has_stree;
+  var elems    = desc.stat_desc.elems;
+  var n, m;          /* iterate over heap elements */
+  var max_code = -1; /* largest code with non zero frequency */
+  var node;          /* new node being created */
+
+  /*
+	 * Construct the initial heap, with least frequent element in
+	 * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+	 * heap[0] is not used.
+	 */
+  s.heap_len = 0;
+  s.heap_max = HEAP_SIZE;
+
+  for (n = 0; n < elems; n++) {
+    if (tree[n * 2]/* .Freq */ !== 0) {
+      s.heap[++s.heap_len] = max_code = n;
+      s.depth[n] = 0;
+
+    } else {
+      tree[n * 2 + 1]/* .Len */ = 0;
+    }
+  }
+
+  /*
+	 * The pkzip format requires that at least one distance code exists, and
+	 * that at least one bit should be sent even if there is only one possible
+	 * code. So to avoid special checks later on we force at least two codes of
+	 * non zero frequency.
+	 */
+  while (s.heap_len < 2) {
+    node = s.heap[++s.heap_len] = (max_code < 2 ? ++max_code : 0);
+    tree[node * 2]/* .Freq */ = 1;
+    s.depth[node] = 0;
+    s.opt_len--;
+
+    if (has_stree) {
+      s.static_len -= stree[node * 2 + 1]/* .Len */;
+    }
+    /* node is 0 or 1 so it does not have extra bits */
+  }
+  desc.max_code = max_code;
+
+  /*
+	 * The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+	 * establish sub-heaps of increasing lengths:
+	 */
+  for (n = (s.heap_len >> 1/* int /2 */); n >= 1; n--) { pqdownheap(s, tree, n); }
+
+  /*
+	 * Construct the Huffman tree by repeatedly combining the least two frequent
+	 * nodes.
+	 */
+  node = elems;              /* next internal node of the tree */
+  do {
+    // pqremove(s, tree, n); /* n = node of least frequency */
+    /** * pqremove ** */
+    n = s.heap[1/* SMALLEST */];
+    s.heap[1/* SMALLEST */] = s.heap[s.heap_len--];
+    pqdownheap(s, tree, 1/* SMALLEST */);
+    /***/
+
+    m = s.heap[1/* SMALLEST */]; /* m = node of next least frequency */
+
+    s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */
+    s.heap[--s.heap_max] = m;
+
+    /* Create a new node father of n and m */
+    tree[node * 2]/* .Freq */ = tree[n * 2]/* .Freq */ + tree[m * 2]/* .Freq */;
+    s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1;
+    tree[n * 2 + 1]/* .Dad */ = tree[m * 2 + 1]/* .Dad */ = node;
+
+    /* and insert the new node in the heap */
+    s.heap[1/* SMALLEST */] = node++;
+    pqdownheap(s, tree, 1/* SMALLEST */);
+
+  } while (s.heap_len >= 2);
+
+  s.heap[--s.heap_max] = s.heap[1/* SMALLEST */];
+
+  /*
+	 * At this point, the fields freq and dad are set. We can now generate the
+	 * bit lengths.
+	 */
+  gen_bitlen(s, desc);
+
+  /* The field len is now set, we can generate the bit codes */
+  gen_codes(tree, max_code, s.bl_count);
+}
+
+
+/*
+ * ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes in
+ * the bit length tree.
+ */
+function scan_tree(s, tree, max_code)
+// deflate_state *s;
+// ct_data *tree; /* the tree to be scanned */
+// int max_code; /* and its largest code of non zero frequency */
+{
+  var n;                     /* iterates over all tree elements */
+  var prevlen = -1;          /* last emitted length */
+  var curlen;                /* length of current code */
+
+  var nextlen = tree[0 * 2 + 1]/* .Len */; /* length of next code */
+
+  var count = 0;             /* repeat count of the current code */
+  var max_count = 7;         /* max repeat count */
+  var min_count = 4;         /* min repeat count */
+
+  if (nextlen === 0) {
+    max_count = 138;
+    min_count = 3;
+  }
+  tree[(max_code + 1) * 2 + 1]/* .Len */ = 0xffff; /* guard */
+
+  for (n = 0; n <= max_code; n++) {
+    curlen = nextlen;
+    nextlen = tree[(n + 1) * 2 + 1]/* .Len */;
+
+    if (++count < max_count && curlen === nextlen) {
+      continue;
+
+    } else if (count < min_count) {
+      s.bl_tree[curlen * 2]/* .Freq */ += count;
+
+    } else if (curlen !== 0) {
+
+      if (curlen !== prevlen) { s.bl_tree[curlen * 2]/* .Freq */++; }
+      s.bl_tree[REP_3_6 * 2]/* .Freq */++;
+
+    } else if (count <= 10) {
+      s.bl_tree[REPZ_3_10 * 2]/* .Freq */++;
+
+    } else {
+      s.bl_tree[REPZ_11_138 * 2]/* .Freq */++;
+    }
+
+    count = 0;
+    prevlen = curlen;
+
+    if (nextlen === 0) {
+      max_count = 138;
+      min_count = 3;
+
+    } else if (curlen === nextlen) {
+      max_count = 6;
+      min_count = 3;
+
+    } else {
+      max_count = 7;
+      min_count = 4;
+    }
+  }
+}
+
+
+/*
+ * ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+function send_tree(s, tree, max_code)
+// deflate_state *s;
+// ct_data *tree; /* the tree to be scanned */
+// int max_code; /* and its largest code of non zero frequency */
+{
+  var n;                     /* iterates over all tree elements */
+  var prevlen = -1;          /* last emitted length */
+  var curlen;                /* length of current code */
+
+  var nextlen = tree[0 * 2 + 1]/* .Len */; /* length of next code */
+
+  var count = 0;             /* repeat count of the current code */
+  var max_count = 7;         /* max repeat count */
+  var min_count = 4;         /* min repeat count */
+
+  /* tree[max_code+1].Len = -1; */  /* guard already set */
+  if (nextlen === 0) {
+    max_count = 138;
+    min_count = 3;
+  }
+
+  for (n = 0; n <= max_code; n++) {
+    curlen = nextlen;
+    nextlen = tree[(n + 1) * 2 + 1]/* .Len */;
+
+    if (++count < max_count && curlen === nextlen) {
+      continue;
+
+    } else if (count < min_count) {
+      do { send_code(s, curlen, s.bl_tree); } while (--count !== 0);
+
+    } else if (curlen !== 0) {
+      if (curlen !== prevlen) {
+        send_code(s, curlen, s.bl_tree);
+        count--;
+      }
+      // Assert(count >= 3 && count <= 6, " 3_6?");
+      send_code(s, REP_3_6, s.bl_tree);
+      send_bits(s, count - 3, 2);
+
+    } else if (count <= 10) {
+      send_code(s, REPZ_3_10, s.bl_tree);
+      send_bits(s, count - 3, 3);
+
+    } else {
+      send_code(s, REPZ_11_138, s.bl_tree);
+      send_bits(s, count - 11, 7);
+    }
+
+    count = 0;
+    prevlen = curlen;
+    if (nextlen === 0) {
+      max_count = 138;
+      min_count = 3;
+
+    } else if (curlen === nextlen) {
+      max_count = 6;
+      min_count = 3;
+
+    } else {
+      max_count = 7;
+      min_count = 4;
+    }
+  }
+}
+
+
+/*
+ * ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+function build_bl_tree(s) {
+  var max_blindex;  /* index of last bit length code of non zero freq */
+
+  /* Determine the bit length frequencies for literal and distance trees */
+  scan_tree(s, s.dyn_ltree, s.l_desc.max_code);
+  scan_tree(s, s.dyn_dtree, s.d_desc.max_code);
+
+  /* Build the bit length tree: */
+  build_tree(s, s.bl_desc);
+  /*
+	 * opt_len now includes the length of the tree representations, except the
+	 * lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+	 */
+
+  /*
+	 * Determine the number of bit length codes to send. The pkzip format
+	 * requires that at least 4 bit length codes be sent. (appnote.txt says 3
+	 * but the actual value used is 4.)
+	 */
+  for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {
+    if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/* .Len */ !== 0) {
+      break;
+    }
+  }
+  /* Update opt_len to include the bit length tree and counts */
+  s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
+  // Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+  // s->opt_len, s->static_len));
+
+  return max_blindex;
+}
+
+
+/*
+ * ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree. IN
+ * assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+function send_all_trees(s, lcodes, dcodes, blcodes)
+// deflate_state *s;
+// int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+  var rank;                    /* index in bl_order */
+
+  // Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough
+	// codes");
+  // Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+  // "too many codes");
+  // Tracev((stderr, "\nbl counts: "));
+  send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */
+  send_bits(s, dcodes - 1,   5);
+  send_bits(s, blcodes - 4,  4); /* not -3 as stated in appnote.txt */
+  for (rank = 0; rank < blcodes; rank++) {
+    // Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+    send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/* .Len */, 3);
+  }
+  // Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+  send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */
+  // Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+  send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */
+  // Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+
+/*
+ * ===========================================================================
+ * Check if the data type is TEXT or BINARY, using the following algorithm: -
+ * TEXT if the two conditions below are satisfied: a) There are no non-portable
+ * control characters belonging to the "black list" (0..6, 14..25, 28..31). b)
+ * There is at least one printable character belonging to the "white list" (9
+ * {TAB}, 10 {LF}, 13 {CR}, 32..255). - BINARY otherwise. - The following
+ * partially-portable control characters form a "gray list" that is ignored in
+ * this detection algorithm: (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27
+ * {ESC}). IN assertion: the fields Freq of dyn_ltree are set.
+ */
+function detect_data_type(s) {
+  /*
+	 * black_mask is the bit mask of black-listed bytes set bits 0..6, 14..25,
+	 * and 28..31 0xf3ffc07f = binary 11110011111111111100000001111111
+	 */
+  var black_mask = 0xf3ffc07f;
+  var n;
+
+  /* Check for non-textual ("black-listed") bytes. */
+  for (n = 0; n <= 31; n++, black_mask >>>= 1) {
+    if ((black_mask & 1) && (s.dyn_ltree[n * 2]/* .Freq */ !== 0)) {
+      return Z_BINARY;
+    }
+  }
+
+  /* Check for textual ("white-listed") bytes. */
+  if (s.dyn_ltree[9 * 2]/* .Freq */ !== 0 || s.dyn_ltree[10 * 2]/* .Freq */ !== 0 ||
+      s.dyn_ltree[13 * 2]/* .Freq */ !== 0) {
+    return Z_TEXT;
+  }
+  for (n = 32; n < LITERALS; n++) {
+    if (s.dyn_ltree[n * 2]/* .Freq */ !== 0) {
+      return Z_TEXT;
+    }
+  }
+
+  /*
+	 * There are no "black-listed" or "white-listed" bytes: this stream either
+	 * is empty or has tolerated ("gray-listed") bytes only.
+	 */
+  return Z_BINARY;
+}
+
+
+var static_init_done = false;
+
+/*
+ * ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+function _tr_init(s)
+{
+
+  if (!static_init_done) {
+    tr_static_init();
+    static_init_done = true;
+  }
+
+  s.l_desc  = new TreeDesc(s.dyn_ltree, static_l_desc);
+  s.d_desc  = new TreeDesc(s.dyn_dtree, static_d_desc);
+  s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc);
+
+  s.bi_buf = 0;
+  s.bi_valid = 0;
+
+  /* Initialize the first block of the first file: */
+  init_block(s);
+}
+
+
+/*
+ * ===========================================================================
+ * Send a stored block
+ */
+function _tr_stored_block(s, buf, stored_len, last)
+// DeflateState *s;
+// charf *buf; /* input block */
+// ulg stored_len; /* length of input block */
+// int last; /* one if this is the last block for a file */
+{
+  send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3);    /* send block type */
+  copy_block(s, buf, stored_len, true); /* with header */
+}
+
+
+/*
+ * ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate. This takes
+ * 10 bits, of which 7 may remain in the bit buffer.
+ */
+function _tr_align(s) {
+  send_bits(s, STATIC_TREES << 1, 3);
+  send_code(s, END_BLOCK, static_ltree);
+  bi_flush(s);
+}
+
+
+/*
+ * ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file.
+ */
+function _tr_flush_block(s, buf, stored_len, last)
+// DeflateState *s;
+// charf *buf; /* input block, or NULL if too old */
+// ulg stored_len; /* length of input block */
+// int last; /* one if this is the last block for a file */
+{
+  var opt_lenb, static_lenb;  /* opt_len and static_len in bytes */
+  var max_blindex = 0;        /*
+								 * index of last bit length code of non zero
+								 * freq
+								 */
+
+  /* Build the Huffman trees unless a stored block is forced */
+  if (s.level > 0) {
+
+    /* Check if the file is binary or text */
+    if (s.strm.data_type === Z_UNKNOWN) {
+      s.strm.data_type = detect_data_type(s);
+    }
+
+    /* Construct the literal and distance trees */
+    build_tree(s, s.l_desc);
+    // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+    // s->static_len));
+
+    build_tree(s, s.d_desc);
+    // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+    // s->static_len));
+    /*
+	 * At this point, opt_len and static_len are the total bit lengths of the
+	 * compressed block data, excluding the tree representations.
+	 */
+
+    /*
+	 * Build the bit length tree for the above two trees, and get the index in
+	 * bl_order of the last bit length code to send.
+	 */
+    max_blindex = build_bl_tree(s);
+
+    /* Determine the best encoding. Compute the block lengths in bytes. */
+    opt_lenb = (s.opt_len + 3 + 7) >>> 3;
+    static_lenb = (s.static_len + 3 + 7) >>> 3;
+
+    // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+    // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+    // s->last_lit));
+
+    if (static_lenb <= opt_lenb) { opt_lenb = static_lenb; }
+
+  } else {
+    // Assert(buf != (char*)0, "lost buf");
+    opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+  }
+
+  if ((stored_len + 4 <= opt_lenb) && (buf !== -1)) {
+    /* 4: two words for the lengths */
+
+    /*
+	 * The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. Otherwise
+	 * we can't have processed more than WSIZE input bytes since the last block
+	 * flush, because compression would have been successful. If LIT_BUFSIZE <=
+	 * WSIZE, it is never too late to transform a block into a stored block.
+	 */
+    _tr_stored_block(s, buf, stored_len, last);
+
+  } else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) {
+
+    send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3);
+    compress_block(s, static_ltree, static_dtree);
+
+  } else {
+    send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3);
+    send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1);
+    compress_block(s, s.dyn_ltree, s.dyn_dtree);
+  }
+  // Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+  /*
+	 * The above check is made mod 2^32, for files larger than 512 MB and uLong
+	 * implemented on 32 bits.
+	 */
+  init_block(s);
+
+  if (last) {
+    bi_windup(s);
+  }
+  // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+  // s->compressed_len-7*last));
+}
+
+/*
+ * ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if the
+ * current block must be flushed.
+ */
+function _tr_tally(s, dist, lc)
+// deflate_state *s;
+// unsigned dist; /* distance of matched string */
+// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+  // var out_length, in_length, dcode;
+
+  s.pending_buf[s.d_buf + s.last_lit * 2]     = (dist >>> 8) & 0xff;
+  s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff;
+
+  s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff;
+  s.last_lit++;
+
+  if (dist === 0) {
+    /* lc is the unmatched char */
+    s.dyn_ltree[lc * 2]/* .Freq */++;
+  } else {
+    s.matches++;
+    /* Here, lc is the match length - MIN_MATCH */
+    dist--;             /* dist = match distance - 1 */
+    // Assert((ush)dist < (ush)MAX_DIST(s) &&
+    // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+    // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
+
+    s.dyn_ltree[(_length_code[lc] + LITERALS + 1) * 2]/* .Freq */++;
+    s.dyn_dtree[d_code(dist) * 2]/* .Freq */++;
+  }
+
+// (!) This block is disabled in zlib defailts,
+// don't enable it for binary compatibility
+
+// #ifdef TRUNCATE_BLOCK
+// /* Try to guess if it is profitable to stop the current block here */
+// if ((s.last_lit & 0x1fff) === 0 && s.level > 2) {
+// /* Compute an upper bound for the compressed length */
+// out_length = s.last_lit*8;
+// in_length = s.strstart - s.block_start;
+//
+// for (dcode = 0; dcode < D_CODES; dcode++) {
+// out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]);
+// }
+// out_length >>>= 3;
+// //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+// // s->last_lit, in_length, out_length,
+// // 100L - out_length*100L/in_length));
+// if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int
+// /2*/) {
+// return true;
+// }
+// }
+// #endif
+
+  return (s.last_lit === s.lit_bufsize - 1);
+  /*
+	 * We avoid equality with lit_bufsize because of wraparound at 64K on 16 bit
+	 * machines and because stored blocks are restricted to 64K-1 bytes.
+	 */
+}
+
+exports._tr_init  = _tr_init;
+exports._tr_stored_block = _tr_stored_block;
+exports._tr_flush_block  = _tr_flush_block;
+exports._tr_tally = _tr_tally;
+exports._tr_align = _tr_align;
+
+},{"../utils/common":3}],13:[function(require,module,exports){
+'use strict';
+
+
+function ZStream() {
+  /* next input byte */
+  this.input = null; // JS specific, because we have no pointers
+  this.next_in = 0;
+  /* number of bytes available at input */
+  this.avail_in = 0;
+  /* total number of input bytes read so far */
+  this.total_in = 0;
+  /* next output byte should be put there */
+  this.output = null; // JS specific, because we have no pointers
+  this.next_out = 0;
+  /* remaining free space at output */
+  this.avail_out = 0;
+  /* total number of bytes output so far */
+  this.total_out = 0;
+  /* last error message, NULL if no error */
+  this.msg = ''/* Z_NULL */;
+  /* not visible by applications */
+  this.state = null;
+  /* best guess about the data type: binary or text */
+  this.data_type = 2/* Z_UNKNOWN */;
+  /* adler32 value of the uncompressed data */
+  this.adler = 0;
+}
+
+module.exports = ZStream;
+
+},{}],14:[function(require,module,exports){
+(function (process,Buffer){
+var msg = require('pako/lib/zlib/messages');
+var zstream = require('pako/lib/zlib/zstream');
+var zlib_deflate = require('pako/lib/zlib/deflate.js');
+var zlib_inflate = require('pako/lib/zlib/inflate.js');
+var constants = require('pako/lib/zlib/constants');
+
+for (var key in constants) {
+  exports[key] = constants[key];
+}
+
+// zlib modes
+exports.NONE = 0;
+exports.DEFLATE = 1;
+exports.INFLATE = 2;
+exports.GZIP = 3;
+exports.GUNZIP = 4;
+exports.DEFLATERAW = 5;
+exports.INFLATERAW = 6;
+exports.UNZIP = 7;
+
+/**
+ * Emulate Node's zlib C++ layer for use by the JS layer in index.js
+ */
+function Zlib(mode) {
+  if (mode < exports.DEFLATE || mode > exports.UNZIP)
+    throw new TypeError("Bad argument");
+    
+  this.mode = mode;
+  this.init_done = false;
+  this.write_in_progress = false;
+  this.pending_close = false;
+  this.windowBits = 0;
+  this.level = 0;
+  this.memLevel = 0;
+  this.strategy = 0;
+  this.dictionary = null;
+}
+
+Zlib.prototype.init = function(windowBits, level, memLevel, strategy, dictionary) {
+  this.windowBits = windowBits;
+  this.level = level;
+  this.memLevel = memLevel;
+  this.strategy = strategy;
+  // dictionary not supported.
+  
+  if (this.mode === exports.GZIP || this.mode === exports.GUNZIP)
+    this.windowBits += 16;
+    
+  if (this.mode === exports.UNZIP)
+    this.windowBits += 32;
+    
+  if (this.mode === exports.DEFLATERAW || this.mode === exports.INFLATERAW)
+    this.windowBits = -this.windowBits;
+    
+  this.strm = new zstream();
+  
+  switch (this.mode) {
+    case exports.DEFLATE:
+    case exports.GZIP:
+    case exports.DEFLATERAW:
+      var status = zlib_deflate.deflateInit2(
+        this.strm,
+        this.level,
+        exports.Z_DEFLATED,
+        this.windowBits,
+        this.memLevel,
+        this.strategy
+      );
+      break;
+    case exports.INFLATE:
+    case exports.GUNZIP:
+    case exports.INFLATERAW:
+    case exports.UNZIP:
+      var status  = zlib_inflate.inflateInit2(
+        this.strm,
+        this.windowBits
+      );
+      break;
+    default:
+      throw new Error("Unknown mode " + this.mode);
+  }
+  
+  if (status !== exports.Z_OK) {
+    this._error(status);
+    return;
+  }
+  
+  this.write_in_progress = false;
+  this.init_done = true;
+};
+
+Zlib.prototype.params = function() {
+  throw new Error("deflateParams Not supported");
+};
+
+Zlib.prototype._writeCheck = function() {
+  if (!this.init_done)
+    throw new Error("write before init");
+    
+  if (this.mode === exports.NONE)
+    throw new Error("already finalized");
+    
+  if (this.write_in_progress)
+    throw new Error("write already in progress");
+    
+  if (this.pending_close)
+    throw new Error("close is pending");
+};
+
+Zlib.prototype.write = function(flush, input, in_off, in_len, out, out_off, out_len) {    
+  this._writeCheck();
+  this.write_in_progress = true;
+  
+  var self = this;
+  process.nextTick(function() {
+    self.write_in_progress = false;
+    var res = self._write(flush, input, in_off, in_len, out, out_off, out_len);
+    self.callback(res[0], res[1]);
+    
+    if (self.pending_close)
+      self.close();
+  });
+  
+  return this;
+};
+
+// set method for Node buffers, used by pako
+function bufferSet(data, offset) {
+  for (var i = 0; i < data.length; i++) {
+    this[offset + i] = data[i];
+  }
+}
+
+Zlib.prototype.writeSync = function(flush, input, in_off, in_len, out, out_off, out_len) {
+  this._writeCheck();
+  return this._write(flush, input, in_off, in_len, out, out_off, out_len);
+};
+
+Zlib.prototype._write = function(flush, input, in_off, in_len, out, out_off, out_len) {
+  this.write_in_progress = true;
+  
+  if (flush !== exports.Z_NO_FLUSH &&
+      flush !== exports.Z_PARTIAL_FLUSH &&
+      flush !== exports.Z_SYNC_FLUSH &&
+      flush !== exports.Z_FULL_FLUSH &&
+      flush !== exports.Z_FINISH &&
+      flush !== exports.Z_BLOCK) {
+    throw new Error("Invalid flush value");
+  }
+  
+  if (input == null) {
+    input = new Buffer(0);
+    in_len = 0;
+    in_off = 0;
+  }
+  
+  if (out._set)
+    out.set = out._set;
+  else
+    out.set = bufferSet;
+  
+  var strm = this.strm;
+  strm.avail_in = in_len;
+  strm.input = input;
+  strm.next_in = in_off;
+  strm.avail_out = out_len;
+  strm.output = out;
+  strm.next_out = out_off;
+  
+  switch (this.mode) {
+    case exports.DEFLATE:
+    case exports.GZIP:
+    case exports.DEFLATERAW:
+      var status = zlib_deflate.deflate(strm, flush);
+      break;
+    case exports.UNZIP:
+    case exports.INFLATE:
+    case exports.GUNZIP:
+    case exports.INFLATERAW:
+      var status = zlib_inflate.inflate(strm, flush);
+      break;
+    default:
+      throw new Error("Unknown mode " + this.mode);
+  }
+  
+  if (status !== exports.Z_STREAM_END && status !== exports.Z_OK) {
+    this._error(status);
+  }
+  
+  this.write_in_progress = false;
+  return [strm.avail_in, strm.avail_out];
+};
+
+Zlib.prototype.close = function() {
+  if (this.write_in_progress) {
+    this.pending_close = true;
+    return;
+  }
+  
+  this.pending_close = false;
+  
+  if (this.mode === exports.DEFLATE || this.mode === exports.GZIP || this.mode === exports.DEFLATERAW) {
+    zlib_deflate.deflateEnd(this.strm);
+  } else {
+    zlib_inflate.inflateEnd(this.strm);
+  }
+  
+  this.mode = exports.NONE;
+};
+
+Zlib.prototype.reset = function() {
+  switch (this.mode) {
+    case exports.DEFLATE:
+    case exports.DEFLATERAW:
+      var status = zlib_deflate.deflateReset(this.strm);
+      break;
+    case exports.INFLATE:
+    case exports.INFLATERAW:
+      var status = zlib_inflate.inflateReset(this.strm);
+      break;
+  }
+  
+  if (status !== exports.Z_OK) {
+    this._error(status);
+  }
+};
+
+Zlib.prototype._error = function(status) {
+  this.onerror(msg[status] + ': ' + this.strm.msg, status);
+  
+  this.write_in_progress = false;
+  if (this.pending_close)
+    this.close();
+};
+
+exports.Zlib = Zlib;
+
+}).call(this,require('_process'),require("buffer").Buffer)
+},{"_process":23,"buffer":16,"pako/lib/zlib/constants":5,"pako/lib/zlib/deflate.js":7,"pako/lib/zlib/inflate.js":9,"pako/lib/zlib/messages":11,"pako/lib/zlib/zstream":13}],15:[function(require,module,exports){
+(function (process,Buffer){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var Transform = require('_stream_transform');
+
+var binding = require('./binding');
+var util = require('util');
+var assert = require('assert').ok;
+
+// zlib doesn't provide these, so kludge them in following the same
+// const naming scheme zlib uses.
+binding.Z_MIN_WINDOWBITS = 8;
+binding.Z_MAX_WINDOWBITS = 15;
+binding.Z_DEFAULT_WINDOWBITS = 15;
+
+// fewer than 64 bytes per chunk is stupid.
+// technically it could work with as few as 8, but even 64 bytes
+// is absurdly low. Usually a MB or more is best.
+binding.Z_MIN_CHUNK = 64;
+binding.Z_MAX_CHUNK = Infinity;
+binding.Z_DEFAULT_CHUNK = (16 * 1024);
+
+binding.Z_MIN_MEMLEVEL = 1;
+binding.Z_MAX_MEMLEVEL = 9;
+binding.Z_DEFAULT_MEMLEVEL = 8;
+
+binding.Z_MIN_LEVEL = -1;
+binding.Z_MAX_LEVEL = 9;
+binding.Z_DEFAULT_LEVEL = binding.Z_DEFAULT_COMPRESSION;
+
+// expose all the zlib constants
+Object.keys(binding).forEach(function(k) {
+  if (k.match(/^Z/)) exports[k] = binding[k];
+});
+
+// translation table for return codes.
+exports.codes = {
+  Z_OK: binding.Z_OK,
+  Z_STREAM_END: binding.Z_STREAM_END,
+  Z_NEED_DICT: binding.Z_NEED_DICT,
+  Z_ERRNO: binding.Z_ERRNO,
+  Z_STREAM_ERROR: binding.Z_STREAM_ERROR,
+  Z_DATA_ERROR: binding.Z_DATA_ERROR,
+  Z_MEM_ERROR: binding.Z_MEM_ERROR,
+  Z_BUF_ERROR: binding.Z_BUF_ERROR,
+  Z_VERSION_ERROR: binding.Z_VERSION_ERROR
+};
+
+Object.keys(exports.codes).forEach(function(k) {
+  exports.codes[exports.codes[k]] = k;
+});
+
+exports.Deflate = Deflate;
+exports.Inflate = Inflate;
+exports.Gzip = Gzip;
+exports.Gunzip = Gunzip;
+exports.DeflateRaw = DeflateRaw;
+exports.InflateRaw = InflateRaw;
+exports.Unzip = Unzip;
+
+exports.createDeflate = function(o) {
+  return new Deflate(o);
+};
+
+exports.createInflate = function(o) {
+  return new Inflate(o);
+};
+
+exports.createDeflateRaw = function(o) {
+  return new DeflateRaw(o);
+};
+
+exports.createInflateRaw = function(o) {
+  return new InflateRaw(o);
+};
+
+exports.createGzip = function(o) {
+  return new Gzip(o);
+};
+
+exports.createGunzip = function(o) {
+  return new Gunzip(o);
+};
+
+exports.createUnzip = function(o) {
+  return new Unzip(o);
+};
+
+
+// Convenience methods.
+// compress/decompress a string or buffer in one step.
+exports.deflate = function(buffer, opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+  return zlibBuffer(new Deflate(opts), buffer, callback);
+};
+
+exports.deflateSync = function(buffer, opts) {
+  return zlibBufferSync(new Deflate(opts), buffer);
+};
+
+exports.gzip = function(buffer, opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+  return zlibBuffer(new Gzip(opts), buffer, callback);
+};
+
+exports.gzipSync = function(buffer, opts) {
+  return zlibBufferSync(new Gzip(opts), buffer);
+};
+
+exports.deflateRaw = function(buffer, opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+  return zlibBuffer(new DeflateRaw(opts), buffer, callback);
+};
+
+exports.deflateRawSync = function(buffer, opts) {
+  return zlibBufferSync(new DeflateRaw(opts), buffer);
+};
+
+exports.unzip = function(buffer, opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+  return zlibBuffer(new Unzip(opts), buffer, callback);
+};
+
+exports.unzipSync = function(buffer, opts) {
+  return zlibBufferSync(new Unzip(opts), buffer);
+};
+
+exports.inflate = function(buffer, opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+  return zlibBuffer(new Inflate(opts), buffer, callback);
+};
+
+exports.inflateSync = function(buffer, opts) {
+  return zlibBufferSync(new Inflate(opts), buffer);
+};
+
+exports.gunzip = function(buffer, opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+  return zlibBuffer(new Gunzip(opts), buffer, callback);
+};
+
+exports.gunzipSync = function(buffer, opts) {
+  return zlibBufferSync(new Gunzip(opts), buffer);
+};
+
+exports.inflateRaw = function(buffer, opts, callback) {
+  if (typeof opts === 'function') {
+    callback = opts;
+    opts = {};
+  }
+  return zlibBuffer(new InflateRaw(opts), buffer, callback);
+};
+
+exports.inflateRawSync = function(buffer, opts) {
+  return zlibBufferSync(new InflateRaw(opts), buffer);
+};
+
+function zlibBuffer(engine, buffer, callback) {
+  var buffers = [];
+  var nread = 0;
+
+  engine.on('error', onError);
+  engine.on('end', onEnd);
+
+  engine.end(buffer);
+  flow();
+
+  function flow() {
+    var chunk;
+    while (null !== (chunk = engine.read())) {
+      buffers.push(chunk);
+      nread += chunk.length;
+    }
+    engine.once('readable', flow);
+  }
+
+  function onError(err) {
+    engine.removeListener('end', onEnd);
+    engine.removeListener('readable', flow);
+    callback(err);
+  }
+
+  function onEnd() {
+    var buf = Buffer.concat(buffers, nread);
+    buffers = [];
+    callback(null, buf);
+    engine.close();
+  }
+}
+
+function zlibBufferSync(engine, buffer) {
+  if (typeof buffer === 'string')
+    buffer = new Buffer(buffer);
+  if (!Buffer.isBuffer(buffer))
+    throw new TypeError('Not a string or buffer');
+
+  var flushFlag = binding.Z_FINISH;
+
+  return engine._processChunk(buffer, flushFlag);
+}
+
+// generic zlib
+// minimal 2-byte header
+function Deflate(opts) {
+  if (!(this instanceof Deflate)) return new Deflate(opts);
+  Zlib.call(this, opts, binding.DEFLATE);
+}
+
+function Inflate(opts) {
+  if (!(this instanceof Inflate)) return new Inflate(opts);
+  Zlib.call(this, opts, binding.INFLATE);
+}
+
+
+
+// gzip - bigger header, same deflate compression
+function Gzip(opts) {
+  if (!(this instanceof Gzip)) return new Gzip(opts);
+  Zlib.call(this, opts, binding.GZIP);
+}
+
+function Gunzip(opts) {
+  if (!(this instanceof Gunzip)) return new Gunzip(opts);
+  Zlib.call(this, opts, binding.GUNZIP);
+}
+
+
+
+// raw - no header
+function DeflateRaw(opts) {
+  if (!(this instanceof DeflateRaw)) return new DeflateRaw(opts);
+  Zlib.call(this, opts, binding.DEFLATERAW);
+}
+
+function InflateRaw(opts) {
+  if (!(this instanceof InflateRaw)) return new InflateRaw(opts);
+  Zlib.call(this, opts, binding.INFLATERAW);
+}
+
+
+// auto-detect header.
+function Unzip(opts) {
+  if (!(this instanceof Unzip)) return new Unzip(opts);
+  Zlib.call(this, opts, binding.UNZIP);
+}
+
+
+// the Zlib class they all inherit from
+// This thing manages the queue of requests, and returns
+// true or false if there is anything in the queue when
+// you call the .write() method.
+
+function Zlib(opts, mode) {
+  this._opts = opts = opts || {};
+  this._chunkSize = opts.chunkSize || exports.Z_DEFAULT_CHUNK;
+
+  Transform.call(this, opts);
+
+  if (opts.flush) {
+    if (opts.flush !== binding.Z_NO_FLUSH &&
+        opts.flush !== binding.Z_PARTIAL_FLUSH &&
+        opts.flush !== binding.Z_SYNC_FLUSH &&
+        opts.flush !== binding.Z_FULL_FLUSH &&
+        opts.flush !== binding.Z_FINISH &&
+        opts.flush !== binding.Z_BLOCK) {
+      throw new Error('Invalid flush flag: ' + opts.flush);
+    }
+  }
+  this._flushFlag = opts.flush || binding.Z_NO_FLUSH;
+
+  if (opts.chunkSize) {
+    if (opts.chunkSize < exports.Z_MIN_CHUNK ||
+        opts.chunkSize > exports.Z_MAX_CHUNK) {
+      throw new Error('Invalid chunk size: ' + opts.chunkSize);
+    }
+  }
+
+  if (opts.windowBits) {
+    if (opts.windowBits < exports.Z_MIN_WINDOWBITS ||
+        opts.windowBits > exports.Z_MAX_WINDOWBITS) {
+      throw new Error('Invalid windowBits: ' + opts.windowBits);
+    }
+  }
+
+  if (opts.level) {
+    if (opts.level < exports.Z_MIN_LEVEL ||
+        opts.level > exports.Z_MAX_LEVEL) {
+      throw new Error('Invalid compression level: ' + opts.level);
+    }
+  }
+
+  if (opts.memLevel) {
+    if (opts.memLevel < exports.Z_MIN_MEMLEVEL ||
+        opts.memLevel > exports.Z_MAX_MEMLEVEL) {
+      throw new Error('Invalid memLevel: ' + opts.memLevel);
+    }
+  }
+
+  if (opts.strategy) {
+    if (opts.strategy != exports.Z_FILTERED &&
+        opts.strategy != exports.Z_HUFFMAN_ONLY &&
+        opts.strategy != exports.Z_RLE &&
+        opts.strategy != exports.Z_FIXED &&
+        opts.strategy != exports.Z_DEFAULT_STRATEGY) {
+      throw new Error('Invalid strategy: ' + opts.strategy);
+    }
+  }
+
+  if (opts.dictionary) {
+    if (!Buffer.isBuffer(opts.dictionary)) {
+      throw new Error('Invalid dictionary: it should be a Buffer instance');
+    }
+  }
+
+  this._binding = new binding.Zlib(mode);
+
+  var self = this;
+  this._hadError = false;
+  this._binding.onerror = function(message, errno) {
+    // there is no way to cleanly recover.
+    // continuing only obscures problems.
+    self._binding = null;
+    self._hadError = true;
+
+    var error = new Error(message);
+    error.errno = errno;
+    error.code = exports.codes[errno];
+    self.emit('error', error);
+  };
+
+  var level = exports.Z_DEFAULT_COMPRESSION;
+  if (typeof opts.level === 'number') level = opts.level;
+
+  var strategy = exports.Z_DEFAULT_STRATEGY;
+  if (typeof opts.strategy === 'number') strategy = opts.strategy;
+
+  this._binding.init(opts.windowBits || exports.Z_DEFAULT_WINDOWBITS,
+                     level,
+                     opts.memLevel || exports.Z_DEFAULT_MEMLEVEL,
+                     strategy,
+                     opts.dictionary);
+
+  this._buffer = new Buffer(this._chunkSize);
+  this._offset = 0;
+  this._closed = false;
+  this._level = level;
+  this._strategy = strategy;
+
+  this.once('end', this.close);
+}
+
+util.inherits(Zlib, Transform);
+
+Zlib.prototype.params = function(level, strategy, callback) {
+  if (level < exports.Z_MIN_LEVEL ||
+      level > exports.Z_MAX_LEVEL) {
+    throw new RangeError('Invalid compression level: ' + level);
+  }
+  if (strategy != exports.Z_FILTERED &&
+      strategy != exports.Z_HUFFMAN_ONLY &&
+      strategy != exports.Z_RLE &&
+      strategy != exports.Z_FIXED &&
+      strategy != exports.Z_DEFAULT_STRATEGY) {
+    throw new TypeError('Invalid strategy: ' + strategy);
+  }
+
+  if (this._level !== level || this._strategy !== strategy) {
+    var self = this;
+    this.flush(binding.Z_SYNC_FLUSH, function() {
+      self._binding.params(level, strategy);
+      if (!self._hadError) {
+        self._level = level;
+        self._strategy = strategy;
+        if (callback) callback();
+      }
+    });
+  } else {
+    process.nextTick(callback);
+  }
+};
+
+Zlib.prototype.reset = function() {
+  return this._binding.reset();
+};
+
+// This is the _flush function called by the transform class,
+// internally, when the last chunk has been written.
+Zlib.prototype._flush = function(callback) {
+  this._transform(new Buffer(0), '', callback);
+};
+
+Zlib.prototype.flush = function(kind, callback) {
+  var ws = this._writableState;
+
+  if (typeof kind === 'function' || (kind === void 0 && !callback)) {
+    callback = kind;
+    kind = binding.Z_FULL_FLUSH;
+  }
+
+  if (ws.ended) {
+    if (callback)
+      process.nextTick(callback);
+  } else if (ws.ending) {
+    if (callback)
+      this.once('end', callback);
+  } else if (ws.needDrain) {
+    var self = this;
+    this.once('drain', function() {
+      self.flush(callback);
+    });
+  } else {
+    this._flushFlag = kind;
+    this.write(new Buffer(0), '', callback);
+  }
+};
+
+Zlib.prototype.close = function(callback) {
+  if (callback)
+    process.nextTick(callback);
+
+  if (this._closed)
+    return;
+
+  this._closed = true;
+
+  this._binding.close();
+
+  var self = this;
+  process.nextTick(function() {
+    self.emit('close');
+  });
+};
+
+Zlib.prototype._transform = function(chunk, encoding, cb) {
+  var flushFlag;
+  var ws = this._writableState;
+  var ending = ws.ending || ws.ended;
+  var last = ending && (!chunk || ws.length === chunk.length);
+
+  if (!chunk === null && !Buffer.isBuffer(chunk))
+    return cb(new Error('invalid input'));
+
+  // If it's the last chunk, or a final flush, we use the Z_FINISH flush flag.
+  // If it's explicitly flushing at some other time, then we use
+  // Z_FULL_FLUSH. Otherwise, use Z_NO_FLUSH for maximum compression
+  // goodness.
+  if (last)
+    flushFlag = binding.Z_FINISH;
+  else {
+    flushFlag = this._flushFlag;
+    // once we've flushed the last of the queue, stop flushing and
+    // go back to the normal behavior.
+    if (chunk.length >= ws.length) {
+      this._flushFlag = this._opts.flush || binding.Z_NO_FLUSH;
+    }
+  }
+
+  var self = this;
+  this._processChunk(chunk, flushFlag, cb);
+};
+
+Zlib.prototype._processChunk = function(chunk, flushFlag, cb) {
+  var availInBefore = chunk && chunk.length;
+  var availOutBefore = this._chunkSize - this._offset;
+  var inOff = 0;
+
+  var self = this;
+
+  var async = typeof cb === 'function';
+
+  if (!async) {
+    var buffers = [];
+    var nread = 0;
+
+    var error;
+    this.on('error', function(er) {
+      error = er;
+    });
+
+    do {
+      var res = this._binding.writeSync(flushFlag,
+                                        chunk, // in
+                                        inOff, // in_off
+                                        availInBefore, // in_len
+                                        this._buffer, // out
+                                        this._offset, // out_off
+                                        availOutBefore); // out_len
+    } while (!this._hadError && callback(res[0], res[1]));
+
+    if (this._hadError) {
+      throw error;
+    }
+
+    var buf = Buffer.concat(buffers, nread);
+    this.close();
+
+    return buf;
+  }
+
+  var req = this._binding.write(flushFlag,
+                                chunk, // in
+                                inOff, // in_off
+                                availInBefore, // in_len
+                                this._buffer, // out
+                                this._offset, // out_off
+                                availOutBefore); // out_len
+
+  req.buffer = chunk;
+  req.callback = callback;
+
+  function callback(availInAfter, availOutAfter) {
+    if (self._hadError)
+      return;
+
+    var have = availOutBefore - availOutAfter;
+    assert(have >= 0, 'have should not go down');
+
+    if (have > 0) {
+      var out = self._buffer.slice(self._offset, self._offset + have);
+      self._offset += have;
+      // serve some output to the consumer.
+      if (async) {
+        self.push(out);
+      } else {
+        buffers.push(out);
+        nread += out.length;
+      }
+    }
+
+    // exhausted the output buffer, or used all the input create a new one.
+    if (availOutAfter === 0 || self._offset >= self._chunkSize) {
+      availOutBefore = self._chunkSize;
+      self._offset = 0;
+      self._buffer = new Buffer(self._chunkSize);
+    }
+
+    if (availOutAfter === 0) {
+      // Not actually done. Need to reprocess.
+      // Also, update the availInBefore to the availInAfter value,
+      // so that if we have to hit it a third (fourth, etc.) time,
+      // it'll have the correct byte counts.
+      inOff += (availInBefore - availInAfter);
+      availInBefore = availInAfter;
+
+      if (!async)
+        return true;
+
+      var newReq = self._binding.write(flushFlag,
+                                       chunk,
+                                       inOff,
+                                       availInBefore,
+                                       self._buffer,
+                                       self._offset,
+                                       self._chunkSize);
+      newReq.callback = callback; // this same function
+      newReq.buffer = chunk;
+      return;
+    }
+
+    if (!async)
+      return false;
+
+    // finished with the chunk.
+    cb();
+  }
+};
+
+util.inherits(Deflate, Zlib);
+util.inherits(Inflate, Zlib);
+util.inherits(Gzip, Zlib);
+util.inherits(Gunzip, Zlib);
+util.inherits(DeflateRaw, Zlib);
+util.inherits(InflateRaw, Zlib);
+util.inherits(Unzip, Zlib);
+
+}).call(this,require('_process'),require("buffer").Buffer)
+},{"./binding":14,"_process":23,"_stream_transform":40,"assert":1,"buffer":16,"util":47}],16:[function(require,module,exports){
+/*
+ * ! The buffer module from node.js, for the browser.
+ * 
+ * @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org> @license
+ * MIT
+ */
+/* eslint-disable no-proto */
+
+'use strict'
+
+var base64 = require('base64-js')
+var ieee754 = require('ieee754')
+
+exports.Buffer = Buffer
+exports.SlowBuffer = SlowBuffer
+exports.INSPECT_MAX_BYTES = 50
+
+var K_MAX_LENGTH = 0x7fffffff
+exports.kMaxLength = K_MAX_LENGTH
+
+/**
+ * If `Buffer.TYPED_ARRAY_SUPPORT`: === true Use Uint8Array implementation
+ * (fastest) === false Print warning and recommend using `buffer` v4.x which has
+ * an Object implementation (most compatible, even IE6)
+ * 
+ * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari
+ * 5.1+, Opera 11.6+, iOS 4.2+.
+ * 
+ * We report that the browser does not support typed arrays if the are not
+ * subclassable using __proto__. Firefox 4-29 lacks support for adding new
+ * properties to `Uint8Array` (See:
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support for
+ * __proto__ and has a buggy typed array implementation.
+ */
+Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport()
+
+if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' &&
+    typeof console.error === 'function') {
+  console.error(
+    'This browser lacks typed array (Uint8Array) support which is required by ' +
+    '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.'
+  )
+}
+
+function typedArraySupport () {
+  // Can typed array instances can be augmented?
+  try {
+    var arr = new Uint8Array(1)
+    arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}
+    return arr.foo() === 42
+  } catch (e) {
+    return false
+  }
+}
+
+function createBuffer (length) {
+  if (length > K_MAX_LENGTH) {
+    throw new RangeError('Invalid typed array length')
+  }
+  // Return an augmented `Uint8Array` instance
+  var buf = new Uint8Array(length)
+  buf.__proto__ = Buffer.prototype
+  return buf
+}
+
+/**
+ * The Buffer constructor returns instances of `Uint8Array` that have their
+ * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass
+ * of `Uint8Array`, so the returned instances will have all the node `Buffer`
+ * methods and the `Uint8Array` methods. Square bracket notation works as
+ * expected -- it returns a single octet.
+ * 
+ * The `Uint8Array` prototype remains unmodified.
+ */
+
+function Buffer (arg, encodingOrOffset, length) {
+  // Common case.
+  if (typeof arg === 'number') {
+    if (typeof encodingOrOffset === 'string') {
+      throw new Error(
+        'If encoding is specified then the first argument must be a string'
+      )
+    }
+    return allocUnsafe(arg)
+  }
+  return from(arg, encodingOrOffset, length)
+}
+
+// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97
+if (typeof Symbol !== 'undefined' && Symbol.species &&
+    Buffer[Symbol.species] === Buffer) {
+  Object.defineProperty(Buffer, Symbol.species, {
+    value: null,
+    configurable: true,
+    enumerable: false,
+    writable: false
+  })
+}
+
+Buffer.poolSize = 8192 // not used by this implementation
+
+function from (value, encodingOrOffset, length) {
+  if (typeof value === 'number') {
+    throw new TypeError('"value" argument must not be a number')
+  }
+
+  if (value instanceof ArrayBuffer) {
+    return fromArrayBuffer(value, encodingOrOffset, length)
+  }
+
+  if (typeof value === 'string') {
+    return fromString(value, encodingOrOffset)
+  }
+
+  return fromObject(value)
+}
+
+/**
+ * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError if
+ * value is a number. Buffer.from(str[, encoding]) Buffer.from(array)
+ * Buffer.from(buffer) Buffer.from(arrayBuffer[, byteOffset[, length]])
+ */
+Buffer.from = function (value, encodingOrOffset, length) {
+  return from(value, encodingOrOffset, length)
+}
+
+// Note: Change prototype *after* Buffer.from is defined to workaround Chrome
+// bug:
+// https://github.com/feross/buffer/pull/148
+Buffer.prototype.__proto__ = Uint8Array.prototype
+Buffer.__proto__ = Uint8Array
+
+function assertSize (size) {
+  if (typeof size !== 'number') {
+    throw new TypeError('"size" argument must be a number')
+  } else if (size < 0) {
+    throw new RangeError('"size" argument must not be negative')
+  }
+}
+
+function alloc (size, fill, encoding) {
+  assertSize(size)
+  if (size <= 0) {
+    return createBuffer(size)
+  }
+  if (fill !== undefined) {
+    // Only pay attention to encoding if it's a string. This
+    // prevents accidentally sending in a number that would
+    // be interpretted as a start offset.
+    return typeof encoding === 'string'
+      ? createBuffer(size).fill(fill, encoding)
+      : createBuffer(size).fill(fill)
+  }
+  return createBuffer(size)
+}
+
+/**
+ * Creates a new filled Buffer instance. alloc(size[, fill[, encoding]])
+ */
+Buffer.alloc = function (size, fill, encoding) {
+  return alloc(size, fill, encoding)
+}
+
+function allocUnsafe (size) {
+  assertSize(size)
+  return createBuffer(size < 0 ? 0 : checked(size) | 0)
+}
+
+/**
+ * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer
+ * instance.
+ */
+Buffer.allocUnsafe = function (size) {
+  return allocUnsafe(size)
+}
+/**
+ * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer
+ * instance.
+ */
+Buffer.allocUnsafeSlow = function (size) {
+  return allocUnsafe(size)
+}
+
+function fromString (string, encoding) {
+  if (typeof encoding !== 'string' || encoding === '') {
+    encoding = 'utf8'
+  }
+
+  if (!Buffer.isEncoding(encoding)) {
+    throw new TypeError('"encoding" must be a valid string encoding')
+  }
+
+  var length = byteLength(string, encoding) | 0
+  var buf = createBuffer(length)
+
+  var actual = buf.write(string, encoding)
+
+  if (actual !== length) {
+    // Writing a hex string, for example, that contains invalid characters will
+    // cause everything after the first invalid character to be ignored. (e.g.
+    // 'abxxcd' will be treated as 'ab')
+    buf = buf.slice(0, actual)
+  }
+
+  return buf
+}
+
+function fromArrayLike (array) {
+  var length = array.length < 0 ? 0 : checked(array.length) | 0
+  var buf = createBuffer(length)
+  for (var i = 0; i < length; i += 1) {
+    buf[i] = array[i] & 255
+  }
+  return buf
+}
+
+function fromArrayBuffer (array, byteOffset, length) {
+  if (byteOffset < 0 || array.byteLength < byteOffset) {
+    throw new RangeError('\'offset\' is out of bounds')
+  }
+
+  if (array.byteLength < byteOffset + (length || 0)) {
+    throw new RangeError('\'length\' is out of bounds')
+  }
+
+  var buf
+  if (byteOffset === undefined && length === undefined) {
+    buf = new Uint8Array(array)
+  } else if (length === undefined) {
+    buf = new Uint8Array(array, byteOffset)
+  } else {
+    buf = new Uint8Array(array, byteOffset, length)
+  }
+
+  // Return an augmented `Uint8Array` instance
+  buf.__proto__ = Buffer.prototype
+  return buf
+}
+
+function fromObject (obj) {
+  if (Buffer.isBuffer(obj)) {
+    var len = checked(obj.length) | 0
+    var buf = createBuffer(len)
+
+    if (buf.length === 0) {
+      return buf
+    }
+
+    obj.copy(buf, 0, 0, len)
+    return buf
+  }
+
+  if (obj) {
+    if (isArrayBufferView(obj) || 'length' in obj) {
+      if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) {
+        return createBuffer(0)
+      }
+      return fromArrayLike(obj)
+    }
+
+    if (obj.type === 'Buffer' && Array.isArray(obj.data)) {
+      return fromArrayLike(obj.data)
+    }
+  }
+
+  throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')
+}
+
+function checked (length) {
+  // Note: cannot use `length < K_MAX_LENGTH` here because that fails when
+  // length is NaN (which is otherwise coerced to zero.)
+  if (length >= K_MAX_LENGTH) {
+    throw new RangeError('Attempt to allocate Buffer larger than maximum ' +
+                         'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes')
+  }
+  return length | 0
+}
+
+function SlowBuffer (length) {
+  if (+length != length) { // eslint-disable-line eqeqeq
+    length = 0
+  }
+  return Buffer.alloc(+length)
+}
+
+Buffer.isBuffer = function isBuffer (b) {
+  return b != null && b._isBuffer === true
+}
+
+Buffer.compare = function compare (a, b) {
+  if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {
+    throw new TypeError('Arguments must be Buffers')
+  }
+
+  if (a === b) return 0
+
+  var x = a.length
+  var y = b.length
+
+  for (var i = 0, len = Math.min(x, y); i < len; ++i) {
+    if (a[i] !== b[i]) {
+      x = a[i]
+      y = b[i]
+      break
+    }
+  }
+
+  if (x < y) return -1
+  if (y < x) return 1
+  return 0
+}
+
+Buffer.isEncoding = function isEncoding (encoding) {
+  switch (String(encoding).toLowerCase()) {
+    case 'hex':
+    case 'utf8':
+    case 'utf-8':
+    case 'ascii':
+    case 'latin1':
+    case 'binary':
+    case 'base64':
+    case 'ucs2':
+    case 'ucs-2':
+    case 'utf16le':
+    case 'utf-16le':
+      return true
+    default:
+      return false
+  }
+}
+
+Buffer.concat = function concat (list, length) {
+  if (!Array.isArray(list)) {
+    throw new TypeError('"list" argument must be an Array of Buffers')
+  }
+
+  if (list.length === 0) {
+    return Buffer.alloc(0)
+  }
+
+  var i
+  if (length === undefined) {
+    length = 0
+    for (i = 0; i < list.length; ++i) {
+      length += list[i].length
+    }
+  }
+
+  var buffer = Buffer.allocUnsafe(length)
+  var pos = 0
+  for (i = 0; i < list.length; ++i) {
+    var buf = list[i]
+    if (!Buffer.isBuffer(buf)) {
+      throw new TypeError('"list" argument must be an Array of Buffers')
+    }
+    buf.copy(buffer, pos)
+    pos += buf.length
+  }
+  return buffer
+}
+
+function byteLength (string, encoding) {
+  if (Buffer.isBuffer(string)) {
+    return string.length
+  }
+  if (isArrayBufferView(string) || string instanceof ArrayBuffer) {
+    return string.byteLength
+  }
+  if (typeof string !== 'string') {
+    string = '' + string
+  }
+
+  var len = string.length
+  if (len === 0) return 0
+
+  // Use a for loop to avoid recursion
+  var loweredCase = false
+  for (;;) {
+    switch (encoding) {
+      case 'ascii':
+      case 'latin1':
+      case 'binary':
+        return len
+      case 'utf8':
+      case 'utf-8':
+      case undefined:
+        return utf8ToBytes(string).length
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return len * 2
+      case 'hex':
+        return len >>> 1
+      case 'base64':
+        return base64ToBytes(string).length
+      default:
+        if (loweredCase) return utf8ToBytes(string).length // assume utf8
+        encoding = ('' + encoding).toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+Buffer.byteLength = byteLength
+
+function slowToString (encoding, start, end) {
+  var loweredCase = false
+
+  // No need to verify that "this.length <= MAX_UINT32" since it's a read-only
+  // property of a typed array.
+
+  // This behaves neither like String nor Uint8Array in that we set start/end
+  // to their upper/lower bounds if the value passed is out of range.
+  // undefined is handled specially as per ECMA-262 6th Edition,
+  // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.
+  if (start === undefined || start < 0) {
+    start = 0
+  }
+  // Return early if start > this.length. Done here to prevent potential
+	// uint32
+  // coercion fail below.
+  if (start > this.length) {
+    return ''
+  }
+
+  if (end === undefined || end > this.length) {
+    end = this.length
+  }
+
+  if (end <= 0) {
+    return ''
+  }
+
+  // Force coersion to uint32. This will also coerce falsey/NaN values to 0.
+  end >>>= 0
+  start >>>= 0
+
+  if (end <= start) {
+    return ''
+  }
+
+  if (!encoding) encoding = 'utf8'
+
+  while (true) {
+    switch (encoding) {
+      case 'hex':
+        return hexSlice(this, start, end)
+
+      case 'utf8':
+      case 'utf-8':
+        return utf8Slice(this, start, end)
+
+      case 'ascii':
+        return asciiSlice(this, start, end)
+
+      case 'latin1':
+      case 'binary':
+        return latin1Slice(this, start, end)
+
+      case 'base64':
+        return base64Slice(this, start, end)
+
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return utf16leSlice(this, start, end)
+
+      default:
+        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
+        encoding = (encoding + '').toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+
+// This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package)
+// to detect a Buffer instance. It's not possible to use `instanceof Buffer`
+// reliably in a browserify context because there could be multiple different
+// copies of the 'buffer' package in use. This method works even for Buffer
+// instances that were created from another copy of the `buffer` package.
+// See: https://github.com/feross/buffer/issues/154
+Buffer.prototype._isBuffer = true
+
+function swap (b, n, m) {
+  var i = b[n]
+  b[n] = b[m]
+  b[m] = i
+}
+
+Buffer.prototype.swap16 = function swap16 () {
+  var len = this.length
+  if (len % 2 !== 0) {
+    throw new RangeError('Buffer size must be a multiple of 16-bits')
+  }
+  for (var i = 0; i < len; i += 2) {
+    swap(this, i, i + 1)
+  }
+  return this
+}
+
+Buffer.prototype.swap32 = function swap32 () {
+  var len = this.length
+  if (len % 4 !== 0) {
+    throw new RangeError('Buffer size must be a multiple of 32-bits')
+  }
+  for (var i = 0; i < len; i += 4) {
+    swap(this, i, i + 3)
+    swap(this, i + 1, i + 2)
+  }
+  return this
+}
+
+Buffer.prototype.swap64 = function swap64 () {
+  var len = this.length
+  if (len % 8 !== 0) {
+    throw new RangeError('Buffer size must be a multiple of 64-bits')
+  }
+  for (var i = 0; i < len; i += 8) {
+    swap(this, i, i + 7)
+    swap(this, i + 1, i + 6)
+    swap(this, i + 2, i + 5)
+    swap(this, i + 3, i + 4)
+  }
+  return this
+}
+
+Buffer.prototype.toString = function toString () {
+  var length = this.length
+  if (length === 0) return ''
+  if (arguments.length === 0) return utf8Slice(this, 0, length)
+  return slowToString.apply(this, arguments)
+}
+
+Buffer.prototype.equals = function equals (b) {
+  if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')
+  if (this === b) return true
+  return Buffer.compare(this, b) === 0
+}
+
+Buffer.prototype.inspect = function inspect () {
+  var str = ''
+  var max = exports.INSPECT_MAX_BYTES
+  if (this.length > 0) {
+    str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')
+    if (this.length > max) str += ' ... '
+  }
+  return '<Buffer ' + str + '>'
+}
+
+Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {
+  if (!Buffer.isBuffer(target)) {
+    throw new TypeError('Argument must be a Buffer')
+  }
+
+  if (start === undefined) {
+    start = 0
+  }
+  if (end === undefined) {
+    end = target ? target.length : 0
+  }
+  if (thisStart === undefined) {
+    thisStart = 0
+  }
+  if (thisEnd === undefined) {
+    thisEnd = this.length
+  }
+
+  if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {
+    throw new RangeError('out of range index')
+  }
+
+  if (thisStart >= thisEnd && start >= end) {
+    return 0
+  }
+  if (thisStart >= thisEnd) {
+    return -1
+  }
+  if (start >= end) {
+    return 1
+  }
+
+  start >>>= 0
+  end >>>= 0
+  thisStart >>>= 0
+  thisEnd >>>= 0
+
+  if (this === target) return 0
+
+  var x = thisEnd - thisStart
+  var y = end - start
+  var len = Math.min(x, y)
+
+  var thisCopy = this.slice(thisStart, thisEnd)
+  var targetCopy = target.slice(start, end)
+
+  for (var i = 0; i < len; ++i) {
+    if (thisCopy[i] !== targetCopy[i]) {
+      x = thisCopy[i]
+      y = targetCopy[i]
+      break
+    }
+  }
+
+  if (x < y) return -1
+  if (y < x) return 1
+  return 0
+}
+
+// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,
+// OR the last index of `val` in `buffer` at offset <= `byteOffset`.
+//
+// Arguments:
+// - buffer - a Buffer to search
+// - val - a string, Buffer, or number
+// - byteOffset - an index into `buffer`; will be clamped to an int32
+// - encoding - an optional encoding, relevant is val is a string
+// - dir - true for indexOf, false for lastIndexOf
+function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
+  // Empty buffer means no match
+  if (buffer.length === 0) return -1
+
+  // Normalize byteOffset
+  if (typeof byteOffset === 'string') {
+    encoding = byteOffset
+    byteOffset = 0
+  } else if (byteOffset > 0x7fffffff) {
+    byteOffset = 0x7fffffff
+  } else if (byteOffset < -0x80000000) {
+    byteOffset = -0x80000000
+  }
+  byteOffset = +byteOffset  // Coerce to Number.
+  if (numberIsNaN(byteOffset)) {
+    // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer
+    byteOffset = dir ? 0 : (buffer.length - 1)
+  }
+
+  // Normalize byteOffset: negative offsets start from the end of the buffer
+  if (byteOffset < 0) byteOffset = buffer.length + byteOffset
+  if (byteOffset >= buffer.length) {
+    if (dir) return -1
+    else byteOffset = buffer.length - 1
+  } else if (byteOffset < 0) {
+    if (dir) byteOffset = 0
+    else return -1
+  }
+
+  // Normalize val
+  if (typeof val === 'string') {
+    val = Buffer.from(val, encoding)
+  }
+
+  // Finally, search either indexOf (if dir is true) or lastIndexOf
+  if (Buffer.isBuffer(val)) {
+    // Special case: looking for empty string/buffer always fails
+    if (val.length === 0) {
+      return -1
+    }
+    return arrayIndexOf(buffer, val, byteOffset, encoding, dir)
+  } else if (typeof val === 'number') {
+    val = val & 0xFF // Search for a byte value [0-255]
+    if (typeof Uint8Array.prototype.indexOf === 'function') {
+      if (dir) {
+        return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)
+      } else {
+        return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)
+      }
+    }
+    return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)
+  }
+
+  throw new TypeError('val must be string, number or Buffer')
+}
+
+function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
+  var indexSize = 1
+  var arrLength = arr.length
+  var valLength = val.length
+
+  if (encoding !== undefined) {
+    encoding = String(encoding).toLowerCase()
+    if (encoding === 'ucs2' || encoding === 'ucs-2' ||
+        encoding === 'utf16le' || encoding === 'utf-16le') {
+      if (arr.length < 2 || val.length < 2) {
+        return -1
+      }
+      indexSize = 2
+      arrLength /= 2
+      valLength /= 2
+      byteOffset /= 2
+    }
+  }
+
+  function read (buf, i) {
+    if (indexSize === 1) {
+      return buf[i]
+    } else {
+      return buf.readUInt16BE(i * indexSize)
+    }
+  }
+
+  var i
+  if (dir) {
+    var foundIndex = -1
+    for (i = byteOffset; i < arrLength; i++) {
+      if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {
+        if (foundIndex === -1) foundIndex = i
+        if (i - foundIndex + 1 === valLength) return foundIndex * indexSize
+      } else {
+        if (foundIndex !== -1) i -= i - foundIndex
+        foundIndex = -1
+      }
+    }
+  } else {
+    if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength
+    for (i = byteOffset; i >= 0; i--) {
+      var found = true
+      for (var j = 0; j < valLength; j++) {
+        if (read(arr, i + j) !== read(val, j)) {
+          found = false
+          break
+        }
+      }
+      if (found) return i
+    }
+  }
+
+  return -1
+}
+
+Buffer.prototype.includes = function includes (val, byteOffset, encoding) {
+  return this.indexOf(val, byteOffset, encoding) !== -1
+}
+
+Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {
+  return bidirectionalIndexOf(this, val, byteOffset, encoding, true)
+}
+
+Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {
+  return bidirectionalIndexOf(this, val, byteOffset, encoding, false)
+}
+
+function hexWrite (buf, string, offset, length) {
+  offset = Number(offset) || 0
+  var remaining = buf.length - offset
+  if (!length) {
+    length = remaining
+  } else {
+    length = Number(length)
+    if (length > remaining) {
+      length = remaining
+    }
+  }
+
+  // must be an even number of digits
+  var strLen = string.length
+  if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')
+
+  if (length > strLen / 2) {
+    length = strLen / 2
+  }
+  for (var i = 0; i < length; ++i) {
+    var parsed = parseInt(string.substr(i * 2, 2), 16)
+    if (numberIsNaN(parsed)) return i
+    buf[offset + i] = parsed
+  }
+  return i
+}
+
+function utf8Write (buf, string, offset, length) {
+  return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)
+}
+
+function asciiWrite (buf, string, offset, length) {
+  return blitBuffer(asciiToBytes(string), buf, offset, length)
+}
+
+function latin1Write (buf, string, offset, length) {
+  return asciiWrite(buf, string, offset, length)
+}
+
+function base64Write (buf, string, offset, length) {
+  return blitBuffer(base64ToBytes(string), buf, offset, length)
+}
+
+function ucs2Write (buf, string, offset, length) {
+  return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)
+}
+
+Buffer.prototype.write = function write (string, offset, length, encoding) {
+  // Buffer#write(string)
+  if (offset === undefined) {
+    encoding = 'utf8'
+    length = this.length
+    offset = 0
+  // Buffer#write(string, encoding)
+  } else if (length === undefined && typeof offset === 'string') {
+    encoding = offset
+    length = this.length
+    offset = 0
+  // Buffer#write(string, offset[, length][, encoding])
+  } else if (isFinite(offset)) {
+    offset = offset >>> 0
+    if (isFinite(length)) {
+      length = length >>> 0
+      if (encoding === undefined) encoding = 'utf8'
+    } else {
+      encoding = length
+      length = undefined
+    }
+  } else {
+    throw new Error(
+      'Buffer.write(string, encoding, offset[, length]) is no longer supported'
+    )
+  }
+
+  var remaining = this.length - offset
+  if (length === undefined || length > remaining) length = remaining
+
+  if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {
+    throw new RangeError('Attempt to write outside buffer bounds')
+  }
+
+  if (!encoding) encoding = 'utf8'
+
+  var loweredCase = false
+  for (;;) {
+    switch (encoding) {
+      case 'hex':
+        return hexWrite(this, string, offset, length)
+
+      case 'utf8':
+      case 'utf-8':
+        return utf8Write(this, string, offset, length)
+
+      case 'ascii':
+        return asciiWrite(this, string, offset, length)
+
+      case 'latin1':
+      case 'binary':
+        return latin1Write(this, string, offset, length)
+
+      case 'base64':
+        // Warning: maxLength not taken into account in base64Write
+        return base64Write(this, string, offset, length)
+
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return ucs2Write(this, string, offset, length)
+
+      default:
+        if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)
+        encoding = ('' + encoding).toLowerCase()
+        loweredCase = true
+    }
+  }
+}
+
+Buffer.prototype.toJSON = function toJSON () {
+  return {
+    type: 'Buffer',
+    data: Array.prototype.slice.call(this._arr || this, 0)
+  }
+}
+
+function base64Slice (buf, start, end) {
+  if (start === 0 && end === buf.length) {
+    return base64.fromByteArray(buf)
+  } else {
+    return base64.fromByteArray(buf.slice(start, end))
+  }
+}
+
+function utf8Slice (buf, start, end) {
+  end = Math.min(buf.length, end)
+  var res = []
+
+  var i = start
+  while (i < end) {
+    var firstByte = buf[i]
+    var codePoint = null
+    var bytesPerSequence = (firstByte > 0xEF) ? 4
+      : (firstByte > 0xDF) ? 3
+      : (firstByte > 0xBF) ? 2
+      : 1
+
+    if (i + bytesPerSequence <= end) {
+      var secondByte, thirdByte, fourthByte, tempCodePoint
+
+      switch (bytesPerSequence) {
+        case 1:
+          if (firstByte < 0x80) {
+            codePoint = firstByte
+          }
+          break
+        case 2:
+          secondByte = buf[i + 1]
+          if ((secondByte & 0xC0) === 0x80) {
+            tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)
+            if (tempCodePoint > 0x7F) {
+              codePoint = tempCodePoint
+            }
+          }
+          break
+        case 3:
+          secondByte = buf[i + 1]
+          thirdByte = buf[i + 2]
+          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {
+            tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)
+            if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {
+              codePoint = tempCodePoint
+            }
+          }
+          break
+        case 4:
+          secondByte = buf[i + 1]
+          thirdByte = buf[i + 2]
+          fourthByte = buf[i + 3]
+          if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {
+            tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)
+            if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {
+              codePoint = tempCodePoint
+            }
+          }
+      }
+    }
+
+    if (codePoint === null) {
+      // we did not generate a valid codePoint so insert a
+      // replacement char (U+FFFD) and advance only 1 byte
+      codePoint = 0xFFFD
+      bytesPerSequence = 1
+    } else if (codePoint > 0xFFFF) {
+      // encode to utf16 (surrogate pair dance)
+      codePoint -= 0x10000
+      res.push(codePoint >>> 10 & 0x3FF | 0xD800)
+      codePoint = 0xDC00 | codePoint & 0x3FF
+    }
+
+    res.push(codePoint)
+    i += bytesPerSequence
+  }
+
+  return decodeCodePointsArray(res)
+}
+
+// Based on http://stackoverflow.com/a/22747272/680742, the browser with
+// the lowest limit is Chrome, with 0x10000 args.
+// We go 1 magnitude less, for safety
+var MAX_ARGUMENTS_LENGTH = 0x1000
+
+function decodeCodePointsArray (codePoints) {
+  var len = codePoints.length
+  if (len <= MAX_ARGUMENTS_LENGTH) {
+    return String.fromCharCode.apply(String, codePoints) // avoid extra
+															// slice()
+  }
+
+  // Decode in chunks to avoid "call stack size exceeded".
+  var res = ''
+  var i = 0
+  while (i < len) {
+    res += String.fromCharCode.apply(
+      String,
+      codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
+    )
+  }
+  return res
+}
+
+function asciiSlice (buf, start, end) {
+  var ret = ''
+  end = Math.min(buf.length, end)
+
+  for (var i = start; i < end; ++i) {
+    ret += String.fromCharCode(buf[i] & 0x7F)
+  }
+  return ret
+}
+
+function latin1Slice (buf, start, end) {
+  var ret = ''
+  end = Math.min(buf.length, end)
+
+  for (var i = start; i < end; ++i) {
+    ret += String.fromCharCode(buf[i])
+  }
+  return ret
+}
+
+function hexSlice (buf, start, end) {
+  var len = buf.length
+
+  if (!start || start < 0) start = 0
+  if (!end || end < 0 || end > len) end = len
+
+  var out = ''
+  for (var i = start; i < end; ++i) {
+    out += toHex(buf[i])
+  }
+  return out
+}
+
+function utf16leSlice (buf, start, end) {
+  var bytes = buf.slice(start, end)
+  var res = ''
+  for (var i = 0; i < bytes.length; i += 2) {
+    res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256))
+  }
+  return res
+}
+
+Buffer.prototype.slice = function slice (start, end) {
+  var len = this.length
+  start = ~~start
+  end = end === undefined ? len : ~~end
+
+  if (start < 0) {
+    start += len
+    if (start < 0) start = 0
+  } else if (start > len) {
+    start = len
+  }
+
+  if (end < 0) {
+    end += len
+    if (end < 0) end = 0
+  } else if (end > len) {
+    end = len
+  }
+
+  if (end < start) end = start
+
+  var newBuf = this.subarray(start, end)
+  // Return an augmented `Uint8Array` instance
+  newBuf.__proto__ = Buffer.prototype
+  return newBuf
+}
+
+/*
+ * Need to make sure that buffer isn't trying to write out of bounds.
+ */
+function checkOffset (offset, ext, length) {
+  if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')
+  if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')
+}
+
+Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {
+  offset = offset >>> 0
+  byteLength = byteLength >>> 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var val = this[offset]
+  var mul = 1
+  var i = 0
+  while (++i < byteLength && (mul *= 0x100)) {
+    val += this[offset + i] * mul
+  }
+
+  return val
+}
+
+Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {
+  offset = offset >>> 0
+  byteLength = byteLength >>> 0
+  if (!noAssert) {
+    checkOffset(offset, byteLength, this.length)
+  }
+
+  var val = this[offset + --byteLength]
+  var mul = 1
+  while (byteLength > 0 && (mul *= 0x100)) {
+    val += this[offset + --byteLength] * mul
+  }
+
+  return val
+}
+
+Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {
+  offset = offset >>> 0
+  if (!noAssert) checkOffset(offset, 1, this.length)
+  return this[offset]
+}
+
+Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {
+  offset = offset >>> 0
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  return this[offset] | (this[offset + 1] << 8)
+}
+
+Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {
+  offset = offset >>> 0
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  return (this[offset] << 8) | this[offset + 1]
+}
+
+Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {
+  offset = offset >>> 0
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return ((this[offset]) |
+      (this[offset + 1] << 8) |
+      (this[offset + 2] << 16)) +
+      (this[offset + 3] * 0x1000000)
+}
+
+Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {
+  offset = offset >>> 0
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset] * 0x1000000) +
+    ((this[offset + 1] << 16) |
+    (this[offset + 2] << 8) |
+    this[offset + 3])
+}
+
+Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {
+  offset = offset >>> 0
+  byteLength = byteLength >>> 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var val = this[offset]
+  var mul = 1
+  var i = 0
+  while (++i < byteLength && (mul *= 0x100)) {
+    val += this[offset + i] * mul
+  }
+  mul *= 0x80
+
+  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+
+  return val
+}
+
+Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {
+  offset = offset >>> 0
+  byteLength = byteLength >>> 0
+  if (!noAssert) checkOffset(offset, byteLength, this.length)
+
+  var i = byteLength
+  var mul = 1
+  var val = this[offset + --i]
+  while (i > 0 && (mul *= 0x100)) {
+    val += this[offset + --i] * mul
+  }
+  mul *= 0x80
+
+  if (val >= mul) val -= Math.pow(2, 8 * byteLength)
+
+  return val
+}
+
+Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) {
+  offset = offset >>> 0
+  if (!noAssert) checkOffset(offset, 1, this.length)
+  if (!(this[offset] & 0x80)) return (this[offset])
+  return ((0xff - this[offset] + 1) * -1)
+}
+
+Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {
+  offset = offset >>> 0
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  var val = this[offset] | (this[offset + 1] << 8)
+  return (val & 0x8000) ? val | 0xFFFF0000 : val
+}
+
+Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {
+  offset = offset >>> 0
+  if (!noAssert) checkOffset(offset, 2, this.length)
+  var val = this[offset + 1] | (this[offset] << 8)
+  return (val & 0x8000) ? val | 0xFFFF0000 : val
+}
+
+Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {
+  offset = offset >>> 0
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset]) |
+    (this[offset + 1] << 8) |
+    (this[offset + 2] << 16) |
+    (this[offset + 3] << 24)
+}
+
+Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {
+  offset = offset >>> 0
+  if (!noAssert) checkOffset(offset, 4, this.length)
+
+  return (this[offset] << 24) |
+    (this[offset + 1] << 16) |
+    (this[offset + 2] << 8) |
+    (this[offset + 3])
+}
+
+Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {
+  offset = offset >>> 0
+  if (!noAssert) checkOffset(offset, 4, this.length)
+  return ieee754.read(this, offset, true, 23, 4)
+}
+
+Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {
+  offset = offset >>> 0
+  if (!noAssert) checkOffset(offset, 4, this.length)
+  return ieee754.read(this, offset, false, 23, 4)
+}
+
+Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {
+  offset = offset >>> 0
+  if (!noAssert) checkOffset(offset, 8, this.length)
+  return ieee754.read(this, offset, true, 52, 8)
+}
+
+Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {
+  offset = offset >>> 0
+  if (!noAssert) checkOffset(offset, 8, this.length)
+  return ieee754.read(this, offset, false, 52, 8)
+}
+
+function checkInt (buf, value, offset, ext, max, min) {
+  if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance')
+  if (value > max || value < min) throw new RangeError('"value" argument is out of bounds')
+  if (offset + ext > buf.length) throw new RangeError('Index out of range')
+}
+
+Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  byteLength = byteLength >>> 0
+  if (!noAssert) {
+    var maxBytes = Math.pow(2, 8 * byteLength) - 1
+    checkInt(this, value, offset, byteLength, maxBytes, 0)
+  }
+
+  var mul = 1
+  var i = 0
+  this[offset] = value & 0xFF
+  while (++i < byteLength && (mul *= 0x100)) {
+    this[offset + i] = (value / mul) & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  byteLength = byteLength >>> 0
+  if (!noAssert) {
+    var maxBytes = Math.pow(2, 8 * byteLength) - 1
+    checkInt(this, value, offset, byteLength, maxBytes, 0)
+  }
+
+  var i = byteLength - 1
+  var mul = 1
+  this[offset + i] = value & 0xFF
+  while (--i >= 0 && (mul *= 0x100)) {
+    this[offset + i] = (value / mul) & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)
+  this[offset] = (value & 0xff)
+  return offset + 1
+}
+
+Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+  this[offset] = (value & 0xff)
+  this[offset + 1] = (value >>> 8)
+  return offset + 2
+}
+
+Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)
+  this[offset] = (value >>> 8)
+  this[offset + 1] = (value & 0xff)
+  return offset + 2
+}
+
+Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+  this[offset + 3] = (value >>> 24)
+  this[offset + 2] = (value >>> 16)
+  this[offset + 1] = (value >>> 8)
+  this[offset] = (value & 0xff)
+  return offset + 4
+}
+
+Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)
+  this[offset] = (value >>> 24)
+  this[offset + 1] = (value >>> 16)
+  this[offset + 2] = (value >>> 8)
+  this[offset + 3] = (value & 0xff)
+  return offset + 4
+}
+
+Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) {
+    var limit = Math.pow(2, (8 * byteLength) - 1)
+
+    checkInt(this, value, offset, byteLength, limit - 1, -limit)
+  }
+
+  var i = 0
+  var mul = 1
+  var sub = 0
+  this[offset] = value & 0xFF
+  while (++i < byteLength && (mul *= 0x100)) {
+    if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {
+      sub = 1
+    }
+    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) {
+    var limit = Math.pow(2, (8 * byteLength) - 1)
+
+    checkInt(this, value, offset, byteLength, limit - 1, -limit)
+  }
+
+  var i = byteLength - 1
+  var mul = 1
+  var sub = 0
+  this[offset + i] = value & 0xFF
+  while (--i >= 0 && (mul *= 0x100)) {
+    if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {
+      sub = 1
+    }
+    this[offset + i] = ((value / mul) >> 0) - sub & 0xFF
+  }
+
+  return offset + byteLength
+}
+
+Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)
+  if (value < 0) value = 0xff + value + 1
+  this[offset] = (value & 0xff)
+  return offset + 1
+}
+
+Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+  this[offset] = (value & 0xff)
+  this[offset + 1] = (value >>> 8)
+  return offset + 2
+}
+
+Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)
+  this[offset] = (value >>> 8)
+  this[offset + 1] = (value & 0xff)
+  return offset + 2
+}
+
+Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+  this[offset] = (value & 0xff)
+  this[offset + 1] = (value >>> 8)
+  this[offset + 2] = (value >>> 16)
+  this[offset + 3] = (value >>> 24)
+  return offset + 4
+}
+
+Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)
+  if (value < 0) value = 0xffffffff + value + 1
+  this[offset] = (value >>> 24)
+  this[offset + 1] = (value >>> 16)
+  this[offset + 2] = (value >>> 8)
+  this[offset + 3] = (value & 0xff)
+  return offset + 4
+}
+
+function checkIEEE754 (buf, value, offset, ext, max, min) {
+  if (offset + ext > buf.length) throw new RangeError('Index out of range')
+  if (offset < 0) throw new RangeError('Index out of range')
+}
+
+function writeFloat (buf, value, offset, littleEndian, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) {
+    checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)
+  }
+  ieee754.write(buf, value, offset, littleEndian, 23, 4)
+  return offset + 4
+}
+
+Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {
+  return writeFloat(this, value, offset, true, noAssert)
+}
+
+Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {
+  return writeFloat(this, value, offset, false, noAssert)
+}
+
+function writeDouble (buf, value, offset, littleEndian, noAssert) {
+  value = +value
+  offset = offset >>> 0
+  if (!noAssert) {
+    checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)
+  }
+  ieee754.write(buf, value, offset, littleEndian, 52, 8)
+  return offset + 8
+}
+
+Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {
+  return writeDouble(this, value, offset, true, noAssert)
+}
+
+Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {
+  return writeDouble(this, value, offset, false, noAssert)
+}
+
+// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)
+Buffer.prototype.copy = function copy (target, targetStart, start, end) {
+  if (!start) start = 0
+  if (!end && end !== 0) end = this.length
+  if (targetStart >= target.length) targetStart = target.length
+  if (!targetStart) targetStart = 0
+  if (end > 0 && end < start) end = start
+
+  // Copy 0 bytes; we're done
+  if (end === start) return 0
+  if (target.length === 0 || this.length === 0) return 0
+
+  // Fatal error conditions
+  if (targetStart < 0) {
+    throw new RangeError('targetStart out of bounds')
+  }
+  if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')
+  if (end < 0) throw new RangeError('sourceEnd out of bounds')
+
+  // Are we oob?
+  if (end > this.length) end = this.length
+  if (target.length - targetStart < end - start) {
+    end = target.length - targetStart + start
+  }
+
+  var len = end - start
+  var i
+
+  if (this === target && start < targetStart && targetStart < end) {
+    // descending copy from end
+    for (i = len - 1; i >= 0; --i) {
+      target[i + targetStart] = this[i + start]
+    }
+  } else if (len < 1000) {
+    // ascending copy from start
+    for (i = 0; i < len; ++i) {
+      target[i + targetStart] = this[i + start]
+    }
+  } else {
+    Uint8Array.prototype.set.call(
+      target,
+      this.subarray(start, start + len),
+      targetStart
+    )
+  }
+
+  return len
+}
+
+// Usage:
+// buffer.fill(number[, offset[, end]])
+// buffer.fill(buffer[, offset[, end]])
+// buffer.fill(string[, offset[, end]][, encoding])
+Buffer.prototype.fill = function fill (val, start, end, encoding) {
+  // Handle string cases:
+  if (typeof val === 'string') {
+    if (typeof start === 'string') {
+      encoding = start
+      start = 0
+      end = this.length
+    } else if (typeof end === 'string') {
+      encoding = end
+      end = this.length
+    }
+    if (val.length === 1) {
+      var code = val.charCodeAt(0)
+      if (code < 256) {
+        val = code
+      }
+    }
+    if (encoding !== undefined && typeof encoding !== 'string') {
+      throw new TypeError('encoding must be a string')
+    }
+    if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {
+      throw new TypeError('Unknown encoding: ' + encoding)
+    }
+  } else if (typeof val === 'number') {
+    val = val & 255
+  }
+
+  // Invalid ranges are not set to a default, so can range check early.
+  if (start < 0 || this.length < start || this.length < end) {
+    throw new RangeError('Out of range index')
+  }
+
+  if (end <= start) {
+    return this
+  }
+
+  start = start >>> 0
+  end = end === undefined ? this.length : end >>> 0
+
+  if (!val) val = 0
+
+  var i
+  if (typeof val === 'number') {
+    for (i = start; i < end; ++i) {
+      this[i] = val
+    }
+  } else {
+    var bytes = Buffer.isBuffer(val)
+      ? val
+      : new Buffer(val, encoding)
+    var len = bytes.length
+    for (i = 0; i < end - start; ++i) {
+      this[i + start] = bytes[i % len]
+    }
+  }
+
+  return this
+}
+
+// HELPER FUNCTIONS
+// ================
+
+var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g
+
+function base64clean (str) {
+  // Node strips out invalid characters like \n and \t from the string,
+	// base64-js does not
+  str = str.trim().replace(INVALID_BASE64_RE, '')
+  // Node converts strings with length < 2 to ''
+  if (str.length < 2) return ''
+  // Node allows for non-padded base64 strings (missing trailing ===),
+	// base64-js does not
+  while (str.length % 4 !== 0) {
+    str = str + '='
+  }
+  return str
+}
+
+function toHex (n) {
+  if (n < 16) return '0' + n.toString(16)
+  return n.toString(16)
+}
+
+function utf8ToBytes (string, units) {
+  units = units || Infinity
+  var codePoint
+  var length = string.length
+  var leadSurrogate = null
+  var bytes = []
+
+  for (var i = 0; i < length; ++i) {
+    codePoint = string.charCodeAt(i)
+
+    // is surrogate component
+    if (codePoint > 0xD7FF && codePoint < 0xE000) {
+      // last char was a lead
+      if (!leadSurrogate) {
+        // no lead yet
+        if (codePoint > 0xDBFF) {
+          // unexpected trail
+          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+          continue
+        } else if (i + 1 === length) {
+          // unpaired lead
+          if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+          continue
+        }
+
+        // valid lead
+        leadSurrogate = codePoint
+
+        continue
+      }
+
+      // 2 leads in a row
+      if (codePoint < 0xDC00) {
+        if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+        leadSurrogate = codePoint
+        continue
+      }
+
+      // valid surrogate pair
+      codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000
+    } else if (leadSurrogate) {
+      // valid bmp char, but last char was a lead
+      if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)
+    }
+
+    leadSurrogate = null
+
+    // encode utf8
+    if (codePoint < 0x80) {
+      if ((units -= 1) < 0) break
+      bytes.push(codePoint)
+    } else if (codePoint < 0x800) {
+      if ((units -= 2) < 0) break
+      bytes.push(
+        codePoint >> 0x6 | 0xC0,
+        codePoint & 0x3F | 0x80
+      )
+    } else if (codePoint < 0x10000) {
+      if ((units -= 3) < 0) break
+      bytes.push(
+        codePoint >> 0xC | 0xE0,
+        codePoint >> 0x6 & 0x3F | 0x80,
+        codePoint & 0x3F | 0x80
+      )
+    } else if (codePoint < 0x110000) {
+      if ((units -= 4) < 0) break
+      bytes.push(
+        codePoint >> 0x12 | 0xF0,
+        codePoint >> 0xC & 0x3F | 0x80,
+        codePoint >> 0x6 & 0x3F | 0x80,
+        codePoint & 0x3F | 0x80
+      )
+    } else {
+      throw new Error('Invalid code point')
+    }
+  }
+
+  return bytes
+}
+
+function asciiToBytes (str) {
+  var byteArray = []
+  for (var i = 0; i < str.length; ++i) {
+    // Node's code seems to be doing this and not & 0x7F..
+    byteArray.push(str.charCodeAt(i) & 0xFF)
+  }
+  return byteArray
+}
+
+function utf16leToBytes (str, units) {
+  var c, hi, lo
+  var byteArray = []
+  for (var i = 0; i < str.length; ++i) {
+    if ((units -= 2) < 0) break
+
+    c = str.charCodeAt(i)
+    hi = c >> 8
+    lo = c % 256
+    byteArray.push(lo)
+    byteArray.push(hi)
+  }
+
+  return byteArray
+}
+
+function base64ToBytes (str) {
+  return base64.toByteArray(base64clean(str))
+}
+
+function blitBuffer (src, dst, offset, length) {
+  for (var i = 0; i < length; ++i) {
+    if ((i + offset >= dst.length) || (i >= src.length)) break
+    dst[i + offset] = src[i]
+  }
+  return i
+}
+
+// Node 0.10 supports `ArrayBuffer` but lacks `ArrayBuffer.isView`
+function isArrayBufferView (obj) {
+  return (typeof ArrayBuffer.isView === 'function') && ArrayBuffer.isView(obj)
+}
+
+function numberIsNaN (obj) {
+  return obj !== obj // eslint-disable-line no-self-compare
+}
+
+},{"base64-js":17,"ieee754":18}],17:[function(require,module,exports){
+'use strict'
+
+exports.byteLength = byteLength
+exports.toByteArray = toByteArray
+exports.fromByteArray = fromByteArray
+
+var lookup = []
+var revLookup = []
+var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array
+
+var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
+for (var i = 0, len = code.length; i < len; ++i) {
+  lookup[i] = code[i]
+  revLookup[code.charCodeAt(i)] = i
+}
+
+revLookup['-'.charCodeAt(0)] = 62
+revLookup['_'.charCodeAt(0)] = 63
+
+function placeHoldersCount (b64) {
+  var len = b64.length
+  if (len % 4 > 0) {
+    throw new Error('Invalid string. Length must be a multiple of 4')
+  }
+
+  // the number of equal signs (place holders)
+  // if there are two placeholders, than the two characters before it
+  // represent one byte
+  // if there is only one, then the three characters before it represent 2
+	// bytes
+  // this is just a cheap hack to not do indexOf twice
+  return b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0
+}
+
+function byteLength (b64) {
+  // base64 is 4/3 + up to two characters of the original data
+  return (b64.length * 3 / 4) - placeHoldersCount(b64)
+}
+
+function toByteArray (b64) {
+  var i, l, tmp, placeHolders, arr
+  var len = b64.length
+  placeHolders = placeHoldersCount(b64)
+
+  arr = new Arr((len * 3 / 4) - placeHolders)
+
+  // if there are placeholders, only get up to the last complete 4 chars
+  l = placeHolders > 0 ? len - 4 : len
+
+  var L = 0
+
+  for (i = 0; i < l; i += 4) {
+    tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]
+    arr[L++] = (tmp >> 16) & 0xFF
+    arr[L++] = (tmp >> 8) & 0xFF
+    arr[L++] = tmp & 0xFF
+  }
+
+  if (placeHolders === 2) {
+    tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4)
+    arr[L++] = tmp & 0xFF
+  } else if (placeHolders === 1) {
+    tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2)
+    arr[L++] = (tmp >> 8) & 0xFF
+    arr[L++] = tmp & 0xFF
+  }
+
+  return arr
+}
+
+function tripletToBase64 (num) {
+  return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F]
+}
+
+function encodeChunk (uint8, start, end) {
+  var tmp
+  var output = []
+  for (var i = start; i < end; i += 3) {
+    tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2])
+    output.push(tripletToBase64(tmp))
+  }
+  return output.join('')
+}
+
+function fromByteArray (uint8) {
+  var tmp
+  var len = uint8.length
+  var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes
+  var output = ''
+  var parts = []
+  var maxChunkLength = 16383 // must be multiple of 3
+
+  // go through the array every three bytes, we'll deal with trailing stuff
+	// later
+  for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
+    parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)))
+  }
+
+  // pad the end with zeros, but make sure to not forget the extra bytes
+  if (extraBytes === 1) {
+    tmp = uint8[len - 1]
+    output += lookup[tmp >> 2]
+    output += lookup[(tmp << 4) & 0x3F]
+    output += '=='
+  } else if (extraBytes === 2) {
+    tmp = (uint8[len - 2] << 8) + (uint8[len - 1])
+    output += lookup[tmp >> 10]
+    output += lookup[(tmp >> 4) & 0x3F]
+    output += lookup[(tmp << 2) & 0x3F]
+    output += '='
+  }
+
+  parts.push(output)
+
+  return parts.join('')
+}
+
+},{}],18:[function(require,module,exports){
+exports.read = function (buffer, offset, isLE, mLen, nBytes) {
+  var e, m
+  var eLen = nBytes * 8 - mLen - 1
+  var eMax = (1 << eLen) - 1
+  var eBias = eMax >> 1
+  var nBits = -7
+  var i = isLE ? (nBytes - 1) : 0
+  var d = isLE ? -1 : 1
+  var s = buffer[offset + i]
+
+  i += d
+
+  e = s & ((1 << (-nBits)) - 1)
+  s >>= (-nBits)
+  nBits += eLen
+  for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
+
+  m = e & ((1 << (-nBits)) - 1)
+  e >>= (-nBits)
+  nBits += mLen
+  for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
+
+  if (e === 0) {
+    e = 1 - eBias
+  } else if (e === eMax) {
+    return m ? NaN : ((s ? -1 : 1) * Infinity)
+  } else {
+    m = m + Math.pow(2, mLen)
+    e = e - eBias
+  }
+  return (s ? -1 : 1) * m * Math.pow(2, e - mLen)
+}
+
+exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
+  var e, m, c
+  var eLen = nBytes * 8 - mLen - 1
+  var eMax = (1 << eLen) - 1
+  var eBias = eMax >> 1
+  var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)
+  var i = isLE ? 0 : (nBytes - 1)
+  var d = isLE ? 1 : -1
+  var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0
+
+  value = Math.abs(value)
+
+  if (isNaN(value) || value === Infinity) {
+    m = isNaN(value) ? 1 : 0
+    e = eMax
+  } else {
+    e = Math.floor(Math.log(value) / Math.LN2)
+    if (value * (c = Math.pow(2, -e)) < 1) {
+      e--
+      c *= 2
+    }
+    if (e + eBias >= 1) {
+      value += rt / c
+    } else {
+      value += rt * Math.pow(2, 1 - eBias)
+    }
+    if (value * c >= 2) {
+      e++
+      c /= 2
+    }
+
+    if (e + eBias >= eMax) {
+      m = 0
+      e = eMax
+    } else if (e + eBias >= 1) {
+      m = (value * c - 1) * Math.pow(2, mLen)
+      e = e + eBias
+    } else {
+      m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)
+      e = 0
+    }
+  }
+
+  for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
+
+  e = (e << mLen) | m
+  eLen += mLen
+  for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
+
+  buffer[offset + i - d] |= s * 128
+}
+
+},{}],19:[function(require,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+function EventEmitter() {
+  this._events = this._events || {};
+  this._maxListeners = this._maxListeners || undefined;
+}
+module.exports = EventEmitter;
+
+// Backwards-compat with node 0.10.x
+EventEmitter.EventEmitter = EventEmitter;
+
+EventEmitter.prototype._events = undefined;
+EventEmitter.prototype._maxListeners = undefined;
+
+// By default EventEmitters will print a warning if more than 10 listeners are
+// added to it. This is a useful default which helps finding memory leaks.
+EventEmitter.defaultMaxListeners = 10;
+
+// Obviously not all Emitters should be limited to 10. This function allows
+// that to be increased. Set to zero for unlimited.
+EventEmitter.prototype.setMaxListeners = function(n) {
+  if (!isNumber(n) || n < 0 || isNaN(n))
+    throw TypeError('n must be a positive number');
+  this._maxListeners = n;
+  return this;
+};
+
+EventEmitter.prototype.emit = function(type) {
+  var er, handler, len, args, i, listeners;
+
+  if (!this._events)
+    this._events = {};
+
+  // If there is no 'error' event listener then throw.
+  if (type === 'error') {
+    if (!this._events.error ||
+        (isObject(this._events.error) && !this._events.error.length)) {
+      er = arguments[1];
+      if (er instanceof Error) {
+        throw er; // Unhandled 'error' event
+      } else {
+        // At least give some kind of context to the user
+        var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
+        err.context = er;
+        throw err;
+      }
+    }
+  }
+
+  handler = this._events[type];
+
+  if (isUndefined(handler))
+    return false;
+
+  if (isFunction(handler)) {
+    switch (arguments.length) {
+      // fast cases
+      case 1:
+        handler.call(this);
+        break;
+      case 2:
+        handler.call(this, arguments[1]);
+        break;
+      case 3:
+        handler.call(this, arguments[1], arguments[2]);
+        break;
+      // slower
+      default:
+        args = Array.prototype.slice.call(arguments, 1);
+        handler.apply(this, args);
+    }
+  } else if (isObject(handler)) {
+    args = Array.prototype.slice.call(arguments, 1);
+    listeners = handler.slice();
+    len = listeners.length;
+    for (i = 0; i < len; i++)
+      listeners[i].apply(this, args);
+  }
+
+  return true;
+};
+
+EventEmitter.prototype.addListener = function(type, listener) {
+  var m;
+
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  if (!this._events)
+    this._events = {};
+
+  // To avoid recursion in the case that type === "newListener"! Before
+  // adding it to the listeners, first emit "newListener".
+  if (this._events.newListener)
+    this.emit('newListener', type,
+              isFunction(listener.listener) ?
+              listener.listener : listener);
+
+  if (!this._events[type])
+    // Optimize the case of one listener. Don't need the extra array object.
+    this._events[type] = listener;
+  else if (isObject(this._events[type]))
+    // If we've already got an array, just append.
+    this._events[type].push(listener);
+  else
+    // Adding the second element, need to change to array.
+    this._events[type] = [this._events[type], listener];
+
+  // Check for listener leak
+  if (isObject(this._events[type]) && !this._events[type].warned) {
+    if (!isUndefined(this._maxListeners)) {
+      m = this._maxListeners;
+    } else {
+      m = EventEmitter.defaultMaxListeners;
+    }
+
+    if (m && m > 0 && this._events[type].length > m) {
+      this._events[type].warned = true;
+      console.error('(node) warning: possible EventEmitter memory ' +
+                    'leak detected. %d listeners added. ' +
+                    'Use emitter.setMaxListeners() to increase limit.',
+                    this._events[type].length);
+      if (typeof console.trace === 'function') {
+        // not supported in IE 10
+        console.trace();
+      }
+    }
+  }
+
+  return this;
+};
+
+EventEmitter.prototype.on = EventEmitter.prototype.addListener;
+
+EventEmitter.prototype.once = function(type, listener) {
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  var fired = false;
+
+  function g() {
+    this.removeListener(type, g);
+
+    if (!fired) {
+      fired = true;
+      listener.apply(this, arguments);
+    }
+  }
+
+  g.listener = listener;
+  this.on(type, g);
+
+  return this;
+};
+
+// emits a 'removeListener' event iff the listener was removed
+EventEmitter.prototype.removeListener = function(type, listener) {
+  var list, position, length, i;
+
+  if (!isFunction(listener))
+    throw TypeError('listener must be a function');
+
+  if (!this._events || !this._events[type])
+    return this;
+
+  list = this._events[type];
+  length = list.length;
+  position = -1;
+
+  if (list === listener ||
+      (isFunction(list.listener) && list.listener === listener)) {
+    delete this._events[type];
+    if (this._events.removeListener)
+      this.emit('removeListener', type, listener);
+
+  } else if (isObject(list)) {
+    for (i = length; i-- > 0;) {
+      if (list[i] === listener ||
+          (list[i].listener && list[i].listener === listener)) {
+        position = i;
+        break;
+      }
+    }
+
+    if (position < 0)
+      return this;
+
+    if (list.length === 1) {
+      list.length = 0;
+      delete this._events[type];
+    } else {
+      list.splice(position, 1);
+    }
+
+    if (this._events.removeListener)
+      this.emit('removeListener', type, listener);
+  }
+
+  return this;
+};
+
+EventEmitter.prototype.removeAllListeners = function(type) {
+  var key, listeners;
+
+  if (!this._events)
+    return this;
+
+  // not listening for removeListener, no need to emit
+  if (!this._events.removeListener) {
+    if (arguments.length === 0)
+      this._events = {};
+    else if (this._events[type])
+      delete this._events[type];
+    return this;
+  }
+
+  // emit removeListener for all listeners on all events
+  if (arguments.length === 0) {
+    for (key in this._events) {
+      if (key === 'removeListener') continue;
+      this.removeAllListeners(key);
+    }
+    this.removeAllListeners('removeListener');
+    this._events = {};
+    return this;
+  }
+
+  listeners = this._events[type];
+
+  if (isFunction(listeners)) {
+    this.removeListener(type, listeners);
+  } else if (listeners) {
+    // LIFO order
+    while (listeners.length)
+      this.removeListener(type, listeners[listeners.length - 1]);
+  }
+  delete this._events[type];
+
+  return this;
+};
+
+EventEmitter.prototype.listeners = function(type) {
+  var ret;
+  if (!this._events || !this._events[type])
+    ret = [];
+  else if (isFunction(this._events[type]))
+    ret = [this._events[type]];
+  else
+    ret = this._events[type].slice();
+  return ret;
+};
+
+EventEmitter.prototype.listenerCount = function(type) {
+  if (this._events) {
+    var evlistener = this._events[type];
+
+    if (isFunction(evlistener))
+      return 1;
+    else if (evlistener)
+      return evlistener.length;
+  }
+  return 0;
+};
+
+EventEmitter.listenerCount = function(emitter, type) {
+  return emitter.listenerCount(type);
+};
+
+function isFunction(arg) {
+  return typeof arg === 'function';
+}
+
+function isNumber(arg) {
+  return typeof arg === 'number';
+}
+
+function isObject(arg) {
+  return typeof arg === 'object' && arg !== null;
+}
+
+function isUndefined(arg) {
+  return arg === void 0;
+}
+
+},{}],20:[function(require,module,exports){
+if (typeof Object.create === 'function') {
+  // implementation from standard node.js 'util' module
+  module.exports = function inherits(ctor, superCtor) {
+    ctor.super_ = superCtor
+    ctor.prototype = Object.create(superCtor.prototype, {
+      constructor: {
+        value: ctor,
+        enumerable: false,
+        writable: true,
+        configurable: true
+      }
+    });
+  };
+} else {
+  // old school shim for old browsers
+  module.exports = function inherits(ctor, superCtor) {
+    ctor.super_ = superCtor
+    var TempCtor = function () {}
+    TempCtor.prototype = superCtor.prototype
+    ctor.prototype = new TempCtor()
+    ctor.prototype.constructor = ctor
+  }
+}
+
+},{}],21:[function(require,module,exports){
+/*
+ * ! Determine if an object is a Buffer
+ * 
+ * @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org> @license
+ * MIT
+ */
+
+// The _isBuffer check is for Safari 5-7 support, because it's missing
+// Object.prototype.constructor. Remove this eventually
+module.exports = function (obj) {
+  return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)
+}
+
+function isBuffer (obj) {
+  return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)
+}
+
+// For Node v0.10 support. Remove this eventually.
+function isSlowBuffer (obj) {
+  return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))
+}
+
+},{}],22:[function(require,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// resolves . and .. elements in a path array with directory names there
+// must be no slashes, empty elements, or device names (c:\) in the array
+// (so also no leading and trailing slashes - it does not distinguish
+// relative and absolute paths)
+function normalizeArray(parts, allowAboveRoot) {
+  // if the path tries to go above the root, `up` ends up > 0
+  var up = 0;
+  for (var i = parts.length - 1; i >= 0; i--) {
+    var last = parts[i];
+    if (last === '.') {
+      parts.splice(i, 1);
+    } else if (last === '..') {
+      parts.splice(i, 1);
+      up++;
+    } else if (up) {
+      parts.splice(i, 1);
+      up--;
+    }
+  }
+
+  // if the path is allowed to go above the root, restore leading ..s
+  if (allowAboveRoot) {
+    for (; up--; up) {
+      parts.unshift('..');
+    }
+  }
+
+  return parts;
+}
+
+// Split a filename into [root, dir, basename, ext], unix version
+// 'root' is just a slash, or nothing.
+var splitPathRe =
+    /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
+var splitPath = function(filename) {
+  return splitPathRe.exec(filename).slice(1);
+};
+
+// path.resolve([from ...], to)
+// posix version
+exports.resolve = function() {
+  var resolvedPath = '',
+      resolvedAbsolute = false;
+
+  for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+    var path = (i >= 0) ? arguments[i] : process.cwd();
+
+    // Skip empty and invalid entries
+    if (typeof path !== 'string') {
+      throw new TypeError('Arguments to path.resolve must be strings');
+    } else if (!path) {
+      continue;
+    }
+
+    resolvedPath = path + '/' + resolvedPath;
+    resolvedAbsolute = path.charAt(0) === '/';
+  }
+
+  // At this point the path should be resolved to a full absolute path, but
+  // handle relative paths to be safe (might happen when process.cwd() fails)
+
+  // Normalize the path
+  resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
+    return !!p;
+  }), !resolvedAbsolute).join('/');
+
+  return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
+};
+
+// path.normalize(path)
+// posix version
+exports.normalize = function(path) {
+  var isAbsolute = exports.isAbsolute(path),
+      trailingSlash = substr(path, -1) === '/';
+
+  // Normalize the path
+  path = normalizeArray(filter(path.split('/'), function(p) {
+    return !!p;
+  }), !isAbsolute).join('/');
+
+  if (!path && !isAbsolute) {
+    path = '.';
+  }
+  if (path && trailingSlash) {
+    path += '/';
+  }
+
+  return (isAbsolute ? '/' : '') + path;
+};
+
+// posix version
+exports.isAbsolute = function(path) {
+  return path.charAt(0) === '/';
+};
+
+// posix version
+exports.join = function() {
+  var paths = Array.prototype.slice.call(arguments, 0);
+  return exports.normalize(filter(paths, function(p, index) {
+    if (typeof p !== 'string') {
+      throw new TypeError('Arguments to path.join must be strings');
+    }
+    return p;
+  }).join('/'));
+};
+
+
+// path.relative(from, to)
+// posix version
+exports.relative = function(from, to) {
+  from = exports.resolve(from).substr(1);
+  to = exports.resolve(to).substr(1);
+
+  function trim(arr) {
+    var start = 0;
+    for (; start < arr.length; start++) {
+      if (arr[start] !== '') break;
+    }
+
+    var end = arr.length - 1;
+    for (; end >= 0; end--) {
+      if (arr[end] !== '') break;
+    }
+
+    if (start > end) return [];
+    return arr.slice(start, end - start + 1);
+  }
+
+  var fromParts = trim(from.split('/'));
+  var toParts = trim(to.split('/'));
+
+  var length = Math.min(fromParts.length, toParts.length);
+  var samePartsLength = length;
+  for (var i = 0; i < length; i++) {
+    if (fromParts[i] !== toParts[i]) {
+      samePartsLength = i;
+      break;
+    }
+  }
+
+  var outputParts = [];
+  for (var i = samePartsLength; i < fromParts.length; i++) {
+    outputParts.push('..');
+  }
+
+  outputParts = outputParts.concat(toParts.slice(samePartsLength));
+
+  return outputParts.join('/');
+};
+
+exports.sep = '/';
+exports.delimiter = ':';
+
+exports.dirname = function(path) {
+  var result = splitPath(path),
+      root = result[0],
+      dir = result[1];
+
+  if (!root && !dir) {
+    // No dirname whatsoever
+    return '.';
+  }
+
+  if (dir) {
+    // It has a dirname, strip trailing slash
+    dir = dir.substr(0, dir.length - 1);
+  }
+
+  return root + dir;
+};
+
+
+exports.basename = function(path, ext) {
+  var f = splitPath(path)[2];
+  // TODO: make this comparison case-insensitive on windows?
+  if (ext && f.substr(-1 * ext.length) === ext) {
+    f = f.substr(0, f.length - ext.length);
+  }
+  return f;
+};
+
+
+exports.extname = function(path) {
+  return splitPath(path)[3];
+};
+
+function filter (xs, f) {
+    if (xs.filter) return xs.filter(f);
+    var res = [];
+    for (var i = 0; i < xs.length; i++) {
+        if (f(xs[i], i, xs)) res.push(xs[i]);
+    }
+    return res;
+}
+
+// String.prototype.substr - negative index don't work in IE8
+var substr = 'ab'.substr(-1) === 'b'
+    ? function (str, start, len) { return str.substr(start, len) }
+    : function (str, start, len) {
+        if (start < 0) start = str.length + start;
+        return str.substr(start, len);
+    }
+;
+
+}).call(this,require('_process'))
+},{"_process":23}],23:[function(require,module,exports){
+// shim for using process in browser
+var process = module.exports = {};
+
+// cached from whatever global is present so that test runners that stub it
+// don't break things. But we need to wrap it in a try catch in case it is
+// wrapped in strict mode code which doesn't define any globals. It's inside a
+// function because try/catches deoptimize in certain engines.
+
+var cachedSetTimeout;
+var cachedClearTimeout;
+
+function defaultSetTimout() {
+    throw new Error('setTimeout has not been defined');
+}
+function defaultClearTimeout () {
+    throw new Error('clearTimeout has not been defined');
+}
+(function () {
+    try {
+        if (typeof setTimeout === 'function') {
+            cachedSetTimeout = setTimeout;
+        } else {
+            cachedSetTimeout = defaultSetTimout;
+        }
+    } catch (e) {
+        cachedSetTimeout = defaultSetTimout;
+    }
+    try {
+        if (typeof clearTimeout === 'function') {
+            cachedClearTimeout = clearTimeout;
+        } else {
+            cachedClearTimeout = defaultClearTimeout;
+        }
+    } catch (e) {
+        cachedClearTimeout = defaultClearTimeout;
+    }
+} ())
+function runTimeout(fun) {
+    if (cachedSetTimeout === setTimeout) {
+        // normal enviroments in sane situations
+        return setTimeout(fun, 0);
+    }
+    // if setTimeout wasn't available but was latter defined
+    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
+        cachedSetTimeout = setTimeout;
+        return setTimeout(fun, 0);
+    }
+    try {
+        // when when somebody has screwed with setTimeout but no I.E. maddness
+        return cachedSetTimeout(fun, 0);
+    } catch(e){
+        try {
+            // When we are in I.E. but the script has been evaled so I.E.
+			// doesn't trust the global object when called normally
+            return cachedSetTimeout.call(null, fun, 0);
+        } catch(e){
+            // same as above but when it's a version of I.E. that must have the
+			// global object for 'this', hopfully our context correct otherwise
+			// it will throw a global error
+            return cachedSetTimeout.call(this, fun, 0);
+        }
+    }
+
+
+}
+function runClearTimeout(marker) {
+    if (cachedClearTimeout === clearTimeout) {
+        // normal enviroments in sane situations
+        return clearTimeout(marker);
+    }
+    // if clearTimeout wasn't available but was latter defined
+    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
+        cachedClearTimeout = clearTimeout;
+        return clearTimeout(marker);
+    }
+    try {
+        // when when somebody has screwed with setTimeout but no I.E. maddness
+        return cachedClearTimeout(marker);
+    } catch (e){
+        try {
+            // When we are in I.E. but the script has been evaled so I.E.
+			// doesn't trust the global object when called normally
+            return cachedClearTimeout.call(null, marker);
+        } catch (e){
+            // same as above but when it's a version of I.E. that must have the
+			// global object for 'this', hopfully our context correct otherwise
+			// it will throw a global error.
+            // Some versions of I.E. have different rules for clearTimeout vs
+			// setTimeout
+            return cachedClearTimeout.call(this, marker);
+        }
+    }
+
+
+
+}
+var queue = [];
+var draining = false;
+var currentQueue;
+var queueIndex = -1;
+
+function cleanUpNextTick() {
+    if (!draining || !currentQueue) {
+        return;
+    }
+    draining = false;
+    if (currentQueue.length) {
+        queue = currentQueue.concat(queue);
+    } else {
+        queueIndex = -1;
+    }
+    if (queue.length) {
+        drainQueue();
+    }
+}
+
+function drainQueue() {
+    if (draining) {
+        return;
+    }
+    var timeout = runTimeout(cleanUpNextTick);
+    draining = true;
+
+    var len = queue.length;
+    while(len) {
+        currentQueue = queue;
+        queue = [];
+        while (++queueIndex < len) {
+            if (currentQueue) {
+                currentQueue[queueIndex].run();
+            }
+        }
+        queueIndex = -1;
+        len = queue.length;
+    }
+    currentQueue = null;
+    draining = false;
+    runClearTimeout(timeout);
+}
+
+process.nextTick = function (fun) {
+    var args = new Array(arguments.length - 1);
+    if (arguments.length > 1) {
+        for (var i = 1; i < arguments.length; i++) {
+            args[i - 1] = arguments[i];
+        }
+    }
+    queue.push(new Item(fun, args));
+    if (queue.length === 1 && !draining) {
+        runTimeout(drainQueue);
+    }
+};
+
+// v8 likes predictible objects
+function Item(fun, array) {
+    this.fun = fun;
+    this.array = array;
+}
+Item.prototype.run = function () {
+    this.fun.apply(null, this.array);
+};
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
+process.version = ''; // empty string to avoid regexp issues
+process.versions = {};
+
+function noop() {}
+
+process.on = noop;
+process.addListener = noop;
+process.once = noop;
+process.off = noop;
+process.removeListener = noop;
+process.removeAllListeners = noop;
+process.emit = noop;
+process.prependListener = noop;
+process.prependOnceListener = noop;
+
+process.listeners = function (name) { return [] }
+
+process.binding = function (name) {
+    throw new Error('process.binding is not supported');
+};
+
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+    throw new Error('process.chdir is not supported');
+};
+process.umask = function() { return 0; };
+
+},{}],24:[function(require,module,exports){
+module.exports = require('./lib/_stream_duplex.js');
+
+},{"./lib/_stream_duplex.js":25}],25:[function(require,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// a duplex stream is just a stream that is both readable and writable.
+// Since JS doesn't have multiple prototypal inheritance, this class
+// prototypally inherits from Readable, and then parasitically from
+// Writable.
+
+'use strict';
+
+/* <replacement> */
+
+var processNextTick = require('process-nextick-args');
+/* </replacement> */
+
+/* <replacement> */
+var objectKeys = Object.keys || function (obj) {
+  var keys = [];
+  for (var key in obj) {
+    keys.push(key);
+  }return keys;
+};
+/* </replacement> */
+
+module.exports = Duplex;
+
+/* <replacement> */
+var util = require('core-util-is');
+util.inherits = require('inherits');
+/* </replacement> */
+
+var Readable = require('./_stream_readable');
+var Writable = require('./_stream_writable');
+
+util.inherits(Duplex, Readable);
+
+var keys = objectKeys(Writable.prototype);
+for (var v = 0; v < keys.length; v++) {
+  var method = keys[v];
+  if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method];
+}
+
+function Duplex(options) {
+  if (!(this instanceof Duplex)) return new Duplex(options);
+
+  Readable.call(this, options);
+  Writable.call(this, options);
+
+  if (options && options.readable === false) this.readable = false;
+
+  if (options && options.writable === false) this.writable = false;
+
+  this.allowHalfOpen = true;
+  if (options && options.allowHalfOpen === false) this.allowHalfOpen = false;
+
+  this.once('end', onend);
+}
+
+// the no-half-open enforcer
+function onend() {
+  // if we allow half-open state, or if the writable side ended,
+  // then we're ok.
+  if (this.allowHalfOpen || this._writableState.ended) return;
+
+  // no more data can be written.
+  // But allow more writes to happen in this tick.
+  processNextTick(onEndNT, this);
+}
+
+function onEndNT(self) {
+  self.end();
+}
+
+Object.defineProperty(Duplex.prototype, 'destroyed', {
+  get: function () {
+    if (this._readableState === undefined || this._writableState === undefined) {
+      return false;
+    }
+    return this._readableState.destroyed && this._writableState.destroyed;
+  },
+  set: function (value) {
+    // we ignore the value if the stream
+    // has not been initialized yet
+    if (this._readableState === undefined || this._writableState === undefined) {
+      return;
+    }
+
+    // backward compatibility, the user is explicitly
+    // managing destroyed
+    this._readableState.destroyed = value;
+    this._writableState.destroyed = value;
+  }
+});
+
+Duplex.prototype._destroy = function (err, cb) {
+  this.push(null);
+  this.end();
+
+  processNextTick(cb, err);
+};
+
+function forEach(xs, f) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    f(xs[i], i);
+  }
+}
+},{"./_stream_readable":27,"./_stream_writable":29,"core-util-is":33,"inherits":20,"process-nextick-args":35}],26:[function(require,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// a passthrough stream.
+// basically just the most minimal sort of Transform stream.
+// Every written chunk gets output as-is.
+
+'use strict';
+
+module.exports = PassThrough;
+
+var Transform = require('./_stream_transform');
+
+/* <replacement> */
+var util = require('core-util-is');
+util.inherits = require('inherits');
+/* </replacement> */
+
+util.inherits(PassThrough, Transform);
+
+function PassThrough(options) {
+  if (!(this instanceof PassThrough)) return new PassThrough(options);
+
+  Transform.call(this, options);
+}
+
+PassThrough.prototype._transform = function (chunk, encoding, cb) {
+  cb(null, chunk);
+};
+},{"./_stream_transform":28,"core-util-is":33,"inherits":20}],27:[function(require,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+'use strict';
+
+/* <replacement> */
+
+var processNextTick = require('process-nextick-args');
+/* </replacement> */
+
+module.exports = Readable;
+
+/* <replacement> */
+var isArray = require('isarray');
+/* </replacement> */
+
+/* <replacement> */
+var Duplex;
+/* </replacement> */
+
+Readable.ReadableState = ReadableState;
+
+/* <replacement> */
+var EE = require('events').EventEmitter;
+
+var EElistenerCount = function (emitter, type) {
+  return emitter.listeners(type).length;
+};
+/* </replacement> */
+
+/* <replacement> */
+var Stream = require('./internal/streams/stream');
+/* </replacement> */
+
+// TODO(bmeurer): Change this back to const once hole checks are
+// properly optimized away early in Ignition+TurboFan.
+/* <replacement> */
+var Buffer = require('safe-buffer').Buffer;
+function _uint8ArrayToBuffer(chunk) {
+  return Buffer.from(chunk);
+}
+function _isUint8Array(obj) {
+  return Object.prototype.toString.call(obj) === '[object Uint8Array]' || Buffer.isBuffer(obj);
+}
+/* </replacement> */
+
+/* <replacement> */
+var util = require('core-util-is');
+util.inherits = require('inherits');
+/* </replacement> */
+
+/* <replacement> */
+var debugUtil = require('util');
+var debug = void 0;
+if (debugUtil && debugUtil.debuglog) {
+  debug = debugUtil.debuglog('stream');
+} else {
+  debug = function () {};
+}
+/* </replacement> */
+
+var BufferList = require('./internal/streams/BufferList');
+var destroyImpl = require('./internal/streams/destroy');
+var StringDecoder;
+
+util.inherits(Readable, Stream);
+
+var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume'];
+
+function prependListener(emitter, event, fn) {
+  // Sadly this is not cacheable as some libraries bundle their own
+  // event emitter implementation with them.
+  if (typeof emitter.prependListener === 'function') {
+    return emitter.prependListener(event, fn);
+  } else {
+    // This is a hack to make sure that our error handler is attached before any
+    // userland ones. NEVER DO THIS. This is here only because this code needs
+    // to continue to work with older versions of Node.js that do not include
+    // the prependListener() method. The goal is to eventually remove this hack.
+    if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]];
+  }
+}
+
+function ReadableState(options, stream) {
+  Duplex = Duplex || require('./_stream_duplex');
+
+  options = options || {};
+
+  // object stream flag. Used to make read(n) ignore n and to
+  // make all the buffer merging and length checks go away
+  this.objectMode = !!options.objectMode;
+
+  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode;
+
+  // the point at which it stops calling _read() to fill the buffer
+  // Note: 0 is a valid value, means "don't call _read preemptively ever"
+  var hwm = options.highWaterMark;
+  var defaultHwm = this.objectMode ? 16 : 16 * 1024;
+  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
+
+  // cast to ints.
+  this.highWaterMark = Math.floor(this.highWaterMark);
+
+  // A linked list is used to store data chunks instead of an array because
+	// the
+  // linked list can remove elements from the beginning faster than
+  // array.shift()
+  this.buffer = new BufferList();
+  this.length = 0;
+  this.pipes = null;
+  this.pipesCount = 0;
+  this.flowing = null;
+  this.ended = false;
+  this.endEmitted = false;
+  this.reading = false;
+
+  // a flag to be able to tell if the event 'readable'/'data' is emitted
+  // immediately, or on a later tick. We set this to true at first, because
+  // any actions that shouldn't happen until "later" should generally also
+  // not happen before the first read call.
+  this.sync = true;
+
+  // whenever we return null, then we set a flag to say
+  // that we're awaiting a 'readable' event emission.
+  this.needReadable = false;
+  this.emittedReadable = false;
+  this.readableListening = false;
+  this.resumeScheduled = false;
+
+  // has it been destroyed
+  this.destroyed = false;
+
+  // Crypto is kind of old and crusty. Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // the number of writers that are awaiting a drain event in .pipe()s
+  this.awaitDrain = 0;
+
+  // if true, a maybeReadMore has been scheduled
+  this.readingMore = false;
+
+  this.decoder = null;
+  this.encoding = null;
+  if (options.encoding) {
+    if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
+    this.decoder = new StringDecoder(options.encoding);
+    this.encoding = options.encoding;
+  }
+}
+
+function Readable(options) {
+  Duplex = Duplex || require('./_stream_duplex');
+
+  if (!(this instanceof Readable)) return new Readable(options);
+
+  this._readableState = new ReadableState(options, this);
+
+  // legacy
+  this.readable = true;
+
+  if (options) {
+    if (typeof options.read === 'function') this._read = options.read;
+
+    if (typeof options.destroy === 'function') this._destroy = options.destroy;
+  }
+
+  Stream.call(this);
+}
+
+Object.defineProperty(Readable.prototype, 'destroyed', {
+  get: function () {
+    if (this._readableState === undefined) {
+      return false;
+    }
+    return this._readableState.destroyed;
+  },
+  set: function (value) {
+    // we ignore the value if the stream
+    // has not been initialized yet
+    if (!this._readableState) {
+      return;
+    }
+
+    // backward compatibility, the user is explicitly
+    // managing destroyed
+    this._readableState.destroyed = value;
+  }
+});
+
+Readable.prototype.destroy = destroyImpl.destroy;
+Readable.prototype._undestroy = destroyImpl.undestroy;
+Readable.prototype._destroy = function (err, cb) {
+  this.push(null);
+  cb(err);
+};
+
+// Manually shove something into the read() buffer.
+// This returns true if the highWaterMark has not been hit yet,
+// similar to how Writable.write() returns true if you should
+// write() some more.
+Readable.prototype.push = function (chunk, encoding) {
+  var state = this._readableState;
+  var skipChunkCheck;
+
+  if (!state.objectMode) {
+    if (typeof chunk === 'string') {
+      encoding = encoding || state.defaultEncoding;
+      if (encoding !== state.encoding) {
+        chunk = Buffer.from(chunk, encoding);
+        encoding = '';
+      }
+      skipChunkCheck = true;
+    }
+  } else {
+    skipChunkCheck = true;
+  }
+
+  return readableAddChunk(this, chunk, encoding, false, skipChunkCheck);
+};
+
+// Unshift should *always* be something directly out of read()
+Readable.prototype.unshift = function (chunk) {
+  return readableAddChunk(this, chunk, null, true, false);
+};
+
+function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) {
+  var state = stream._readableState;
+  if (chunk === null) {
+    state.reading = false;
+    onEofChunk(stream, state);
+  } else {
+    var er;
+    if (!skipChunkCheck) er = chunkInvalid(state, chunk);
+    if (er) {
+      stream.emit('error', er);
+    } else if (state.objectMode || chunk && chunk.length > 0) {
+      if (typeof chunk !== 'string' && Object.getPrototypeOf(chunk) !== Buffer.prototype && !state.objectMode) {
+        chunk = _uint8ArrayToBuffer(chunk);
+      }
+
+      if (addToFront) {
+        if (state.endEmitted) stream.emit('error', new Error('stream.unshift() after end event'));else addChunk(stream, state, chunk, true);
+      } else if (state.ended) {
+        stream.emit('error', new Error('stream.push() after EOF'));
+      } else {
+        state.reading = false;
+        if (state.decoder && !encoding) {
+          chunk = state.decoder.write(chunk);
+          if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state);
+        } else {
+          addChunk(stream, state, chunk, false);
+        }
+      }
+    } else if (!addToFront) {
+      state.reading = false;
+    }
+  }
+
+  return needMoreData(state);
+}
+
+function addChunk(stream, state, chunk, addToFront) {
+  if (state.flowing && state.length === 0 && !state.sync) {
+    stream.emit('data', chunk);
+    stream.read(0);
+  } else {
+    // update the buffer info.
+    state.length += state.objectMode ? 1 : chunk.length;
+    if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk);
+
+    if (state.needReadable) emitReadable(stream);
+  }
+  maybeReadMore(stream, state);
+}
+
+function chunkInvalid(state, chunk) {
+  var er;
+  if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
+    er = new TypeError('Invalid non-string/buffer chunk');
+  }
+  return er;
+}
+
+// if it's past the high water mark, we can push in some more.
+// Also, if we have no data yet, we can stand some
+// more bytes. This is to work around cases where hwm=0,
+// such as the repl. Also, if the push() triggered a
+// readable event, and the user called read(largeNumber) such that
+// needReadable was set, then we ought to push more, so that another
+// 'readable' event will be triggered.
+function needMoreData(state) {
+  return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0);
+}
+
+Readable.prototype.isPaused = function () {
+  return this._readableState.flowing === false;
+};
+
+// backwards compatibility.
+Readable.prototype.setEncoding = function (enc) {
+  if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder;
+  this._readableState.decoder = new StringDecoder(enc);
+  this._readableState.encoding = enc;
+  return this;
+};
+
+// Don't raise the hwm > 8MB
+var MAX_HWM = 0x800000;
+function computeNewHighWaterMark(n) {
+  if (n >= MAX_HWM) {
+    n = MAX_HWM;
+  } else {
+    // Get the next highest power of 2 to prevent increasing hwm excessively in
+    // tiny amounts
+    n--;
+    n |= n >>> 1;
+    n |= n >>> 2;
+    n |= n >>> 4;
+    n |= n >>> 8;
+    n |= n >>> 16;
+    n++;
+  }
+  return n;
+}
+
+// This function is designed to be inlinable, so please take care when making
+// changes to the function body.
+function howMuchToRead(n, state) {
+  if (n <= 0 || state.length === 0 && state.ended) return 0;
+  if (state.objectMode) return 1;
+  if (n !== n) {
+    // Only flow one buffer at a time
+    if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length;
+  }
+  // If we're asking for more than the current hwm, then raise the hwm.
+  if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n);
+  if (n <= state.length) return n;
+  // Don't have enough
+  if (!state.ended) {
+    state.needReadable = true;
+    return 0;
+  }
+  return state.length;
+}
+
+// you can override either this method, or the async _read(n) below.
+Readable.prototype.read = function (n) {
+  debug('read', n);
+  n = parseInt(n, 10);
+  var state = this._readableState;
+  var nOrig = n;
+
+  if (n !== 0) state.emittedReadable = false;
+
+  // if we're doing read(0) to trigger a readable event, but we
+  // already have a bunch of data in the buffer, then just trigger
+  // the 'readable' event and move on.
+  if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) {
+    debug('read: emitReadable', state.length, state.ended);
+    if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this);
+    return null;
+  }
+
+  n = howMuchToRead(n, state);
+
+  // if we've ended, and we're now clear, then finish it up.
+  if (n === 0 && state.ended) {
+    if (state.length === 0) endReadable(this);
+    return null;
+  }
+
+  // All the actual chunk generation logic needs to be
+  // *below* the call to _read. The reason is that in certain
+  // synthetic stream cases, such as passthrough streams, _read
+  // may be a completely synchronous operation which may change
+  // the state of the read buffer, providing enough data when
+  // before there was *not* enough.
+  //
+  // So, the steps are:
+  // 1. Figure out what the state of things will be after we do
+  // a read from the buffer.
+  //
+  // 2. If that resulting state will trigger a _read, then call _read.
+  // Note that this may be asynchronous, or synchronous. Yes, it is
+  // deeply ugly to write APIs this way, but that still doesn't mean
+  // that the Readable class should behave improperly, as streams are
+  // designed to be sync/async agnostic.
+  // Take note if the _read call is sync or async (ie, if the read call
+  // has returned yet), so that we know whether or not it's safe to emit
+  // 'readable' etc.
+  //
+  // 3. Actually pull the requested chunks out of the buffer and return.
+
+  // if we need a readable event, then we need to do some reading.
+  var doRead = state.needReadable;
+  debug('need readable', doRead);
+
+  // if we currently have less than the highWaterMark, then also read some
+  if (state.length === 0 || state.length - n < state.highWaterMark) {
+    doRead = true;
+    debug('length less than watermark', doRead);
+  }
+
+  // however, if we've ended, then there's no point, and if we're already
+  // reading, then it's unnecessary.
+  if (state.ended || state.reading) {
+    doRead = false;
+    debug('reading or ended', doRead);
+  } else if (doRead) {
+    debug('do read');
+    state.reading = true;
+    state.sync = true;
+    // if the length is currently zero, then we *need* a readable event.
+    if (state.length === 0) state.needReadable = true;
+    // call internal read method
+    this._read(state.highWaterMark);
+    state.sync = false;
+    // If _read pushed data synchronously, then `reading` will be false,
+    // and we need to re-evaluate how much data we can return to the user.
+    if (!state.reading) n = howMuchToRead(nOrig, state);
+  }
+
+  var ret;
+  if (n > 0) ret = fromList(n, state);else ret = null;
+
+  if (ret === null) {
+    state.needReadable = true;
+    n = 0;
+  } else {
+    state.length -= n;
+  }
+
+  if (state.length === 0) {
+    // If we have nothing in the buffer, then we want to know
+    // as soon as we *do* get something into the buffer.
+    if (!state.ended) state.needReadable = true;
+
+    // If we tried to read() past the EOF, then emit end on the next tick.
+    if (nOrig !== n && state.ended) endReadable(this);
+  }
+
+  if (ret !== null) this.emit('data', ret);
+
+  return ret;
+};
+
+function onEofChunk(stream, state) {
+  if (state.ended) return;
+  if (state.decoder) {
+    var chunk = state.decoder.end();
+    if (chunk && chunk.length) {
+      state.buffer.push(chunk);
+      state.length += state.objectMode ? 1 : chunk.length;
+    }
+  }
+  state.ended = true;
+
+  // emit 'readable' now to make sure it gets picked up.
+  emitReadable(stream);
+}
+
+// Don't emit readable right away in sync mode, because this can trigger
+// another read() call => stack overflow. This way, it might trigger
+// a nextTick recursion warning, but that's not so bad.
+function emitReadable(stream) {
+  var state = stream._readableState;
+  state.needReadable = false;
+  if (!state.emittedReadable) {
+    debug('emitReadable', state.flowing);
+    state.emittedReadable = true;
+    if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream);
+  }
+}
+
+function emitReadable_(stream) {
+  debug('emit readable');
+  stream.emit('readable');
+  flow(stream);
+}
+
+// at this point, the user has presumably seen the 'readable' event,
+// and called read() to consume some data. that may have triggered
+// in turn another _read(n) call, in which case reading = true if
+// it's in progress.
+// However, if we're not ended, or reading, and the length < hwm,
+// then go ahead and try to read some more preemptively.
+function maybeReadMore(stream, state) {
+  if (!state.readingMore) {
+    state.readingMore = true;
+    processNextTick(maybeReadMore_, stream, state);
+  }
+}
+
+function maybeReadMore_(stream, state) {
+  var len = state.length;
+  while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) {
+    debug('maybeReadMore read 0');
+    stream.read(0);
+    if (len === state.length)
+      // didn't get any data, stop spinning.
+      break;else len = state.length;
+  }
+  state.readingMore = false;
+}
+
+// abstract method. to be overridden in specific implementation classes.
+// call cb(er, data) where data is <= n in length.
+// for virtual (non-string, non-buffer) streams, "length" is somewhat
+// arbitrary, and perhaps not very meaningful.
+Readable.prototype._read = function (n) {
+  this.emit('error', new Error('_read() is not implemented'));
+};
+
+Readable.prototype.pipe = function (dest, pipeOpts) {
+  var src = this;
+  var state = this._readableState;
+
+  switch (state.pipesCount) {
+    case 0:
+      state.pipes = dest;
+      break;
+    case 1:
+      state.pipes = [state.pipes, dest];
+      break;
+    default:
+      state.pipes.push(dest);
+      break;
+  }
+  state.pipesCount += 1;
+  debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts);
+
+  var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr;
+
+  var endFn = doEnd ? onend : unpipe;
+  if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn);
+
+  dest.on('unpipe', onunpipe);
+  function onunpipe(readable, unpipeInfo) {
+    debug('onunpipe');
+    if (readable === src) {
+      if (unpipeInfo && unpipeInfo.hasUnpiped === false) {
+        unpipeInfo.hasUnpiped = true;
+        cleanup();
+      }
+    }
+  }
+
+  function onend() {
+    debug('onend');
+    dest.end();
+  }
+
+  // when the dest drains, it reduces the awaitDrain counter
+  // on the source. This would be more elegant with a .once()
+  // handler in flow(), but adding and removing repeatedly is
+  // too slow.
+  var ondrain = pipeOnDrain(src);
+  dest.on('drain', ondrain);
+
+  var cleanedUp = false;
+  function cleanup() {
+    debug('cleanup');
+    // cleanup event handlers once the pipe is broken
+    dest.removeListener('close', onclose);
+    dest.removeListener('finish', onfinish);
+    dest.removeListener('drain', ondrain);
+    dest.removeListener('error', onerror);
+    dest.removeListener('unpipe', onunpipe);
+    src.removeListener('end', onend);
+    src.removeListener('end', unpipe);
+    src.removeListener('data', ondata);
+
+    cleanedUp = true;
+
+    // if the reader is waiting for a drain event from this
+    // specific writer, then it would cause it to never start
+    // flowing again.
+    // So, if this is awaiting a drain, then we just call it now.
+    // If we don't know, then assume that we are waiting for one.
+    if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain();
+  }
+
+  // If the user pushes more data while we're writing to dest then we'll end
+	// up
+  // in ondata again. However, we only want to increase awaitDrain once
+	// because
+  // dest will only emit one 'drain' event for the multiple writes.
+  // => Introduce a guard on increasing awaitDrain.
+  var increasedAwaitDrain = false;
+  src.on('data', ondata);
+  function ondata(chunk) {
+    debug('ondata');
+    increasedAwaitDrain = false;
+    var ret = dest.write(chunk);
+    if (false === ret && !increasedAwaitDrain) {
+      // If the user unpiped during `dest.write()`, it is possible
+      // to get stuck in a permanently paused state if that write
+      // also returned false.
+      // => Check whether `dest` is still a piping destination.
+      if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) {
+        debug('false write response, pause', src._readableState.awaitDrain);
+        src._readableState.awaitDrain++;
+        increasedAwaitDrain = true;
+      }
+      src.pause();
+    }
+  }
+
+  // if the dest has an error, then stop piping into it.
+  // however, don't suppress the throwing behavior for this.
+  function onerror(er) {
+    debug('onerror', er);
+    unpipe();
+    dest.removeListener('error', onerror);
+    if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er);
+  }
+
+  // Make sure our error handler is attached before userland ones.
+  prependListener(dest, 'error', onerror);
+
+  // Both close and finish should trigger unpipe, but only once.
+  function onclose() {
+    dest.removeListener('finish', onfinish);
+    unpipe();
+  }
+  dest.once('close', onclose);
+  function onfinish() {
+    debug('onfinish');
+    dest.removeListener('close', onclose);
+    unpipe();
+  }
+  dest.once('finish', onfinish);
+
+  function unpipe() {
+    debug('unpipe');
+    src.unpipe(dest);
+  }
+
+  // tell the dest that it's being piped to
+  dest.emit('pipe', src);
+
+  // start the flow if it hasn't been started already.
+  if (!state.flowing) {
+    debug('pipe resume');
+    src.resume();
+  }
+
+  return dest;
+};
+
+function pipeOnDrain(src) {
+  return function () {
+    var state = src._readableState;
+    debug('pipeOnDrain', state.awaitDrain);
+    if (state.awaitDrain) state.awaitDrain--;
+    if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) {
+      state.flowing = true;
+      flow(src);
+    }
+  };
+}
+
+Readable.prototype.unpipe = function (dest) {
+  var state = this._readableState;
+  var unpipeInfo = { hasUnpiped: false };
+
+  // if we're not piping anywhere, then do nothing.
+  if (state.pipesCount === 0) return this;
+
+  // just one destination. most common case.
+  if (state.pipesCount === 1) {
+    // passed in one, but it's not the right one.
+    if (dest && dest !== state.pipes) return this;
+
+    if (!dest) dest = state.pipes;
+
+    // got a match.
+    state.pipes = null;
+    state.pipesCount = 0;
+    state.flowing = false;
+    if (dest) dest.emit('unpipe', this, unpipeInfo);
+    return this;
+  }
+
+  // slow case. multiple pipe destinations.
+
+  if (!dest) {
+    // remove all.
+    var dests = state.pipes;
+    var len = state.pipesCount;
+    state.pipes = null;
+    state.pipesCount = 0;
+    state.flowing = false;
+
+    for (var i = 0; i < len; i++) {
+      dests[i].emit('unpipe', this, unpipeInfo);
+    }return this;
+  }
+
+  // try to find the right one.
+  var index = indexOf(state.pipes, dest);
+  if (index === -1) return this;
+
+  state.pipes.splice(index, 1);
+  state.pipesCount -= 1;
+  if (state.pipesCount === 1) state.pipes = state.pipes[0];
+
+  dest.emit('unpipe', this, unpipeInfo);
+
+  return this;
+};
+
+// set up data events if they are asked for
+// Ensure readable listeners eventually get something
+Readable.prototype.on = function (ev, fn) {
+  var res = Stream.prototype.on.call(this, ev, fn);
+
+  if (ev === 'data') {
+    // Start flowing on next tick if stream isn't explicitly paused
+    if (this._readableState.flowing !== false) this.resume();
+  } else if (ev === 'readable') {
+    var state = this._readableState;
+    if (!state.endEmitted && !state.readableListening) {
+      state.readableListening = state.needReadable = true;
+      state.emittedReadable = false;
+      if (!state.reading) {
+        processNextTick(nReadingNextTick, this);
+      } else if (state.length) {
+        emitReadable(this);
+      }
+    }
+  }
+
+  return res;
+};
+Readable.prototype.addListener = Readable.prototype.on;
+
+function nReadingNextTick(self) {
+  debug('readable nexttick read 0');
+  self.read(0);
+}
+
+// pause() and resume() are remnants of the legacy readable stream API
+// If the user uses them, then switch into old mode.
+Readable.prototype.resume = function () {
+  var state = this._readableState;
+  if (!state.flowing) {
+    debug('resume');
+    state.flowing = true;
+    resume(this, state);
+  }
+  return this;
+};
+
+function resume(stream, state) {
+  if (!state.resumeScheduled) {
+    state.resumeScheduled = true;
+    processNextTick(resume_, stream, state);
+  }
+}
+
+function resume_(stream, state) {
+  if (!state.reading) {
+    debug('resume read 0');
+    stream.read(0);
+  }
+
+  state.resumeScheduled = false;
+  state.awaitDrain = 0;
+  stream.emit('resume');
+  flow(stream);
+  if (state.flowing && !state.reading) stream.read(0);
+}
+
+Readable.prototype.pause = function () {
+  debug('call pause flowing=%j', this._readableState.flowing);
+  if (false !== this._readableState.flowing) {
+    debug('pause');
+    this._readableState.flowing = false;
+    this.emit('pause');
+  }
+  return this;
+};
+
+function flow(stream) {
+  var state = stream._readableState;
+  debug('flow', state.flowing);
+  while (state.flowing && stream.read() !== null) {}
+}
+
+// wrap an old-style stream as the async data source.
+// This is *not* part of the readable stream interface.
+// It is an ugly unfortunate mess of history.
+Readable.prototype.wrap = function (stream) {
+  var state = this._readableState;
+  var paused = false;
+
+  var self = this;
+  stream.on('end', function () {
+    debug('wrapped end');
+    if (state.decoder && !state.ended) {
+      var chunk = state.decoder.end();
+      if (chunk && chunk.length) self.push(chunk);
+    }
+
+    self.push(null);
+  });
+
+  stream.on('data', function (chunk) {
+    debug('wrapped data');
+    if (state.decoder) chunk = state.decoder.write(chunk);
+
+    // don't skip over falsy values in objectMode
+    if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return;
+
+    var ret = self.push(chunk);
+    if (!ret) {
+      paused = true;
+      stream.pause();
+    }
+  });
+
+  // proxy all the other methods.
+  // important when wrapping filters and duplexes.
+  for (var i in stream) {
+    if (this[i] === undefined && typeof stream[i] === 'function') {
+      this[i] = function (method) {
+        return function () {
+          return stream[method].apply(stream, arguments);
+        };
+      }(i);
+    }
+  }
+
+  // proxy certain important events.
+  for (var n = 0; n < kProxyEvents.length; n++) {
+    stream.on(kProxyEvents[n], self.emit.bind(self, kProxyEvents[n]));
+  }
+
+  // when we try to consume some more bytes, simply unpause the
+  // underlying stream.
+  self._read = function (n) {
+    debug('wrapped _read', n);
+    if (paused) {
+      paused = false;
+      stream.resume();
+    }
+  };
+
+  return self;
+};
+
+// exposed for testing purposes only.
+Readable._fromList = fromList;
+
+// Pluck off n bytes from an array of buffers.
+// Length is the combined lengths of all the buffers in the list.
+// This function is designed to be inlinable, so please take care when making
+// changes to the function body.
+function fromList(n, state) {
+  // nothing buffered
+  if (state.length === 0) return null;
+
+  var ret;
+  if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) {
+    // read it all, truncate the list
+    if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length);
+    state.buffer.clear();
+  } else {
+    // read part of list
+    ret = fromListPartial(n, state.buffer, state.decoder);
+  }
+
+  return ret;
+}
+
+// Extracts only enough buffered data to satisfy the amount requested.
+// This function is designed to be inlinable, so please take care when making
+// changes to the function body.
+function fromListPartial(n, list, hasStrings) {
+  var ret;
+  if (n < list.head.data.length) {
+    // slice is the same for buffers and strings
+    ret = list.head.data.slice(0, n);
+    list.head.data = list.head.data.slice(n);
+  } else if (n === list.head.data.length) {
+    // first chunk is a perfect match
+    ret = list.shift();
+  } else {
+    // result spans more than one buffer
+    ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list);
+  }
+  return ret;
+}
+
+// Copies a specified amount of characters from the list of buffered data
+// chunks.
+// This function is designed to be inlinable, so please take care when making
+// changes to the function body.
+function copyFromBufferString(n, list) {
+  var p = list.head;
+  var c = 1;
+  var ret = p.data;
+  n -= ret.length;
+  while (p = p.next) {
+    var str = p.data;
+    var nb = n > str.length ? str.length : n;
+    if (nb === str.length) ret += str;else ret += str.slice(0, n);
+    n -= nb;
+    if (n === 0) {
+      if (nb === str.length) {
+        ++c;
+        if (p.next) list.head = p.next;else list.head = list.tail = null;
+      } else {
+        list.head = p;
+        p.data = str.slice(nb);
+      }
+      break;
+    }
+    ++c;
+  }
+  list.length -= c;
+  return ret;
+}
+
+// Copies a specified amount of bytes from the list of buffered data chunks.
+// This function is designed to be inlinable, so please take care when making
+// changes to the function body.
+function copyFromBuffer(n, list) {
+  var ret = Buffer.allocUnsafe(n);
+  var p = list.head;
+  var c = 1;
+  p.data.copy(ret);
+  n -= p.data.length;
+  while (p = p.next) {
+    var buf = p.data;
+    var nb = n > buf.length ? buf.length : n;
+    buf.copy(ret, ret.length - n, 0, nb);
+    n -= nb;
+    if (n === 0) {
+      if (nb === buf.length) {
+        ++c;
+        if (p.next) list.head = p.next;else list.head = list.tail = null;
+      } else {
+        list.head = p;
+        p.data = buf.slice(nb);
+      }
+      break;
+    }
+    ++c;
+  }
+  list.length -= c;
+  return ret;
+}
+
+function endReadable(stream) {
+  var state = stream._readableState;
+
+  // If we get here before consuming all the bytes, then that is a
+  // bug in node. Should never happen.
+  if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream');
+
+  if (!state.endEmitted) {
+    state.ended = true;
+    processNextTick(endReadableNT, state, stream);
+  }
+}
+
+function endReadableNT(state, stream) {
+  // Check that we didn't get one last unshift.
+  if (!state.endEmitted && state.length === 0) {
+    state.endEmitted = true;
+    stream.readable = false;
+    stream.emit('end');
+  }
+}
+
+function forEach(xs, f) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    f(xs[i], i);
+  }
+}
+
+function indexOf(xs, x) {
+  for (var i = 0, l = xs.length; i < l; i++) {
+    if (xs[i] === x) return i;
+  }
+  return -1;
+}
+}).call(this,require('_process'))
+},{"./_stream_duplex":25,"./internal/streams/BufferList":30,"./internal/streams/destroy":31,"./internal/streams/stream":32,"_process":23,"core-util-is":33,"events":19,"inherits":20,"isarray":34,"process-nextick-args":35,"safe-buffer":36,"string_decoder/":43,"util":2}],28:[function(require,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// a transform stream is a readable/writable stream where you do
+// something with the data. Sometimes it's called a "filter",
+// but that's not a great name for it, since that implies a thing where
+// some bits pass through, and others are simply ignored. (That would
+// be a valid example of a transform, of course.)
+//
+// While the output is causally related to the input, it's not a
+// necessarily symmetric or synchronous transformation. For example,
+// a zlib stream might take multiple plain-text writes(), and then
+// emit a single compressed chunk some time in the future.
+//
+// Here's how this works:
+//
+// The Transform stream has all the aspects of the readable and writable
+// stream classes. When you write(chunk), that calls _write(chunk,cb)
+// internally, and returns false if there's a lot of pending writes
+// buffered up. When you call read(), that calls _read(n) until
+// there's enough pending readable data buffered up.
+//
+// In a transform stream, the written data is placed in a buffer. When
+// _read(n) is called, it transforms the queued up data, calling the
+// buffered _write cb's as it consumes chunks. If consuming a single
+// written chunk would result in multiple output chunks, then the first
+// outputted bit calls the readcb, and subsequent chunks just go into
+// the read buffer, and will cause it to emit 'readable' if necessary.
+//
+// This way, back-pressure is actually determined by the reading side,
+// since _read has to be called to start processing a new chunk. However,
+// a pathological inflate type of transform can cause excessive buffering
+// here. For example, imagine a stream where every byte of input is
+// interpreted as an integer from 0-255, and then results in that many
+// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in
+// 1kb of data being output. In this case, you could write a very small
+// amount of input, and end up with a very large amount of output. In
+// such a pathological inflating mechanism, there'd be no way to tell
+// the system to stop doing the transform. A single 4MB write could
+// cause the system to run out of memory.
+//
+// However, even in such a pathological case, only a single written chunk
+// would be consumed, and then the rest would wait (un-transformed) until
+// the results of the previous transformed chunk were consumed.
+
+'use strict';
+
+module.exports = Transform;
+
+var Duplex = require('./_stream_duplex');
+
+/* <replacement> */
+var util = require('core-util-is');
+util.inherits = require('inherits');
+/* </replacement> */
+
+util.inherits(Transform, Duplex);
+
+function TransformState(stream) {
+  this.afterTransform = function (er, data) {
+    return afterTransform(stream, er, data);
+  };
+
+  this.needTransform = false;
+  this.transforming = false;
+  this.writecb = null;
+  this.writechunk = null;
+  this.writeencoding = null;
+}
+
+function afterTransform(stream, er, data) {
+  var ts = stream._transformState;
+  ts.transforming = false;
+
+  var cb = ts.writecb;
+
+  if (!cb) {
+    return stream.emit('error', new Error('write callback called multiple times'));
+  }
+
+  ts.writechunk = null;
+  ts.writecb = null;
+
+  if (data !== null && data !== undefined) stream.push(data);
+
+  cb(er);
+
+  var rs = stream._readableState;
+  rs.reading = false;
+  if (rs.needReadable || rs.length < rs.highWaterMark) {
+    stream._read(rs.highWaterMark);
+  }
+}
+
+function Transform(options) {
+  if (!(this instanceof Transform)) return new Transform(options);
+
+  Duplex.call(this, options);
+
+  this._transformState = new TransformState(this);
+
+  var stream = this;
+
+  // start out asking for a readable event once data is transformed.
+  this._readableState.needReadable = true;
+
+  // we have implemented the _read method, and done the other things
+  // that Readable wants before the first _read call, so unset the
+  // sync guard flag.
+  this._readableState.sync = false;
+
+  if (options) {
+    if (typeof options.transform === 'function') this._transform = options.transform;
+
+    if (typeof options.flush === 'function') this._flush = options.flush;
+  }
+
+  // When the writable side finishes, then flush out anything remaining.
+  this.once('prefinish', function () {
+    if (typeof this._flush === 'function') this._flush(function (er, data) {
+      done(stream, er, data);
+    });else done(stream);
+  });
+}
+
+Transform.prototype.push = function (chunk, encoding) {
+  this._transformState.needTransform = false;
+  return Duplex.prototype.push.call(this, chunk, encoding);
+};
+
+// This is the part where you do stuff!
+// override this function in implementation classes.
+// 'chunk' is an input chunk.
+//
+// Call `push(newChunk)` to pass along transformed output
+// to the readable side. You may call 'push' zero or more times.
+//
+// Call `cb(err)` when you are done with this chunk. If you pass
+// an error, then that'll put the hurt on the whole operation. If you
+// never call cb(), then you'll never get another chunk.
+Transform.prototype._transform = function (chunk, encoding, cb) {
+  throw new Error('_transform() is not implemented');
+};
+
+Transform.prototype._write = function (chunk, encoding, cb) {
+  var ts = this._transformState;
+  ts.writecb = cb;
+  ts.writechunk = chunk;
+  ts.writeencoding = encoding;
+  if (!ts.transforming) {
+    var rs = this._readableState;
+    if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark);
+  }
+};
+
+// Doesn't matter what the args are here.
+// _transform does all the work.
+// That we got here means that the readable side wants more data.
+Transform.prototype._read = function (n) {
+  var ts = this._transformState;
+
+  if (ts.writechunk !== null && ts.writecb && !ts.transforming) {
+    ts.transforming = true;
+    this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform);
+  } else {
+    // mark that we need a transform, so that any data that comes in
+    // will get processed, now that we've asked for it.
+    ts.needTransform = true;
+  }
+};
+
+Transform.prototype._destroy = function (err, cb) {
+  var _this = this;
+
+  Duplex.prototype._destroy.call(this, err, function (err2) {
+    cb(err2);
+    _this.emit('close');
+  });
+};
+
+function done(stream, er, data) {
+  if (er) return stream.emit('error', er);
+
+  if (data !== null && data !== undefined) stream.push(data);
+
+  // if there's nothing in the write buffer, then that means
+  // that nothing more will ever be provided
+  var ws = stream._writableState;
+  var ts = stream._transformState;
+
+  if (ws.length) throw new Error('Calling transform done when ws.length != 0');
+
+  if (ts.transforming) throw new Error('Calling transform done when still transforming');
+
+  return stream.push(null);
+}
+},{"./_stream_duplex":25,"core-util-is":33,"inherits":20}],29:[function(require,module,exports){
+(function (process){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// A bit simpler than readable streams.
+// Implement an async ._write(chunk, encoding, cb), and it'll handle all
+// the drain event emission and buffering.
+
+'use strict';
+
+/* <replacement> */
+
+var processNextTick = require('process-nextick-args');
+/* </replacement> */
+
+module.exports = Writable;
+
+/* <replacement> */
+function WriteReq(chunk, encoding, cb) {
+  this.chunk = chunk;
+  this.encoding = encoding;
+  this.callback = cb;
+  this.next = null;
+}
+
+// It seems a linked list but it is not
+// there will be only 2 of these for each stream
+function CorkedRequest(state) {
+  var _this = this;
+
+  this.next = null;
+  this.entry = null;
+  this.finish = function () {
+    onCorkedFinish(_this, state);
+  };
+}
+/* </replacement> */
+
+/* <replacement> */
+var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick;
+/* </replacement> */
+
+/* <replacement> */
+var Duplex;
+/* </replacement> */
+
+Writable.WritableState = WritableState;
+
+/* <replacement> */
+var util = require('core-util-is');
+util.inherits = require('inherits');
+/* </replacement> */
+
+/* <replacement> */
+var internalUtil = {
+  deprecate: require('util-deprecate')
+};
+/* </replacement> */
+
+/* <replacement> */
+var Stream = require('./internal/streams/stream');
+/* </replacement> */
+
+/* <replacement> */
+var Buffer = require('safe-buffer').Buffer;
+function _uint8ArrayToBuffer(chunk) {
+  return Buffer.from(chunk);
+}
+function _isUint8Array(obj) {
+  return Object.prototype.toString.call(obj) === '[object Uint8Array]' || Buffer.isBuffer(obj);
+}
+/* </replacement> */
+
+var destroyImpl = require('./internal/streams/destroy');
+
+util.inherits(Writable, Stream);
+
+function nop() {}
+
+function WritableState(options, stream) {
+  Duplex = Duplex || require('./_stream_duplex');
+
+  options = options || {};
+
+  // object stream flag to indicate whether or not this stream
+  // contains buffers or objects.
+  this.objectMode = !!options.objectMode;
+
+  if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode;
+
+  // the point at which write() starts returning false
+  // Note: 0 is a valid value, means that we always return false if
+  // the entire buffer is not flushed immediately on write()
+  var hwm = options.highWaterMark;
+  var defaultHwm = this.objectMode ? 16 : 16 * 1024;
+  this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm;
+
+  // cast to ints.
+  this.highWaterMark = Math.floor(this.highWaterMark);
+
+  // if _final has been called
+  this.finalCalled = false;
+
+  // drain event flag.
+  this.needDrain = false;
+  // at the start of calling end()
+  this.ending = false;
+  // when end() has been called, and returned
+  this.ended = false;
+  // when 'finish' is emitted
+  this.finished = false;
+
+  // has it been destroyed
+  this.destroyed = false;
+
+  // should we decode strings into buffers before passing to _write?
+  // this is here so that some node-core streams can optimize string
+  // handling at a lower level.
+  var noDecode = options.decodeStrings === false;
+  this.decodeStrings = !noDecode;
+
+  // Crypto is kind of old and crusty. Historically, its default string
+  // encoding is 'binary' so we have to make this configurable.
+  // Everything else in the universe uses 'utf8', though.
+  this.defaultEncoding = options.defaultEncoding || 'utf8';
+
+  // not an actual buffer we keep track of, but a measurement
+  // of how much we're waiting to get pushed to some underlying
+  // socket or file.
+  this.length = 0;
+
+  // a flag to see when we're in the middle of a write.
+  this.writing = false;
+
+  // when true all writes will be buffered until .uncork() call
+  this.corked = 0;
+
+  // a flag to be able to tell if the onwrite cb is called immediately,
+  // or on a later tick. We set this to true at first, because any
+  // actions that shouldn't happen until "later" should generally also
+  // not happen before the first write call.
+  this.sync = true;
+
+  // a flag to know if we're processing previously buffered items, which
+  // may call the _write() callback in the same tick, so that we don't
+  // end up in an overlapped onwrite situation.
+  this.bufferProcessing = false;
+
+  // the callback that's passed to _write(chunk,cb)
+  this.onwrite = function (er) {
+    onwrite(stream, er);
+  };
+
+  // the callback that the user supplies to write(chunk,encoding,cb)
+  this.writecb = null;
+
+  // the amount that is being written when _write is called.
+  this.writelen = 0;
+
+  this.bufferedRequest = null;
+  this.lastBufferedRequest = null;
+
+  // number of pending user-supplied write callbacks
+  // this must be 0 before 'finish' can be emitted
+  this.pendingcb = 0;
+
+  // emit prefinish if the only thing we're waiting for is _write cbs
+  // This is relevant for synchronous Transform streams
+  this.prefinished = false;
+
+  // True if the error was already emitted and should not be thrown again
+  this.errorEmitted = false;
+
+  // count buffered requests
+  this.bufferedRequestCount = 0;
+
+  // allocate the first CorkedRequest, there is always
+  // one allocated and free to use, and we maintain at most two
+  this.corkedRequestsFree = new CorkedRequest(this);
+}
+
+WritableState.prototype.getBuffer = function getBuffer() {
+  var current = this.bufferedRequest;
+  var out = [];
+  while (current) {
+    out.push(current);
+    current = current.next;
+  }
+  return out;
+};
+
+(function () {
+  try {
+    Object.defineProperty(WritableState.prototype, 'buffer', {
+      get: internalUtil.deprecate(function () {
+        return this.getBuffer();
+      }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003')
+    });
+  } catch (_) {}
+})();
+
+// Test _writableState for inheritance to account for Duplex streams,
+// whose prototype chain only points to Readable.
+var realHasInstance;
+if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') {
+  realHasInstance = Function.prototype[Symbol.hasInstance];
+  Object.defineProperty(Writable, Symbol.hasInstance, {
+    value: function (object) {
+      if (realHasInstance.call(this, object)) return true;
+
+      return object && object._writableState instanceof WritableState;
+    }
+  });
+} else {
+  realHasInstance = function (object) {
+    return object instanceof this;
+  };
+}
+
+function Writable(options) {
+  Duplex = Duplex || require('./_stream_duplex');
+
+  // Writable ctor is applied to Duplexes, too.
+  // `realHasInstance` is necessary because using plain `instanceof`
+  // would return false, as no `_writableState` property is attached.
+
+  // Trying to use the custom `instanceof` for Writable here will also break
+	// the
+  // Node.js LazyTransform implementation, which has a non-trivial getter for
+  // `_writableState` that would lead to infinite recursion.
+  if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) {
+    return new Writable(options);
+  }
+
+  this._writableState = new WritableState(options, this);
+
+  // legacy.
+  this.writable = true;
+
+  if (options) {
+    if (typeof options.write === 'function') this._write = options.write;
+
+    if (typeof options.writev === 'function') this._writev = options.writev;
+
+    if (typeof options.destroy === 'function') this._destroy = options.destroy;
+
+    if (typeof options.final === 'function') this._final = options.final;
+  }
+
+  Stream.call(this);
+}
+
+// Otherwise people can pipe Writable streams, which is just wrong.
+Writable.prototype.pipe = function () {
+  this.emit('error', new Error('Cannot pipe, not readable'));
+};
+
+function writeAfterEnd(stream, cb) {
+  var er = new Error('write after end');
+  // TODO: defer error events consistently everywhere, not just the cb
+  stream.emit('error', er);
+  processNextTick(cb, er);
+}
+
+// Checks that a user-supplied chunk is valid, especially for the particular
+// mode the stream is in. Currently this means that `null` is never accepted
+// and undefined/non-string values are only allowed in object mode.
+function validChunk(stream, state, chunk, cb) {
+  var valid = true;
+  var er = false;
+
+  if (chunk === null) {
+    er = new TypeError('May not write null values to stream');
+  } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) {
+    er = new TypeError('Invalid non-string/buffer chunk');
+  }
+  if (er) {
+    stream.emit('error', er);
+    processNextTick(cb, er);
+    valid = false;
+  }
+  return valid;
+}
+
+Writable.prototype.write = function (chunk, encoding, cb) {
+  var state = this._writableState;
+  var ret = false;
+  var isBuf = _isUint8Array(chunk) && !state.objectMode;
+
+  if (isBuf && !Buffer.isBuffer(chunk)) {
+    chunk = _uint8ArrayToBuffer(chunk);
+  }
+
+  if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding;
+
+  if (typeof cb !== 'function') cb = nop;
+
+  if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) {
+    state.pendingcb++;
+    ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb);
+  }
+
+  return ret;
+};
+
+Writable.prototype.cork = function () {
+  var state = this._writableState;
+
+  state.corked++;
+};
+
+Writable.prototype.uncork = function () {
+  var state = this._writableState;
+
+  if (state.corked) {
+    state.corked--;
+
+    if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state);
+  }
+};
+
+Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) {
+  // node::ParseEncoding() requires lower case.
+  if (typeof encoding === 'string') encoding = encoding.toLowerCase();
+  if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding);
+  this._writableState.defaultEncoding = encoding;
+  return this;
+};
+
+function decodeChunk(state, chunk, encoding) {
+  if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') {
+    chunk = Buffer.from(chunk, encoding);
+  }
+  return chunk;
+}
+
+// if we're already writing something, then just put this
+// in the queue, and wait our turn. Otherwise, call _write
+// If we return false, then we need a drain event, so set that flag.
+function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) {
+  if (!isBuf) {
+    var newChunk = decodeChunk(state, chunk, encoding);
+    if (chunk !== newChunk) {
+      isBuf = true;
+      encoding = 'buffer';
+      chunk = newChunk;
+    }
+  }
+  var len = state.objectMode ? 1 : chunk.length;
+
+  state.length += len;
+
+  var ret = state.length < state.highWaterMark;
+  // we must ensure that previous needDrain will not be reset to false.
+  if (!ret) state.needDrain = true;
+
+  if (state.writing || state.corked) {
+    var last = state.lastBufferedRequest;
+    state.lastBufferedRequest = {
+      chunk: chunk,
+      encoding: encoding,
+      isBuf: isBuf,
+      callback: cb,
+      next: null
+    };
+    if (last) {
+      last.next = state.lastBufferedRequest;
+    } else {
+      state.bufferedRequest = state.lastBufferedRequest;
+    }
+    state.bufferedRequestCount += 1;
+  } else {
+    doWrite(stream, state, false, len, chunk, encoding, cb);
+  }
+
+  return ret;
+}
+
+function doWrite(stream, state, writev, len, chunk, encoding, cb) {
+  state.writelen = len;
+  state.writecb = cb;
+  state.writing = true;
+  state.sync = true;
+  if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite);
+  state.sync = false;
+}
+
+function onwriteError(stream, state, sync, er, cb) {
+  --state.pendingcb;
+
+  if (sync) {
+    // defer the callback if we are being called synchronously
+    // to avoid piling up things on the stack
+    processNextTick(cb, er);
+    // this can emit finish, and it will always happen
+    // after error
+    processNextTick(finishMaybe, stream, state);
+    stream._writableState.errorEmitted = true;
+    stream.emit('error', er);
+  } else {
+    // the caller expect this to happen before if
+    // it is async
+    cb(er);
+    stream._writableState.errorEmitted = true;
+    stream.emit('error', er);
+    // this can emit finish, but finish must
+    // always follow error
+    finishMaybe(stream, state);
+  }
+}
+
+function onwriteStateUpdate(state) {
+  state.writing = false;
+  state.writecb = null;
+  state.length -= state.writelen;
+  state.writelen = 0;
+}
+
+function onwrite(stream, er) {
+  var state = stream._writableState;
+  var sync = state.sync;
+  var cb = state.writecb;
+
+  onwriteStateUpdate(state);
+
+  if (er) onwriteError(stream, state, sync, er, cb);else {
+    // Check if we're actually ready to finish, but don't emit yet
+    var finished = needFinish(state);
+
+    if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) {
+      clearBuffer(stream, state);
+    }
+
+    if (sync) {
+      /* <replacement> */
+      asyncWrite(afterWrite, stream, state, finished, cb);
+      /* </replacement> */
+    } else {
+      afterWrite(stream, state, finished, cb);
+    }
+  }
+}
+
+function afterWrite(stream, state, finished, cb) {
+  if (!finished) onwriteDrain(stream, state);
+  state.pendingcb--;
+  cb();
+  finishMaybe(stream, state);
+}
+
+// Must force callback to be called on nextTick, so that we don't
+// emit 'drain' before the write() consumer gets the 'false' return
+// value, and has a chance to attach a 'drain' listener.
+function onwriteDrain(stream, state) {
+  if (state.length === 0 && state.needDrain) {
+    state.needDrain = false;
+    stream.emit('drain');
+  }
+}
+
+// if there's something in the buffer waiting, then process it
+function clearBuffer(stream, state) {
+  state.bufferProcessing = true;
+  var entry = state.bufferedRequest;
+
+  if (stream._writev && entry && entry.next) {
+    // Fast case, write everything using _writev()
+    var l = state.bufferedRequestCount;
+    var buffer = new Array(l);
+    var holder = state.corkedRequestsFree;
+    holder.entry = entry;
+
+    var count = 0;
+    var allBuffers = true;
+    while (entry) {
+      buffer[count] = entry;
+      if (!entry.isBuf) allBuffers = false;
+      entry = entry.next;
+      count += 1;
+    }
+    buffer.allBuffers = allBuffers;
+
+    doWrite(stream, state, true, state.length, buffer, '', holder.finish);
+
+    // doWrite is almost always async, defer these to save a bit of time
+    // as the hot path ends with doWrite
+    state.pendingcb++;
+    state.lastBufferedRequest = null;
+    if (holder.next) {
+      state.corkedRequestsFree = holder.next;
+      holder.next = null;
+    } else {
+      state.corkedRequestsFree = new CorkedRequest(state);
+    }
+  } else {
+    // Slow case, write chunks one-by-one
+    while (entry) {
+      var chunk = entry.chunk;
+      var encoding = entry.encoding;
+      var cb = entry.callback;
+      var len = state.objectMode ? 1 : chunk.length;
+
+      doWrite(stream, state, false, len, chunk, encoding, cb);
+      entry = entry.next;
+      // if we didn't call the onwrite immediately, then
+      // it means that we need to wait until it does.
+      // also, that means that the chunk and cb are currently
+      // being processed, so move the buffer counter past them.
+      if (state.writing) {
+        break;
+      }
+    }
+
+    if (entry === null) state.lastBufferedRequest = null;
+  }
+
+  state.bufferedRequestCount = 0;
+  state.bufferedRequest = entry;
+  state.bufferProcessing = false;
+}
+
+Writable.prototype._write = function (chunk, encoding, cb) {
+  cb(new Error('_write() is not implemented'));
+};
+
+Writable.prototype._writev = null;
+
+Writable.prototype.end = function (chunk, encoding, cb) {
+  var state = this._writableState;
+
+  if (typeof chunk === 'function') {
+    cb = chunk;
+    chunk = null;
+    encoding = null;
+  } else if (typeof encoding === 'function') {
+    cb = encoding;
+    encoding = null;
+  }
+
+  if (chunk !== null && chunk !== undefined) this.write(chunk, encoding);
+
+  // .end() fully uncorks
+  if (state.corked) {
+    state.corked = 1;
+    this.uncork();
+  }
+
+  // ignore unnecessary end() calls.
+  if (!state.ending && !state.finished) endWritable(this, state, cb);
+};
+
+function needFinish(state) {
+  return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing;
+}
+function callFinal(stream, state) {
+  stream._final(function (err) {
+    state.pendingcb--;
+    if (err) {
+      stream.emit('error', err);
+    }
+    state.prefinished = true;
+    stream.emit('prefinish');
+    finishMaybe(stream, state);
+  });
+}
+function prefinish(stream, state) {
+  if (!state.prefinished && !state.finalCalled) {
+    if (typeof stream._final === 'function') {
+      state.pendingcb++;
+      state.finalCalled = true;
+      processNextTick(callFinal, stream, state);
+    } else {
+      state.prefinished = true;
+      stream.emit('prefinish');
+    }
+  }
+}
+
+function finishMaybe(stream, state) {
+  var need = needFinish(state);
+  if (need) {
+    prefinish(stream, state);
+    if (state.pendingcb === 0) {
+      state.finished = true;
+      stream.emit('finish');
+    }
+  }
+  return need;
+}
+
+function endWritable(stream, state, cb) {
+  state.ending = true;
+  finishMaybe(stream, state);
+  if (cb) {
+    if (state.finished) processNextTick(cb);else stream.once('finish', cb);
+  }
+  state.ended = true;
+  stream.writable = false;
+}
+
+function onCorkedFinish(corkReq, state, err) {
+  var entry = corkReq.entry;
+  corkReq.entry = null;
+  while (entry) {
+    var cb = entry.callback;
+    state.pendingcb--;
+    cb(err);
+    entry = entry.next;
+  }
+  if (state.corkedRequestsFree) {
+    state.corkedRequestsFree.next = corkReq;
+  } else {
+    state.corkedRequestsFree = corkReq;
+  }
+}
+
+Object.defineProperty(Writable.prototype, 'destroyed', {
+  get: function () {
+    if (this._writableState === undefined) {
+      return false;
+    }
+    return this._writableState.destroyed;
+  },
+  set: function (value) {
+    // we ignore the value if the stream
+    // has not been initialized yet
+    if (!this._writableState) {
+      return;
+    }
+
+    // backward compatibility, the user is explicitly
+    // managing destroyed
+    this._writableState.destroyed = value;
+  }
+});
+
+Writable.prototype.destroy = destroyImpl.destroy;
+Writable.prototype._undestroy = destroyImpl.undestroy;
+Writable.prototype._destroy = function (err, cb) {
+  this.end();
+  cb(err);
+};
+
+}).call(this,require('_process'))
+},{"./_stream_duplex":25,"./internal/streams/destroy":31,"./internal/streams/stream":32,"_process":23,"core-util-is":33,"inherits":20,"process-nextick-args":35,"safe-buffer":36,"util-deprecate":37}],30:[function(require,module,exports){
+'use strict';
+
+/* <replacement> */
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Buffer = require('safe-buffer').Buffer;
+/* </replacement> */
+
+function copyBuffer(src, target, offset) {
+  src.copy(target, offset);
+}
+
+module.exports = function () {
+  function BufferList() {
+    _classCallCheck(this, BufferList);
+
+    this.head = null;
+    this.tail = null;
+    this.length = 0;
+  }
+
+  BufferList.prototype.push = function push(v) {
+    var entry = { data: v, next: null };
+    if (this.length > 0) this.tail.next = entry;else this.head = entry;
+    this.tail = entry;
+    ++this.length;
+  };
+
+  BufferList.prototype.unshift = function unshift(v) {
+    var entry = { data: v, next: this.head };
+    if (this.length === 0) this.tail = entry;
+    this.head = entry;
+    ++this.length;
+  };
+
+  BufferList.prototype.shift = function shift() {
+    if (this.length === 0) return;
+    var ret = this.head.data;
+    if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next;
+    --this.length;
+    return ret;
+  };
+
+  BufferList.prototype.clear = function clear() {
+    this.head = this.tail = null;
+    this.length = 0;
+  };
+
+  BufferList.prototype.join = function join(s) {
+    if (this.length === 0) return '';
+    var p = this.head;
+    var ret = '' + p.data;
+    while (p = p.next) {
+      ret += s + p.data;
+    }return ret;
+  };
+
+  BufferList.prototype.concat = function concat(n) {
+    if (this.length === 0) return Buffer.alloc(0);
+    if (this.length === 1) return this.head.data;
+    var ret = Buffer.allocUnsafe(n >>> 0);
+    var p = this.head;
+    var i = 0;
+    while (p) {
+      copyBuffer(p.data, ret, i);
+      i += p.data.length;
+      p = p.next;
+    }
+    return ret;
+  };
+
+  return BufferList;
+}();
+},{"safe-buffer":36}],31:[function(require,module,exports){
+'use strict';
+
+/* <replacement> */
+
+var processNextTick = require('process-nextick-args');
+/* </replacement> */
+
+// undocumented cb() API, needed for core, not for public API
+function destroy(err, cb) {
+  var _this = this;
+
+  var readableDestroyed = this._readableState && this._readableState.destroyed;
+  var writableDestroyed = this._writableState && this._writableState.destroyed;
+
+  if (readableDestroyed || writableDestroyed) {
+    if (cb) {
+      cb(err);
+    } else if (err && (!this._writableState || !this._writableState.errorEmitted)) {
+      processNextTick(emitErrorNT, this, err);
+    }
+    return;
+  }
+
+  // we set destroyed to true before firing error callbacks in order
+  // to make it re-entrance safe in case destroy() is called within callbacks
+
+  if (this._readableState) {
+    this._readableState.destroyed = true;
+  }
+
+  // if this is a duplex stream mark the writable part as destroyed as well
+  if (this._writableState) {
+    this._writableState.destroyed = true;
+  }
+
+  this._destroy(err || null, function (err) {
+    if (!cb && err) {
+      processNextTick(emitErrorNT, _this, err);
+      if (_this._writableState) {
+        _this._writableState.errorEmitted = true;
+      }
+    } else if (cb) {
+      cb(err);
+    }
+  });
+}
+
+function undestroy() {
+  if (this._readableState) {
+    this._readableState.destroyed = false;
+    this._readableState.reading = false;
+    this._readableState.ended = false;
+    this._readableState.endEmitted = false;
+  }
+
+  if (this._writableState) {
+    this._writableState.destroyed = false;
+    this._writableState.ended = false;
+    this._writableState.ending = false;
+    this._writableState.finished = false;
+    this._writableState.errorEmitted = false;
+  }
+}
+
+function emitErrorNT(self, err) {
+  self.emit('error', err);
+}
+
+module.exports = {
+  destroy: destroy,
+  undestroy: undestroy
+};
+},{"process-nextick-args":35}],32:[function(require,module,exports){
+module.exports = require('events').EventEmitter;
+
+},{"events":19}],33:[function(require,module,exports){
+(function (Buffer){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// NOTE: These type checking functions intentionally don't use `instanceof`
+// because it is fragile and can be easily faked with `Object.create()`.
+
+function isArray(arg) {
+  if (Array.isArray) {
+    return Array.isArray(arg);
+  }
+  return objectToString(arg) === '[object Array]';
+}
+exports.isArray = isArray;
+
+function isBoolean(arg) {
+  return typeof arg === 'boolean';
+}
+exports.isBoolean = isBoolean;
+
+function isNull(arg) {
+  return arg === null;
+}
+exports.isNull = isNull;
+
+function isNullOrUndefined(arg) {
+  return arg == null;
+}
+exports.isNullOrUndefined = isNullOrUndefined;
+
+function isNumber(arg) {
+  return typeof arg === 'number';
+}
+exports.isNumber = isNumber;
+
+function isString(arg) {
+  return typeof arg === 'string';
+}
+exports.isString = isString;
+
+function isSymbol(arg) {
+  return typeof arg === 'symbol';
+}
+exports.isSymbol = isSymbol;
+
+function isUndefined(arg) {
+  return arg === void 0;
+}
+exports.isUndefined = isUndefined;
+
+function isRegExp(re) {
+  return objectToString(re) === '[object RegExp]';
+}
+exports.isRegExp = isRegExp;
+
+function isObject(arg) {
+  return typeof arg === 'object' && arg !== null;
+}
+exports.isObject = isObject;
+
+function isDate(d) {
+  return objectToString(d) === '[object Date]';
+}
+exports.isDate = isDate;
+
+function isError(e) {
+  return (objectToString(e) === '[object Error]' || e instanceof Error);
+}
+exports.isError = isError;
+
+function isFunction(arg) {
+  return typeof arg === 'function';
+}
+exports.isFunction = isFunction;
+
+function isPrimitive(arg) {
+  return arg === null ||
+         typeof arg === 'boolean' ||
+         typeof arg === 'number' ||
+         typeof arg === 'string' ||
+         typeof arg === 'symbol' ||  // ES6 symbol
+         typeof arg === 'undefined';
+}
+exports.isPrimitive = isPrimitive;
+
+exports.isBuffer = Buffer.isBuffer;
+
+function objectToString(o) {
+  return Object.prototype.toString.call(o);
+}
+
+}).call(this,{"isBuffer":require("../../../../insert-module-globals/node_modules/is-buffer/index.js")})
+},{"../../../../insert-module-globals/node_modules/is-buffer/index.js":21}],34:[function(require,module,exports){
+var toString = {}.toString;
+
+module.exports = Array.isArray || function (arr) {
+  return toString.call(arr) == '[object Array]';
+};
+
+},{}],35:[function(require,module,exports){
+(function (process){
+'use strict';
+
+if (!process.version ||
+    process.version.indexOf('v0.') === 0 ||
+    process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) {
+  module.exports = nextTick;
+} else {
+  module.exports = process.nextTick;
+}
+
+function nextTick(fn, arg1, arg2, arg3) {
+  if (typeof fn !== 'function') {
+    throw new TypeError('"callback" argument must be a function');
+  }
+  var len = arguments.length;
+  var args, i;
+  switch (len) {
+  case 0:
+  case 1:
+    return process.nextTick(fn);
+  case 2:
+    return process.nextTick(function afterTickOne() {
+      fn.call(null, arg1);
+    });
+  case 3:
+    return process.nextTick(function afterTickTwo() {
+      fn.call(null, arg1, arg2);
+    });
+  case 4:
+    return process.nextTick(function afterTickThree() {
+      fn.call(null, arg1, arg2, arg3);
+    });
+  default:
+    args = new Array(len - 1);
+    i = 0;
+    while (i < args.length) {
+      args[i++] = arguments[i];
+    }
+    return process.nextTick(function afterTick() {
+      fn.apply(null, args);
+    });
+  }
+}
+
+}).call(this,require('_process'))
+},{"_process":23}],36:[function(require,module,exports){
+/* eslint-disable node/no-deprecated-api */
+var buffer = require('buffer')
+var Buffer = buffer.Buffer
+
+// alternative to using Object.keys for old browsers
+function copyProps (src, dst) {
+  for (var key in src) {
+    dst[key] = src[key]
+  }
+}
+if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
+  module.exports = buffer
+} else {
+  // Copy properties from require('buffer')
+  copyProps(buffer, exports)
+  exports.Buffer = SafeBuffer
+}
+
+function SafeBuffer (arg, encodingOrOffset, length) {
+  return Buffer(arg, encodingOrOffset, length)
+}
+
+// Copy static methods from Buffer
+copyProps(Buffer, SafeBuffer)
+
+SafeBuffer.from = function (arg, encodingOrOffset, length) {
+  if (typeof arg === 'number') {
+    throw new TypeError('Argument must not be a number')
+  }
+  return Buffer(arg, encodingOrOffset, length)
+}
+
+SafeBuffer.alloc = function (size, fill, encoding) {
+  if (typeof size !== 'number') {
+    throw new TypeError('Argument must be a number')
+  }
+  var buf = Buffer(size)
+  if (fill !== undefined) {
+    if (typeof encoding === 'string') {
+      buf.fill(fill, encoding)
+    } else {
+      buf.fill(fill)
+    }
+  } else {
+    buf.fill(0)
+  }
+  return buf
+}
+
+SafeBuffer.allocUnsafe = function (size) {
+  if (typeof size !== 'number') {
+    throw new TypeError('Argument must be a number')
+  }
+  return Buffer(size)
+}
+
+SafeBuffer.allocUnsafeSlow = function (size) {
+  if (typeof size !== 'number') {
+    throw new TypeError('Argument must be a number')
+  }
+  return buffer.SlowBuffer(size)
+}
+
+},{"buffer":16}],37:[function(require,module,exports){
+(function (global){
+
+/**
+ * Module exports.
+ */
+
+module.exports = deprecate;
+
+/**
+ * Mark that a method should not be used. Returns a modified function which
+ * warns once by default.
+ * 
+ * If `localStorage.noDeprecation = true` is set, then it is a no-op.
+ * 
+ * If `localStorage.throwDeprecation = true` is set, then deprecated functions
+ * will throw an Error when invoked.
+ * 
+ * If `localStorage.traceDeprecation = true` is set, then deprecated functions
+ * will invoke `console.trace()` instead of `console.error()`.
+ * 
+ * @param {Function}
+ *            fn - the function to deprecate
+ * @param {String}
+ *            msg - the string to print to the console when `fn` is invoked
+ * @returns {Function} a new "deprecated" version of `fn`
+ * @api public
+ */
+
+function deprecate (fn, msg) {
+  if (config('noDeprecation')) {
+    return fn;
+  }
+
+  var warned = false;
+  function deprecated() {
+    if (!warned) {
+      if (config('throwDeprecation')) {
+        throw new Error(msg);
+      } else if (config('traceDeprecation')) {
+        console.trace(msg);
+      } else {
+        console.warn(msg);
+      }
+      warned = true;
+    }
+    return fn.apply(this, arguments);
+  }
+
+  return deprecated;
+}
+
+/**
+ * Checks `localStorage` for boolean values for the given `name`.
+ * 
+ * @param {String}
+ *            name
+ * @returns {Boolean}
+ * @api private
+ */
+
+function config (name) {
+  // accessing global.localStorage can trigger a DOMException in sandboxed
+	// iframes
+  try {
+    if (!global.localStorage) return false;
+  } catch (_) {
+    return false;
+  }
+  var val = global.localStorage[name];
+  if (null == val) return false;
+  return String(val).toLowerCase() === 'true';
+}
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{}],38:[function(require,module,exports){
+module.exports = require('./readable').PassThrough
+
+},{"./readable":39}],39:[function(require,module,exports){
+exports = module.exports = require('./lib/_stream_readable.js');
+exports.Stream = exports;
+exports.Readable = exports;
+exports.Writable = require('./lib/_stream_writable.js');
+exports.Duplex = require('./lib/_stream_duplex.js');
+exports.Transform = require('./lib/_stream_transform.js');
+exports.PassThrough = require('./lib/_stream_passthrough.js');
+
+},{"./lib/_stream_duplex.js":25,"./lib/_stream_passthrough.js":26,"./lib/_stream_readable.js":27,"./lib/_stream_transform.js":28,"./lib/_stream_writable.js":29}],40:[function(require,module,exports){
+module.exports = require('./readable').Transform
+
+},{"./readable":39}],41:[function(require,module,exports){
+module.exports = require('./lib/_stream_writable.js');
+
+},{"./lib/_stream_writable.js":29}],42:[function(require,module,exports){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+module.exports = Stream;
+
+var EE = require('events').EventEmitter;
+var inherits = require('inherits');
+
+inherits(Stream, EE);
+Stream.Readable = require('readable-stream/readable.js');
+Stream.Writable = require('readable-stream/writable.js');
+Stream.Duplex = require('readable-stream/duplex.js');
+Stream.Transform = require('readable-stream/transform.js');
+Stream.PassThrough = require('readable-stream/passthrough.js');
+
+// Backwards-compat with node 0.4.x
+Stream.Stream = Stream;
+
+
+
+// old-style streams. Note that the pipe method (the only relevant
+// part of this class) is overridden in the Readable class.
+
+function Stream() {
+  EE.call(this);
+}
+
+Stream.prototype.pipe = function(dest, options) {
+  var source = this;
+
+  function ondata(chunk) {
+    if (dest.writable) {
+      if (false === dest.write(chunk) && source.pause) {
+        source.pause();
+      }
+    }
+  }
+
+  source.on('data', ondata);
+
+  function ondrain() {
+    if (source.readable && source.resume) {
+      source.resume();
+    }
+  }
+
+  dest.on('drain', ondrain);
+
+  // If the 'end' option is not supplied, dest.end() will be called when
+  // source gets the 'end' or 'close' events. Only dest.end() once.
+  if (!dest._isStdio && (!options || options.end !== false)) {
+    source.on('end', onend);
+    source.on('close', onclose);
+  }
+
+  var didOnEnd = false;
+  function onend() {
+    if (didOnEnd) return;
+    didOnEnd = true;
+
+    dest.end();
+  }
+
+
+  function onclose() {
+    if (didOnEnd) return;
+    didOnEnd = true;
+
+    if (typeof dest.destroy === 'function') dest.destroy();
+  }
+
+  // don't leave dangling pipes when there are errors.
+  function onerror(er) {
+    cleanup();
+    if (EE.listenerCount(this, 'error') === 0) {
+      throw er; // Unhandled stream error in pipe.
+    }
+  }
+
+  source.on('error', onerror);
+  dest.on('error', onerror);
+
+  // remove all the event listeners that were added.
+  function cleanup() {
+    source.removeListener('data', ondata);
+    dest.removeListener('drain', ondrain);
+
+    source.removeListener('end', onend);
+    source.removeListener('close', onclose);
+
+    source.removeListener('error', onerror);
+    dest.removeListener('error', onerror);
+
+    source.removeListener('end', cleanup);
+    source.removeListener('close', cleanup);
+
+    dest.removeListener('close', cleanup);
+  }
+
+  source.on('end', cleanup);
+  source.on('close', cleanup);
+
+  dest.on('close', cleanup);
+
+  dest.emit('pipe', source);
+
+  // Allow for unix-like usage: A.pipe(B).pipe(C)
+  return dest;
+};
+
+},{"events":19,"inherits":20,"readable-stream/duplex.js":24,"readable-stream/passthrough.js":38,"readable-stream/readable.js":39,"readable-stream/transform.js":40,"readable-stream/writable.js":41}],43:[function(require,module,exports){
+'use strict';
+
+var Buffer = require('safe-buffer').Buffer;
+
+var isEncoding = Buffer.isEncoding || function (encoding) {
+  encoding = '' + encoding;
+  switch (encoding && encoding.toLowerCase()) {
+    case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw':
+      return true;
+    default:
+      return false;
+  }
+};
+
+function _normalizeEncoding(enc) {
+  if (!enc) return 'utf8';
+  var retried;
+  while (true) {
+    switch (enc) {
+      case 'utf8':
+      case 'utf-8':
+        return 'utf8';
+      case 'ucs2':
+      case 'ucs-2':
+      case 'utf16le':
+      case 'utf-16le':
+        return 'utf16le';
+      case 'latin1':
+      case 'binary':
+        return 'latin1';
+      case 'base64':
+      case 'ascii':
+      case 'hex':
+        return enc;
+      default:
+        if (retried) return; // undefined
+        enc = ('' + enc).toLowerCase();
+        retried = true;
+    }
+  }
+};
+
+// Do not cache `Buffer.isEncoding` when checking encoding names as some
+// modules monkey-patch it to support additional encodings
+function normalizeEncoding(enc) {
+  var nenc = _normalizeEncoding(enc);
+  if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc);
+  return nenc || enc;
+}
+
+// StringDecoder provides an interface for efficiently splitting a series of
+// buffers into a series of JS strings without breaking apart multi-byte
+// characters.
+exports.StringDecoder = StringDecoder;
+function StringDecoder(encoding) {
+  this.encoding = normalizeEncoding(encoding);
+  var nb;
+  switch (this.encoding) {
+    case 'utf16le':
+      this.text = utf16Text;
+      this.end = utf16End;
+      nb = 4;
+      break;
+    case 'utf8':
+      this.fillLast = utf8FillLast;
+      nb = 4;
+      break;
+    case 'base64':
+      this.text = base64Text;
+      this.end = base64End;
+      nb = 3;
+      break;
+    default:
+      this.write = simpleWrite;
+      this.end = simpleEnd;
+      return;
+  }
+  this.lastNeed = 0;
+  this.lastTotal = 0;
+  this.lastChar = Buffer.allocUnsafe(nb);
+}
+
+StringDecoder.prototype.write = function (buf) {
+  if (buf.length === 0) return '';
+  var r;
+  var i;
+  if (this.lastNeed) {
+    r = this.fillLast(buf);
+    if (r === undefined) return '';
+    i = this.lastNeed;
+    this.lastNeed = 0;
+  } else {
+    i = 0;
+  }
+  if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i);
+  return r || '';
+};
+
+StringDecoder.prototype.end = utf8End;
+
+// Returns only complete characters in a Buffer
+StringDecoder.prototype.text = utf8Text;
+
+// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer
+StringDecoder.prototype.fillLast = function (buf) {
+  if (this.lastNeed <= buf.length) {
+    buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed);
+    return this.lastChar.toString(this.encoding, 0, this.lastTotal);
+  }
+  buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length);
+  this.lastNeed -= buf.length;
+};
+
+// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a
+// continuation byte.
+function utf8CheckByte(byte) {
+  if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4;
+  return -1;
+}
+
+// Checks at most 3 bytes at the end of a Buffer in order to detect an
+// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4)
+// needed to complete the UTF-8 character (if applicable) are returned.
+function utf8CheckIncomplete(self, buf, i) {
+  var j = buf.length - 1;
+  if (j < i) return 0;
+  var nb = utf8CheckByte(buf[j]);
+  if (nb >= 0) {
+    if (nb > 0) self.lastNeed = nb - 1;
+    return nb;
+  }
+  if (--j < i) return 0;
+  nb = utf8CheckByte(buf[j]);
+  if (nb >= 0) {
+    if (nb > 0) self.lastNeed = nb - 2;
+    return nb;
+  }
+  if (--j < i) return 0;
+  nb = utf8CheckByte(buf[j]);
+  if (nb >= 0) {
+    if (nb > 0) {
+      if (nb === 2) nb = 0;else self.lastNeed = nb - 3;
+    }
+    return nb;
+  }
+  return 0;
+}
+
+// Validates as many continuation bytes for a multi-byte UTF-8 character as
+// needed or are available. If we see a non-continuation byte where we expect
+// one, we "replace" the validated continuation bytes we've seen so far with
+// UTF-8 replacement characters ('\ufffd'), to match v8's UTF-8 decoding
+// behavior. The continuation byte check is included three times in the case
+// where all of the continuation bytes for a character exist in the same buffer.
+// It is also done this way as a slight performance increase instead of using a
+// loop.
+function utf8CheckExtraBytes(self, buf, p) {
+  if ((buf[0] & 0xC0) !== 0x80) {
+    self.lastNeed = 0;
+    return '\ufffd'.repeat(p);
+  }
+  if (self.lastNeed > 1 && buf.length > 1) {
+    if ((buf[1] & 0xC0) !== 0x80) {
+      self.lastNeed = 1;
+      return '\ufffd'.repeat(p + 1);
+    }
+    if (self.lastNeed > 2 && buf.length > 2) {
+      if ((buf[2] & 0xC0) !== 0x80) {
+        self.lastNeed = 2;
+        return '\ufffd'.repeat(p + 2);
+      }
+    }
+  }
+}
+
+// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer.
+function utf8FillLast(buf) {
+  var p = this.lastTotal - this.lastNeed;
+  var r = utf8CheckExtraBytes(this, buf, p);
+  if (r !== undefined) return r;
+  if (this.lastNeed <= buf.length) {
+    buf.copy(this.lastChar, p, 0, this.lastNeed);
+    return this.lastChar.toString(this.encoding, 0, this.lastTotal);
+  }
+  buf.copy(this.lastChar, p, 0, buf.length);
+  this.lastNeed -= buf.length;
+}
+
+// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a
+// partial character, the character's bytes are buffered until the required
+// number of bytes are available.
+function utf8Text(buf, i) {
+  var total = utf8CheckIncomplete(this, buf, i);
+  if (!this.lastNeed) return buf.toString('utf8', i);
+  this.lastTotal = total;
+  var end = buf.length - (total - this.lastNeed);
+  buf.copy(this.lastChar, 0, end);
+  return buf.toString('utf8', i, end);
+}
+
+// For UTF-8, a replacement character for each buffered byte of a (partial)
+// character needs to be added to the output.
+function utf8End(buf) {
+  var r = buf && buf.length ? this.write(buf) : '';
+  if (this.lastNeed) return r + '\ufffd'.repeat(this.lastTotal - this.lastNeed);
+  return r;
+}
+
+// UTF-16LE typically needs two bytes per character, but even if we have an even
+// number of bytes available, we need to check if we end on a leading/high
+// surrogate. In that case, we need to wait for the next two bytes in order to
+// decode the last character properly.
+function utf16Text(buf, i) {
+  if ((buf.length - i) % 2 === 0) {
+    var r = buf.toString('utf16le', i);
+    if (r) {
+      var c = r.charCodeAt(r.length - 1);
+      if (c >= 0xD800 && c <= 0xDBFF) {
+        this.lastNeed = 2;
+        this.lastTotal = 4;
+        this.lastChar[0] = buf[buf.length - 2];
+        this.lastChar[1] = buf[buf.length - 1];
+        return r.slice(0, -1);
+      }
+    }
+    return r;
+  }
+  this.lastNeed = 1;
+  this.lastTotal = 2;
+  this.lastChar[0] = buf[buf.length - 1];
+  return buf.toString('utf16le', i, buf.length - 1);
+}
+
+// For UTF-16LE we do not explicitly append special replacement characters if we
+// end on a partial character, we simply let v8 handle that.
+function utf16End(buf) {
+  var r = buf && buf.length ? this.write(buf) : '';
+  if (this.lastNeed) {
+    var end = this.lastTotal - this.lastNeed;
+    return r + this.lastChar.toString('utf16le', 0, end);
+  }
+  return r;
+}
+
+function base64Text(buf, i) {
+  var n = (buf.length - i) % 3;
+  if (n === 0) return buf.toString('base64', i);
+  this.lastNeed = 3 - n;
+  this.lastTotal = 3;
+  if (n === 1) {
+    this.lastChar[0] = buf[buf.length - 1];
+  } else {
+    this.lastChar[0] = buf[buf.length - 2];
+    this.lastChar[1] = buf[buf.length - 1];
+  }
+  return buf.toString('base64', i, buf.length - n);
+}
+
+function base64End(buf) {
+  var r = buf && buf.length ? this.write(buf) : '';
+  if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed);
+  return r;
+}
+
+// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex)
+function simpleWrite(buf) {
+  return buf.toString(this.encoding);
+}
+
+function simpleEnd(buf) {
+  return buf && buf.length ? this.write(buf) : '';
+}
+},{"safe-buffer":44}],44:[function(require,module,exports){
+arguments[4][36][0].apply(exports,arguments)
+},{"buffer":16,"dup":36}],45:[function(require,module,exports){
+arguments[4][20][0].apply(exports,arguments)
+},{"dup":20}],46:[function(require,module,exports){
+module.exports = function isBuffer(arg) {
+  return arg && typeof arg === 'object'
+    && typeof arg.copy === 'function'
+    && typeof arg.fill === 'function'
+    && typeof arg.readUInt8 === 'function';
+}
+},{}],47:[function(require,module,exports){
+(function (process,global){
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var formatRegExp = /%[sdj%]/g;
+exports.format = function(f) {
+  if (!isString(f)) {
+    var objects = [];
+    for (var i = 0; i < arguments.length; i++) {
+      objects.push(inspect(arguments[i]));
+    }
+    return objects.join(' ');
+  }
+
+  var i = 1;
+  var args = arguments;
+  var len = args.length;
+  var str = String(f).replace(formatRegExp, function(x) {
+    if (x === '%%') return '%';
+    if (i >= len) return x;
+    switch (x) {
+      case '%s': return String(args[i++]);
+      case '%d': return Number(args[i++]);
+      case '%j':
+        try {
+          return JSON.stringify(args[i++]);
+        } catch (_) {
+          return '[Circular]';
+        }
+      default:
+        return x;
+    }
+  });
+  for (var x = args[i]; i < len; x = args[++i]) {
+    if (isNull(x) || !isObject(x)) {
+      str += ' ' + x;
+    } else {
+      str += ' ' + inspect(x);
+    }
+  }
+  return str;
+};
+
+
+// Mark that a method should not be used.
+// Returns a modified function which warns once by default.
+// If --no-deprecation is set, then it is a no-op.
+exports.deprecate = function(fn, msg) {
+  // Allow for deprecating things in the process of starting up.
+  if (isUndefined(global.process)) {
+    return function() {
+      return exports.deprecate(fn, msg).apply(this, arguments);
+    };
+  }
+
+  if (process.noDeprecation === true) {
+    return fn;
+  }
+
+  var warned = false;
+  function deprecated() {
+    if (!warned) {
+      if (process.throwDeprecation) {
+        throw new Error(msg);
+      } else if (process.traceDeprecation) {
+        console.trace(msg);
+      } else {
+        console.error(msg);
+      }
+      warned = true;
+    }
+    return fn.apply(this, arguments);
+  }
+
+  return deprecated;
+};
+
+
+var debugs = {};
+var debugEnviron;
+exports.debuglog = function(set) {
+  if (isUndefined(debugEnviron))
+    debugEnviron = process.env.NODE_DEBUG || '';
+  set = set.toUpperCase();
+  if (!debugs[set]) {
+    if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
+      var pid = process.pid;
+      debugs[set] = function() {
+        var msg = exports.format.apply(exports, arguments);
+        console.error('%s %d: %s', set, pid, msg);
+      };
+    } else {
+      debugs[set] = function() {};
+    }
+  }
+  return debugs[set];
+};
+
+
+/**
+ * Echos the value of a value. Trys to print the value out in the best way
+ * possible given the different types.
+ * 
+ * @param {Object}
+ *            obj The object to print out.
+ * @param {Object}
+ *            opts Optional options object that alters the output.
+ */
+/* legacy: obj, showHidden, depth, colors */
+function inspect(obj, opts) {
+  // default options
+  var ctx = {
+    seen: [],
+    stylize: stylizeNoColor
+  };
+  // legacy...
+  if (arguments.length >= 3) ctx.depth = arguments[2];
+  if (arguments.length >= 4) ctx.colors = arguments[3];
+  if (isBoolean(opts)) {
+    // legacy...
+    ctx.showHidden = opts;
+  } else if (opts) {
+    // got an "options" object
+    exports._extend(ctx, opts);
+  }
+  // set default options
+  if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
+  if (isUndefined(ctx.depth)) ctx.depth = 2;
+  if (isUndefined(ctx.colors)) ctx.colors = false;
+  if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
+  if (ctx.colors) ctx.stylize = stylizeWithColor;
+  return formatValue(ctx, obj, ctx.depth);
+}
+exports.inspect = inspect;
+
+
+// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
+inspect.colors = {
+  'bold' : [1, 22],
+  'italic' : [3, 23],
+  'underline' : [4, 24],
+  'inverse' : [7, 27],
+  'white' : [37, 39],
+  'grey' : [90, 39],
+  'black' : [30, 39],
+  'blue' : [34, 39],
+  'cyan' : [36, 39],
+  'green' : [32, 39],
+  'magenta' : [35, 39],
+  'red' : [31, 39],
+  'yellow' : [33, 39]
+};
+
+// Don't use 'blue' not visible on cmd.exe
+inspect.styles = {
+  'special': 'cyan',
+  'number': 'yellow',
+  'boolean': 'yellow',
+  'undefined': 'grey',
+  'null': 'bold',
+  'string': 'green',
+  'date': 'magenta',
+  // "name": intentionally not styling
+  'regexp': 'red'
+};
+
+
+function stylizeWithColor(str, styleType) {
+  var style = inspect.styles[styleType];
+
+  if (style) {
+    return '\u001b[' + inspect.colors[style][0] + 'm' + str +
+           '\u001b[' + inspect.colors[style][1] + 'm';
+  } else {
+    return str;
+  }
+}
+
+
+function stylizeNoColor(str, styleType) {
+  return str;
+}
+
+
+function arrayToHash(array) {
+  var hash = {};
+
+  array.forEach(function(val, idx) {
+    hash[val] = true;
+  });
+
+  return hash;
+}
+
+
+function formatValue(ctx, value, recurseTimes) {
+  // Provide a hook for user-specified inspect functions.
+  // Check that value is an object with an inspect function on it
+  if (ctx.customInspect &&
+      value &&
+      isFunction(value.inspect) &&
+      // Filter out the util module, it's inspect function is special
+      value.inspect !== exports.inspect &&
+      // Also filter out any prototype objects using the circular check.
+      !(value.constructor && value.constructor.prototype === value)) {
+    var ret = value.inspect(recurseTimes, ctx);
+    if (!isString(ret)) {
+      ret = formatValue(ctx, ret, recurseTimes);
+    }
+    return ret;
+  }
+
+  // Primitive types cannot have properties
+  var primitive = formatPrimitive(ctx, value);
+  if (primitive) {
+    return primitive;
+  }
+
+  // Look up the keys of the object.
+  var keys = Object.keys(value);
+  var visibleKeys = arrayToHash(keys);
+
+  if (ctx.showHidden) {
+    keys = Object.getOwnPropertyNames(value);
+  }
+
+  // IE doesn't make error fields non-enumerable
+  // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
+  if (isError(value)
+      && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
+    return formatError(value);
+  }
+
+  // Some type of object without properties can be shortcutted.
+  if (keys.length === 0) {
+    if (isFunction(value)) {
+      var name = value.name ? ': ' + value.name : '';
+      return ctx.stylize('[Function' + name + ']', 'special');
+    }
+    if (isRegExp(value)) {
+      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
+    }
+    if (isDate(value)) {
+      return ctx.stylize(Date.prototype.toString.call(value), 'date');
+    }
+    if (isError(value)) {
+      return formatError(value);
+    }
+  }
+
+  var base = '', array = false, braces = ['{', '}'];
+
+  // Make Array say that they are Array
+  if (isArray(value)) {
+    array = true;
+    braces = ['[', ']'];
+  }
+
+  // Make functions say that they are functions
+  if (isFunction(value)) {
+    var n = value.name ? ': ' + value.name : '';
+    base = ' [Function' + n + ']';
+  }
+
+  // Make RegExps say that they are RegExps
+  if (isRegExp(value)) {
+    base = ' ' + RegExp.prototype.toString.call(value);
+  }
+
+  // Make dates with properties first say the date
+  if (isDate(value)) {
+    base = ' ' + Date.prototype.toUTCString.call(value);
+  }
+
+  // Make error with message first say the error
+  if (isError(value)) {
+    base = ' ' + formatError(value);
+  }
+
+  if (keys.length === 0 && (!array || value.length == 0)) {
+    return braces[0] + base + braces[1];
+  }
+
+  if (recurseTimes < 0) {
+    if (isRegExp(value)) {
+      return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
+    } else {
+      return ctx.stylize('[Object]', 'special');
+    }
+  }
+
+  ctx.seen.push(value);
+
+  var output;
+  if (array) {
+    output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
+  } else {
+    output = keys.map(function(key) {
+      return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
+    });
+  }
+
+  ctx.seen.pop();
+
+  return reduceToSingleString(output, base, braces);
+}
+
+
+function formatPrimitive(ctx, value) {
+  if (isUndefined(value))
+    return ctx.stylize('undefined', 'undefined');
+  if (isString(value)) {
+    var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
+                                             .replace(/'/g, "\\'")
+                                             .replace(/\\"/g, '"') + '\'';
+    return ctx.stylize(simple, 'string');
+  }
+  if (isNumber(value))
+    return ctx.stylize('' + value, 'number');
+  if (isBoolean(value))
+    return ctx.stylize('' + value, 'boolean');
+  // For some reason typeof null is "object", so special case here.
+  if (isNull(value))
+    return ctx.stylize('null', 'null');
+}
+
+
+function formatError(value) {
+  return '[' + Error.prototype.toString.call(value) + ']';
+}
+
+
+function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
+  var output = [];
+  for (var i = 0, l = value.length; i < l; ++i) {
+    if (hasOwnProperty(value, String(i))) {
+      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
+          String(i), true));
+    } else {
+      output.push('');
+    }
+  }
+  keys.forEach(function(key) {
+    if (!key.match(/^\d+$/)) {
+      output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
+          key, true));
+    }
+  });
+  return output;
+}
+
+
+function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
+  var name, str, desc;
+  desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
+  if (desc.get) {
+    if (desc.set) {
+      str = ctx.stylize('[Getter/Setter]', 'special');
+    } else {
+      str = ctx.stylize('[Getter]', 'special');
+    }
+  } else {
+    if (desc.set) {
+      str = ctx.stylize('[Setter]', 'special');
+    }
+  }
+  if (!hasOwnProperty(visibleKeys, key)) {
+    name = '[' + key + ']';
+  }
+  if (!str) {
+    if (ctx.seen.indexOf(desc.value) < 0) {
+      if (isNull(recurseTimes)) {
+        str = formatValue(ctx, desc.value, null);
+      } else {
+        str = formatValue(ctx, desc.value, recurseTimes - 1);
+      }
+      if (str.indexOf('\n') > -1) {
+        if (array) {
+          str = str.split('\n').map(function(line) {
+            return '  ' + line;
+          }).join('\n').substr(2);
+        } else {
+          str = '\n' + str.split('\n').map(function(line) {
+            return '   ' + line;
+          }).join('\n');
+        }
+      }
+    } else {
+      str = ctx.stylize('[Circular]', 'special');
+    }
+  }
+  if (isUndefined(name)) {
+    if (array && key.match(/^\d+$/)) {
+      return str;
+    }
+    name = JSON.stringify('' + key);
+    if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
+      name = name.substr(1, name.length - 2);
+      name = ctx.stylize(name, 'name');
+    } else {
+      name = name.replace(/'/g, "\\'")
+                 .replace(/\\"/g, '"')
+                 .replace(/(^"|"$)/g, "'");
+      name = ctx.stylize(name, 'string');
+    }
+  }
+
+  return name + ': ' + str;
+}
+
+
+function reduceToSingleString(output, base, braces) {
+  var numLinesEst = 0;
+  var length = output.reduce(function(prev, cur) {
+    numLinesEst++;
+    if (cur.indexOf('\n') >= 0) numLinesEst++;
+    return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
+  }, 0);
+
+  if (length > 60) {
+    return braces[0] +
+           (base === '' ? '' : base + '\n ') +
+           ' ' +
+           output.join(',\n  ') +
+           ' ' +
+           braces[1];
+  }
+
+  return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
+}
+
+
+// NOTE: These type checking functions intentionally don't use `instanceof`
+// because it is fragile and can be easily faked with `Object.create()`.
+function isArray(ar) {
+  return Array.isArray(ar);
+}
+exports.isArray = isArray;
+
+function isBoolean(arg) {
+  return typeof arg === 'boolean';
+}
+exports.isBoolean = isBoolean;
+
+function isNull(arg) {
+  return arg === null;
+}
+exports.isNull = isNull;
+
+function isNullOrUndefined(arg) {
+  return arg == null;
+}
+exports.isNullOrUndefined = isNullOrUndefined;
+
+function isNumber(arg) {
+  return typeof arg === 'number';
+}
+exports.isNumber = isNumber;
+
+function isString(arg) {
+  return typeof arg === 'string';
+}
+exports.isString = isString;
+
+function isSymbol(arg) {
+  return typeof arg === 'symbol';
+}
+exports.isSymbol = isSymbol;
+
+function isUndefined(arg) {
+  return arg === void 0;
+}
+exports.isUndefined = isUndefined;
+
+function isRegExp(re) {
+  return isObject(re) && objectToString(re) === '[object RegExp]';
+}
+exports.isRegExp = isRegExp;
+
+function isObject(arg) {
+  return typeof arg === 'object' && arg !== null;
+}
+exports.isObject = isObject;
+
+function isDate(d) {
+  return isObject(d) && objectToString(d) === '[object Date]';
+}
+exports.isDate = isDate;
+
+function isError(e) {
+  return isObject(e) &&
+      (objectToString(e) === '[object Error]' || e instanceof Error);
+}
+exports.isError = isError;
+
+function isFunction(arg) {
+  return typeof arg === 'function';
+}
+exports.isFunction = isFunction;
+
+function isPrimitive(arg) {
+  return arg === null ||
+         typeof arg === 'boolean' ||
+         typeof arg === 'number' ||
+         typeof arg === 'string' ||
+         typeof arg === 'symbol' ||  // ES6 symbol
+         typeof arg === 'undefined';
+}
+exports.isPrimitive = isPrimitive;
+
+exports.isBuffer = require('./support/isBuffer');
+
+function objectToString(o) {
+  return Object.prototype.toString.call(o);
+}
+
+
+function pad(n) {
+  return n < 10 ? '0' + n.toString(10) : n.toString(10);
+}
+
+
+var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
+              'Oct', 'Nov', 'Dec'];
+
+// 26 Feb 16:19:34
+function timestamp() {
+  var d = new Date();
+  var time = [pad(d.getHours()),
+              pad(d.getMinutes()),
+              pad(d.getSeconds())].join(':');
+  return [d.getDate(), months[d.getMonth()], time].join(' ');
+}
+
+
+// log is just a thin wrapper to console.log that prepends a timestamp
+exports.log = function() {
+  console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
+};
+
+
+/**
+ * Inherit the prototype methods from one constructor into another.
+ * 
+ * The Function.prototype.inherits from lang.js rewritten as a standalone
+ * function (not on Function.prototype). NOTE: If this file is to be loaded
+ * during bootstrapping this function needs to be rewritten using some native
+ * functions as prototype setup using normal JavaScript does not work as
+ * expected during bootstrapping (see mirror.js in r114903).
+ * 
+ * @param {function}
+ *            ctor Constructor function which needs to inherit the prototype.
+ * @param {function}
+ *            superCtor Constructor function to inherit prototype from.
+ */
+exports.inherits = require('inherits');
+
+exports._extend = function(origin, add) {
+  // Don't do anything if add isn't an object
+  if (!add || !isObject(add)) return origin;
+
+  var keys = Object.keys(add);
+  var i = keys.length;
+  while (i--) {
+    origin[keys[i]] = add[keys[i]];
+  }
+  return origin;
+};
+
+function hasOwnProperty(obj, prop) {
+  return Object.prototype.hasOwnProperty.call(obj, prop);
+}
+
+}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+},{"./support/isBuffer":46,"_process":23,"inherits":45}],48:[function(require,module,exports){
+/* jshint browserify: true */
+
+'use strict';
+
+/**
+ * Optional entry point for browser builds.
+ * 
+ * To use it: `require('avsc/etc/browser/avsc-services')`.
+ */
+
+var avroTypes = require('./avsc-types'),
+    services = require('../../lib/services'),
+    specs = require('../../lib/specs'),
+    utils = require('../../lib/utils');
+
+
+/** Slightly enhanced parsing, supporting IDL declarations. */
+function parse(any, opts) {
+  var schemaOrProtocol = specs.read(any);
+  return schemaOrProtocol.protocol ?
+    services.Service.forProtocol(schemaOrProtocol, opts) :
+    avroTypes.Type.forSchema(schemaOrProtocol, opts);
+}
+
+
+module.exports = {
+  Service: services.Service,
+  assembleProtocol: specs.assembleProtocol,
+  discoverProtocol: services.discoverProtocol,
+  parse: parse,
+  readProtocol: specs.readProtocol,
+  readSchema: specs.readSchema,
+};
+
+utils.copyOwnProperties(avroTypes, module.exports);
+
+},{"../../lib/services":53,"../../lib/specs":54,"../../lib/utils":56,"./avsc-types":49}],49:[function(require,module,exports){
+/* jshint browserify: true */
+
+'use strict';
+
+/**
+ * Optional entry point for browser builds.
+ * 
+ * To use it: `require('avsc/etc/browser/avsc-types')`.
+ */
+
+var types = require('../../lib/types');
+
+
+/** Basic parse method, only supporting JSON parsing. */
+function parse(any, opts) {
+  var schema;
+  if (typeof any == 'string') {
+    try {
+      schema = JSON.parse(any);
+    } catch (err) {
+      schema = any;
+    }
+  } else {
+    schema = any;
+  }
+  return types.Type.forSchema(schema, opts);
+}
+
+
+module.exports = {
+  Type: types.Type,
+  parse: parse,
+  types: types.builtins,
+  // Deprecated exports (not using `util.deprecate` since it causes stack
+  // overflow errors in the browser).
+  combine: types.Type.forTypes,
+  infer: types.Type.forValue
+};
+
+},{"../../lib/types":55}],50:[function(require,module,exports){
+(function (Buffer){
+/* jshint browserify: true */
+
+'use strict';
+
+/**
+ * Shim to enable schema fingerprint computation.
+ * 
+ * MD5 implementation originally from [1], used with permission from the author,
+ * and lightly edited.
+ * 
+ * [1] http://www.myersdaily.org/joseph/javascript/md5-text.html
+ * 
+ */
+
+function createHash(algorithm) {
+  if (algorithm !== 'md5') {
+    throw new Error('only md5 is supported in the browser');
+  }
+  return new Hash();
+}
+
+function Hash() { this.data = undefined; }
+Hash.prototype.end = function (data) { this.data = data; };
+Hash.prototype.read = function () { return md5(this.data); };
+
+function md5cycle(x, k) {
+  var a = x[0], b = x[1], c = x[2], d = x[3];
+
+  a = ff(a, b, c, d, k[0], 7, -680876936);
+  d = ff(d, a, b, c, k[1], 12, -389564586);
+  c = ff(c, d, a, b, k[2], 17,  606105819);
+  b = ff(b, c, d, a, k[3], 22, -1044525330);
+  a = ff(a, b, c, d, k[4], 7, -176418897);
+  d = ff(d, a, b, c, k[5], 12,  1200080426);
+  c = ff(c, d, a, b, k[6], 17, -1473231341);
+  b = ff(b, c, d, a, k[7], 22, -45705983);
+  a = ff(a, b, c, d, k[8], 7,  1770035416);
+  d = ff(d, a, b, c, k[9], 12, -1958414417);
+  c = ff(c, d, a, b, k[10], 17, -42063);
+  b = ff(b, c, d, a, k[11], 22, -1990404162);
+  a = ff(a, b, c, d, k[12], 7,  1804603682);
+  d = ff(d, a, b, c, k[13], 12, -40341101);
+  c = ff(c, d, a, b, k[14], 17, -1502002290);
+  b = ff(b, c, d, a, k[15], 22,  1236535329);
+
+  a = gg(a, b, c, d, k[1], 5, -165796510);
+  d = gg(d, a, b, c, k[6], 9, -1069501632);
+  c = gg(c, d, a, b, k[11], 14,  643717713);
+  b = gg(b, c, d, a, k[0], 20, -373897302);
+  a = gg(a, b, c, d, k[5], 5, -701558691);
+  d = gg(d, a, b, c, k[10], 9,  38016083);
+  c = gg(c, d, a, b, k[15], 14, -660478335);
+  b = gg(b, c, d, a, k[4], 20, -405537848);
+  a = gg(a, b, c, d, k[9], 5,  568446438);
+  d = gg(d, a, b, c, k[14], 9, -1019803690);
+  c = gg(c, d, a, b, k[3], 14, -187363961);
+  b = gg(b, c, d, a, k[8], 20,  1163531501);
+  a = gg(a, b, c, d, k[13], 5, -1444681467);
+  d = gg(d, a, b, c, k[2], 9, -51403784);
+  c = gg(c, d, a, b, k[7], 14,  1735328473);
+  b = gg(b, c, d, a, k[12], 20, -1926607734);
+
+  a = hh(a, b, c, d, k[5], 4, -378558);
+  d = hh(d, a, b, c, k[8], 11, -2022574463);
+  c = hh(c, d, a, b, k[11], 16,  1839030562);
+  b = hh(b, c, d, a, k[14], 23, -35309556);
+  a = hh(a, b, c, d, k[1], 4, -1530992060);
+  d = hh(d, a, b, c, k[4], 11,  1272893353);
+  c = hh(c, d, a, b, k[7], 16, -155497632);
+  b = hh(b, c, d, a, k[10], 23, -1094730640);
+  a = hh(a, b, c, d, k[13], 4,  681279174);
+  d = hh(d, a, b, c, k[0], 11, -358537222);
+  c = hh(c, d, a, b, k[3], 16, -722521979);
+  b = hh(b, c, d, a, k[6], 23,  76029189);
+  a = hh(a, b, c, d, k[9], 4, -640364487);
+  d = hh(d, a, b, c, k[12], 11, -421815835);
+  c = hh(c, d, a, b, k[15], 16,  530742520);
+  b = hh(b, c, d, a, k[2], 23, -995338651);
+
+  a = ii(a, b, c, d, k[0], 6, -198630844);
+  d = ii(d, a, b, c, k[7], 10,  1126891415);
+  c = ii(c, d, a, b, k[14], 15, -1416354905);
+  b = ii(b, c, d, a, k[5], 21, -57434055);
+  a = ii(a, b, c, d, k[12], 6,  1700485571);
+  d = ii(d, a, b, c, k[3], 10, -1894986606);
+  c = ii(c, d, a, b, k[10], 15, -1051523);
+  b = ii(b, c, d, a, k[1], 21, -2054922799);
+  a = ii(a, b, c, d, k[8], 6,  1873313359);
+  d = ii(d, a, b, c, k[15], 10, -30611744);
+  c = ii(c, d, a, b, k[6], 15, -1560198380);
+  b = ii(b, c, d, a, k[13], 21,  1309151649);
+  a = ii(a, b, c, d, k[4], 6, -145523070);
+  d = ii(d, a, b, c, k[11], 10, -1120210379);
+  c = ii(c, d, a, b, k[2], 15,  718787259);
+  b = ii(b, c, d, a, k[9], 21, -343485551);
+
+  x[0] = add32(a, x[0]);
+  x[1] = add32(b, x[1]);
+  x[2] = add32(c, x[2]);
+  x[3] = add32(d, x[3]);
+}
+
+function cmn(q, a, b, x, s, t) {
+  a = add32(add32(a, q), add32(x, t));
+  return add32((a << s) | (a >>> (32 - s)), b);
+}
+
+function ff(a, b, c, d, x, s, t) {
+  return cmn((b & c) | ((~b) & d), a, b, x, s, t);
+}
+
+function gg(a, b, c, d, x, s, t) {
+  return cmn((b & d) | (c & (~d)), a, b, x, s, t);
+}
+
+function hh(a, b, c, d, x, s, t) {
+  return cmn(b ^ c ^ d, a, b, x, s, t);
+}
+
+function ii(a, b, c, d, x, s, t) {
+  return cmn(c ^ (b | (~d)), a, b, x, s, t);
+}
+
+function md51(s) {
+  var n = s.length,
+  state = [1732584193, -271733879, -1732584194, 271733878], i;
+  for (i=64; i<=s.length; i+=64) {
+    md5cycle(state, md5blk(s.substring(i-64, i)));
+  }
+
+  s = s.substring(i-64);
+  var tail = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
+  for (i=0; i<s.length; i++) {
+    tail[i>>2] |= s.charCodeAt(i) << ((i%4) << 3);
+  }
+  tail[i>>2] |= 0x80 << ((i%4) << 3);
+  if (i > 55) {
+    md5cycle(state, tail);
+    for (i=0; i<16; i++) {
+      tail[i] = 0;
+    }
+  }
+  tail[14] = n*8;
+  md5cycle(state, tail);
+  return state;
+}
+
+function md5blk(s) {
+  var md5blks = [], i;
+  for (i=0; i<64; i+=4) {
+    md5blks[i>>2] = s.charCodeAt(i) +
+      (s.charCodeAt(i+1) << 8) +
+      (s.charCodeAt(i+2) << 16) +
+      (s.charCodeAt(i+3) << 24);
+  }
+  return md5blks;
+}
+
+function md5(s) {
+  var arr = md51(s);
+  var buf = new Buffer(16);
+  var i;
+  for (i = 0; i < 4; i++) {
+    buf.writeIntLE(arr[i], i * 4, 4);
+  }
+  return buf;
+}
+
+function add32(a, b) {
+  return (a + b) & 0xFFFFFFFF;
+}
+
+module.exports = {
+  createHash: createHash
+};
+
+}).call(this,require("buffer").Buffer)
+},{"buffer":16}],51:[function(require,module,exports){
+/* jshint node: true */
+
+'use strict';
+
+/** Shim without file-system operations. */
+
+function createError() { return new Error('unsupported in the browser'); }
+
+function createImportHook() {
+  return function (fpath, kind, cb) { cb(createError()); };
+}
+
+function createSyncImportHook() {
+  return function () { throw createError(); };
+}
+
+
+module.exports = {
+  createImportHook: createImportHook,
+  createSyncImportHook: createSyncImportHook,
+  existsSync: function () { return false; },
+  readFileSync: function () { throw createError(); }
+};
+
+},{}],52:[function(require,module,exports){
+(function (process,Buffer){
+/* jshint node: true */
+
+// TODO: Add streams which prefix each record with its length.
+
+'use strict';
+
+/**
+ * This module defines custom streams to write and read Avro files.
+ * 
+ * In particular, the `Block{En,De}coder` streams are able to deal with Avro
+ * container files. None of the streams below depend on the filesystem however,
+ * this way they can also be used in the browser (for example to parse HTTP
+ * responses).
+ */
+
+var types = require('./types'),
+    utils = require('./utils'),
+    stream = require('stream'),
+    util = require('util'),
+    zlib = require('zlib');
+
+
+var OPTS = {namespace: 'org.apache.avro.file'};
+
+var LONG_TYPE = types.Type.forSchema('long', OPTS);
+
+var HEADER_TYPE = types.Type.forSchema({
+  name: 'Header',
+  type: 'record',
+  fields : [
+    {name: 'magic', type: {type: 'fixed', name: 'Magic', size: 4}},
+    {name: 'meta', type: {type: 'map', values: 'bytes'}},
+    {name: 'sync', type: {type: 'fixed', name: 'Sync', size: 16}}
+  ]
+}, OPTS);
+
+var BLOCK_TYPE = types.Type.forSchema({
+  name: 'Block',
+  type: 'record',
+  fields : [
+    {name: 'count', type: 'long'},
+    {name: 'data', type: 'bytes'},
+    {name: 'sync', type: 'Sync'}
+  ]
+}, OPTS);
+
+// First 4 bytes of an Avro object container file.
+var MAGIC_BYTES = new Buffer('Obj\x01');
+
+// Convenience.
+var f = util.format;
+var Tap = utils.Tap;
+
+
+/** Duplex stream for decoding fragments. */
+function RawDecoder(schema, opts) {
+  opts = opts || {};
+
+  var noDecode = !!opts.noDecode;
+  stream.Duplex.call(this, {
+    readableObjectMode: !noDecode,
+    allowHalfOpen: false
+  });
+
+  this._type = types.Type.forSchema(schema);
+  this._tap = new Tap(new Buffer(0));
+  this._writeCb = null;
+  this._needPush = false;
+  this._readValue = createReader(noDecode, this._type);
+  this._finished = false;
+
+  this.on('finish', function () {
+    this._finished = true;
+    this._read();
+  });
+}
+util.inherits(RawDecoder, stream.Duplex);
+
+RawDecoder.prototype._write = function (chunk, encoding, cb) {
+  // Store the write callback and call it when we are done decoding all
+	// records
+  // in this chunk. If we call it right away, we risk loading the entire input
+  // in memory. We only need to store the latest callback since the stream API
+  // guarantees that `_write` won't be called again until we call the
+	// previous.
+  this._writeCb = cb;
+
+  var tap = this._tap;
+  tap.buf = Buffer.concat([tap.buf.slice(tap.pos), chunk]);
+  tap.pos = 0;
+  if (this._needPush) {
+    this._needPush = false;
+    this._read();
+  }
+};
+
+RawDecoder.prototype._read = function () {
+  this._needPush = false;
+
+  var tap = this._tap;
+  var pos = tap.pos;
+  var val = this._readValue(tap);
+  if (tap.isValid()) {
+    this.push(val);
+  } else if (!this._finished) {
+    tap.pos = pos;
+    this._needPush = true;
+    if (this._writeCb) {
+      // This should only ever be false on the first read, and only if it
+      // happens before the first write.
+      this._writeCb();
+    }
+  } else {
+    this.push(null);
+  }
+};
+
+
+/** Duplex stream for decoding object container files. */
+function BlockDecoder(opts) {
+  opts = opts || {};
+
+  var noDecode = !!opts.noDecode;
+  stream.Duplex.call(this, {
+    allowHalfOpen: true, // For async decompressors.
+    readableObjectMode: !noDecode
+  });
+
+  this._rType = opts.readerSchema !== undefined ?
+    types.Type.forSchema(opts.readerSchema) :
+    undefined;
+  this._wType = null;
+  this._codecs = opts.codecs;
+  this._codec = undefined;
+  this._parseHook = opts.parseHook;
+  this._tap = new Tap(new Buffer(0));
+  this._blockTap = new Tap(new Buffer(0));
+  this._syncMarker = null;
+  this._readValue = null;
+  this._noDecode = noDecode;
+  this._queue = new utils.OrderedQueue();
+  this._decompress = null; // Decompression function.
+  this._index = 0; // Next block index.
+  this._needPush = false;
+  this._finished = false;
+
+  this.on('finish', function () {
+    this._finished = true;
+    if (this._needPush) {
+      this._read();
+    }
+  });
+}
+util.inherits(BlockDecoder, stream.Duplex);
+
+BlockDecoder.defaultCodecs = function () {
+  return {
+    'null': function (buf, cb) { cb(null, buf); },
+    'deflate': zlib.inflateRaw
+  };
+};
+
+BlockDecoder.getDefaultCodecs = BlockDecoder.defaultCodecs;
+
+BlockDecoder.prototype._decodeHeader = function () {
+  var tap = this._tap;
+  if (tap.buf.length < MAGIC_BYTES.length) {
+    // Wait until more data arrives.
+    return false;
+  }
+
+  if (!MAGIC_BYTES.equals(tap.buf.slice(0, MAGIC_BYTES.length))) {
+    this.emit('error', new Error('invalid magic bytes'));
+    return false;
+  }
+
+  var header = HEADER_TYPE._read(tap);
+  if (!tap.isValid()) {
+    return false;
+  }
+
+  this._codec = (header.meta['avro.codec'] || 'null').toString();
+  var codecs = this._codecs || BlockDecoder.getDefaultCodecs();
+  this._decompress = codecs[this._codec];
+  if (!this._decompress) {
+    this.emit('error', new Error(f('unknown codec: %s', this._codec)));
+    return;
+  }
+
+  try {
+    var schema = JSON.parse(header.meta['avro.schema'].toString());
+    if (this._parseHook) {
+      schema = this._parseHook(schema);
+    }
+    this._wType = types.Type.forSchema(schema);
+  } catch (err) {
+    this.emit('error', err);
+    return;
+  }
+
+  this._readValue = createReader(this._noDecode, this._wType, this._rType);
+  this._syncMarker = header.sync;
+  this.emit('metadata', this._wType, this._codec, header);
+  return true;
+};
+
+BlockDecoder.prototype._write = function (chunk, encoding, cb) {
+  var tap = this._tap;
+  tap.buf = Buffer.concat([tap.buf, chunk]);
+  tap.pos = 0;
+
+  if (!this._decodeHeader()) {
+    process.nextTick(cb);
+    return;
+  }
+
+  // We got the header, switch to block decoding mode. Also, call it directly
+  // in case we already have all the data (in which case `_write` wouldn't get
+  // called anymore).
+  this._write = this._writeChunk;
+  this._write(new Buffer(0), encoding, cb);
+};
+
+BlockDecoder.prototype._writeChunk = function (chunk, encoding, cb) {
+  var tap = this._tap;
+  tap.buf = Buffer.concat([tap.buf.slice(tap.pos), chunk]);
+  tap.pos = 0;
+
+  var nBlocks = 1;
+  var block;
+  while ((block = tryReadBlock(tap))) {
+    if (!this._syncMarker.equals(block.sync)) {
+      this.emit('error', new Error('invalid sync marker'));
+      return;
+    }
+    nBlocks++;
+    this._decompress(block.data, this._createBlockCallback(chunkCb));
+  }
+  chunkCb();
+
+  function chunkCb() {
+    if (!--nBlocks) {
+      cb();
+    }
+  }
+};
+
+BlockDecoder.prototype._createBlockCallback = function (cb) {
+  var self = this;
+  var index = this._index++;
+
+  return function (cause, data) {
+    if (cause) {
+      var err = new Error(f('%s codec decompression error', self._codec));
+      err.cause = cause;
+      self.emit('error', err);
+      cb();
+    } else {
+      self._queue.push(new BlockData(index, data, cb));
+      if (self._needPush) {
+        self._read();
+      }
+    }
+  };
+};
+
+BlockDecoder.prototype._read = function () {
+  this._needPush = false;
+
+  var tap = this._blockTap;
+  if (tap.pos >= tap.buf.length) {
+    var data = this._queue.pop();
+    if (!data) {
+      if (this._finished) {
+        this.push(null);
+      } else {
+        this._needPush = true;
+      }
+      return; // Wait for more data.
+    }
+    data.cb();
+    tap.buf = data.buf;
+    tap.pos = 0;
+  }
+
+  this.push(this._readValue(tap)); // The read is guaranteed valid.
+};
+
+
+/** Duplex stream for encoding. */
+function RawEncoder(schema, opts) {
+  opts = opts || {};
+
+  stream.Transform.call(this, {
+    writableObjectMode: true,
+    allowHalfOpen: false
+  });
+
+  this._type = types.Type.forSchema(schema);
+  this._writeValue = function (tap, val) {
+    try {
+      this._type._write(tap, val);
+    } catch (err) {
+      this.emit('error', err);
+    }
+  };
+  this._tap = new Tap(new Buffer(opts.batchSize || 65536));
+}
+util.inherits(RawEncoder, stream.Transform);
+
+RawEncoder.prototype._transform = function (val, encoding, cb) {
+  var tap = this._tap;
+  var buf = tap.buf;
+  var pos = tap.pos;
+
+  this._writeValue(tap, val);
+  if (!tap.isValid()) {
+    if (pos) {
+      // Emit any valid data.
+      this.push(copyBuffer(tap.buf, 0, pos));
+    }
+    var len = tap.pos - pos;
+    if (len > buf.length) {
+      // Not enough space for last written object, need to resize.
+      tap.buf = new Buffer(2 * len);
+    }
+    tap.pos = 0;
+    this._writeValue(tap, val); // Rewrite last failed write.
+  }
+
+  cb();
+};
+
+RawEncoder.prototype._flush = function (cb) {
+  var tap = this._tap;
+  var pos = tap.pos;
+  if (pos) {
+    // This should only ever be false if nothing is written to the stream.
+    this.push(tap.buf.slice(0, pos));
+  }
+  cb();
+};
+
+
+/**
+ * Duplex stream to write object container files.
+ * 
+ * @param schema
+ * @param opts
+ *            {Object}
+ *  + `blockSize`, uncompressed. + `codec` + `codecs` + `noCheck` +
+ * `omitHeader`, useful to append to an existing block file.
+ */
+function BlockEncoder(schema, opts) {
+  opts = opts || {};
+
+  stream.Duplex.call(this, {
+    allowHalfOpen: true, // To support async compressors.
+    writableObjectMode: true
+  });
+
+  var type;
+  if (types.Type.isType(schema)) {
+    type = schema;
+    schema = undefined;
+  } else {
+    // Keep full schema to be able to write it to the header later.
+    type = types.Type.forSchema(schema);
+  }
+
+  this._schema = schema;
+  this._type = type;
+  this._writeValue = function (tap, val) {
+    try {
+      this._type._write(tap, val);
+    } catch (err) {
+      this.emit('error', err);
+    }
+  };
+  this._blockSize = opts.blockSize || 65536;
+  this._tap = new Tap(new Buffer(this._blockSize));
+  this._codecs = opts.codecs;
+  this._codec = opts.codec || 'null';
+  this._blockCount = 0;
+  this._syncMarker = opts.syncMarker || new utils.Lcg().nextBuffer(16);
+  this._queue = new utils.OrderedQueue();
+  this._pending = 0;
+  this._finished = false;
+  this._needHeader = false;
+  this._needPush = false;
+
+  var codec = this._codec;
+  this._compress = (this._codecs || BlockEncoder.getDefaultCodecs())[codec];
+  if (!this._compress) {
+    throw new Error(f('unsupported codec: %s', codec));
+  }
+
+  if (opts.omitHeader !== undefined) { // Legacy option.
+    opts.writeHeader = opts.omitHeader ? 'never' : 'auto';
+  }
+  switch (opts.writeHeader) {
+    case false:
+    case 'never':
+      break;
+    case undefined: // Backwards-compatibility (eager default would be better).
+    case 'auto':
+      this._needHeader = true;
+      break;
+    default:
+      this._writeHeader();
+  }
+
+  this.on('finish', function () {
+    this._finished = true;
+    if (this._blockCount) {
+      this._flushChunk();
+    } else if (this._finished && this._needPush) {
+      // We don't need to check `_isPending` since `_blockCount` is always
+      // positive after the first flush.
+      this.push(null);
+    }
+  });
+}
+util.inherits(BlockEncoder, stream.Duplex);
+
+BlockEncoder.defaultCodecs = function () {
+  return {
+    'null': function (buf, cb) { cb(null, buf); },
+    'deflate': zlib.deflateRaw
+  };
+};
+
+BlockEncoder.getDefaultCodecs = BlockEncoder.defaultCodecs;
+
+BlockEncoder.prototype._writeHeader = function () {
+  var schemaStr = JSON.stringify(
+    this._schema ? this._schema : this._type.getSchema({exportAttrs: true})
+  );
+  var meta = {
+    'avro.schema': new Buffer(schemaStr),
+    'avro.codec': new Buffer(this._codec)
+  };
+  var Header = HEADER_TYPE.getRecordConstructor();
+  var header = new Header(MAGIC_BYTES, meta, this._syncMarker);
+  this.push(header.toBuffer());
+};
+
+BlockEncoder.prototype._write = function (val, encoding, cb) {
+  if (this._needHeader) {
+    this._writeHeader();
+    this._needHeader = false;
+  }
+
+  var tap = this._tap;
+  var pos = tap.pos;
+  var flushing = false;
+
+  this._writeValue(tap, val);
+  if (!tap.isValid()) {
+    if (pos) {
+      this._flushChunk(pos, cb);
+      flushing = true;
+    }
+    var len = tap.pos - pos;
+    if (len > this._blockSize) {
+      // Not enough space for last written object, need to resize.
+      this._blockSize = len * 2;
+    }
+    tap.buf = new Buffer(this._blockSize);
+    tap.pos = 0;
+    this._writeValue(tap, val); // Rewrite last failed write.
+  }
+  this._blockCount++;
+
+  if (!flushing) {
+    cb();
+  }
+};
+
+BlockEncoder.prototype._flushChunk = function (pos, cb) {
+  var tap = this._tap;
+  pos = pos || tap.pos;
+  this._compress(tap.buf.slice(0, pos), this._createBlockCallback(cb));
+  this._blockCount = 0;
+};
+
+BlockEncoder.prototype._read = function () {
+  var self = this;
+  var data = this._queue.pop();
+  if (!data) {
+    if (this._finished && !this._pending) {
+      process.nextTick(function () { self.push(null); });
+    } else {
+      this._needPush = true;
+    }
+    return;
+  }
+
+  this.push(LONG_TYPE.toBuffer(data.count, true));
+  this.push(LONG_TYPE.toBuffer(data.buf.length, true));
+  this.push(data.buf);
+  this.push(this._syncMarker);
+
+  if (!this._finished) {
+    data.cb();
+  }
+};
+
+BlockEncoder.prototype._createBlockCallback = function (cb) {
+  var self = this;
+  var index = this._index++;
+  var count = this._blockCount;
+  this._pending++;
+
+  return function (cause, data) {
+    if (cause) {
+      var err = new Error(f('%s codec compression error', self._codec));
+      err.cause = cause;
+      self.emit('error', err);
+      return;
+    }
+    self._pending--;
+    self._queue.push(new BlockData(index, data, cb, count));
+    if (self._needPush) {
+      self._needPush = false;
+      self._read();
+    }
+  };
+};
+
+
+// Helpers.
+
+/**
+ * An indexed block.
+ * 
+ * This can be used to preserve block order since compression and decompression
+ * can cause some some blocks to be returned out of order. The count is only
+ * used when encoding.
+ */
+function BlockData(index, buf, cb, count) {
+  this.index = index;
+  this.buf = buf;
+  this.cb = cb;
+  this.count = count | 0;
+}
+
+/** Maybe get a block. */
+function tryReadBlock(tap) {
+  var pos = tap.pos;
+  var block = BLOCK_TYPE._read(tap);
+  if (!tap.isValid()) {
+    tap.pos = pos;
+    return null;
+  }
+  return block;
+}
+
+/** Create bytes consumer, either reading or skipping records. */
+function createReader(noDecode, writerType, readerType) {
+  if (noDecode) {
+    return (function (skipper) {
+      return function (tap) {
+        var pos = tap.pos;
+        skipper(tap);
+        return tap.buf.slice(pos, tap.pos);
+      };
+    })(writerType._skip);
+  } else if (readerType) {
+    var resolver = readerType.createResolver(writerType);
+    return function (tap) { return resolver._read(tap); };
+  } else {
+    return function (tap) { return writerType._read(tap); };
+  }
+}
+
+/** Copy a buffer. This avoids creating a slice of the original buffer. */
+function copyBuffer(buf, pos, len) {
+  var copy = new Buffer(len);
+  buf.copy(copy, 0, pos, pos + len);
+  return copy;
+}
+
+
+module.exports = {
+  HEADER_TYPE: HEADER_TYPE, // For tests.
+  MAGIC_BYTES: MAGIC_BYTES, // Idem.
+  streams: {
+    BlockDecoder: BlockDecoder,
+    BlockEncoder: BlockEncoder,
+    RawDecoder: RawDecoder,
+    RawEncoder: RawEncoder
+  }
+};
+
+}).call(this,require('_process'),require("buffer").Buffer)
+},{"./types":55,"./utils":56,"_process":23,"buffer":16,"stream":42,"util":47,"zlib":15}],53:[function(require,module,exports){
+(function (process,Buffer){
+/* jshint node: true */
+
+// TODO: Add broadcast option to client `_emitMessage`, accessible for one-way
+// messages.
+// TODO: Add `server.mount` method to allow combining servers. The API is as
+// follows: a mounted server's (i.e. the method's argument) handlers have lower
+// precedence than the original server (i.e. `this`); the mounted server's
+// middlewares are only invoked for its handlers.
+// TODO: Change `objectMode` client and server channel option to `encoding`
+// (accepting `'netty'`, `'standard'`, and `null` or `undefined`). Perhaps also
+// expose encoders (API TBD).
+
+'use strict';
+
+/** This module implements Avro's IPC/RPC logic. */
+
+var types = require('./types'),
+    utils = require('./utils'),
+    events = require('events'),
+    stream = require('stream'),
+    util = require('util');
+
+
+// A few convenience imports.
+var Tap = utils.Tap;
+var Type = types.Type;
+var debug = util.debuglog('avsc:services');
+var f = util.format;
+
+// Various useful types. We instantiate options once, to share the registry.
+var OPTS = {namespace: 'org.apache.avro.ipc'};
+
+var BOOLEAN_TYPE = Type.forSchema('boolean', OPTS);
+
+var MAP_BYTES_TYPE = Type.forSchema({type: 'map', values: 'bytes'}, OPTS);
+
+var STRING_TYPE = Type.forSchema('string', OPTS);
+
+var HANDSHAKE_REQUEST_TYPE = Type.forSchema({
+  name: 'HandshakeRequest',
+  type: 'record',
+  fields: [
+    {name: 'clientHash', type: {name: 'MD5', type: 'fixed', size: 16}},
+    {name: 'clientProtocol', type: ['null', 'string'], 'default': null},
+    {name: 'serverHash', type: 'MD5'},
+    {name: 'meta', type: ['null', MAP_BYTES_TYPE], 'default': null}
+  ]
+}, OPTS);
+
+var HANDSHAKE_RESPONSE_TYPE = Type.forSchema({
+  name: 'HandshakeResponse',
+  type: 'record',
+  fields: [
+    {
+      name: 'match',
+      type: {
+        name: 'HandshakeMatch',
+        type: 'enum',
+        symbols: ['BOTH', 'CLIENT', 'NONE']
+      }
+    },
+    {name: 'serverProtocol', type: ['null', 'string'], 'default': null},
+    {name: 'serverHash', type: ['null', 'MD5'], 'default': null},
+    {name: 'meta', type: ['null', MAP_BYTES_TYPE], 'default': null}
+  ]
+}, OPTS);
+
+// Prefix used to differentiate between messages when sharing a stream. This
+// length should be smaller than 16. The remainder is used for disambiguating
+// between concurrent messages (the current value, 16, therefore supports ~64k
+// concurrent messages).
+var PREFIX_LENGTH = 16;
+
+// Internal message, used to check protocol compatibility.
+var PING_MESSAGE = new Message(
+  '', // Empty name (invalid for other "normal" messages).
+  Type.forSchema({name: 'PingRequest', type: 'record', fields: []}, OPTS),
+  Type.forSchema(['string'], OPTS),
+  Type.forSchema('null', OPTS)
+);
+
+/** An Avro message, containing its request, response, etc. */
+function Message(name, reqType, errType, resType, oneWay, doc) {
+  this.name = name;
+  if (!Type.isType(reqType, 'record')) {
+    throw new Error('invalid request type');
+  }
+  this.requestType = reqType;
+  if (
+    !Type.isType(errType, 'union') ||
+    !Type.isType(errType.getTypes()[0], 'string')
+  ) {
+    throw new Error('invalid error type');
+  }
+  this.errorType = errType;
+  if (oneWay) {
+    if (!Type.isType(resType, 'null') || errType.getTypes().length > 1) {
+      throw new Error('inapplicable one-way parameter');
+    }
+  }
+  this.responseType = resType;
+  this.oneWay = !!oneWay;
+  this.doc = doc !== undefined ? '' + doc : undefined;
+  Object.freeze(this);
+}
+
+Message.forSchema = function (name, schema, opts) {
+  opts = opts || {};
+  if (!types.isValidName(name)) {
+    throw new Error(f('invalid message name: %s', name));
+  }
+  // We use a record with a placeholder name here (the user might have set
+  // `noAnonymousTypes`, so we can't use an anonymous one). We remove it from
+  // the registry afterwards to avoid exposing it outside.
+  if (!Array.isArray(schema.request)) {
+    throw new Error(f('invalid message request: %s', name));
+  }
+  var recordName = f('%s.%sRequest', OPTS.namespace, utils.capitalize(name));
+  var reqType = Type.forSchema({
+    name: recordName,
+    type: 'record',
+    namespace: opts.namespace || '', // Don't leak request namespace.
+    fields: schema.request
+  }, opts);
+  delete opts.registry[recordName];
+  if (!schema.response) {
+    throw new Error(f('invalid message response: %s', name));
+  }
+  var resType = Type.forSchema(schema.response, opts);
+  if (schema.errors !== undefined && !Array.isArray(schema.errors)) {
+    throw new Error(f('invalid message errors: %s', name));
+  }
+  var errType = Type.forSchema(['string'].concat(schema.errors || []), opts);
+  var oneWay = !!schema['one-way'];
+  return new Message(name, reqType, errType, resType, oneWay, schema.doc);
+};
+
+Message.prototype.schema = Type.prototype.getSchema;
+
+Message.prototype._attrs = function (opts) {
+  var reqSchema = this.requestType._attrs(opts);
+  var schema = {
+    request: reqSchema.fields,
+    response: this.responseType._attrs(opts)
+  };
+  var msgDoc = this.doc;
+  if (msgDoc !== undefined) {
+    schema.doc = msgDoc;
+  }
+  var errSchema = this.errorType._attrs(opts);
+  if (errSchema.length > 1) {
+    schema.errors = errSchema.slice(1);
+  }
+  if (this.oneWay) {
+    schema['one-way'] = true;
+  }
+  return schema;
+};
+
+// Deprecated.
+
+utils.addDeprecatedGetters(
+  Message,
+  ['name', 'errorType', 'requestType', 'responseType']
+);
+
+Message.prototype.isOneWay = util.deprecate(
+  function () { return this.oneWay; },
+  'use `.oneWay` directly instead of `.isOneWay()`'
+);
+
+/**
+ * An Avro RPC service.
+ * 
+ * This constructor shouldn't be called directly, but via the
+ * `Service.forProtocol` method. This function performs little logic to better
+ * support efficient copy.
+ */
+function Service(name, messages, types, ptcl, server) {
+  if (typeof name != 'string') {
+    // Let's be helpful in case this class is instantiated directly.
+    return Service.forProtocol(name, messages);
+  }
+
+  this.name = name;
+  this._messagesByName = messages || {};
+  this.messages = Object.freeze(utils.objectValues(this._messagesByName));
+
+  this._typesByName = types || {};
+  this.types = Object.freeze(utils.objectValues(this._typesByName));
+
+  this.protocol = ptcl;
+  // We cache a string rather than a buffer to not retain an entire slab.
+  this._hashStr = utils.getHash(JSON.stringify(ptcl)).toString('binary');
+  this.doc = ptcl.doc ? '' + ptcl.doc : undefined;
+
+  // We add a server to each protocol for backwards-compatibility (to allow
+	// the
+  // use of `protocol.on`). This covers all cases except the use of the
+  // `strictErrors` option, which requires moving to the new API.
+  this._server = server || this.createServer({silent: true});
+  Object.freeze(this);
+}
+
+Service.Client = Client;
+
+Service.Server = Server;
+
+Service.compatible = function (clientSvc, serverSvc) {
+  try {
+    createReaders(clientSvc, serverSvc);
+  } catch (err) {
+    return false;
+  }
+  return true;
+};
+
+Service.forProtocol = function (ptcl, opts) {
+  opts = opts || {};
+
+  var name = ptcl.protocol;
+  if (!name) {
+    throw new Error('missing protocol name');
+  }
+  if (ptcl.namespace !== undefined) {
+    opts.namespace = ptcl.namespace;
+  } else {
+    var match = /^(.*)\.[^.]+$/.exec(name);
+    if (match) {
+      opts.namespace = match[1];
+    }
+  }
+  name = types.qualify(name, opts.namespace);
+
+  if (ptcl.types) {
+    ptcl.types.forEach(function (obj) { Type.forSchema(obj, opts); });
+  }
+  var msgs;
+  if (ptcl.messages) {
+    msgs = {};
+    Object.keys(ptcl.messages).forEach(function (key) {
+      msgs[key] = Message.forSchema(key, ptcl.messages[key], opts);
+    });
+  }
+
+  return new Service(name, msgs, opts.registry, ptcl);
+};
+
+Service.isService = function (any) {
+  // Not fool-proof but likely sufficient.
+  return !!any && any.hasOwnProperty('_hashStr');
+};
+
+Service.prototype.createClient = function (opts) {
+  var client = new Client(this, opts);
+  process.nextTick(function () {
+    // We delay this processing such that we can attach handlers to the client
+    // before any channels get created.
+    if (opts && opts.server) {
+      // Convenience in-memory client. This can be useful to make requests
+      // relatively efficiently to an in-process server. Note that it is still
+      // is less efficient than direct method calls (because of the
+      // serialization, which does provide "type-safety" though).
+      var obj = {objectMode: true};
+      var pts = [new stream.PassThrough(obj), new stream.PassThrough(obj)];
+      opts.server.createChannel({readable: pts[0], writable: pts[1]}, obj);
+      client.createChannel({readable: pts[1], writable: pts[0]}, obj);
+    } else if (opts && opts.transport) {
+      // Convenience functionality for the common single channel use-case: we
+      // add a single channel using default options to the client.
+      client.createChannel(opts.transport);
+    }
+  });
+  return client;
+};
+
+Service.prototype.createServer = function (opts) {
+  return new Server(this, opts);
+};
+
+Object.defineProperty(Service.prototype, 'hash', {
+  enumerable: true,
+  get: function () { return new Buffer(this._hashStr, 'binary'); }
+});
+
+Service.prototype.message = function (name) {
+  return this._messagesByName[name];
+};
+
+Service.prototype.type = function (name) {
+  return this._typesByName[name];
+};
+
+Service.prototype.inspect = function () {
+  return f('<Service %j>', this.name);
+};
+
+// Deprecated methods.
+
+utils.addDeprecatedGetters(
+  Service,
+  ['message', 'messages', 'name', 'type', 'types']
+);
+
+Service.prototype.createEmitter = util.deprecate(
+  function (transport, opts) {
+    opts = opts || {};
+    var client = this.createClient({
+      cache: opts.cache,
+      buffering: false,
+      strictTypes: opts.strictErrors,
+      timeout: opts.timeout
+    });
+    var channel = client.createChannel(transport, opts);
+    forwardErrors(client, channel);
+    return channel;
+  },
+  'use `.createClient()` instead of `.createEmitter()`'
+);
+
+Service.prototype.createListener = util.deprecate(
+  function (transport, opts) {
+    if (opts && opts.strictErrors) {
+      throw new Error('use `.createServer()` to support strict errors');
+    }
+    return this._server.createChannel(transport, opts);
+  },
+  'use `.createServer().createChannel()` instead of `.createListener()`'
+);
+
+Service.prototype.emit = util.deprecate(
+  function (name, req, channel, cb) {
+    if (!channel || !this.equals(channel.client._svc$)) {
+      throw new Error('invalid emitter');
+    }
+
+    var client = channel.client;
+    // In case the method is overridden.
+    Client.prototype.emitMessage.call(client, name, req, cb && cb.bind(this));
+    return channel.getPending();
+  },
+  'create a client via `.createClient()` to emit messages instead of `.emit()`'
+);
+
+Service.prototype.equals = util.deprecate(
+  function (any) {
+    return (
+      Service.isService(any) &&
+      this.getFingerprint().equals(any.getFingerprint())
+    );
+  },
+  'equality testing is deprecated, compare the `.protocol`s instead'
+);
+
+Service.prototype.getFingerprint = util.deprecate(
+  function (algorithm) {
+    return utils.getHash(JSON.stringify(this.protocol), algorithm);
+  },
+  'use `.hash` instead of `.getFingerprint()`'
+);
+
+Service.prototype.getSchema = util.deprecate(
+  Type.prototype.getSchema,
+  'use `.protocol` instead of `.getSchema()`'
+);
+
+Service.prototype.on = util.deprecate(
+  function (name, handler) {
+    var self = this; // This protocol.
+    this._server.onMessage(name, function (req, cb) {
+      return handler.call(self, req, this.channel, cb);
+    });
+    return this;
+  },
+  'use `.createServer().onMessage()` instead of `.on()`'
+);
+
+Service.prototype.subprotocol = util.deprecate(
+  function () {
+    var parent = this._server;
+    var opts = {strictTypes: parent._strict, cache: parent._cache};
+    var server = new Server(parent.service, opts);
+    server._handlers = Object.create(parent._handlers);
+    return new Service(
+      this.name,
+      this._messagesByName,
+      this._typesByName,
+      this.protocol,
+      server
+    );
+  },
+  '`.subprotocol()` will be removed in 5.1'
+);
+
+Service.prototype._attrs = function (opts) {
+  var ptcl = {protocol: this.name};
+
+  var types = [];
+  this.types.forEach(function (t) {
+    if (t.getName() === undefined) {
+      // Don't include any unnamed types (e.g. primitives).
+      return;
+    }
+    var typeSchema = t._attrs(opts);
+    if (typeof typeSchema != 'string') {
+      // Some of the named types might already have been defined in a
+      // previous type, in this case we don't include its reference.
+      types.push(typeSchema);
+    }
+  });
+  if (types.length) {
+    ptcl.types = types;
+  }
+
+  var msgNames = Object.keys(this._messagesByName);
+  if (msgNames.length) {
+    ptcl.messages = {};
+    msgNames.forEach(function (name) {
+      ptcl.messages[name] = this._messagesByName[name]._attrs(opts);
+    }, this);
+  }
+
+  if (opts && opts.exportAttrs && this.doc !== undefined) {
+    ptcl.doc = this.doc;
+  }
+  return ptcl;
+};
+
+/** Function to retrieve a remote service's protocol. */
+function discoverProtocol(transport, opts, cb) {
+  if (cb === undefined && typeof opts == 'function') {
+    cb = opts;
+    opts = undefined;
+  }
+
+  var svc = new Service({protocol: 'Empty'}, OPTS);
+  var ptclStr;
+  svc.createClient({timeout: opts && opts.timeout})
+    .createChannel(transport, {
+      scope: opts && opts.scope,
+      endWritable: typeof transport == 'function' // Stateless transports
+													// only.
+    }).once('handshake', function (hreq, hres) {
+        ptclStr = hres.serverProtocol;
+        this.destroy(true);
+      })
+      .once('eot', function (pending, err) {
+        // Stateless transports will throw an interrupted error when the
+        // channel is destroyed, we ignore it here.
+        if (err && !/interrupted/.test(err)) {
+          cb(err); // Likely timeout.
+        } else {
+          cb(null, JSON.parse(ptclStr));
+        }
+      });
+}
+
+/** Load-balanced message sender. */
+function Client(svc, opts) {
+  opts = opts || {};
+  events.EventEmitter.call(this);
+
+  // We have to suffix all client properties to be safe, since the message
+  // names aren't prefixed with clients (unlike servers).
+  this._svc$ = svc;
+  this._channels$ = []; // Active channels.
+  this._fns$ = []; // Middleware functions.
+
+  this._buffering$ = !!opts.buffering;
+  this._cache$ = opts.cache || {}; // For backwards compatibility.
+  this._policy$ = opts.channelPolicy;
+  this._strict$ = !!opts.strictTypes;
+  this._timeout$ = utils.getOption(opts, 'timeout', 10000);
+
+  if (opts.remoteProtocols) {
+    insertRemoteProtocols(this._cache$, opts.remoteProtocols, svc, true);
+  }
+
+  this._svc$.messages.forEach(function (msg) {
+    this[msg.name] = this._createMessageHandler$(msg);
+  }, this);
+}
+util.inherits(Client, events.EventEmitter);
+
+Client.prototype.activeChannels = function () {
+  return this._channels$.slice();
+};
+
+Client.prototype.createChannel = function (transport, opts) {
+  var objectMode = opts && opts.objectMode;
+  var channel;
+  if (typeof transport == 'function') {
+    var writableFactory;
+    if (objectMode) {
+      writableFactory = transport;
+    } else {
+      // We provide a default standard-compliant codec. This should support
+      // most use-cases (for example when speaking to the official Java and
+      // Python implementations over HTTP, or when this library is used for
+      // both the emitting and listening sides).
+      writableFactory = function (cb) {
+        var encoder = new FrameEncoder();
+        var writable = transport(function (err, readable) {
+          if (err) {
+            cb(err);
+            return;
+          }
+          // Since the decoder isn't exposed (so can't have an error handler
+          // attached, we forward any errors to the client). Since errors
+			// would
+          // only get thrown when the decoder flushes (if there is trailing
+          // data), at which point the source will have ended, there is no
+			// need
+          // to add re-piping logic (destination errors trigger an unpipe).
+          var decoder = new FrameDecoder()
+            .once('error', function (err) { channel.destroy(err); });
+          cb(null, readable.pipe(decoder));
+        });
+        if (writable) {
+          encoder.pipe(writable);
+          return encoder;
+        }
+      };
+    }
+    channel = new StatelessClientChannel(this, writableFactory, opts);
+  } else {
+    var readable, writable;
+    if (isStream(transport)) {
+      readable = writable = transport;
+    } else {
+      readable = transport.readable;
+      writable = transport.writable;
+    }
+    if (!objectMode) {
+      // To ease communication with Java servers, we provide a default codec
+      // compatible with Java servers' `NettyTransportCodec`'s implementation.
+      var decoder = new NettyDecoder();
+      readable = readable.pipe(decoder);
+      var encoder = new NettyEncoder();
+      encoder.pipe(writable);
+      writable = encoder;
+    }
+    channel = new StatefulClientChannel(this, readable, writable, opts);
+    if (!objectMode) {
+      // Since we never expose the automatically created encoder and decoder,
+      // we release them ourselves here when the channel ends. (Unlike for
+      // stateless channels, it is conceivable for the underlying stream to be
+      // reused afterwards).
+      channel.once('eot', function () {
+        readable.unpipe(decoder);
+        encoder.unpipe(writable);
+      });
+      // We also forward any (trailing data) error.
+      decoder.once('error', function (err) { channel.destroy(err); });
+    }
+  }
+  var channels = this._channels$;
+  channels.push(channel);
+  channel.once('_drain', function () {
+    // Remove the channel from the list of active ones.
+    channels.splice(channels.indexOf(this), 1);
+  });
+  // We restrict buffering to startup, otherwise we risk silently hiding
+	// errors
+  // (especially since channel timeouts don't apply yet).
+  this._buffering$ = false;
+  this.emit('channel', channel);
+  return channel;
+};
+
+Client.prototype.destroyChannels = function (opts) {
+  this._channels$.forEach(function (channel) {
+    channel.destroy(opts && opts.noWait);
+  });
+};
+
+Client.prototype.emitMessage = function (name, req, opts, cb) {
+  var msg = getExistingMessage(this._svc$, name);
+  var wreq = new WrappedRequest(msg, {}, req);
+  this._emitMessage$(wreq, opts, cb);
+};
+
+Client.prototype.remoteProtocols = function () {
+  return getRemoteProtocols(this._cache$, true);
+};
+
+Object.defineProperty(Client.prototype, 'service', {
+  enumerable: true,
+  get: function () { return this._svc$; }
+});
+
+Client.prototype.use = function (/* fn ... */) {
+  var i, l, fn;
+  for (i = 0, l = arguments.length; i < l; i++) {
+    fn = arguments[i];
+    this._fns$.push(fn.length < 3 ? fn(this) : fn);
+  }
+  return this;
+};
+
+Client.prototype._emitMessage$ = function (wreq, opts, cb) {
+  // Common logic between `client.emitMessage` and the "named" message
+	// methods.
+  if (!cb && typeof opts === 'function') {
+    cb = opts;
+    opts = undefined;
+  }
+  var self = this;
+  var channels = this._channels$;
+  var numChannels = channels.length;
+  if (!numChannels) {
+    if (this._buffering$) {
+      debug('no active client channels, buffering call');
+      this.once('channel', function () {
+        this._emitMessage$(wreq, opts, cb);
+      });
+    } else {
+      var err = new Error('no active channels');
+      process.nextTick(function () {
+        if (cb) {
+          cb.call(new CallContext(wreq._msg), err);
+        } else {
+          self.emit('error', err);
+        }
+      });
+    }
+    return;
+  }
+
+  opts = opts || {};
+  if (opts.timeout === undefined) {
+    opts.timeout = this._timeout$;
+  }
+
+  var channel;
+  if (numChannels === 1) {
+    // Common case, optimized away.
+    channel = channels[0];
+  } else if (this._policy$) {
+    channel = this._policy$(this._channels$.slice());
+  } else {
+    // Random selection, cheap and likely good enough for most use-cases.
+    channel = channels[Math.floor(Math.random() * numChannels)];
+  }
+
+  channel._emit(wreq, opts, function (err, wres) {
+    var ctx = this; // Call context.
+    var errType = ctx.message.errorType;
+    if (err) {
+      // System error, likely the message wasn't sent (or an error occurred
+      // while decoding the response).
+      if (self._strict$) {
+        err = errType.clone(err.message, {wrapUnions: true});
+      }
+      done(err);
+      return;
+    }
+    if (!wres) {
+      // This is a one way message.
+      done();
+      return;
+    }
+    // Message transmission succeeded, we transmit the message data; massaging
+    // any error strings into actual `Error` objects in non-strict mode.
+    err = wres.error;
+    if (!self._strict$) {
+      // Try to coerce an eventual error into more idiomatic JavaScript types:
+      // `undefined` becomes `null` and a remote string "system" error is
+      // wrapped inside an actual `Error` object.
+      if (err === undefined) {
+        err = null;
+      } else {
+        if (Type.isType(errType, 'union:unwrapped')) {
+          if (typeof err == 'string') {
+            err = new Error(err);
+          }
+        } else if (err && err.string && typeof err.string == 'string') {
+          err = new Error(err.string);
+        }
+      }
+    }
+    done(err, wres.response);
+
+    function done(err, res) {
+      if (cb) {
+        cb.call(ctx, err, res);
+      } else if (err) {
+        self.emit('error', err);
+      }
+    }
+  });
+};
+
+Client.prototype._createMessageHandler$ = function (msg) {
+  // jshint -W054
+  var fields = msg.requestType.getFields();
+  var names = fields.map(function (f) { return f.getName(); });
+  var body = 'return function ' + msg.name + '(';
+  if (names.length) {
+    body += names.join(', ') + ', ';
+  }
+  body += 'opts, cb) {\n';
+  body += '  var req = {';
+  body += names.map(function (n) { return n + ': ' + n; }).join(', ');
+  body += '};\n';
+  body += '  return this.emitMessage(\'' + msg.name + '\', req, opts, cb);\n';
+  body += '};';
+  return (new Function(body))();
+};
+
+/** Message receiver. */
+function Server(svc, opts) {
+  opts = opts || {};
+  events.EventEmitter.call(this);
+
+  this.service = svc;
+  this._handlers = {};
+  this._fns = []; // Middleware functions.
+  this._channels = {}; // Active channels.
+  this._nextChannelId = 1;
+
+  this._cache = opts.cache || {}; // Deprecated.
+  this._defaultHandler = opts.defaultHandler;
+  this._sysErrFormatter = opts.systemErrorFormatter;
+  this._silent = !!opts.silent;
+  this._strict = !!opts.strictTypes;
+
+  if (opts.remoteProtocols) {
+    insertRemoteProtocols(this._cache, opts.remoteProtocols, svc, false);
+  }
+
+  svc.messages.forEach(function (msg) {
+    var name = msg.name;
+    if (!opts.noCapitalize) {
+      name = utils.capitalize(name);
+    }
+    this['on' + name] = this._createMessageHandler(msg);
+  }, this);
+}
+util.inherits(Server, events.EventEmitter);
+
+Server.prototype.activeChannels = function () {
+  return utils.objectValues(this._channels);
+};
+
+Server.prototype.createChannel = function (transport, opts) {
+  var objectMode = opts && opts.objectMode;
+  var channel;
+  if (typeof transport == 'function') {
+    var readableFactory;
+    if (objectMode) {
+      readableFactory = transport;
+    } else {
+      readableFactory = function (cb) {
+        var decoder = new FrameDecoder()
+          .once('error', function (err) { channel.destroy(err); });
+        return transport(function (err, writable) {
+          if (err) {
+            cb(err);
+            return;
+          }
+          var encoder = new FrameEncoder();
+          encoder.pipe(writable);
+          cb(null, encoder);
+        }).pipe(decoder);
+      };
+    }
+    channel = new StatelessServerChannel(this, readableFactory, opts);
+  } else {
+    var readable, writable;
+    if (isStream(transport)) {
+      readable = writable = transport;
+    } else {
+      readable = transport.readable;
+      writable = transport.writable;
+    }
+    if (!objectMode) {
+      var decoder = new NettyDecoder();
+      readable = readable.pipe(decoder);
+      var encoder = new NettyEncoder();
+      encoder.pipe(writable);
+      writable = encoder;
+    }
+    channel = new StatefulServerChannel(this, readable, writable, opts);
+    if (!objectMode) {
+      // Similar to client channels, since we never expose the encoder and
+      // decoder, we must release them ourselves here.
+      channel.once('eot', function () {
+        readable.unpipe(decoder);
+        encoder.unpipe(writable);
+      });
+      decoder.once('error', function (err) { channel.destroy(err); });
+    }
+  }
+
+  if (!this.listeners('error').length) {
+    this.on('error', this._onError);
+  }
+  var channelId = this._nextChannelId++;
+  var channels = this._channels;
+  channels[channelId] = channel
+    .once('eot', function () { delete channels[channelId]; });
+  this.emit('channel', channel);
+  return channel;
+};
+
+Server.prototype.onMessage = function (name, handler) {
+  getExistingMessage(this.service, name); // Check message existence.
+  this._handlers[name] = handler;
+  return this;
+};
+
+Server.prototype.remoteProtocols = function () {
+  return getRemoteProtocols(this._cache, false);
+};
+
+Server.prototype.use = function (/* fn ... */) {
+  var i, l, fn;
+  for (i = 0, l = arguments.length; i < l; i++) {
+    fn = arguments[i];
+    this._fns.push(fn.length < 3 ? fn(this) : fn);
+  }
+  return this;
+};
+
+Server.prototype._createMessageHandler = function (msg) {
+  // jshint -W054
+  var name = msg.name;
+  var fields = msg.requestType.fields;
+  var numArgs = fields.length;
+  var args = fields.length ?
+    ', ' + fields.map(function (f) { return 'req.' + f.name; }).join(', ') :
+    '';
+  // We are careful to not lose the initial handler's number of arguments (or
+  // more specifically whether it would have access to the callback or not).
+  // This is useful to implement "smart promisification" logic downstream.
+  var body = 'return function (handler) {\n';
+  body += '  if (handler.length > ' + numArgs + ') {\n';
+  body += '    return this.onMessage(\'' + name + '\', function (req, cb) {\n';
+  body += '      return handler.call(this' + args + ', cb);\n';
+  body += '    });\n';
+  body += '  } else {\n';
+  body += '    return this.onMessage(\'' + name + '\', function (req) {\n';
+  body += '      return handler.call(this' + args + ');\n';
+  body += '    });\n';
+  body += '  }\n';
+  body += '};\n';
+  return (new Function(body))();
+};
+
+Server.prototype._onError = function (err) {
+  /* istanbul ignore if */
+  if (!this._silent && err.rpcCode !== 'UNKNOWN_PROTOCOL') {
+    console.error();
+    if (err.rpcCode) {
+      console.error(err.rpcCode);
+      console.error(err.cause);
+    } else {
+      console.error('INTERNAL_SERVER_ERROR');
+      console.error(err);
+    }
+  }
+};
+
+/** Base message emitter class. See below for the two available variants. */
+function ClientChannel(client, opts) {
+  opts = opts || {};
+  events.EventEmitter.call(this);
+
+  this.client = client;
+  this.timeout = utils.getOption(opts, 'timeout', client._timeout$);
+  this._endWritable = !!utils.getOption(opts, 'endWritable', true);
+  this._prefix = normalizedPrefix(opts.scope);
+
+  var cache = client._cache$;
+  var clientSvc = client._svc$;
+  var hash = opts.serverHash;
+  if (!hash) {
+    hash = clientSvc.hash;
+  }
+  var adapter = cache[hash];
+  if (!adapter) {
+    // This might happen even if the server hash option was set if the cache
+    // doesn't contain the corresponding adapter. In this case we fall back to
+    // the client's protocol (as mandated by the spec).
+    hash = clientSvc.hash;
+    adapter = cache[hash] = new Adapter(clientSvc, clientSvc, hash);
+  }
+  this._adapter = adapter;
+
+  this._registry = new Registry(this, PREFIX_LENGTH);
+  this.pending = 0;
+  this.destroyed = false;
+  this.draining = false;
+  this.once('_eot', function (pending, err) {
+    // Since this listener is only run once, we will only forward an error if
+    // it is present during the initial `destroy` call, which is OK.
+    debug('client channel EOT');
+    this.destroyed = true;
+    this.emit('eot', pending, err);
+  });
+}
+util.inherits(ClientChannel, events.EventEmitter);
+
+ClientChannel.prototype.destroy = function (noWait) {
+  debug('destroying client channel');
+  if (!this.draining) {
+    this.draining = true;
+    this.emit('_drain');
+  }
+  var registry = this._registry;
+  var pending = this.pending;
+  if (noWait) {
+    registry.clear();
+  }
+  if (noWait || !pending) {
+    if (isError(noWait)) {
+      debug('fatal client channel error: %s', noWait);
+      this.emit('_eot', pending, noWait);
+    } else {
+      this.emit('_eot', pending);
+    }
+  } else {
+    debug('client channel entering drain mode (%s pending)', pending);
+  }
+};
+
+ClientChannel.prototype.ping = function (timeout, cb) {
+  if (!cb && typeof timeout == 'function') {
+    cb = timeout;
+    timeout = undefined;
+  }
+  var self = this;
+  var wreq = new WrappedRequest(PING_MESSAGE);
+  this._emit(wreq, {timeout: timeout}, function (err) {
+    if (cb) {
+      cb.call(self, err);
+    } else if (err) {
+      self.destroy(err);
+    }
+  });
+};
+
+ClientChannel.prototype._createHandshakeRequest = function (adapter, noSvc) {
+  var svc = this.client._svc$;
+  return {
+    clientHash: svc.hash,
+    clientProtocol: noSvc ? null : JSON.stringify(svc.protocol),
+    serverHash: adapter._hash
+  };
+};
+
+ClientChannel.prototype._emit = function (wreq, opts, cb) {
+  var msg = wreq._msg;
+  var wres = msg.oneWay ? undefined : new WrappedResponse(msg, {});
+  var ctx = new CallContext(msg, this);
+  var self = this;
+  this.pending++;
+  process.nextTick(function () {
+    if (!msg.name) {
+      // Ping request, bypass middleware.
+      onTransition(wreq, wres, onCompletion);
+    } else {
+      self.emit('outgoingCall', ctx, opts);
+      var fns = self.client._fns$;
+      debug('starting client middleware chain (%s middleware)', fns.length);
+      chainMiddleware({
+        fns: fns,
+        ctx: ctx,
+        wreq: wreq,
+        wres: wres,
+        onTransition: onTransition,
+        onCompletion: onCompletion,
+        onError: onError
+      });
+    }
+  });
+
+  function onTransition(wreq, wres, prev) {
+    // Serialize the message.
+    var err, reqBuf;
+    if (self.destroyed) {
+      err = new Error('channel destroyed');
+    } else {
+      try {
+        reqBuf = wreq.toBuffer();
+      } catch (cause) {
+        err = serializationError(
+          f('invalid %j request', msg.name),
+          wreq,
+          [
+            {name: 'headers', type: MAP_BYTES_TYPE},
+            {name: 'request', type: msg.requestType}
+          ]
+        );
+      }
+    }
+    if (err) {
+      prev(err);
+      return;
+    }
+
+    // Generate the response callback.
+    var timeout = (opts && opts.timeout !== undefined) ?
+      opts.timeout :
+      self.timeout;
+    var id = self._registry.add(timeout, function (err, resBuf, adapter) {
+      if (!err && !msg.oneWay) {
+        try {
+          adapter._decodeResponse(resBuf, wres, msg);
+        } catch (cause) {
+          err = cause;
+        }
+      }
+      prev(err);
+    });
+    id |= self._prefix;
+
+    debug('sending message %s', id);
+    self._send(id, reqBuf, !!msg && msg.oneWay);
+  }
+
+  function onCompletion(err) {
+    self.pending--;
+    cb.call(ctx, err, wres);
+    if (self.draining && !self.destroyed && !self.pending) {
+      self.destroy();
+    }
+  }
+
+  function onError(err) {
+    // This will happen if a middleware callback is called multiple times. We
+    // forward the error to the client rather than emit it on the channel since
+    // middleware are a client-level abstraction, so better handled there.
+    self.client.emit('error', err, self);
+  }
+};
+
+ClientChannel.prototype._getAdapter = function (hres) {
+  var hash = hres.serverHash;
+  var cache = this.client._cache$;
+  var adapter = cache[hash];
+  if (adapter) {
+    return adapter;
+  }
+  var ptcl = JSON.parse(hres.serverProtocol);
+  var serverSvc = Service.forProtocol(ptcl);
+  adapter = new Adapter(this.client._svc$, serverSvc, hash, true);
+  return cache[hash] = adapter;
+};
+
+ClientChannel.prototype._matchesPrefix = function (id) {
+  return matchesPrefix(id, this._prefix);
+};
+
+ClientChannel.prototype._send = utils.abstractFunction;
+
+// Deprecated.
+
+utils.addDeprecatedGetters(ClientChannel, ['pending', 'timeout']);
+
+ClientChannel.prototype.getCache = util.deprecate(
+  function () { return this.client._cache$; },
+  'use `.remoteProtocols()` instead of `.getCache()`'
+);
+
+ClientChannel.prototype.getProtocol = util.deprecate(
+  function () {
+    return this.client._svc$;
+  },
+  'use `.service` instead or `.getProtocol()`'
+);
+
+ClientChannel.prototype.isDestroyed = util.deprecate(
+  function () { return this.destroyed; },
+  'use `.destroyed` instead of `.isDestroyed`'
+);
+
+/**
+ * Factory-based client channel.
+ * 
+ * This channel doesn't keep a persistent connection to the server and requires
+ * prepending a handshake to each message emitted. Usage examples include
+ * talking to an HTTP server (where the factory returns an HTTP request).
+ * 
+ * Since each message will use its own writable/readable stream pair, the
+ * advantage of this channel is that it is able to keep track of which response
+ * corresponds to each request without relying on transport ordering. In
+ * particular, this means these channels are compatible with any server
+ * implementation.
+ */
+function StatelessClientChannel(client, writableFactory, opts) {
+  ClientChannel.call(this, client, opts);
+  this._writableFactory = writableFactory;
+
+  if (!opts || !opts.noPing) {
+    // Ping the server to check whether the remote protocol is compatible.
+    // If not, this will throw an error on the channel.
+    debug('emitting ping request');
+    this.ping();
+  }
+}
+util.inherits(StatelessClientChannel, ClientChannel);
+
+StatelessClientChannel.prototype._send = function (id, reqBuf) {
+  var cb = this._registry.get(id);
+  var adapter = this._adapter;
+  var self = this;
+  process.nextTick(emit);
+  return true;
+
+  function emit(retry) {
+    if (self.destroyed) {
+      // The request's callback will already have been called.
+      return;
+    }
+
+    var hreq = self._createHandshakeRequest(adapter, !retry);
+
+    var writable = self._writableFactory.call(self, function (err, readable) {
+      if (err) {
+        cb(err);
+        return;
+      }
+      readable.on('data', function (obj) {
+        debug('received response %s', obj.id);
+        // We don't check that the prefix matches since the ID likely hasn't
+        // been propagated to the response (see default stateless codec).
+        var buf = Buffer.concat(obj.payload);
+        try {
+          var parts = readHead(HANDSHAKE_RESPONSE_TYPE, buf);
+          var hres = parts.head;
+          if (hres.serverHash) {
+            adapter = self._getAdapter(hres);
+          }
+        } catch (cause) {
+          cb(cause);
+          return;
+        }
+        var match = hres.match;
+        debug('handshake match: %s', match);
+        self.emit('handshake', hreq, hres);
+        if (match === 'NONE') {
+          // Try again, including the full protocol this time.
+          process.nextTick(function() { emit(true); });
+        } else {
+          // Change the default adapter.
+          self._adapter = adapter;
+          cb(null, parts.tail, adapter);
+        }
+      });
+    });
+    if (!writable) {
+      cb(new Error('invalid writable stream'));
+      return;
+    }
+    writable.write({
+      id: id,
+      payload: [HANDSHAKE_REQUEST_TYPE.toBuffer(hreq), reqBuf]
+    });
+    if (self._endWritable) {
+      writable.end();
+    }
+  }
+};
+
+/**
+ * Multiplexing client channel.
+ * 
+ * These channels reuse the same streams (both readable and writable) for all
+ * messages. This avoids a lot of overhead (e.g. creating new connections,
+ * re-issuing handshakes) but requires the underlying transport to support
+ * forwarding message IDs.
+ */
+function StatefulClientChannel(client, readable, writable, opts) {
+  ClientChannel.call(this, client, opts);
+  this._readable = readable;
+  this._writable = writable;
+  this._connected = !!(opts && opts.noPing);
+  this._readable.on('end', onEnd);
+  this._writable.on('finish', onFinish);
+
+  var self = this;
+  var timer = null;
+  this.once('eot', function () {
+    if (timer) {
+      clearTimeout(timer);
+      timer = null;
+    }
+    if (!self._connected) {
+      // Clear any buffered calls (they are guaranteed to error out when
+      // reaching the transition phase).
+      self.emit('_ready');
+    }
+    // Remove references to this channel to avoid potential memory leaks.
+    this._writable.removeListener('finish', onFinish);
+    if (this._endWritable) {
+      debug('ending transport');
+      this._writable.end();
+    }
+    this._readable
+      .removeListener('data', onPing)
+      .removeListener('data', onMessage)
+      .removeListener('end', onEnd);
+  });
+
+  var hreq; // For handshake events.
+  if (this._connected) {
+    this._readable.on('data', onMessage);
+  } else {
+    this._readable.on('data', onPing);
+    process.nextTick(ping);
+    if (self.timeout) {
+      timer = setTimeout(function () {
+        self.destroy(new Error('timeout'));
+      }, self.timeout);
+    }
+  }
+
+  function ping(retry) {
+    if (self.destroyed) {
+      return;
+    }
+    hreq = self._createHandshakeRequest(self._adapter, !retry);
+    var payload = [
+      HANDSHAKE_REQUEST_TYPE.toBuffer(hreq),
+      new Buffer([0, 0]) // No header, no data (empty message name).
+    ];
+    // We can use a static ID here since we are guaranteed that this message is
+    // the only one on the channel (for this scope at least).
+    self._writable.write({id: self._prefix, payload: payload});
+  }
+
+  function onPing(obj) {
+    if (!self._matchesPrefix(obj.id)) {
+      debug('discarding unscoped response %s (still connecting)', obj.id);
+      return;
+    }
+    var buf = Buffer.concat(obj.payload);
+    try {
+      var hres = readHead(HANDSHAKE_RESPONSE_TYPE, buf).head;
+      if (hres.serverHash) {
+        self._adapter = self._getAdapter(hres);
+      }
+    } catch (cause) {
+      // This isn't a recoverable error.
+      self.destroy(cause);
+      return;
+    }
+    var match = hres.match;
+    debug('handshake match: %s', match);
+    self.emit('handshake', hreq, hres);
+    if (match === 'NONE') {
+      process.nextTick(function () { ping(true); });
+    } else {
+      debug('successfully connected');
+      if (timer) {
+        clearTimeout(timer);
+        timer = null;
+      }
+      self._readable.removeListener('data', onPing).on('data', onMessage);
+      self._connected = true;
+      self.emit('_ready');
+      hreq = null; // Release reference.
+    }
+  }
+
+  // Callback used after a connection has been established.
+  function onMessage(obj) {
+    var id = obj.id;
+    if (!self._matchesPrefix(id)) {
+      debug('discarding unscoped message %s', id);
+      return;
+    }
+    var cb = self._registry.get(id);
+    if (cb) {
+      process.nextTick(function () {
+        debug('received message %s', id);
+        // Ensure that the initial callback gets called asynchronously, even
+        // for completely synchronous transports (otherwise the number of
+        // pending requests will sometimes be inconsistent between stateful and
+        // stateless transports).
+        cb(null, Buffer.concat(obj.payload), self._adapter);
+      });
+    }
+  }
+
+  function onEnd() { self.destroy(true); }
+  function onFinish() { self.destroy(); }
+}
+util.inherits(StatefulClientChannel, ClientChannel);
+
+StatefulClientChannel.prototype._emit = function () {
+  // Override this method to allow calling `_emit` even before the channel is
+  // connected. Note that we don't perform this logic in `_send` since we want
+  // to guarantee that `'handshake'` events are emitted before any
+  // `'outgoingCall'` events.
+  if (this._connected || this.draining) {
+    ClientChannel.prototype._emit.apply(this, arguments);
+  } else {
+    debug('queuing request');
+    var args = [];
+    var i, l;
+    for (i = 0, l = arguments.length; i < l; i++) {
+      args.push(arguments[i]);
+    }
+    this.once('_ready', function () { this._emit.apply(this, args); });
+  }
+};
+
+StatefulClientChannel.prototype._send = function (id, reqBuf, oneWay) {
+  if (oneWay) {
+    var self = this;
+    // Clear the callback, passing in an empty header.
+    process.nextTick(function () {
+      self._registry.get(id)(null, new Buffer([0, 0, 0]), self._adapter);
+    });
+  }
+  return this._writable.write({id: id, payload: [reqBuf]});
+};
+
+/** The server-side emitter equivalent. */
+function ServerChannel(server, opts) {
+  opts = opts || {};
+  events.EventEmitter.call(this);
+
+  this.server = server;
+  this._endWritable = !!utils.getOption(opts, 'endWritable', true);
+  this._prefix = normalizedPrefix(opts.scope);
+
+  var cache = server._cache;
+  var svc = server.service;
+  var hash = svc.hash;
+  if (!cache[hash]) {
+    // Add the channel's protocol to the cache if it isn't already there. This
+    // will save a handshake the first time on channels with the same protocol.
+    cache[hash] = new Adapter(svc, svc, hash);
+  }
+  this._adapter = null;
+
+  this.destroyed = false;
+  this.draining = false;
+  this.pending = 0;
+  this.once('_eot', function (pending, err) {
+    debug('server channel EOT');
+    this.emit('eot', pending, err);
+  });
+}
+util.inherits(ServerChannel, events.EventEmitter);
+
+ServerChannel.prototype.destroy = function (noWait) {
+  if (!this.draining) {
+    this.draining = true;
+    this.emit('_drain');
+  }
+  if (noWait || !this.pending) {
+    this.destroyed = true;
+    if (isError(noWait)) {
+      debug('fatal server channel error: %s', noWait);
+      this.emit('_eot', this.pending, noWait);
+    } else {
+      this.emit('_eot', this.pending);
+    }
+  }
+};
+
+ServerChannel.prototype._createHandshakeResponse = function (err, hreq) {
+  var svc = this.server.service;
+  var buf = svc.hash;
+  var serverMatch = hreq && hreq.serverHash.equals(buf);
+  return {
+    match: err ? 'NONE' : (serverMatch ? 'BOTH' : 'CLIENT'),
+    serverProtocol: serverMatch ? null : JSON.stringify(svc.protocol),
+    serverHash: serverMatch ? null : buf
+  };
+};
+
+ServerChannel.prototype._getAdapter = function (hreq) {
+  var hash = hreq.clientHash;
+  var adapter = this.server._cache[hash];
+  if (adapter) {
+    return adapter;
+  }
+  if (!hreq.clientProtocol) {
+    throw toRpcError('UNKNOWN_PROTOCOL');
+  }
+  var ptcl = JSON.parse(hreq.clientProtocol);
+  var clientSvc = Service.forProtocol(ptcl);
+  adapter = new Adapter(clientSvc, this.server.service, hash, true);
+  return this.server._cache[hash] = adapter;
+};
+
+ServerChannel.prototype._matchesPrefix = function (id) {
+  return matchesPrefix(id, this._prefix);
+};
+
+ServerChannel.prototype._receive = function (reqBuf, adapter, cb) {
+  var self = this;
+  var wreq;
+  try {
+    wreq = adapter._decodeRequest(reqBuf);
+  } catch (cause) {
+    cb(self._encodeSystemError(toRpcError('INVALID_REQUEST', cause)));
+    return;
+  }
+
+  var msg = wreq._msg;
+  var wres = new WrappedResponse(msg, {});
+  if (!msg.name) {
+    // Ping message, we don't invoke middleware logic in this case.
+    wres.response = null;
+    cb(wres.toBuffer(), false);
+    return;
+  }
+
+  var ctx = new CallContext(msg, this);
+  self.emit('incomingCall', ctx);
+  var fns = this.server._fns;
+  debug('starting server middleware chain (%s middleware)', fns.length);
+  self.pending++;
+  chainMiddleware({
+    fns: fns,
+    ctx: ctx,
+    wreq: wreq,
+    wres: wres,
+    onTransition: onTransition,
+    onCompletion: onCompletion,
+    onError: onError
+  });
+
+  function onTransition(wreq, wres, prev) {
+    var handler = self.server._handlers[msg.name];
+    if (!handler) {
+      // The underlying service hasn't implemented a handler.
+      var defaultHandler = self.server._defaultHandler;
+      if (defaultHandler) {
+        // We call the default handler with arguments similar (slightly
+        // simpler, there are no phases here) to middleware such that it can
+        // easily access the message name (useful to implement proxies).
+        defaultHandler.call(ctx, wreq, wres, prev);
+      } else {
+        var cause = new Error(f('no handler for %s', msg.name));
+        prev(toRpcError('NOT_IMPLEMENTED', cause));
+      }
+    } else {
+      var pending = !msg.oneWay;
+      try {
+        if (pending) {
+          handler.call(ctx, wreq.request, function (err, res) {
+            pending = false;
+            wres.error = err;
+            wres.response = res;
+            prev();
+          });
+        } else {
+          handler.call(ctx, wreq.request);
+          prev();
+        }
+      } catch (err) {
+        // We catch synchronous failures (same as express) and return the
+        // failure. Note that the server process can still crash if an error
+        // is thrown after the handler returns but before the response is
+        // sent (again, same as express). We are careful to only trigger the
+        // response callback once, emitting the errors afterwards instead.
+        if (pending) {
+          pending = false;
+          prev(err);
+        } else {
+          onError(err);
+        }
+      }
+    }
+  }
+
+  function onCompletion(err) {
+    self.pending--;
+    var server = self.server;
+    var resBuf;
+    if (!err) {
+      var resErr = wres.error;
+      var isStrict = server._strict;
+      if (!isStrict) {
+        if (isError(resErr)) {
+          // If the error type is wrapped, we must wrap the error too.
+          wres.error = msg.errorType.clone(resErr.message, {wrapUnions: true});
+        } else if (resErr === null) {
+          // We also allow `null`'s as error in this mode, converting them to
+          // the Avro-compatible `undefined`.
+          resErr = wres.error = undefined;
+        }
+        if (
+          resErr === undefined &&
+          wres.response === undefined &&
+          msg.responseType.isValid(null)
+        ) {
+          // Finally, for messages with `null` as acceptable response type, we
+          // allow `undefined`; converting them to `null`. This allows users
+			// to
+          // write a more natural `cb()` instead of `cb(null, null)`.
+          wres.response = null;
+        }
+      }
+      try {
+        resBuf = wres.toBuffer();
+      } catch (cause) {
+        // Note that we don't add an RPC code here such that the client
+        // receives the default `INTERNAL_SERVER_ERROR` one.
+        if (wres.error !== undefined) {
+          err = serializationError(
+            f('invalid %j error', msg.name), // Sic.
+            wres,
+            [
+              {name: 'headers', type: MAP_BYTES_TYPE},
+              {name: 'error', type: msg.errorType}
+            ]
+          );
+        } else {
+          err = serializationError(
+            f('invalid %j response', msg.name),
+            wres,
+            [
+              {name: 'headers', type: MAP_BYTES_TYPE},
+              {name: 'response', type: msg.responseType}
+            ]
+          );
+        }
+      }
+    }
+    if (!resBuf) {
+      // The headers are only available if the message isn't one-way.
+      resBuf = self._encodeSystemError(err, wres.headers);
+    } else if (resErr !== undefined) {
+      server.emit('error', toRpcError('APPLICATION_ERROR', resErr));
+    }
+    cb(resBuf, msg.oneWay);
+    if (self.draining && !self.pending) {
+      self.destroy();
+    }
+  }
+
+  function onError(err) {
+    // Similar to the client equivalent, we redirect this error to the server
+    // since middleware are defined at server-level.
+    self.server.emit('error', err, self);
+  }
+};
+
+// Deprecated.
+
+utils.addDeprecatedGetters(ServerChannel, ['pending']);
+
+ServerChannel.prototype.getCache = util.deprecate(
+  function () { return this.server._cache; },
+  'use `.remoteProtocols()` instead of `.getCache()`'
+);
+
+ServerChannel.prototype.getProtocol = util.deprecate(
+  function () {
+    return this.server.service;
+  },
+  'use `.service` instead of `.getProtocol()`'
+);
+
+ServerChannel.prototype.isDestroyed = util.deprecate(
+  function () { return this.destroyed; },
+  'use `.destroyed` instead of `.isDestroyed`'
+);
+
+/**
+ * Encode an error and optional header into a valid Avro response.
+ * 
+ * @param err
+ *            {Error} Error to encode.
+ * @param header
+ *            {Object} Optional response header.
+ */
+ServerChannel.prototype._encodeSystemError = function (err, header) {
+  var server = this.server;
+  server.emit('error', err, this);
+  var errStr;
+  if (server._sysErrFormatter) {
+    // Format the error into a string to send over the wire.
+    errStr = server._sysErrFormatter.call(this, err);
+  } else if (err.rpcCode) {
+    // By default, only forward the error's message when the RPC code is set
+    // (i.e. when this isn't an internal server error).
+    errStr = err.message;
+  }
+  var hdrBuf;
+  if (header) {
+    try {
+      // Propagate the header if possible.
+      hdrBuf = MAP_BYTES_TYPE.toBuffer(header);
+    } catch (cause) {
+      server.emit('error', cause, this);
+    }
+  }
+  return Buffer.concat([
+    hdrBuf || new Buffer([0]),
+    new Buffer([1, 0]), // Error flag and first union index.
+    STRING_TYPE.toBuffer(errStr || 'internal server error')
+  ]);
+};
+
+/**
+ * Server channel for stateless transport.
+ * 
+ * This channel expect a handshake to precede each message.
+ */
+function StatelessServerChannel(server, readableFactory, opts) {
+  ServerChannel.call(this, server, opts);
+
+  this._writable = undefined;
+  var self = this;
+  var readable;
+
+  process.nextTick(function () {
+    // Delay listening to allow handlers to be attached even if the factory is
+    // purely synchronous.
+    readable = readableFactory.call(self, function (err, writable) {
+      process.nextTick(function () {
+        // We delay once more here in case this call is synchronous, to allow
+        // the readable to always be populated first.
+        if (err) {
+          onFinish(err);
+          return;
+        }
+        self._writable = writable.on('finish', onFinish);
+        self.emit('_writable');
+      });
+    }).on('data', onRequest).on('end', onEnd);
+  });
+
+
+  function onRequest(obj) {
+    var id = obj.id;
+    var buf = Buffer.concat(obj.payload);
+    var err;
+    try {
+      var parts = readHead(HANDSHAKE_REQUEST_TYPE, buf);
+      var hreq = parts.head;
+      var adapter = self._getAdapter(hreq);
+    } catch (cause) {
+      err = toRpcError('INVALID_HANDSHAKE_REQUEST', cause);
+    }
+
+    var hres = self._createHandshakeResponse(err, hreq);
+    self.emit('handshake', hreq, hres);
+    if (err) {
+      done(self._encodeSystemError(err));
+    } else {
+      self._receive(parts.tail, adapter, done);
+    }
+
+    function done(resBuf) {
+      if (!self.destroyed) {
+        if (!self._writable) {
+          self.once('_writable', function () { done(resBuf); });
+          return;
+        }
+        self._writable.write({
+          id: id,
+          payload: [HANDSHAKE_RESPONSE_TYPE.toBuffer(hres), resBuf]
+        });
+      }
+      if (self._writable && self._endWritable) {
+        self._writable.end();
+      }
+    }
+  }
+
+  function onEnd() { self.destroy(); }
+
+  function onFinish(err) {
+    readable
+      .removeListener('data', onRequest)
+      .removeListener('end', onEnd);
+    self.destroy(err || true);
+  }
+}
+util.inherits(StatelessServerChannel, ServerChannel);
+
+/**
+ * Stateful transport listener.
+ * 
+ * A handshake is done when the channel first receives a message, then all
+ * messages are sent without.
+ */
+function StatefulServerChannel(server, readable, writable, opts) {
+  ServerChannel.call(this, server, opts);
+  this._adapter = undefined;
+  this._writable = writable.on('finish', onFinish);
+  this._readable = readable.on('data', onHandshake).on('end', onEnd);
+
+  this
+    .once('_drain', function () {
+      // Stop listening to incoming events.
+      this._readable
+        .removeListener('data', onHandshake)
+        .removeListener('data', onRequest)
+        .removeListener('end', onEnd);
+    })
+    .once('eot', function () {
+      // Clean up any references to the channel on the underlying streams.
+      this._writable.removeListener('finish', onFinish);
+      if (this._endWritable) {
+        this._writable.end();
+      }
+    });
+
+  var self = this;
+
+  function onHandshake(obj) {
+    var id = obj.id;
+    if (!self._matchesPrefix(id)) {
+      return;
+    }
+    var buf = Buffer.concat(obj.payload);
+    var err;
+    try {
+      var parts = readHead(HANDSHAKE_REQUEST_TYPE, buf);
+      var hreq = parts.head;
+      self._adapter = self._getAdapter(hreq);
+    } catch (cause) {
+      err = toRpcError('INVALID_HANDSHAKE_REQUEST', cause);
+    }
+    var hres = self._createHandshakeResponse(err, hreq);
+    self.emit('handshake', hreq, hres);
+    if (err) {
+      // Either the client's protocol was unknown or it isn't compatible.
+      done(self._encodeSystemError(err));
+    } else {
+      self._readable
+        .removeListener('data', onHandshake)
+        .on('data', onRequest);
+      self._receive(parts.tail, self._adapter, done);
+    }
+
+    function done(resBuf) {
+      if (self.destroyed) {
+        return;
+      }
+      self._writable.write({
+        id: id,
+        payload: [HANDSHAKE_RESPONSE_TYPE.toBuffer(hres), resBuf]
+      });
+    }
+  }
+
+  function onRequest(obj) {
+    // These requests are not prefixed with handshakes.
+    var id = obj.id;
+    if (!self._matchesPrefix(id)) {
+      return;
+    }
+    var reqBuf = Buffer.concat(obj.payload);
+    self._receive(reqBuf, self._adapter, function (resBuf, oneWay) {
+      if (self.destroyed || oneWay) {
+        return;
+      }
+      self._writable.write({id: id, payload: [resBuf]});
+    });
+  }
+
+  function onEnd() { self.destroy(); }
+
+  function onFinish() { self.destroy(true); }
+}
+util.inherits(StatefulServerChannel, ServerChannel);
+
+// Helpers.
+
+/** Enhanced request, used inside forward middleware functions. */
+function WrappedRequest(msg, hdrs, req) {
+  this._msg = msg;
+  this.headers = hdrs || {};
+  this.request = req || {};
+}
+
+WrappedRequest.prototype.toBuffer = function () {
+  var msg = this._msg;
+  return Buffer.concat([
+    MAP_BYTES_TYPE.toBuffer(this.headers),
+    STRING_TYPE.toBuffer(msg.name),
+    msg.requestType.toBuffer(this.request)
+  ]);
+};
+
+/** Enhanced response, used inside forward middleware functions. */
+function WrappedResponse(msg, hdr, err, res) {
+  this._msg = msg;
+  this.headers = hdr;
+  this.error = err;
+  this.response = res;
+}
+
+WrappedResponse.prototype.toBuffer = function () {
+  var hdr = MAP_BYTES_TYPE.toBuffer(this.headers);
+  var hasError = this.error !== undefined;
+  return Buffer.concat([
+    hdr,
+    BOOLEAN_TYPE.toBuffer(hasError),
+    hasError ?
+      this._msg.errorType.toBuffer(this.error) :
+      this._msg.responseType.toBuffer(this.response)
+  ]);
+};
+
+/**
+ * Context for all middleware and handlers.
+ * 
+ * It exposes a `locals` object which can be used to pass information between
+ * each other during a given call.
+ */
+function CallContext(msg, channel) {
+  this.channel = channel;
+  this.locals = {};
+  this.message = msg;
+  Object.freeze(this);
+}
+
+/**
+ * Callback registry.
+ * 
+ * Callbacks added must accept an error as first argument. This is used by
+ * client channels to store pending calls. This class isn't exposed by the
+ * public API.
+ */
+function Registry(ctx, prefixLength) {
+  this._ctx = ctx; // Context for all callbacks.
+  this._mask = ~0 >>> (prefixLength | 0); // 16 bits by default.
+  this._id = 0; // Unique integer ID for each call.
+  this._n = 0; // Number of pending calls.
+  this._cbs = {};
+}
+
+Registry.prototype.get = function (id) { return this._cbs[id & this._mask]; };
+
+Registry.prototype.add = function (timeout, fn) {
+  this._id = (this._id + 1) & this._mask;
+
+  var self = this;
+  var id = this._id;
+  var timer;
+  if (timeout > 0) {
+    timer = setTimeout(function () { cb(new Error('timeout')); }, timeout);
+  }
+
+  this._cbs[id] = cb;
+  this._n++;
+  return id;
+
+  function cb() {
+    if (!self._cbs[id]) {
+      // The callback has already run.
+      return;
+    }
+    delete self._cbs[id];
+    self._n--;
+    if (timer) {
+      clearTimeout(timer);
+    }
+    fn.apply(self._ctx, arguments);
+  }
+};
+
+Registry.prototype.clear = function () {
+  Object.keys(this._cbs).forEach(function (id) {
+    this._cbs[id](new Error('interrupted'));
+  }, this);
+};
+
+/**
+ * Service resolution helper.
+ * 
+ * It is used both by client and server channels, to respectively decode errors
+ * and responses, or requests.
+ */
+function Adapter(clientSvc, serverSvc, hash, isRemote) {
+  this._clientSvc = clientSvc;
+  this._serverSvc = serverSvc;
+  this._hash = hash; // Convenience to access it when creating handshakes.
+  this._isRemote = !!isRemote;
+  this._readers = createReaders(clientSvc, serverSvc);
+}
+
+Adapter.prototype._decodeRequest = function (buf) {
+  var tap = new Tap(buf);
+  var hdr = MAP_BYTES_TYPE._read(tap);
+  var name = STRING_TYPE._read(tap);
+  var msg, req;
+  if (name) {
+    msg = this._serverSvc.message(name);
+    req = this._readers[name + '?']._read(tap);
+  } else {
+    msg = PING_MESSAGE;
+  }
+  if (!tap.isValid()) {
+    throw new Error(f('truncated %s request', name || 'ping$'));
+  }
+  return new WrappedRequest(msg, hdr, req);
+};
+
+Adapter.prototype._decodeResponse = function (buf, wres, msg) {
+  var tap = new Tap(buf);
+  utils.copyOwnProperties(MAP_BYTES_TYPE._read(tap), wres.headers, true);
+  var isError = BOOLEAN_TYPE._read(tap);
+  var name = msg.name;
+  if (name) {
+    var reader = this._readers[name + (isError ? '*' : '!')];
+    msg = this._clientSvc.message(name);
+    if (isError) {
+      wres.error = reader._read(tap);
+    } else {
+      wres.response = reader._read(tap);
+    }
+    if (!tap.isValid()) {
+      throw new Error(f('truncated %s response', name));
+    }
+  } else {
+    msg = PING_MESSAGE;
+  }
+};
+
+/** Standard "un-framing" stream. */
+function FrameDecoder() {
+  stream.Transform.call(this, {readableObjectMode: true});
+  this._id = undefined;
+  this._buf = new Buffer(0);
+  this._bufs = [];
+
+  this.on('finish', function () { this.push(null); });
+}
+util.inherits(FrameDecoder, stream.Transform);
+
+FrameDecoder.prototype._transform = function (buf, encoding, cb) {
+  buf = Buffer.concat([this._buf, buf]);
+  var frameLength;
+  while (
+    buf.length >= 4 &&
+    buf.length >= (frameLength = buf.readInt32BE(0)) + 4
+  ) {
+    if (frameLength) {
+      this._bufs.push(buf.slice(4, frameLength + 4));
+    } else {
+      var bufs = this._bufs;
+      this._bufs = [];
+      this.push({id: null, payload: bufs});
+    }
+    buf = buf.slice(frameLength + 4);
+  }
+  this._buf = buf;
+  cb();
+};
+
+FrameDecoder.prototype._flush = function () {
+  if (this._buf.length || this._bufs.length) {
+    var bufs = this._bufs.slice();
+    bufs.unshift(this._buf);
+    var err = toRpcError('TRAILING_DATA');
+    // Attach the data to help debugging (e.g. if the encoded bytes contain a
+    // human-readable protocol like HTTP).
+    err.trailingData = Buffer.concat(bufs).toString();
+    this.emit('error', err);
+  }
+};
+
+/** Standard framing stream. */
+function FrameEncoder() {
+  stream.Transform.call(this, {writableObjectMode: true});
+  this.on('finish', function () { this.push(null); });
+}
+util.inherits(FrameEncoder, stream.Transform);
+
+FrameEncoder.prototype._transform = function (obj, encoding, cb) {
+  var bufs = obj.payload;
+  var i, l, buf;
+  for (i = 0, l = bufs.length; i < l; i++) {
+    buf = bufs[i];
+    this.push(intBuffer(buf.length));
+    this.push(buf);
+  }
+  this.push(intBuffer(0));
+  cb();
+};
+
+/** Netty-compatible decoding stream. */
+function NettyDecoder() {
+  stream.Transform.call(this, {readableObjectMode: true});
+  this._id = undefined;
+  this._frameCount = 0;
+  this._buf = new Buffer(0);
+  this._bufs = [];
+
+  this.on('finish', function () { this.push(null); });
+}
+util.inherits(NettyDecoder, stream.Transform);
+
+NettyDecoder.prototype._transform = function (buf, encoding, cb) {
+  buf = Buffer.concat([this._buf, buf]);
+
+  while (true) {
+    if (this._id === undefined) {
+      if (buf.length < 8) {
+        this._buf = buf;
+        cb();
+        return;
+      }
+      this._id = buf.readInt32BE(0);
+      this._frameCount = buf.readInt32BE(4);
+      buf = buf.slice(8);
+    }
+
+    var frameLength;
+    while (
+      this._frameCount &&
+      buf.length >= 4 &&
+      buf.length >= (frameLength = buf.readInt32BE(0)) + 4
+    ) {
+      this._frameCount--;
+      this._bufs.push(buf.slice(4, frameLength + 4));
+      buf = buf.slice(frameLength + 4);
+    }
+
+    if (this._frameCount) {
+      this._buf = buf;
+      cb();
+      return;
+    } else {
+      var obj = {id: this._id, payload: this._bufs};
+      this._bufs = [];
+      this._id = undefined;
+      this.push(obj);
+    }
+  }
+};
+
+NettyDecoder.prototype._flush = FrameDecoder.prototype._flush;
+
+/** Netty-compatible encoding stream. */
+function NettyEncoder() {
+  stream.Transform.call(this, {writableObjectMode: true});
+  this.on('finish', function () { this.push(null); });
+}
+util.inherits(NettyEncoder, stream.Transform);
+
+NettyEncoder.prototype._transform = function (obj, encoding, cb) {
+  var bufs = obj.payload;
+  var l = bufs.length;
+  var buf;
+  // Header: [ ID, number of frames ]
+  buf = new Buffer(8);
+  buf.writeInt32BE(obj.id, 0);
+  buf.writeInt32BE(l, 4);
+  this.push(buf);
+  // Frames, each: [ length, bytes ]
+  var i;
+  for (i = 0; i < l; i++) {
+    buf = bufs[i];
+    this.push(intBuffer(buf.length));
+    this.push(buf);
+  }
+  cb();
+};
+
+/**
+ * Returns a buffer containing an integer's big-endian representation.
+ * 
+ * @param n
+ *            {Number} Integer.
+ */
+function intBuffer(n) {
+  var buf = new Buffer(4);
+  buf.writeInt32BE(n);
+  return buf;
+}
+
+/**
+ * Decode a type used as prefix inside a buffer.
+ * 
+ * @param type
+ *            {Type} The type of the prefix.
+ * @param buf
+ *            {Buffer} Encoded bytes.
+ * 
+ * This function will return an object `{head, tail}` where head contains the
+ * decoded value and tail the rest of the buffer. An error will be thrown if the
+ * prefix cannot be decoded.
+ */
+function readHead(type, buf) {
+  var tap = new Tap(buf);
+  var head = type._read(tap);
+  if (!tap.isValid()) {
+    throw new Error(f('truncated %s', type));
+  }
+  return {head: head, tail: tap.buf.slice(tap.pos)};
+}
+
+/**
+ * Generate a decoder, optimizing the case where reader and writer are equal.
+ * 
+ * @param rtype
+ *            {Type} Reader's type.
+ * @param wtype
+ *            {Type} Writer's type.
+ */
+function createReader(rtype, wtype) {
+  return rtype.equals(wtype) ? rtype : rtype.createResolver(wtype);
+}
+
+/**
+ * Generate all readers for a given protocol combination.
+ * 
+ * @param clientSvc
+ *            {Service} Client service.
+ * @param serverSvc
+ *            {Service} Client service.
+ */
+function createReaders(clientSvc, serverSvc) {
+  var obj = {};
+  clientSvc.messages.forEach(function (c) {
+    var n = c.name;
+    var s = serverSvc.message(n);
+    try {
+      if (!s) {
+        throw new Error(f('missing server message: %s', n));
+      }
+      if (s.oneWay !== c.oneWay) {
+        throw new Error(f('inconsistent one-way message: %s', n));
+      }
+      obj[n + '?'] = createReader(s.requestType, c.requestType);
+      obj[n + '*'] = createReader(c.errorType, s.errorType);
+      obj[n + '!'] = createReader(c.responseType, s.responseType);
+    } catch (cause) {
+      throw toRpcError('INCOMPATIBLE_PROTOCOL', cause);
+    }
+  });
+  return obj;
+}
+
+/**
+ * Populate a cache from a list of protocols.
+ * 
+ * @param cache
+ *            {Object} Cache of adapters.
+ * @param svc
+ *            {Service} The local service (either client or server).
+ * @param ptcls
+ *            {Array} Array of protocols to insert.
+ * @param isClient
+ *            {Boolean} Whether the local service is a client's or server's.
+ */
+function insertRemoteProtocols(cache, ptcls, svc, isClient) {
+  Object.keys(ptcls).forEach(function (hash) {
+    var ptcl = ptcls[hash];
+    var clientSvc, serverSvc;
+    if (isClient) {
+      clientSvc = svc;
+      serverSvc = Service.forProtocol(ptcl);
+    } else {
+      clientSvc = Service.forProtocol(ptcl);
+      serverSvc = svc;
+    }
+    cache[hash] = new Adapter(clientSvc, serverSvc, hash, true);
+  });
+}
+
+/**
+ * Extract remote protocols from a cache
+ * 
+ * @param cache
+ *            {Object} Cache of adapters.
+ * @param isClient
+ *            {Boolean} Whether the remote protocols extracted should be the
+ *            servers' or clients'.
+ */
+function getRemoteProtocols(cache, isClient) {
+  var ptcls = {};
+  Object.keys(cache).forEach(function (hs) {
+    var adapter = cache[hs];
+    if (adapter._isRemote) {
+      var svc = isClient ? adapter._serverSvc : adapter._clientSvc;
+      ptcls[hs] = svc.protocol;
+    }
+  });
+  return ptcls;
+}
+
+/**
+ * Check whether something is an `Error`.
+ * 
+ * @param any
+ *            {Object} Any object.
+ */
+function isError(any) {
+  // Also not ideal, but avoids brittle `instanceof` checks.
+  return !!any && Object.prototype.toString.call(any) === '[object Error]';
+}
+
+/**
+ * Forward any errors emitted on the source to the destination.
+ * 
+ * @param src
+ *            {EventEmitter} The initial source of error events.
+ * @param dst
+ *            {EventEmitter} The new target of the source's error events. The
+ *            original source will be provided as second argument (the error
+ *            being the first).
+ * 
+ * As a convenience, the source will be returned.
+ */
+function forwardErrors(src, dst) {
+  return src.on('error', function (err) {
+    dst.emit('error', err, src);
+  });
+}
+
+/**
+ * Create an error.
+ * 
+ * @param msg
+ *            {String} Error message.
+ * @param cause
+ *            {Error} The cause of the error. It is available as `cause` field
+ *            on the outer error.
+ */
+function toError(msg, cause) {
+  var err = new Error(msg);
+  err.cause = cause;
+  return err;
+}
+
+/**
+ * Mark an error.
+ * 
+ * @param rpcCode
+ *            {String} Code representing the failure.
+ * @param cause
+ *            {Error} The cause of the error. It is available as `cause` field
+ *            on the outer error.
+ * 
+ * This is used to keep the argument of channels' `'error'` event errors.
+ */
+function toRpcError(rpcCode, cause) {
+  var err = toError(rpcCode.toLowerCase().replace(/_/g, ' '), cause);
+  err.rpcCode = (cause && cause.rpcCode) ? cause.rpcCode : rpcCode;
+  return err;
+}
+
+/**
+ * Provide a helpful error to identify why serialization failed.
+ * 
+ * @param err
+ *            {Error} The error to decorate.
+ * @param obj
+ *            {...} The object containing fields to validated.
+ * @param fields
+ *            {Array} Information about the fields to validate.
+ */
+function serializationError(msg, obj, fields) {
+  var details = [];
+  var i, l, field;
+  for (i = 0, l = fields.length; i < l; i++) {
+    field = fields[i];
+    field.type.isValid(obj[field.name], {errorHook: errorHook});
+  }
+  var detailsStr = details
+    .map(function (obj) {
+      return f('%s = %j but expected %s', obj.path, obj.value, obj.type);
+    })
+    .join(', ');
+  var err = new Error(f('%s (%s)', msg, detailsStr));
+  err.details = details;
+  return err;
+
+  function errorHook(parts, any, type) {
+    var strs = [];
+    var i, l, part;
+    for (i = 0, l = parts.length; i < l; i++) {
+      part = parts[i];
+      if (isNaN(part)) {
+        strs.push('.' + part);
+      } else {
+        strs.push('[' + part + ']');
+      }
+    }
+    details.push({
+      path: field.name + strs.join(''),
+      value: any,
+      type: type
+    });
+  }
+}
+
+/**
+ * Compute a prefix of fixed length from a string.
+ * 
+ * @param scope
+ *            {String} Namespace to be hashed.
+ */
+function normalizedPrefix(scope) {
+  return scope ?
+    utils.getHash(scope).readInt16BE(0) << (32 - PREFIX_LENGTH) :
+    0;
+}
+
+/**
+ * Check whether an ID matches the prefix.
+ * 
+ * @param id
+ *            {Integer} Number to check.
+ * @param prefix
+ *            {Integer} Already shifted prefix.
+ */
+function matchesPrefix(id, prefix) {
+  return ((id ^ prefix) >> (32 - PREFIX_LENGTH)) === 0;
+}
+
+/**
+ * Check whether something is a stream.
+ * 
+ * @param any
+ *            {Object} Any object.
+ */
+function isStream(any) {
+  // This is a hacky way of checking that the transport is a stream-like
+  // object. We unfortunately can't use `instanceof Stream` checks since
+  // some libraries (e.g. websocket-stream) return streams which don't
+  // inherit from it.
+  return !!(any && any.pipe);
+}
+
+/**
+ * Get a message, asserting that it exists.
+ * 
+ * @param svc
+ *            {Service} The protocol to look into.
+ * @param name
+ *            {String} The message's name.
+ */
+function getExistingMessage(svc, name) {
+  var msg = svc.message(name);
+  if (!msg) {
+    throw new Error(f('unknown message: %s', name));
+  }
+  return msg;
+}
+
+/**
+ * Middleware logic.
+ * 
+ * This is used both in clients and servers to intercept call handling (e.g. to
+ * populate headers, do access control).
+ * 
+ * @param params
+ *            {Object} The following parameters: + fns {Array} Array of
+ *            middleware functions. + ctx {Object} Context used to call the
+ *            middleware functions, onTransition, and onCompletion. + wreq
+ *            {WrappedRequest} + wres {WrappedResponse} + onTransition
+ *            {Function} End of forward phase callback. It accepts an eventual
+ *            error as single argument. This will be used for the backward
+ *            phase. This function is guaranteed to be called at most once. +
+ *            onCompletion {Function} Final handler, it takes an error as unique
+ *            argument. This function is guaranteed to be only at most once. +
+ *            onError {Function} Error handler, called if an intermediate
+ *            callback is called multiple times.
+ */
+function chainMiddleware(params) {
+  var args = [params.wreq, params.wres];
+  var cbs = [];
+  var cause; // Backpropagated error.
+  forward(0);
+
+  function forward(pos) {
+    var isDone = false;
+    if (pos < params.fns.length) {
+      params.fns[pos].apply(params.ctx, args.concat(function (err, cb) {
+        if (isDone) {
+          params.onError(toError('duplicate forward middleware call', err));
+          return;
+        }
+        isDone = true;
+        if (
+          err || (
+            params.wres && ( // Non one-way messages.
+              params.wres.error !== undefined ||
+              params.wres.response !== undefined
+            )
+          )
+        ) {
+          // Stop the forward phase, bypass the handler, and start the
+			// backward
+          // phase. Note that we ignore any callback argument in this case.
+          cause = err;
+          backward();
+          return;
+        }
+        if (cb) {
+          cbs.push(cb);
+        }
+        forward(++pos);
+      }));
+    } else {
+      // Done with the middleware forward functions, call the handler.
+      params.onTransition.apply(params.ctx, args.concat(function (err) {
+        if (isDone) {
+          params.onError(toError('duplicate handler call', err));
+          return;
+        }
+        isDone = true;
+        cause = err;
+        process.nextTick(backward);
+      }));
+    }
+  }
+
+  function backward() {
+    var cb = cbs.pop();
+    if (cb) {
+      var isDone = false;
+      cb.call(params.ctx, cause, function (err) {
+        if (isDone) {
+          params.onError(toError('duplicate backward middleware call', err));
+          return;
+        }
+        // Substitute the error.
+        cause = err;
+        isDone = true;
+        backward();
+      });
+    } else {
+      // Done with all middleware calls.
+      params.onCompletion.call(params.ctx, cause);
+    }
+  }
+}
+
+
+module.exports = {
+  Adapter: Adapter,
+  HANDSHAKE_REQUEST_TYPE: HANDSHAKE_REQUEST_TYPE,
+  HANDSHAKE_RESPONSE_TYPE: HANDSHAKE_RESPONSE_TYPE,
+  Message: Message,
+  Registry: Registry,
+  Service: Service,
+  discoverProtocol: discoverProtocol,
+  streams: {
+    FrameDecoder: FrameDecoder,
+    FrameEncoder: FrameEncoder,
+    NettyDecoder: NettyDecoder,
+    NettyEncoder: NettyEncoder
+  }
+};
+
+}).call(this,require('_process'),require("buffer").Buffer)
+},{"./types":55,"./utils":56,"_process":23,"buffer":16,"events":19,"stream":42,"util":47}],54:[function(require,module,exports){
+/* jshint node: true */
+
+// TODO: Add minimal templating.
+// TODO: Add option to prefix nested type declarations with the outer types'
+// names.
+
+'use strict';
+
+/** IDL to protocol (services) and schema (types) parsing logic. */
+
+var files = require('./files'),
+    utils = require('./utils'),
+    path = require('path'),
+    util = require('util');
+
+
+var f = util.format;
+
+
+// Default type references defined by Avro.
+var TYPE_REFS = {
+  date: {type: 'int', logicalType: 'date'},
+  decimal: {type: 'bytes', logicalType: 'decimal'},
+  time_ms: {type: 'long', logicalType: 'time-millis'},
+  timestamp_ms: {type: 'long', logicalType: 'timestamp-millis'}
+};
+
+
+/** Assemble an IDL file into a decoded protocol. */
+function assembleProtocol(fpath, opts, cb) {
+  if (!cb && typeof opts == 'function') {
+    cb = opts;
+    opts = undefined;
+  }
+  opts = opts || {};
+  if (!opts.importHook) {
+    opts.importHook = files.createImportHook();
+  }
+
+  // Types found in imports. We store them separately to be able to insert
+	// them
+  // in the correct order in the final attributes.
+  var importedTypes = [];
+  var protocol, imports;
+  opts.importHook(fpath, 'idl', function (err, str) {
+    if (err) {
+      cb(err);
+      return;
+    }
+    if (str === undefined) {
+      // Skipped import (likely already imported).
+      cb(null, {});
+      return;
+    }
+    try {
+      var reader = new Reader(str, opts);
+      var obj = reader._readProtocol(str, opts);
+    } catch (err) {
+      err.path = fpath; // To help debug which file caused the error.
+      cb(err);
+      return;
+    }
+    protocol = obj.protocol;
+    imports = obj.imports;
+    fetchImports();
+  });
+
+  function fetchImports() {
+    var info = imports.shift();
+    if (!info) {
+      // We are done with this file. We prepend all imported types to this
+      // file's and we can return the final result.
+      if (importedTypes.length) {
+        protocol.types = protocol.types ?
+          importedTypes.concat(protocol.types) :
+          importedTypes;
+      }
+      cb(null, protocol);
+    } else {
+      var importPath = path.join(path.dirname(fpath), info.name);
+      if (info.kind === 'idl') {
+        assembleProtocol(importPath, opts, mergeImportedSchema);
+      } else {
+        // We are importing a protocol or schema file.
+        opts.importHook(importPath, info.kind, function (err, str) {
+          if (err) {
+            cb(err);
+            return;
+          }
+          switch (info.kind) {
+            case 'protocol':
+            case 'schema':
+              if (str === undefined) {
+                // Flag used to signal an already imported file by the default
+                // import hooks. Implementors who wish to disallow duplicate
+                // imports should provide a custom hook which throws an error
+                // when a duplicate import is detected.
+                mergeImportedSchema(null, {});
+                return;
+              }
+              try {
+                var obj = JSON.parse(str);
+              } catch (err) {
+                err.path = importPath;
+                cb(err);
+                return;
+              }
+              var schema = info.kind === 'schema' ? {types: [obj]} : obj;
+              mergeImportedSchema(null, schema);
+              break;
+            default:
+              cb(new Error(f('invalid import kind: %s', info.kind)));
+          }
+        });
+      }
+    }
+  }
+
+  function mergeImportedSchema(err, importedSchema) {
+    if (err) {
+      cb(err);
+      return;
+    }
+    // Merge first the types (where we don't need to check for duplicates
+    // since instantiating the service will take care of it), then the messages
+    // (where we need to, as duplicates will overwrite each other).
+    (importedSchema.types || []).forEach(function (typeSchema) {
+      // Ensure the imported protocol's namespace is inherited correctly (it
+      // might be different from the current one).
+      if (typeSchema.namespace === undefined) {
+        var namespace = importedSchema.namespace;
+        if (!namespace) {
+          var match = /^(.*)\.[^.]+$/.exec(importedSchema.protocol);
+          if (match) {
+            namespace = match[1];
+          }
+        }
+        typeSchema.namespace = namespace || '';
+      }
+      importedTypes.push(typeSchema);
+    });
+    try {
+      Object.keys(importedSchema.messages || {}).forEach(function (name) {
+        if (!protocol.messages) {
+          protocol.messages = {};
+        }
+        if (protocol.messages[name]) {
+          throw new Error(f('duplicate message: %s', name));
+        }
+        protocol.messages[name] = importedSchema.messages[name];
+      });
+    } catch (err) {
+      cb(err);
+      return;
+    }
+    fetchImports(); // Continue importing any remaining imports.
+  }
+}
+
+// Parsing functions.
+
+/**
+ * Convenience function to parse multiple inputs into protocols and schemas.
+ * 
+ * It should cover most basic use-cases but has a few limitations:
+ *  + It doesn't allow passing options to the parsing step. + The protocol/type
+ * inference logic can be deceived.
+ * 
+ * The parsing logic is as follows:
+ *  + If `str` contains `path.sep` (on windows `\`, otherwise `/`) and is a path
+ * to an existing file, it will first be read as JSON, then as an IDL
+ * specification if JSON parsing failed. If either succeeds, the result is
+ * returned, otherwise the next steps are run using the file's content instead
+ * of the input path. + If `str` is a valid JSON string, it is parsed then
+ * returned. + If `str` is a valid IDL protocol specification, it is parsed and
+ * returned if no imports are present (and an error is thrown if there are any
+ * imports). + If `str` is a valid IDL type specification, it is parsed and
+ * returned. + If neither of the above cases apply, `str` is returned.
+ */
+function read(str) {
+  var schema;
+  if (typeof str == 'string' && ~str.indexOf(path.sep) && files.existsSync(str)) {
+    // Try interpreting `str` as path to a file contain a JSON schema or an IDL
+    // protocol. Note that we add the second check to skip primitive references
+    // (e.g. `"int"`, the most common use-case for `avro.parse`).
+    var contents = files.readFileSync(str, {encoding: 'utf8'});
+    try {
+      return JSON.parse(contents);
+    } catch (err) {
+      var opts = {importHook: files.createSyncImportHook()};
+      assembleProtocol(str, opts, function (err, protocolSchema) {
+        schema = err ? contents : protocolSchema;
+      });
+    }
+  } else {
+    schema = str;
+  }
+  if (typeof schema != 'string' || schema === 'null') {
+    // This last predicate is to allow `read('null')` to work similarly to
+    // `read('int')` and other primitives (null needs to be handled separately
+    // since it is also a valid JSON identifier).
+    return schema;
+  }
+  try {
+    return JSON.parse(schema);
+  } catch (err) {
+    try {
+      return Reader.readProtocol(schema);
+    } catch (err) {
+      try {
+        return Reader.readSchema(schema);
+      } catch (err) {
+        return schema;
+      }
+    }
+  }
+}
+
+function Reader(str, opts) {
+  opts = opts || {};
+
+  this._tk = new Tokenizer(str);
+  this._ackVoidMessages = !!opts.ackVoidMessages;
+  this._implicitTags = !opts.delimitedCollections;
+  this._typeRefs = opts.typeRefs || TYPE_REFS;
+}
+
+Reader.readProtocol = function (str, opts) {
+  var reader = new Reader(str, opts);
+  var protocol = reader._readProtocol();
+  if (protocol.imports.length) {
+    // Imports can only be resolved when the IDL file is provided via its
+    // path, we fail rather than silently ignore imports.
+    throw new Error('unresolvable import');
+  }
+  return protocol.protocol;
+};
+
+Reader.readSchema = function (str, opts) {
+  var reader = new Reader(str, opts);
+  var javadoc = reader._readJavadoc();
+  var schema = reader._readType(javadoc === undefined ? {} : {doc: javadoc});
+  reader._tk.next({id: '(eof)'}); // Check that we have read everything.
+  return schema;
+};
+
+Reader.prototype._readProtocol = function () {
+  var tk = this._tk;
+  var imports = [];
+  var types = [];
+  var messages = {};
+  var pos;
+
+  // Outer declarations (outside of the protocol block).
+  this._readImports(imports);
+  var protocolSchema = {};
+  var protocolJavadoc = this._readJavadoc();
+  if (protocolJavadoc !== undefined) {
+    protocolSchema.doc = protocolJavadoc;
+  }
+  this._readAnnotations(protocolSchema);
+  tk.next({val: 'protocol'});
+  if (!tk.next({val: '{', silent: true})) {
+    // Named protocol.
+    protocolSchema.protocol = tk.next({id: 'name'}).val;
+    tk.next({val: '{'});
+  }
+
+  // Inner declarations.
+  while (!tk.next({val: '}', silent: true})) {
+    if (!this._readImports(imports)) {
+      var javadoc = this._readJavadoc();
+      var typeSchema = this._readType();
+      var numImports = this._readImports(imports, true);
+      var message = undefined;
+      // We mark our position and try to parse a message from here.
+      pos = tk.pos;
+      if (!numImports && (message = this._readMessage(typeSchema))) {
+        // Note that if any imports were found, we cannot be parsing a message.
+        if (javadoc !== undefined && message.schema.doc === undefined) {
+          message.schema.doc = javadoc;
+        }
+        var oneWay = false;
+        if (
+          message.schema.response === 'void' ||
+          message.schema.response.type === 'void'
+        ) {
+          oneWay = !this._ackVoidMessages && !message.schema.errors;
+          if (message.schema.response === 'void') {
+            message.schema.response = 'null';
+          } else {
+            message.schema.response.type = 'null';
+          }
+        }
+        if (oneWay) {
+          message.schema['one-way'] = true;
+        }
+        if (messages[message.name]) {
+          // We have to do this check here otherwise the duplicate will be
+          // overwritten (and service instantiation won't be able to catch
+			// it).
+          throw new Error(f('duplicate message: %s', message.name));
+        }
+        messages[message.name] = message.schema;
+      } else {
+        // This was a standalone type definition.
+        if (javadoc) {
+          if (typeof typeSchema == 'string') {
+            typeSchema = {doc: javadoc, type: typeSchema};
+          } else if (typeSchema.doc === undefined) {
+            typeSchema.doc = javadoc;
+          }
+        }
+        types.push(typeSchema);
+        // We backtrack until just before the type's type name and swallow an
+        // eventual semi-colon (to make type declarations more consistent).
+        tk.pos = pos;
+        tk.next({val: ';', silent: true});
+      }
+      javadoc = undefined;
+    }
+  }
+  tk.next({id: '(eof)'});
+  if (types.length) {
+    protocolSchema.types = types;
+  }
+  if (Object.keys(messages).length) {
+    protocolSchema.messages = messages;
+  }
+  return {protocol: protocolSchema, imports: imports};
+};
+
+Reader.prototype._readAnnotations = function (schema) {
+  var tk = this._tk;
+  while (tk.next({val: '@', silent: true})) {
+    // Annotations are allowed to have names which aren't valid Avro names,
+    // we must advance until we hit the first left parenthesis.
+    var parts = [];
+    while (!tk.next({val: '(', silent: true})) {
+      parts.push(tk.next().val);
+    }
+    schema[parts.join('')] = tk.next({id: 'json'}).val;
+    tk.next({val: ')'});
+  }
+};
+
+Reader.prototype._readMessage = function (responseSchema) {
+  var tk = this._tk;
+  var schema = {request: [], response: responseSchema};
+  this._readAnnotations(schema);
+  var name = tk.next().val;
+  if (tk.next().val !== '(') {
+    // This isn't a message.
+    return;
+  }
+  if (!tk.next({val: ')', silent: true})) {
+    do {
+      schema.request.push(this._readField());
+    } while (!tk.next({val: ')', silent: true}) && tk.next({val: ','}));
+  }
+  var token = tk.next();
+  switch (token.val) {
+    case 'throws':
+      // It doesn't seem like the IDL is explicit about which syntax to used
+      // for multiple errors. We will assume a comma-separated list.
+      schema.errors = [];
+      do {
+        schema.errors.push(this._readType());
+      } while (!tk.next({val: ';', silent: true}) && tk.next({val: ','}));
+      break;
+    case 'oneway':
+      schema['one-way'] = true;
+      tk.next({val: ';'});
+      break;
+    case ';':
+      break;
+    default:
+      throw tk.error('invalid message suffix', token);
+  }
+  return {name: name, schema: schema};
+};
+
+Reader.prototype._readJavadoc = function () {
+  var token = this._tk.next({id: 'javadoc', emitJavadoc: true, silent: true});
+  if (token) {
+    return token.val;
+  }
+};
+
+Reader.prototype._readField = function () {
+  var tk = this._tk;
+  var javadoc = this._readJavadoc();
+  var schema = {type: this._readType()};
+  if (javadoc !== undefined && schema.doc === undefined) {
+    schema.doc = javadoc;
+  }
+  this._readAnnotations(schema);
+  schema.name = tk.next({id: 'name'}).val;
+  if (tk.next({val: '=', silent: true})) {
+    schema['default'] = tk.next({id: 'json'}).val;
+  }
+  return schema;
+};
+
+Reader.prototype._readType = function (schema) {
+  schema = schema || {};
+  this._readAnnotations(schema);
+  schema.type = this._tk.next({id: 'name'}).val;
+  switch (schema.type) {
+    case 'record':
+    case 'error':
+      return this._readRecord(schema);
+    case 'fixed':
+      return this._readFixed(schema);
+    case 'enum':
+      return this._readEnum(schema);
+    case 'map':
+      return this._readMap(schema);
+    case 'array':
+      return this._readArray(schema);
+    case 'union':
+      if (Object.keys(schema).length > 1) {
+        throw new Error('union annotations are not supported');
+      }
+      return this._readUnion();
+    default:
+      // Reference.
+      var ref = this._typeRefs[schema.type];
+      if (ref) {
+        delete schema.type; // Always overwrite the type.
+        utils.copyOwnProperties(ref, schema);
+      }
+      return Object.keys(schema).length > 1 ? schema : schema.type;
+  }
+};
+
+Reader.prototype._readFixed = function (schema) {
+  var tk = this._tk;
+  if (!tk.next({val: '(', silent: true})) {
+    schema.name = tk.next({id: 'name'}).val;
+    tk.next({val: '('});
+  }
+  schema.size = parseInt(tk.next({id: 'number'}).val);
+  tk.next({val: ')'});
+  return schema;
+};
+
+Reader.prototype._readMap = function (schema) {
+  var tk = this._tk;
+  // Brackets are unwieldy when declaring inline types. We allow for them to
+	// be
+  // omitted (but we keep the consistency that if the entry bracket is
+	// present,
+  // the exit one must be as well). Note that this is non-standard.
+  var silent = this._implicitTags;
+  var implicitTags = tk.next({val: '<', silent: silent}) === undefined;
+  schema.values = this._readType();
+  tk.next({val: '>', silent: implicitTags});
+  return schema;
+};
+
+Reader.prototype._readArray = function (schema) {
+  var tk = this._tk;
+  var silent = this._implicitTags;
+  var implicitTags = tk.next({val: '<', silent: silent}) === undefined;
+  schema.items = this._readType();
+  tk.next({val: '>', silent: implicitTags});
+  return schema;
+};
+
+Reader.prototype._readEnum = function (schema) {
+  var tk = this._tk;
+  if (!tk.next({val: '{', silent: true})) {
+    schema.name = tk.next({id: 'name'}).val;
+    tk.next({val: '{'});
+  }
+  schema.symbols = [];
+  do {
+    schema.symbols.push(tk.next().val);
+  } while (!tk.next({val: '}', silent: true}) && tk.next({val: ','}));
+  return schema;
+};
+
+Reader.prototype._readUnion = function () {
+  var tk = this._tk;
+  var arr = [];
+  tk.next({val: '{'});
+  do {
+    arr.push(this._readType());
+  } while (!tk.next({val: '}', silent: true}) && tk.next({val: ','}));
+  return arr;
+};
+
+Reader.prototype._readRecord = function (schema) {
+  var tk = this._tk;
+  if (!tk.next({val: '{', silent: true})) {
+    schema.name = tk.next({id: 'name'}).val;
+    tk.next({val: '{'});
+  }
+  schema.fields = [];
+  while (!tk.next({val: '}', silent: true})) {
+    schema.fields.push(this._readField());
+    tk.next({val: ';'});
+  }
+  return schema;
+};
+
+Reader.prototype._readImports = function (imports, maybeMessage) {
+  var tk = this._tk;
+  var numImports = 0;
+  var pos = tk.pos;
+  while (tk.next({val: 'import', silent: true})) {
+    if (!numImports && maybeMessage && tk.next({val: '(', silent: true})) {
+      // This will happen if a message is named import.
+      tk.pos = pos;
+      return;
+    }
+    var kind = tk.next({id: 'name'}).val;
+    var fname = JSON.parse(tk.next({id: 'string'}).val);
+    tk.next({val: ';'});
+    imports.push({kind: kind, name: fname});
+    numImports++;
+  }
+  return numImports;
+};
+
+// Helpers.
+
+/**
+ * Simple class to split an input string into tokens.
+ * 
+ * There are different types of tokens, characterized by their `id`:
+ *  + `number` numbers. + `name` references. + `string` double-quoted. +
+ * `operator`, anything else, always single character. + `javadoc`, only emitted
+ * when `next` is called with `emitJavadoc` set. + `json`, only emitted when
+ * `next` is called with `'json'` as `id` (the tokenizer doesn't have enough
+ * context to predict these).
+ */
+function Tokenizer(str) {
+  this._str = str;
+  this.pos = 0;
+}
+
+Tokenizer.prototype.next = function (opts) {
+  var token = {pos: this.pos, id: undefined, val: undefined};
+  var javadoc = this._skip(opts && opts.emitJavadoc);
+  if (javadoc) {
+    token.id = 'javadoc';
+    token.val = javadoc;
+  } else {
+    var pos = this.pos;
+    var str = this._str;
+    var c = str.charAt(pos);
+    if (!c) {
+      token.id = '(eof)';
+    } else {
+      if (opts && opts.id === 'json') {
+        token.id = 'json';
+        this.pos = this._endOfJson();
+      } else if (c === '"') {
+        token.id = 'string';
+        this.pos = this._endOfString();
+      } else if (/[0-9]/.test(c)) {
+        token.id = 'number';
+        this.pos = this._endOf(/[0-9]/);
+      } else if (/[`A-Za-z_.]/.test(c)) {
+        token.id = 'name';
+        this.pos = this._endOf(/[`A-Za-z0-9_.]/);
+      } else {
+        token.id = 'operator';
+        this.pos = pos + 1;
+      }
+      token.val = str.slice(pos, this.pos);
+      if (token.id === 'json') {
+        // Let's be nice and give a more helpful error message when this occurs
+        // (JSON parsing errors wouldn't let us find the location otherwise).
+        try {
+          token.val = JSON.parse(token.val);
+        } catch (err) {
+          throw this.error('invalid JSON', token);
+        }
+      } else if (token.id === 'name') {
+        // Unescape names (our parser doesn't need them).
+        token.val = token.val.replace(/`/g, '');
+      }
+    }
+  }
+
+  var err;
+  if (opts && opts.id && opts.id !== token.id) {
+    err = this.error(f('expected ID %s', opts.id), token);
+  } else if (opts && opts.val && opts.val !== token.val) {
+    err = this.error(f('expected value %s', opts.val), token);
+  }
+  if (!err) {
+    return token;
+  } else if (opts && opts.silent) {
+    this.pos = token.pos; // Backtrack to start of token.
+    return undefined;
+  } else {
+    throw err;
+  }
+};
+
+Tokenizer.prototype.error = function (reason, context) {
+  // Context must be either a token or a position.
+  var isToken = typeof context != 'number';
+  var pos = isToken ? context.pos : context;
+  var str = this._str;
+  var lineNum = 1;
+  var lineStart = 0;
+  var i;
+  for (i = 0; i < pos; i++) {
+    if (str.charAt(i) === '\n') {
+      lineNum++;
+      lineStart = i;
+    }
+  }
+  var msg = isToken ? f('invalid token %j: %s', context, reason) : reason;
+  var err = new Error(msg);
+  err.token = isToken ? context : undefined;
+  err.lineNum = lineNum;
+  err.colNum = pos - lineStart;
+  return err;
+};
+
+/** Skip whitespace and comments. */
+Tokenizer.prototype._skip = function (emitJavadoc) {
+  var str = this._str;
+  var isJavadoc = false;
+  var pos, c;
+
+  while ((c = str.charAt(this.pos)) && /\s/.test(c)) {
+    this.pos++;
+  }
+  pos = this.pos;
+  if (c === '/') {
+    switch (str.charAt(this.pos + 1)) {
+    case '/':
+      this.pos += 2;
+      while ((c = str.charAt(this.pos)) && c !== '\n') {
+        this.pos++;
+      }
+      return this._skip(emitJavadoc);
+    case '*':
+      this.pos += 2;
+      if (str.charAt(this.pos) === '*') {
+        isJavadoc = true;
+      }
+      while ((c = str.charAt(this.pos++))) {
+        if (c === '*' && str.charAt(this.pos) === '/') {
+          this.pos++;
+          if (isJavadoc && emitJavadoc) {
+            return extractJavadoc(str.slice(pos + 3, this.pos - 2));
+          }
+          return this._skip(emitJavadoc);
+        }
+      }
+      throw this.error('unterminated comment', pos);
+    }
+  }
+};
+
+/** Generic end of method. */
+Tokenizer.prototype._endOf = function (pat) {
+  var pos = this.pos;
+  var str = this._str;
+  while (pat.test(str.charAt(pos))) {
+    pos++;
+  }
+  return pos;
+};
+
+/** Find end of a string. */
+Tokenizer.prototype._endOfString = function () {
+  var pos = this.pos + 1; // Skip first double quote.
+  var str = this._str;
+  var c;
+  while ((c = str.charAt(pos))) {
+    if (c === '"') {
+      // The spec doesn't explicitly say so, but IDLs likely only
+      // allow double quotes for strings (C- and Java-style).
+      return pos + 1;
+    }
+    if (c === '\\') {
+      pos += 2;
+    } else {
+      pos++;
+    }
+  }
+  throw this.error('unterminated string', pos - 1);
+};
+
+/** Find end of JSON object, throwing an error if the end is reached first. */
+Tokenizer.prototype._endOfJson = function () {
+  var pos = utils.jsonEnd(this._str, this.pos);
+  if (pos < 0) {
+    throw this.error('invalid JSON', pos);
+  }
+  return pos;
+};
+
+/**
+ * Extract Javadoc contents from the comment.
+ * 
+ * The parsing done is very simple and simply removes the line prefixes and
+ * leading / trailing empty lines. It's better to be conservative with
+ * formatting rather than risk losing information.
+ */
+function extractJavadoc(str) {
+  var lines = str
+    .replace(/^[ \t]+|[ \t]+$/g, '') // Trim whitespace.
+    .split('\n').map(function (line, i) {
+      return i ? line.replace(/^\s*\*\s?/, '') : line;
+    });
+  while (!lines[0]) {
+    lines.shift();
+  }
+  while (!lines[lines.length - 1]) {
+    lines.pop();
+  }
+  return lines.join('\n');
+}
+
+
+module.exports = {
+  Tokenizer: Tokenizer,
+  assembleProtocol: assembleProtocol,
+  read: read,
+  readProtocol: Reader.readProtocol,
+  readSchema: Reader.readSchema
+};
+
+},{"./files":51,"./utils":56,"path":22,"util":47}],55:[function(require,module,exports){
+(function (Buffer){
+/* jshint node: true */
+
+// TODO: Make it easier to implement custom types. This will likely require
+// exposing the `Tap` object, perhaps under another name. Probably worth a
+// major release.
+// TODO: Allow configuring when to write the size when writing arrays and maps,
+// and customizing their block size.
+// TODO: Code-generate `compare` and `clone` record and union methods.
+
+'use strict';
+
+/**
+ * This module defines all Avro data types and their serialization logic.
+ * 
+ */
+
+var utils = require('./utils'),
+    buffer = require('buffer'), // For `SlowBuffer`.
+    util = require('util');
+
+
+// Convenience imports.
+var Tap = utils.Tap;
+var debug = util.debuglog('avsc:types');
+var f = util.format;
+
+// All non-union concrete (i.e. non-logical) Avro types.
+var TYPES = {
+  'array': ArrayType,
+  'boolean': BooleanType,
+  'bytes': BytesType,
+  'double': DoubleType,
+  'enum': EnumType,
+  'error': RecordType,
+  'fixed': FixedType,
+  'float': FloatType,
+  'int': IntType,
+  'long': LongType,
+  'map': MapType,
+  'null': NullType,
+  'record': RecordType,
+  'string': StringType
+};
+
+// Valid (field, type, and symbol) name regex.
+var NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
+
+// Random generator.
+var RANDOM = new utils.Lcg();
+
+// Encoding tap (shared for performance).
+var TAP = new Tap(new buffer.SlowBuffer(1024));
+
+// Currently active logical type, used for name redirection.
+var LOGICAL_TYPE = null;
+
+/**
+ * "Abstract" base Avro type.
+ * 
+ * This class' constructor will register any named types to support recursive
+ * schemas. All type values are represented in memory similarly to their JSON
+ * representation, except for:
+ *  + `bytes` and `fixed` which are represented as `Buffer`s. + `union`s which
+ * will be "unwrapped" unless the `wrapUnions` option is set.
+ * 
+ * See individual subclasses for details.
+ */
+function Type(schema, opts) {
+  var type = LOGICAL_TYPE || this;
+  LOGICAL_TYPE = null;
+
+  // Lazily instantiated hash string. It will be generated the first time the
+  // type's default fingerprint is computed (for example when using `equals`).
+  // We use a mutable object since types are frozen after instantiation.
+  this._hash = new Hash();
+  this.name = undefined;
+  this.aliases = undefined;
+  this.doc = (schema && schema.doc) ? '' + schema.doc : undefined;
+
+  if (schema) {
+    // This is a complex (i.e. non-primitive) type.
+    var name = schema.name;
+    var namespace = schema.namespace === undefined ?
+      opts && opts.namespace :
+      schema.namespace;
+    if (name !== undefined) {
+      // This isn't an anonymous type.
+      name = qualify(name, namespace);
+      if (isPrimitive(name)) {
+        // Avro doesn't allow redefining primitive names.
+        throw new Error(f('cannot rename primitive type: %j', name));
+      }
+      var registry = opts && opts.registry;
+      if (registry) {
+        if (registry[name] !== undefined) {
+          throw new Error(f('duplicate type name: %s', name));
+        }
+        registry[name] = type;
+      }
+    } else if (opts && opts.noAnonymousTypes) {
+      throw new Error(f('missing name property in schema: %j', schema));
+    }
+    this.name = name;
+    this.aliases = schema.aliases ?
+      schema.aliases.map(function (s) { return qualify(s, namespace); }) :
+      [];
+  }
+}
+
+Type.forSchema = function (schema, opts) {
+  opts = opts || {};
+  opts.registry = opts.registry || {};
+
+  var UnionType = (function (wrapUnions) {
+    if (wrapUnions === true) {
+      wrapUnions = 'always';
+    } else if (wrapUnions === false) {
+      wrapUnions = 'never';
+    } else if (wrapUnions === undefined) {
+      wrapUnions = 'auto';
+    } else if (typeof wrapUnions == 'string') {
+      wrapUnions = wrapUnions.toLowerCase();
+    }
+    switch (wrapUnions) {
+      case 'always':
+        return WrappedUnionType;
+      case 'never':
+        return UnwrappedUnionType;
+      case 'auto':
+        return undefined; // Determined dynamically later on.
+      default:
+        throw new Error(f('invalid wrap unions option: %j', wrapUnions));
+    }
+  })(opts.wrapUnions);
+
+  if (schema === null) {
+    // Let's be helpful for this common error.
+    throw new Error('invalid type: null (did you mean "null"?)');
+  }
+
+  if (Type.isType(schema)) {
+    return schema;
+  }
+
+  var type;
+  if (opts.typeHook && (type = opts.typeHook(schema, opts))) {
+    if (!Type.isType(type)) {
+      throw new Error(f('invalid typehook return value: %j', type));
+    }
+    return type;
+  }
+
+  if (typeof schema == 'string') { // Type reference.
+    schema = qualify(schema, opts.namespace);
+    type = opts.registry[schema];
+    if (type) {
+      // Type was already defined, return it.
+      return type;
+    }
+    if (isPrimitive(schema)) {
+      // Reference to a primitive type. These are also defined names by
+		// default
+      // so we create the appropriate type and it to the registry for future
+      // reference.
+      return opts.registry[schema] = Type.forSchema({type: schema}, opts);
+    }
+    throw new Error(f('undefined type name: %s', schema));
+  }
+
+  if (schema.logicalType && opts.logicalTypes && !LOGICAL_TYPE) {
+    var DerivedType = opts.logicalTypes[schema.logicalType];
+    if (DerivedType) {
+      var namespace = opts.namespace;
+      var registry = {};
+      Object.keys(opts.registry).forEach(function (key) {
+        registry[key] = opts.registry[key];
+      });
+      try {
+        debug('instantiating logical type for %s', schema.logicalType);
+        return new DerivedType(schema, opts);
+      } catch (err) {
+        debug('failed to instantiate logical type for %s', schema.logicalType);
+        if (opts.assertLogicalTypes) {
+          // The spec mandates that we fall through to the underlying type if
+          // the logical type is invalid. We provide this option to ease
+          // debugging.
+          throw err;
+        }
+        LOGICAL_TYPE = null;
+        opts.namespace = namespace;
+        opts.registry = registry;
+      }
+    }
+  }
+
+  if (Array.isArray(schema)) { // Union.
+    var types = schema.map(function (obj) {
+      return Type.forSchema(obj, opts);
+    });
+    if (!UnionType) {
+      UnionType = isAmbiguous(types) ? WrappedUnionType : UnwrappedUnionType;
+    }
+    type = new UnionType(types, opts);
+  } else { // New type definition.
+    type = (function (typeName) {
+      var Type = TYPES[typeName];
+      if (Type === undefined) {
+        throw new Error(f('unknown type: %j', typeName));
+      }
+      return new Type(schema, opts);
+    })(schema.type);
+  }
+  return type;
+};
+
+Type.forValue = function (val, opts) {
+  opts = opts || {};
+
+  // Sentinel used when inferring the types of empty arrays.
+  opts.emptyArrayType = opts.emptyArrayType || Type.forSchema({
+    type: 'array', items: 'null'
+  });
+
+  // Optional custom inference hook.
+  if (opts.valueHook) {
+    var type = opts.valueHook(val, opts);
+    if (type !== undefined) {
+      if (!Type.isType(type)) {
+        throw new Error(f('invalid value hook return value: %j', type));
+      }
+      return type;
+    }
+  }
+
+  // Default inference logic.
+  switch (typeof val) {
+    case 'string':
+      return Type.forSchema('string', opts);
+    case 'boolean':
+      return Type.forSchema('boolean', opts);
+    case 'number':
+      if ((val | 0) === val) {
+        return Type.forSchema('int', opts);
+      } else if (Math.abs(val) < 9007199254740991) {
+        return Type.forSchema('float', opts);
+      }
+      return Type.forSchema('double', opts);
+    case 'object':
+      if (val === null) {
+        return Type.forSchema('null', opts);
+      } else if (Array.isArray(val)) {
+        if (!val.length) {
+          return opts.emptyArrayType;
+        }
+        return Type.forSchema({
+          type: 'array',
+          items: Type.forTypes(
+            val.map(function (v) { return Type.forValue(v, opts); })
+          )
+        }, opts);
+      } else if (Buffer.isBuffer(val)) {
+        return Type.forSchema('bytes', opts);
+      }
+      var fieldNames = Object.keys(val);
+      if (fieldNames.some(function (s) { return !isValidName(s); })) {
+        // We have to fall back to a map.
+        return Type.forSchema({
+          type: 'map',
+          values: Type.forTypes(fieldNames.map(function (s) {
+            return Type.forValue(val[s], opts);
+          }), opts)
+        }, opts);
+      }
+      return Type.forSchema({
+        type: 'record',
+        fields: fieldNames.map(function (s) {
+          return {name: s, type: Type.forValue(val[s], opts)};
+        })
+      }, opts);
+    default:
+      throw new Error(f('cannot infer type from: %j', val));
+  }
+};
+
+Type.forTypes = function (types, opts) {
+  if (!types.length) {
+    throw new Error('no types to combine');
+  }
+  if (types.length === 1) {
+    return types[0]; // Nothing to do.
+  }
+  opts = opts || {};
+
+  // Extract any union types, with special care for wrapped unions (see
+	// below).
+  var expanded = [];
+  var numWrappedUnions = 0;
+  var isValidWrappedUnion = true;
+  types.forEach(function (type) {
+    switch (type.typeName) {
+      case 'union:unwrapped':
+        isValidWrappedUnion = false;
+        expanded = expanded.concat(type.types);
+        break;
+      case 'union:wrapped':
+        numWrappedUnions++;
+        expanded = expanded.concat(type.types);
+        break;
+      case 'null':
+        expanded.push(type);
+        break;
+      default:
+        isValidWrappedUnion = false;
+        expanded.push(type);
+    }
+  });
+  if (numWrappedUnions) {
+    if (!isValidWrappedUnion) {
+      // It is only valid to combine wrapped unions when no other type is
+      // present other than wrapped unions and nulls (otherwise the values of
+      // others wouldn't be valid in the resulting union).
+      throw new Error('cannot combine wrapped union');
+    }
+    var branchTypes = {};
+    expanded.forEach(function (type) {
+      var name = type.branchName;
+      var branchType = branchTypes[name];
+      if (!branchType) {
+        branchTypes[name] = type;
+      } else if (!type.equals(branchType)) {
+        throw new Error('inconsistent branch type');
+      }
+    });
+    var wrapUnions = opts.wrapUnions;
+    var unionType;
+    opts.wrapUnions = true;
+    try {
+      unionType = Type.forSchema(Object.keys(branchTypes).map(function (name) {
+        return branchTypes[name];
+      }), opts);
+    } catch (err) {
+      opts.wrapUnions = wrapUnions;
+      throw err;
+    }
+    opts.wrapUnions = wrapUnions;
+    return unionType;
+  }
+
+  // Group types by category, similar to the logic for unwrapped unions.
+  var bucketized = {};
+  expanded.forEach(function (type) {
+    var bucket = getTypeBucket(type);
+    var bucketTypes = bucketized[bucket];
+    if (!bucketTypes) {
+      bucketized[bucket] = bucketTypes = [];
+    }
+    bucketTypes.push(type);
+  });
+
+  // Generate the "augmented" type for each group.
+  var buckets = Object.keys(bucketized);
+  var augmented = buckets.map(function (bucket) {
+    var bucketTypes = bucketized[bucket];
+    if (bucketTypes.length === 1) {
+      return bucketTypes[0];
+    } else {
+      switch (bucket) {
+        case 'null':
+        case 'boolean':
+          return bucketTypes[0];
+        case 'number':
+          return combineNumbers(bucketTypes);
+        case 'string':
+          return combineStrings(bucketTypes, opts);
+        case 'buffer':
+          return combineBuffers(bucketTypes, opts);
+        case 'array':
+          // Remove any sentinel arrays (used when inferring from empty
+			// arrays)
+          // to avoid making things nullable when they shouldn't be.
+          bucketTypes = bucketTypes.filter(function (t) {
+            return t !== opts.emptyArrayType;
+          });
+          if (!bucketTypes.length) {
+            // We still don't have a real type, just return the sentinel.
+            return opts.emptyArrayType;
+          }
+          return Type.forSchema({
+            type: 'array',
+            items: Type.forTypes(bucketTypes.map(function (t) {
+              return t.itemsType;
+            }))
+          }, opts);
+        default:
+          return combineObjects(bucketTypes, opts);
+      }
+    }
+  });
+
+  if (augmented.length === 1) {
+    return augmented[0];
+  } else {
+    // We return an (unwrapped) union of all augmented types.
+    return Type.forSchema(augmented, opts);
+  }
+};
+
+Type.isType = function (/* any, [prefix] ... */) {
+  var l = arguments.length;
+  if (!l) {
+    return false;
+  }
+
+  var any = arguments[0];
+  if (
+    !any ||
+    typeof any._update != 'function' ||
+    typeof any.fingerprint != 'function'
+  ) {
+    // Not fool-proof, but most likely good enough.
+    return false;
+  }
+
+  if (l === 1) {
+    // No type names specified, we are done.
+    return true;
+  }
+
+  // We check if at least one of the prefixes matches.
+  var typeName = any.typeName;
+  var i;
+  for (i = 1; i < l; i++) {
+    if (typeName.indexOf(arguments[i]) === 0) {
+      return true;
+    }
+  }
+  return false;
+};
+
+Type.__reset = function (size) {
+  debug('resetting type buffer to %d', size);
+  TAP.buf = new buffer.SlowBuffer(size);
+};
+
+Object.defineProperty(Type.prototype, 'branchName', {
+  enumerable: true,
+  get: function () {
+    if (this.name) {
+      return this.name;
+    }
+    var type = Type.isType(this, 'logical') ? this.underlyingType : this;
+    return Type.isType(type, 'union') ? undefined : type.typeName;
+  }
+});
+
+Type.prototype.clone = function (val, opts) {
+  if (opts) {
+    opts = {
+      coerce: !!opts.coerceBuffers | 0, // Coerce JSON to Buffer.
+      fieldHook: opts.fieldHook,
+      qualifyNames: !!opts.qualifyNames,
+      skip: !!opts.skipMissingFields,
+      wrap: !!opts.wrapUnions | 0 // Wrap first match into union.
+    };
+    return this._copy(val, opts);
+  } else {
+    // If no modifications are required, we can get by with a serialization
+    // roundtrip (generally much faster than a standard deep copy).
+    return this.fromBuffer(this.toBuffer(val));
+  }
+};
+
+Type.prototype.compare = utils.abstractFunction;
+
+Type.prototype.compareBuffers = function (buf1, buf2) {
+  return this._match(new Tap(buf1), new Tap(buf2));
+};
+
+Type.prototype.createResolver = function (type, opts) {
+  if (!Type.isType(type)) {
+    // More explicit error message than the "incompatible type" thrown
+    // otherwise (especially because of the overridden `toJSON` method).
+    throw new Error(f('not a type: %j', type));
+  }
+
+  if (!Type.isType(this, 'logical') && Type.isType(type, 'logical')) {
+    // Trying to read a logical type as a built-in: unwrap the logical type.
+    return this.createResolver(type.underlyingType, opts);
+  }
+
+  opts = opts || {};
+  opts.registry = opts.registry || {};
+
+  var resolver, key;
+  if (
+    Type.isType(this, 'record', 'error') &&
+    Type.isType(type, 'record', 'error')
+  ) {
+    // We allow conversions between records and errors.
+    key = this.name + ':' + type.name; // ':' is illegal in Avro type names.
+    resolver = opts.registry[key];
+    if (resolver) {
+      return resolver;
+    }
+  }
+
+  resolver = new Resolver(this);
+  if (key) { // Register resolver early for recursive schemas.
+    opts.registry[key] = resolver;
+  }
+
+  if (Type.isType(type, 'union')) {
+    var resolvers = type.types.map(function (t) {
+      return this.createResolver(t, opts);
+    }, this);
+    resolver._read = function (tap) {
+      var index = tap.readLong();
+      var resolver = resolvers[index];
+      if (resolver === undefined) {
+        throw new Error(f('invalid union index: %s', index));
+      }
+      return resolvers[index]._read(tap);
+    };
+  } else {
+    this._update(resolver, type, opts);
+  }
+
+  if (!resolver._read) {
+    throw new Error(f('cannot read %s as %s', type, this));
+  }
+  return Object.freeze(resolver);
+};
+
+Type.prototype.decode = function (buf, pos, resolver) {
+  var tap = new Tap(buf, pos);
+  var val = readValue(this, tap, resolver);
+  if (!tap.isValid()) {
+    return {value: undefined, offset: -1};
+  }
+  return {value: val, offset: tap.pos};
+};
+
+Type.prototype.encode = function (val, buf, pos) {
+  var tap = new Tap(buf, pos);
+  this._write(tap, val);
+  if (!tap.isValid()) {
+    // Don't throw as there is no way to predict this. We also return the
+    // number of missing bytes to ease resizing.
+    return buf.length - tap.pos;
+  }
+  return tap.pos;
+};
+
+Type.prototype.equals = function (type) {
+  return (
+    Type.isType(type) &&
+    this.fingerprint().equals(type.fingerprint())
+  );
+};
+
+Type.prototype.fingerprint = function (algorithm) {
+  if (!algorithm) {
+    if (!this._hash.str) {
+      var schemaStr = JSON.stringify(this.schema());
+      this._hash.str = utils.getHash(schemaStr).toString('binary');
+    }
+    return new Buffer(this._hash.str, 'binary');
+  } else {
+    return utils.getHash(JSON.stringify(this.schema()), algorithm);
+  }
+};
+
+Type.prototype.fromBuffer = function (buf, resolver, noCheck) {
+  var tap = new Tap(buf);
+  var val = readValue(this, tap, resolver, noCheck);
+  if (!tap.isValid()) {
+    throw new Error('truncated buffer');
+  }
+  if (!noCheck && tap.pos < buf.length) {
+    throw new Error('trailing data');
+  }
+  return val;
+};
+
+Type.prototype.fromString = function (str) {
+  return this._copy(JSON.parse(str), {coerce: 2});
+};
+
+Type.prototype.inspect = function () {
+  var typeName = this.typeName;
+  var className = getClassName(typeName);
+  if (isPrimitive(typeName)) {
+    // The class name is sufficient to identify the type.
+    return f('<%s>', className);
+  } else {
+    // We add a little metadata for convenience.
+    var obj = this.schema({exportAttrs: true, noDeref: true});
+    if (typeof obj == 'object' && !Type.isType(this, 'logical')) {
+      obj.type = undefined; // Would be redundant with constructor name.
+    }
+    return f('<%s %j>', className, obj);
+  }
+};
+
+Type.prototype.isValid = function (val, opts) {
+  // We only have a single flag for now, so no need to complicate things.
+  var flags = (opts && opts.noUndeclaredFields) | 0;
+  var errorHook = opts && opts.errorHook;
+  var hook, path;
+  if (errorHook) {
+    path = [];
+    hook = function (any, type) {
+      errorHook.call(this, path.slice(), any, type, val);
+    };
+  }
+  return this._check(val, flags, hook, path);
+};
+
+Type.prototype.random = utils.abstractFunction;
+
+Type.prototype.schema = function (opts) {
+  // Copy the options to avoid mutating the original options object when we
+	// add
+  // the registry of dereferenced types.
+  return this._attrs({
+    exportAttrs: !!(opts && opts.exportAttrs),
+    noDeref: !!(opts && opts.noDeref)
+  });
+};
+
+Type.prototype.toBuffer = function (val) {
+  TAP.pos = 0;
+  this._write(TAP, val);
+  var buf = new Buffer(TAP.pos);
+  if (TAP.isValid()) {
+    TAP.buf.copy(buf, 0, 0, TAP.pos);
+  } else {
+    this._write(new Tap(buf), val);
+  }
+  return buf;
+};
+
+Type.prototype.toJSON = function () {
+  // Convenience to allow using `JSON.stringify(type)` to get a type's schema.
+  return this.schema({exportAttrs: true});
+};
+
+Type.prototype.toString = function (val) {
+  if (val === undefined) {
+    // Consistent behavior with standard `toString` expectations.
+    return JSON.stringify(this.schema({noDeref: true}));
+  }
+  return JSON.stringify(this._copy(val, {coerce: 3}));
+};
+
+Type.prototype.wrap = function (val) {
+  var Branch = this._branchConstructor;
+  return Branch === null ? null : new Branch(val);
+};
+
+Type.prototype._attrs = function (opts) {
+  // This function handles a lot of the common logic to schema generation
+  // across types, for example keeping track of which types have already been
+  // de-referenced (i.e. derefed).
+  opts.derefed = opts.derefed || {};
+  var name = this.name;
+  if (name !== undefined) {
+    if (opts.noDeref || opts.derefed[name]) {
+      return name;
+    }
+    opts.derefed[name] = true;
+  }
+  var schema = {};
+  // The order in which we add fields to the `schema` object matters here.
+  // Since JS objects are unordered, this implementation (unfortunately)
+	// relies
+  // on engines returning properties in the same order that they are inserted
+  // in. This is not in the JS spec, but can be "somewhat" safely assumed (see
+  // http://stackoverflow.com/q/5525795/1062617).
+  if (this.name !== undefined) {
+    schema.name = name;
+  }
+  schema.type = this.typeName;
+  var derefedSchema = this._deref(schema, opts);
+  if (derefedSchema !== undefined) {
+    // We allow the original schema to be overridden (this will happen for
+    // primitive types and logical types).
+    schema = derefedSchema;
+  }
+  if (opts.exportAttrs) {
+    if (this.aliases && this.aliases.length) {
+      schema.aliases = this.aliases;
+    }
+    if (this.doc !== undefined) {
+      schema.doc = this.doc;
+    }
+  }
+  return schema;
+};
+
+Type.prototype._createBranchConstructor = function () {
+  // jshint -W054
+  var name = this.branchName;
+  if (name === 'null') {
+    return null;
+  }
+  var attr = ~name.indexOf('.') ? 'this[\'' + name + '\']' : 'this.' + name;
+  var body = 'return function Branch$(val) { ' + attr + ' = val; };';
+  var Branch = (new Function(body))();
+  Branch.type = this;
+  Branch.prototype.unwrap = new Function('return ' + attr + ';');
+  Branch.prototype.unwrapped = Branch.prototype.unwrap; // Deprecated.
+  return Branch;
+};
+
+Type.prototype._peek = function (tap) {
+  var pos = tap.pos;
+  var val = this._read(tap);
+  tap.pos = pos;
+  return val;
+};
+
+Type.prototype._check = utils.abstractFunction;
+Type.prototype._copy = utils.abstractFunction;
+Type.prototype._deref = utils.abstractFunction;
+Type.prototype._match = utils.abstractFunction;
+Type.prototype._read = utils.abstractFunction;
+Type.prototype._skip = utils.abstractFunction;
+Type.prototype._update = utils.abstractFunction;
+Type.prototype._write = utils.abstractFunction;
+
+// "Deprecated" getters (will be explicitly deprecated in 5.1).
+
+Type.prototype.getAliases = function () { return this.aliases; };
+
+Type.prototype.getFingerprint = Type.prototype.fingerprint;
+
+Type.prototype.getName = function (asBranch) {
+  return (this.name || !asBranch) ? this.name : this.branchName;
+};
+
+Type.prototype.getSchema = Type.prototype.schema;
+
+Type.prototype.getTypeName = function () { return this.typeName; };
+
+// Implementations.
+
+/**
+ * Base primitive Avro type.
+ * 
+ * Most of the primitive types share the same cloning and resolution mechanisms,
+ * provided by this class. This class also lets us conveniently check whether a
+ * type is a primitive using `instanceof`.
+ */
+function PrimitiveType(noFreeze) {
+  Type.call(this);
+  this._branchConstructor = this._createBranchConstructor();
+  if (!noFreeze) {
+    // Abstract long types can't be frozen at this stage.
+    Object.freeze(this);
+  }
+}
+util.inherits(PrimitiveType, Type);
+
+PrimitiveType.prototype._update = function (resolver, type) {
+  if (type.constructor === this.constructor) {
+    resolver._read = this._read;
+  }
+};
+
+PrimitiveType.prototype._copy = function (val) {
+  this._check(val, undefined, throwInvalidError);
+  return val;
+};
+
+PrimitiveType.prototype._deref = function () { return this.typeName; };
+
+PrimitiveType.prototype.compare = utils.compare;
+
+/** Nulls. */
+function NullType() { PrimitiveType.call(this); }
+util.inherits(NullType, PrimitiveType);
+
+NullType.prototype._check = function (val, flags, hook) {
+  var b = val === null;
+  if (!b && hook) {
+    hook(val, this);
+  }
+  return b;
+};
+
+NullType.prototype._read = function () { return null; };
+
+NullType.prototype._skip = function () {};
+
+NullType.prototype._write = function (tap, val) {
+  if (val !== null) {
+    throwInvalidError(val, this);
+  }
+};
+
+NullType.prototype._match = function () { return 0; };
+
+NullType.prototype.compare = NullType.prototype._match;
+
+NullType.prototype.typeName = 'null';
+
+NullType.prototype.random = NullType.prototype._read;
+
+/** Booleans. */
+function BooleanType() { PrimitiveType.call(this); }
+util.inherits(BooleanType, PrimitiveType);
+
+BooleanType.prototype._check = function (val, flags, hook) {
+  var b = typeof val == 'boolean';
+  if (!b && hook) {
+    hook(val, this);
+  }
+  return b;
+};
+
+BooleanType.prototype._read = function (tap) { return tap.readBoolean(); };
+
+BooleanType.prototype._skip = function (tap) { tap.skipBoolean(); };
+
+BooleanType.prototype._write = function (tap, val) {
+  if (typeof val != 'boolean') {
+    throwInvalidError(val, this);
+  }
+  tap.writeBoolean(val);
+};
+
+BooleanType.prototype._match = function (tap1, tap2) {
+  return tap1.matchBoolean(tap2);
+};
+
+BooleanType.prototype.typeName = 'boolean';
+
+BooleanType.prototype.random = function () { return RANDOM.nextBoolean(); };
+
+/** Integers. */
+function IntType() { PrimitiveType.call(this); }
+util.inherits(IntType, PrimitiveType);
+
+IntType.prototype._check = function (val, flags, hook) {
+  var b = val === (val | 0);
+  if (!b && hook) {
+    hook(val, this);
+  }
+  return b;
+};
+
+IntType.prototype._read = function (tap) { return tap.readInt(); };
+
+IntType.prototype._skip = function (tap) { tap.skipInt(); };
+
+IntType.prototype._write = function (tap, val) {
+  if (val !== (val | 0)) {
+    throwInvalidError(val, this);
+  }
+  tap.writeInt(val);
+};
+
+IntType.prototype._match = function (tap1, tap2) {
+  return tap1.matchInt(tap2);
+};
+
+IntType.prototype.typeName = 'int';
+
+IntType.prototype.random = function () { return RANDOM.nextInt(1000) | 0; };
+
+/**
+ * Longs.
+ * 
+ * We can't capture all the range unfortunately since JavaScript represents all
+ * numbers internally as `double`s, so the default implementation plays safe and
+ * throws rather than potentially silently change the data. See `__with` or
+ * `AbstractLongType` below for a way to implement a custom long type.
+ */
+function LongType() { PrimitiveType.call(this); }
+util.inherits(LongType, PrimitiveType);
+
+LongType.prototype._check = function (val, flags, hook) {
+  var b = typeof val == 'number' && val % 1 === 0 && isSafeLong(val);
+  if (!b && hook) {
+    hook(val, this);
+  }
+  return b;
+};
+
+LongType.prototype._read = function (tap) {
+  var n = tap.readLong();
+  if (!isSafeLong(n)) {
+    throw new Error('potential precision loss');
+  }
+  return n;
+};
+
+LongType.prototype._skip = function (tap) { tap.skipLong(); };
+
+LongType.prototype._write = function (tap, val) {
+  if (typeof val != 'number' || val % 1 || !isSafeLong(val)) {
+    throwInvalidError(val, this);
+  }
+  tap.writeLong(val);
+};
+
+LongType.prototype._match = function (tap1, tap2) {
+  return tap1.matchLong(tap2);
+};
+
+LongType.prototype._update = function (resolver, type) {
+  switch (type.typeName) {
+    case 'int':
+    case 'long':
+      resolver._read = type._read;
+  }
+};
+
+LongType.prototype.typeName = 'long';
+
+LongType.prototype.random = function () { return RANDOM.nextInt(); };
+
+LongType.__with = function (methods, noUnpack) {
+  methods = methods || {}; // Will give a more helpful error message.
+  // We map some of the methods to a different name to be able to intercept
+  // their input and output (otherwise we wouldn't be able to perform any
+  // unpacking logic, and the type wouldn't work when nested).
+  var mapping = {
+    toBuffer: '_toBuffer',
+    fromBuffer: '_fromBuffer',
+    fromJSON: '_fromJSON',
+    toJSON: '_toJSON',
+    isValid: '_isValid',
+    compare: 'compare'
+  };
+  var type = new AbstractLongType(noUnpack);
+  Object.keys(mapping).forEach(function (name) {
+    if (methods[name] === undefined) {
+      throw new Error(f('missing method implementation: %s', name));
+    }
+    type[mapping[name]] = methods[name];
+  });
+  return Object.freeze(type);
+};
+
+/** Floats. */
+function FloatType() { PrimitiveType.call(this); }
+util.inherits(FloatType, PrimitiveType);
+
+FloatType.prototype._check = function (val, flags, hook) {
+  var b = typeof val == 'number';
+  if (!b && hook) {
+    hook(val, this);
+  }
+  return b;
+};
+
+FloatType.prototype._read = function (tap) { return tap.readFloat(); };
+
+FloatType.prototype._skip = function (tap) { tap.skipFloat(); };
+
+FloatType.prototype._write = function (tap, val) {
+  if (typeof val != 'number') {
+    throwInvalidError(val, this);
+  }
+  tap.writeFloat(val);
+};
+
+FloatType.prototype._match = function (tap1, tap2) {
+  return tap1.matchFloat(tap2);
+};
+
+FloatType.prototype._update = function (resolver, type) {
+  switch (type.typeName) {
+    case 'float':
+    case 'int':
+    case 'long':
+      resolver._read = type._read;
+  }
+};
+
+FloatType.prototype.typeName = 'float';
+
+FloatType.prototype.random = function () { return RANDOM.nextFloat(1e3); };
+
+/** Doubles. */
+function DoubleType() { PrimitiveType.call(this); }
+util.inherits(DoubleType, PrimitiveType);
+
+DoubleType.prototype._check = function (val, flags, hook) {
+  var b = typeof val == 'number';
+  if (!b && hook) {
+    hook(val, this);
+  }
+  return b;
+};
+
+DoubleType.prototype._read = function (tap) { return tap.readDouble(); };
+
+DoubleType.prototype._skip = function (tap) { tap.skipDouble(); };
+
+DoubleType.prototype._write = function (tap, val) {
+  if (typeof val != 'number') {
+    throwInvalidError(val, this);
+  }
+  tap.writeDouble(val);
+};
+
+DoubleType.prototype._match = function (tap1, tap2) {
+  return tap1.matchDouble(tap2);
+};
+
+DoubleType.prototype._update = function (resolver, type) {
+  switch (type.typeName) {
+    case 'double':
+    case 'float':
+    case 'int':
+    case 'long':
+      resolver._read = type._read;
+  }
+};
+
+DoubleType.prototype.typeName = 'double';
+
+DoubleType.prototype.random = function () { return RANDOM.nextFloat(); };
+
+/** Strings. */
+function StringType() { PrimitiveType.call(this); }
+util.inherits(StringType, PrimitiveType);
+
+StringType.prototype._check = function (val, flags, hook) {
+  var b = typeof val == 'string';
+  if (!b && hook) {
+    hook(val, this);
+  }
+  return b;
+};
+
+StringType.prototype._read = function (tap) { return tap.readString(); };
+
+StringType.prototype._skip = function (tap) { tap.skipString(); };
+
+StringType.prototype._write = function (tap, val) {
+  if (typeof val != 'string') {
+    throwInvalidError(val, this);
+  }
+  tap.writeString(val);
+};
+
+StringType.prototype._match = function (tap1, tap2) {
+  return tap1.matchString(tap2);
+};
+
+StringType.prototype._update = function (resolver, type) {
+  switch (type.typeName) {
+    case 'bytes':
+    case 'string':
+      resolver._read = this._read;
+  }
+};
+
+StringType.prototype.typeName = 'string';
+
+StringType.prototype.random = function () {
+  return RANDOM.nextString(RANDOM.nextInt(32));
+};
+
+/**
+ * Bytes.
+ * 
+ * These are represented in memory as `Buffer`s rather than binary-encoded
+ * strings. This is more efficient (when decoding/encoding from bytes, the
+ * common use-case), idiomatic, and convenient.
+ * 
+ * Note the coercion in `_copy`.
+ */
+function BytesType() { PrimitiveType.call(this); }
+util.inherits(BytesType, PrimitiveType);
+
+BytesType.prototype._check = function (val, flags, hook) {
+  var b = Buffer.isBuffer(val);
+  if (!b && hook) {
+    hook(val, this);
+  }
+  return b;
+};
+
+BytesType.prototype._read = function (tap) { return tap.readBytes(); };
+
+BytesType.prototype._skip = function (tap) { tap.skipBytes(); };
+
+BytesType.prototype._write = function (tap, val) {
+  if (!Buffer.isBuffer(val)) {
+    throwInvalidError(val, this);
+  }
+  tap.writeBytes(val);
+};
+
+BytesType.prototype._match = function (tap1, tap2) {
+  return tap1.matchBytes(tap2);
+};
+
+BytesType.prototype._update = StringType.prototype._update;
+
+BytesType.prototype._copy = function (obj, opts) {
+  var buf;
+  switch ((opts && opts.coerce) | 0) {
+    case 3: // Coerce buffers to strings.
+      this._check(obj, undefined, throwInvalidError);
+      return obj.toString('binary');
+    case 2: // Coerce strings to buffers.
+      if (typeof obj != 'string') {
+        throw new Error(f('cannot coerce to buffer: %j', obj));
+      }
+      buf = new Buffer(obj, 'binary');
+      this._check(buf, undefined, throwInvalidError);
+      return buf;
+    case 1: // Coerce buffer JSON representation to buffers.
+      if (!isJsonBuffer(obj)) {
+        throw new Error(f('cannot coerce to buffer: %j', obj));
+      }
+      buf = new Buffer(obj.data);
+      this._check(buf, undefined, throwInvalidError);
+      return buf;
+    default: // Copy buffer.
+      this._check(obj, undefined, throwInvalidError);
+      return new Buffer(obj);
+  }
+};
+
+BytesType.prototype.compare = Buffer.compare;
+
+BytesType.prototype.typeName = 'bytes';
+
+BytesType.prototype.random = function () {
+  return RANDOM.nextBuffer(RANDOM.nextInt(32));
+};
+
+/** Base "abstract" Avro union type. */
+function UnionType(schema, opts) {
+  Type.call(this);
+
+  if (!Array.isArray(schema)) {
+    throw new Error(f('non-array union schema: %j', schema));
+  }
+  if (!schema.length) {
+    throw new Error('empty union');
+  }
+  this.types = Object.freeze(schema.map(function (obj) {
+    return Type.forSchema(obj, opts);
+  }));
+
+  this._branchIndices = {};
+  this.types.forEach(function (type, i) {
+    if (Type.isType(type, 'union')) {
+      throw new Error('unions cannot be directly nested');
+    }
+    var branch = type.branchName;
+    if (this._branchIndices[branch] !== undefined) {
+      throw new Error(f('duplicate union branch name: %j', branch));
+    }
+    this._branchIndices[branch] = i;
+  }, this);
+}
+util.inherits(UnionType, Type);
+
+UnionType.prototype._branchConstructor = function () {
+  throw new Error('unions cannot be directly wrapped');
+};
+
+UnionType.prototype._skip = function (tap) {
+  this.types[tap.readLong()]._skip(tap);
+};
+
+UnionType.prototype._match = function (tap1, tap2) {
+  var n1 = tap1.readLong();
+  var n2 = tap2.readLong();
+  if (n1 === n2) {
+    return this.types[n1]._match(tap1, tap2);
+  } else {
+    return n1 < n2 ? -1 : 1;
+  }
+};
+
+UnionType.prototype._deref = function (schema, opts) {
+  return this.types.map(function (t) { return t._attrs(opts); });
+};
+
+UnionType.prototype.getTypes = function () { return this.types; };
+
+/**
+ * "Natural" union type.
+ * 
+ * This representation doesn't require a wrapping object and is therefore
+ * simpler and generally closer to what users expect. However it cannot be used
+ * to represent all Avro unions since some lead to ambiguities (e.g. if two
+ * number types are in the union).
+ * 
+ * Currently, this union supports at most one type in each of the categories
+ * below:
+ *  + `null` + `boolean` + `int`, `long`, `float`, `double` + `string`, `enum` +
+ * `bytes`, `fixed` + `array` + `map`, `record`
+ */
+function UnwrappedUnionType(schema, opts) {
+  UnionType.call(this, schema, opts);
+
+  this._logicalBranches = null;
+  this._bucketIndices = {};
+  this.types.forEach(function (type, index) {
+    if (Type.isType(type, 'logical')) {
+      if (!this._logicalBranches) {
+        this._logicalBranches = [];
+      }
+      this._logicalBranches.push({index: index, type: type});
+    } else {
+      var bucket = getTypeBucket(type);
+      if (this._bucketIndices[bucket] !== undefined) {
+        throw new Error(f('ambiguous unwrapped union: %j', this));
+      }
+      this._bucketIndices[bucket] = index;
+    }
+  }, this);
+
+  Object.freeze(this);
+}
+util.inherits(UnwrappedUnionType, UnionType);
+
+UnwrappedUnionType.prototype._getIndex = function (val) {
+  var index = this._bucketIndices[getValueBucket(val)];
+  if (this._logicalBranches) {
+    // Slower path, we must run the value through all logical types.
+    index = this._getLogicalIndex(val, index);
+  }
+  return index;
+};
+
+UnwrappedUnionType.prototype._getLogicalIndex = function (any, index) {
+  var logicalBranches = this._logicalBranches;
+  var i, l, branch;
+  for (i = 0, l = logicalBranches.length; i < l; i++) {
+    branch = logicalBranches[i];
+    if (branch.type._check(any)) {
+      if (index === undefined) {
+        index = branch.index;
+      } else {
+        // More than one branch matches the value so we aren't guaranteed to
+        // infer the correct type. We throw rather than corrupt data. This can
+        // be fixed by "tightening" the logical types.
+        throw new Error('ambiguous conversion');
+      }
+    }
+  }
+  return index;
+};
+
+UnwrappedUnionType.prototype._check = function (val, flags, hook, path) {
+  var index = this._getIndex(val);
+  var b = index !== undefined;
+  if (b) {
+    return this.types[index]._check(val, flags, hook, path);
+  }
+  if (hook) {
+    hook(val, this);
+  }
+  return b;
+};
+
+UnwrappedUnionType.prototype._read = function (tap) {
+  var index = tap.readLong();
+  var branchType = this.types[index];
+  if (branchType) {
+    return branchType._read(tap);
+  } else {
+    throw new Error(f('invalid union index: %s', index));
+  }
+};
+
+UnwrappedUnionType.prototype._write = function (tap, val) {
+  var index = this._getIndex(val);
+  if (index === undefined) {
+    throwInvalidError(val, this);
+  }
+  tap.writeLong(index);
+  if (val !== null) {
+    this.types[index]._write(tap, val);
+  }
+};
+
+UnwrappedUnionType.prototype._update = function (resolver, type, opts) {
+  // jshint -W083
+  // (The loop exits after the first function is created.)
+  var i, l, typeResolver;
+  for (i = 0, l = this.types.length; i < l; i++) {
+    try {
+      typeResolver = this.types[i].createResolver(type, opts);
+    } catch (err) {
+      continue;
+    }
+    resolver._read = function (tap) { return typeResolver._read(tap); };
+    return;
+  }
+};
+
+UnwrappedUnionType.prototype._copy = function (val, opts) {
+  var coerce = opts && opts.coerce | 0;
+  var wrap = opts && opts.wrap | 0;
+  var index;
+  if (wrap === 2) {
+    // We are parsing a default, so always use the first branch's type.
+    index = 0;
+  } else {
+    switch (coerce) {
+      case 1:
+        // Using the `coerceBuffers` option can cause corruption and erroneous
+        // failures with unwrapped unions (in rare cases when the union also
+        // contains a record which matches a buffer's JSON representation).
+        if (isJsonBuffer(val) && this._bucketIndices.buffer !== undefined) {
+          index = this._bucketIndices.buffer;
+        } else {
+          index = this._getIndex(val);
+        }
+        break;
+      case 2:
+        // Decoding from JSON, we must unwrap the value.
+        if (val === null) {
+          index = this._bucketIndices['null'];
+        } else if (typeof val === 'object') {
+          var keys = Object.keys(val);
+          if (keys.length === 1) {
+            index = this._branchIndices[keys[0]];
+            val = val[keys[0]];
+          }
+        }
+        break;
+      default:
+        index = this._getIndex(val);
+    }
+    if (index === undefined) {
+      throwInvalidError(val, this);
+    }
+  }
+  var type = this.types[index];
+  if (val === null || wrap === 3) {
+    return type._copy(val, opts);
+  } else {
+    switch (coerce) {
+      case 3:
+        // Encoding to JSON, we wrap the value.
+        var obj = {};
+        obj[type.branchName] = type._copy(val, opts);
+        return obj;
+      default:
+        return type._copy(val, opts);
+    }
+  }
+};
+
+UnwrappedUnionType.prototype.compare = function (val1, val2) {
+  var index1 = this._getIndex(val1);
+  var index2 = this._getIndex(val2);
+  if (index1 === undefined) {
+    throwInvalidError(val1, this);
+  } else if (index2 === undefined) {
+    throwInvalidError(val2, this);
+  } else if (index1 === index2) {
+    return this.types[index1].compare(val1, val2);
+  } else {
+    return utils.compare(index1, index2);
+  }
+};
+
+UnwrappedUnionType.prototype.typeName = 'union:unwrapped';
+
+UnwrappedUnionType.prototype.random = function () {
+  var index = RANDOM.nextInt(this.types.length);
+  return this.types[index].random();
+};
+
+/**
+ * Compatible union type.
+ * 
+ * Values of this type are represented in memory similarly to their JSON
+ * representation (i.e. inside an object with single key the name of the
+ * contained type).
+ * 
+ * This is not ideal, but is the most efficient way to unambiguously support all
+ * unions. Here are a few reasons why the wrapping object is necessary:
+ *  + Unions with multiple number types would have undefined behavior, unless
+ * numbers are wrapped (either everywhere, leading to large performance and
+ * convenience costs; or only when necessary inside unions, making it hard to
+ * understand when numbers are wrapped or not). + Fixed types would have to be
+ * wrapped to be distinguished from bytes. + Using record's constructor names
+ * would work (after a slight change to use the fully qualified name), but would
+ * mean that generic objects could no longer be valid records (making it
+ * inconvenient to do simple things like creating new records).
+ */
+function WrappedUnionType(schema, opts) {
+  UnionType.call(this, schema, opts);
+  Object.freeze(this);
+}
+util.inherits(WrappedUnionType, UnionType);
+
+WrappedUnionType.prototype._check = function (val, flags, hook, path) {
+  var b = false;
+  if (val === null) {
+    // Shortcut type lookup in this case.
+    b = this._branchIndices['null'] !== undefined;
+  } else if (typeof val == 'object') {
+    var keys = Object.keys(val);
+    if (keys.length === 1) {
+      // We require a single key here to ensure that writes are correct and
+      // efficient as soon as a record passes this check.
+      var name = keys[0];
+      var index = this._branchIndices[name];
+      if (index !== undefined) {
+        if (hook) {
+          // Slow path.
+          path.push(name);
+          b = this.types[index]._check(val[name], flags, hook, path);
+          path.pop();
+          return b;
+        } else {
+          return this.types[index]._check(val[name], flags);
+        }
+      }
+    }
+  }
+  if (!b && hook) {
+    hook(val, this);
+  }
+  return b;
+};
+
+WrappedUnionType.prototype._read = function (tap) {
+  var type = this.types[tap.readLong()];
+  if (!type) {
+    throw new Error(f('invalid union index'));
+  }
+  var Branch = type._branchConstructor;
+  if (Branch === null) {
+    return null;
+  } else {
+    return new Branch(type._read(tap));
+  }
+};
+
+WrappedUnionType.prototype._write = function (tap, val) {
+  var index, keys, name;
+  if (val === null) {
+    index = this._branchIndices['null'];
+    if (index === undefined) {
+      throwInvalidError(val, this);
+    }
+    tap.writeLong(index);
+  } else {
+    keys = Object.keys(val);
+    if (keys.length === 1) {
+      name = keys[0];
+      index = this._branchIndices[name];
+    }
+    if (index === undefined) {
+      throwInvalidError(val, this);
+    }
+    tap.writeLong(index);
+    this.types[index]._write(tap, val[name]);
+  }
+};
+
+WrappedUnionType.prototype._update = function (resolver, type, opts) {
+  // jshint -W083
+  // (The loop exits after the first function is created.)
+  var i, l, typeResolver, Branch;
+  for (i = 0, l = this.types.length; i < l; i++) {
+    try {
+      typeResolver = this.types[i].createResolver(type, opts);
+    } catch (err) {
+      continue;
+    }
+    Branch = this.types[i]._branchConstructor;
+    if (Branch) {
+      resolver._read = function (tap) {
+        return new Branch(typeResolver._read(tap));
+      };
+    } else {
+      resolver._read = function () { return null; };
+    }
+    return;
+  }
+};
+
+WrappedUnionType.prototype._copy = function (val, opts) {
+  var wrap = opts && opts.wrap | 0;
+  if (wrap === 2) {
+    var firstType = this.types[0];
+    // Promote into first type (used for schema defaults).
+    if (val === null && firstType.typeName === 'null') {
+      return null;
+    }
+    return new firstType._branchConstructor(firstType._copy(val, opts));
+  }
+  if (val === null && this._branchIndices['null'] !== undefined) {
+    return null;
+  }
+
+  var i, l, obj;
+  if (typeof val == 'object') {
+    var keys = Object.keys(val);
+    if (keys.length === 1) {
+      var name = keys[0];
+      i = this._branchIndices[name];
+      if (i === undefined && opts.qualifyNames) {
+        // We are a bit more flexible than in `_check` here since we have
+        // to deal with other serializers being less strict, so we fall
+        // back to looking up unqualified names.
+        var j, type;
+        for (j = 0, l = this.types.length; j < l; j++) {
+          type = this.types[j];
+          if (type.name && name === unqualify(type.name)) {
+            i = j;
+            break;
+          }
+        }
+      }
+      if (i !== undefined) {
+        obj = this.types[i]._copy(val[name], opts);
+      }
+    }
+  }
+  if (wrap === 1 && obj === undefined) {
+    // Try promoting into first match (convenience, slow).
+    i = 0;
+    l = this.types.length;
+    while (i < l && obj === undefined) {
+      try {
+        obj = this.types[i]._copy(val, opts);
+      } catch (err) {
+        i++;
+      }
+    }
+  }
+  if (obj !== undefined) {
+    return wrap === 3 ? obj : new this.types[i]._branchConstructor(obj);
+  }
+  throwInvalidError(val, this);
+};
+
+WrappedUnionType.prototype.compare = function (val1, val2) {
+  var name1 = val1 === null ? 'null' : Object.keys(val1)[0];
+  var name2 = val2 === null ? 'null' : Object.keys(val2)[0];
+  var index = this._branchIndices[name1];
+  if (name1 === name2) {
+    return name1 === 'null' ?
+      0 :
+      this.types[index].compare(val1[name1], val2[name1]);
+  } else {
+    return utils.compare(index, this._branchIndices[name2]);
+  }
+};
+
+WrappedUnionType.prototype.typeName = 'union:wrapped';
+
+WrappedUnionType.prototype.random = function () {
+  var index = RANDOM.nextInt(this.types.length);
+  var type = this.types[index];
+  var Branch = type._branchConstructor;
+  if (!Branch) {
+    return null;
+  }
+  return new Branch(type.random());
+};
+
+/**
+ * Avro enum type.
+ * 
+ * Represented as strings (with allowed values from the set of symbols). Using
+ * integers would be a reasonable option, but the performance boost is arguably
+ * offset by the legibility cost and the extra deviation from the JSON encoding
+ * convention.
+ * 
+ * An integer representation can still be used (e.g. for compatibility with
+ * TypeScript `enum`s) by overriding the `EnumType` with a `LongType` (e.g. via
+ * `parse`'s registry).
+ */
+function EnumType(schema, opts) {
+  Type.call(this, schema, opts);
+  if (!Array.isArray(schema.symbols) || !schema.symbols.length) {
+    throw new Error(f('invalid enum symbols: %j', schema.symbols));
+  }
+  this.symbols = Object.freeze(schema.symbols.slice());
+  this._indices = {};
+  this.symbols.forEach(function (symbol, i) {
+    if (!isValidName(symbol)) {
+      throw new Error(f('invalid %s symbol: %j', this, symbol));
+    }
+    if (this._indices[symbol] !== undefined) {
+      throw new Error(f('duplicate %s symbol: %j', this, symbol));
+    }
+    this._indices[symbol] = i;
+  }, this);
+  this._branchConstructor = this._createBranchConstructor();
+  Object.freeze(this);
+}
+util.inherits(EnumType, Type);
+
+EnumType.prototype._check = function (val, flags, hook) {
+  var b = this._indices[val] !== undefined;
+  if (!b && hook) {
+    hook(val, this);
+  }
+  return b;
+};
+
+EnumType.prototype._read = function (tap) {
+  var index = tap.readLong();
+  var symbol = this.symbols[index];
+  if (symbol === undefined) {
+    throw new Error(f('invalid %s enum index: %s', this.name, index));
+  }
+  return symbol;
+};
+
+EnumType.prototype._skip = function (tap) { tap.skipLong(); };
+
+EnumType.prototype._write = function (tap, val) {
+  var index = this._indices[val];
+  if (index === undefined) {
+    throwInvalidError(val, this);
+  }
+  tap.writeLong(index);
+};
+
+EnumType.prototype._match = function (tap1, tap2) {
+  return tap1.matchLong(tap2);
+};
+
+EnumType.prototype.compare = function (val1, val2) {
+  return utils.compare(this._indices[val1], this._indices[val2]);
+};
+
+EnumType.prototype._update = function (resolver, type) {
+  var symbols = this.symbols;
+  if (
+    type.typeName === 'enum' &&
+    (!type.name || ~getAliases(this).indexOf(type.name)) &&
+    type.symbols.every(function (s) { return ~symbols.indexOf(s); })
+  ) {
+    resolver.symbols = type.symbols;
+    resolver._read = type._read;
+  }
+};
+
+EnumType.prototype._copy = function (val) {
+  this._check(val, undefined, throwInvalidError);
+  return val;
+};
+
+EnumType.prototype._deref = function (schema) {
+  schema.symbols = this.symbols;
+};
+
+EnumType.prototype.getSymbols = function () { return this.symbols; };
+
+EnumType.prototype.typeName = 'enum';
+
+EnumType.prototype.random = function () {
+  return RANDOM.choice(this.symbols);
+};
+
+/** Avro fixed type. Represented simply as a `Buffer`. */
+function FixedType(schema, opts) {
+  Type.call(this, schema, opts);
+  if (schema.size !== (schema.size | 0) || schema.size < 1) {
+    throw new Error(f('invalid %s size', this.branchName));
+  }
+  this.size = schema.size | 0;
+  this._branchConstructor = this._createBranchConstructor();
+  Object.freeze(this);
+}
+util.inherits(FixedType, Type);
+
+FixedType.prototype._check = function (val, flags, hook) {
+  var b = Buffer.isBuffer(val) && val.length === this.size;
+  if (!b && hook) {
+    hook(val, this);
+  }
+  return b;
+};
+
+FixedType.prototype._read = function (tap) {
+  return tap.readFixed(this.size);
+};
+
+FixedType.prototype._skip = function (tap) {
+  tap.skipFixed(this.size);
+};
+
+FixedType.prototype._write = function (tap, val) {
+  if (!Buffer.isBuffer(val) || val.length !== this.size) {
+    throwInvalidError(val, this);
+  }
+  tap.writeFixed(val, this.size);
+};
+
+FixedType.prototype._match = function (tap1, tap2) {
+  return tap1.matchFixed(tap2, this.size);
+};
+
+FixedType.prototype.compare = Buffer.compare;
+
+FixedType.prototype._update = function (resolver, type) {
+  if (
+    type.typeName === 'fixed' &&
+    this.size === type.size &&
+    (!type.name || ~getAliases(this).indexOf(type.name))
+  ) {
+    resolver.size = this.size;
+    resolver._read = this._read;
+  }
+};
+
+FixedType.prototype._copy = BytesType.prototype._copy;
+
+FixedType.prototype._deref = function (schema) { schema.size = this.size; };
+
+FixedType.prototype.getSize = function () { return this.size; };
+
+FixedType.prototype.typeName = 'fixed';
+
+FixedType.prototype.random = function () {
+  return RANDOM.nextBuffer(this.size);
+};
+
+/** Avro map. Represented as vanilla objects. */
+function MapType(schema, opts) {
+  Type.call(this);
+  if (!schema.values) {
+    throw new Error(f('missing map values: %j', schema));
+  }
+  this.valuesType = Type.forSchema(schema.values, opts);
+  this._branchConstructor = this._createBranchConstructor();
+  Object.freeze(this);
+}
+util.inherits(MapType, Type);
+
+MapType.prototype._check = function (val, flags, hook, path) {
+  if (!val || typeof val != 'object' || Array.isArray(val)) {
+    if (hook) {
+      hook(val, this);
+    }
+    return false;
+  }
+
+  var keys = Object.keys(val);
+  var b = true;
+  var i, l, j, key;
+  if (hook) {
+    // Slow path.
+    j = path.length;
+    path.push('');
+    for (i = 0, l = keys.length; i < l; i++) {
+      key = path[j] = keys[i];
+      if (!this.valuesType._check(val[key], flags, hook, path)) {
+        b = false;
+      }
+    }
+    path.pop();
+  } else {
+    for (i = 0, l = keys.length; i < l; i++) {
+      if (!this.valuesType._check(val[keys[i]], flags)) {
+        return false;
+      }
+    }
+  }
+  return b;
+};
+
+MapType.prototype._read = function (tap) {
+  var values = this.valuesType;
+  var val = {};
+  var n;
+  while ((n = readArraySize(tap))) {
+    while (n--) {
+      var key = tap.readString();
+      val[key] = values._read(tap);
+    }
+  }
+  return val;
+};
+
+MapType.prototype._skip = function (tap) {
+  var values = this.valuesType;
+  var len, n;
+  while ((n = tap.readLong())) {
+    if (n < 0) {
+      len = tap.readLong();
+      tap.pos += len;
+    } else {
+      while (n--) {
+        tap.skipString();
+        values._skip(tap);
+      }
+    }
+  }
+};
+
+MapType.prototype._write = function (tap, val) {
+  if (!val || typeof val != 'object' || Array.isArray(val)) {
+    throwInvalidError(val, this);
+  }
+
+  var values = this.valuesType;
+  var keys = Object.keys(val);
+  var n = keys.length;
+  var i, key;
+  if (n) {
+    tap.writeLong(n);
+    for (i = 0; i < n; i++) {
+      key = keys[i];
+      tap.writeString(key);
+      values._write(tap, val[key]);
+    }
+  }
+  tap.writeLong(0);
+};
+
+MapType.prototype._match = function () {
+  throw new Error('maps cannot be compared');
+};
+
+MapType.prototype._update = function (rsv, type, opts) {
+  if (type.typeName === 'map') {
+    rsv.valuesType = this.valuesType.createResolver(type.valuesType, opts);
+    rsv._read = this._read;
+  }
+};
+
+MapType.prototype._copy = function (val, opts) {
+  if (val && typeof val == 'object' && !Array.isArray(val)) {
+    var values = this.valuesType;
+    var keys = Object.keys(val);
+    var i, l, key;
+    var copy = {};
+    for (i = 0, l = keys.length; i < l; i++) {
+      key = keys[i];
+      copy[key] = values._copy(val[key], opts);
+    }
+    return copy;
+  }
+  throwInvalidError(val, this);
+};
+
+MapType.prototype.compare = MapType.prototype._match;
+
+MapType.prototype.typeName = 'map';
+
+MapType.prototype.getValuesType = function () { return this.valuesType; };
+
+MapType.prototype.random = function () {
+  var val = {};
+  var i, l;
+  for (i = 0, l = RANDOM.nextInt(10); i < l; i++) {
+    val[RANDOM.nextString(RANDOM.nextInt(20))] = this.valuesType.random();
+  }
+  return val;
+};
+
+MapType.prototype._deref = function (schema, opts) {
+  schema.values = this.valuesType._attrs(opts);
+};
+
+/** Avro array. Represented as vanilla arrays. */
+function ArrayType(schema, opts) {
+  Type.call(this);
+  if (!schema.items) {
+    throw new Error(f('missing array items: %j', schema));
+  }
+  this.itemsType = Type.forSchema(schema.items, opts);
+  this._branchConstructor = this._createBranchConstructor();
+  Object.freeze(this);
+}
+util.inherits(ArrayType, Type);
+
+ArrayType.prototype._check = function (val, flags, hook, path) {
+  if (!Array.isArray(val)) {
+    if (hook) {
+      hook(val, this);
+    }
+    return false;
+  }
+
+  var b = true;
+  var i, l, j;
+  if (hook) {
+    // Slow path.
+    j = path.length;
+    path.push('');
+    for (i = 0, l = val.length; i < l; i++) {
+      path[j] = '' + i;
+      if (!this.itemsType._check(val[i], flags, hook, path)) {
+        b = false;
+      }
+    }
+    path.pop();
+  } else {
+    for (i = 0, l = val.length; i < l; i++) {
+      if (!this.itemsType._check(val[i], flags)) {
+        return false;
+      }
+    }
+  }
+  return b;
+};
+
+ArrayType.prototype._read = function (tap) {
+  var items = this.itemsType;
+  var val = [];
+  var i, n;
+  while ((n = tap.readLong())) {
+    if (n < 0) {
+      n = -n;
+      tap.skipLong(); // Skip size.
+    }
+    for (i = 0; i < n; i++) {
+      val[i] = items._read(tap);
+    }
+  }
+  return val;
+};
+
+ArrayType.prototype._skip = function (tap) {
+  var len, n;
+  while ((n = tap.readLong())) {
+    if (n < 0) {
+      len = tap.readLong();
+      tap.pos += len;
+    } else {
+      while (n--) {
+        this.itemsType._skip(tap);
+      }
+    }
+  }
+};
+
+ArrayType.prototype._write = function (tap, val) {
+  if (!Array.isArray(val)) {
+    throwInvalidError(val, this);
+  }
+
+  var n = val.length;
+  var i;
+  if (n) {
+    tap.writeLong(n);
+    for (i = 0; i < n; i++) {
+      this.itemsType._write(tap, val[i]);
+    }
+  }
+  tap.writeLong(0);
+};
+
+ArrayType.prototype._match = function (tap1, tap2) {
+  var n1 = tap1.readLong();
+  var n2 = tap2.readLong();
+  var f;
+  while (n1 && n2) {
+    f = this.itemsType._match(tap1, tap2);
+    if (f) {
+      return f;
+    }
+    if (!--n1) {
+      n1 = readArraySize(tap1);
+    }
+    if (!--n2) {
+      n2 = readArraySize(tap2);
+    }
+  }
+  return utils.compare(n1, n2);
+};
+
+ArrayType.prototype._update = function (resolver, type, opts) {
+  if (type.typeName === 'array') {
+    resolver.itemsType = this.itemsType.createResolver(type.itemsType, opts);
+    resolver._read = this._read;
+  }
+};
+
+ArrayType.prototype._copy = function (val, opts) {
+  if (!Array.isArray(val)) {
+    throwInvalidError(val, this);
+  }
+  var items = new Array(val.length);
+  var i, l;
+  for (i = 0, l = val.length; i < l; i++) {
+    items[i] = this.itemsType._copy(val[i], opts);
+  }
+  return items;
+};
+
+ArrayType.prototype._deref = function (schema, opts) {
+  schema.items = this.itemsType._attrs(opts);
+};
+
+ArrayType.prototype.compare = function (val1, val2) {
+  var n1 = val1.length;
+  var n2 = val2.length;
+  var i, l, f;
+  for (i = 0, l = Math.min(n1, n2); i < l; i++) {
+    if ((f = this.itemsType.compare(val1[i], val2[i]))) {
+      return f;
+    }
+  }
+  return utils.compare(n1, n2);
+};
+
+ArrayType.prototype.getItemsType = function () { return this.itemsType; };
+
+ArrayType.prototype.typeName = 'array';
+
+ArrayType.prototype.random = function () {
+  var arr = [];
+  var i, l;
+  for (i = 0, l = RANDOM.nextInt(10); i < l; i++) {
+    arr.push(this.itemsType.random());
+  }
+  return arr;
+};
+
+/**
+ * Avro record.
+ * 
+ * Values are represented as instances of a programmatically generated
+ * constructor (similar to a "specific record"), available via the
+ * `getRecordConstructor` method. This "specific record class" gives significant
+ * speedups over using generics objects.
+ * 
+ * Note that vanilla objects are still accepted as valid as long as their fields
+ * match (this makes it much more convenient to do simple things like update
+ * nested records).
+ * 
+ * This type is also used for errors (similar, except for the extra `Error`
+ * constructor call) and for messages (see comment below).
+ */
+function RecordType(schema, opts) {
+  // Force creation of the options object in case we need to register this
+  // record's name.
+  opts = opts || {};
+
+  // Save the namespace to restore it as we leave this record's scope.
+  var namespace = opts.namespace;
+  if (schema.namespace !== undefined) {
+    opts.namespace = schema.namespace;
+  } else if (schema.name) {
+    // Fully qualified names' namespaces are used when no explicit namespace
+    // attribute was specified.
+    var match = /^(.*)\.[^.]+$/.exec(schema.name);
+    if (match) {
+      opts.namespace = match[1];
+    }
+  }
+  Type.call(this, schema, opts);
+
+  if (!Array.isArray(schema.fields)) {
+    throw new Error(f('non-array record fields: %j', schema.fields));
+  }
+  if (utils.hasDuplicates(schema.fields, function (f) { return f.name; })) {
+    throw new Error(f('duplicate field name: %j', schema.fields));
+  }
+  this._fieldsByName = {};
+  this.fields = Object.freeze(schema.fields.map(function (f) {
+    var field = new Field(f, opts);
+    this._fieldsByName[field.name] = field;
+    return field;
+  }, this));
+  this._branchConstructor = this._createBranchConstructor();
+  this._isError = schema.type === 'error';
+  this.recordConstructor = this._createConstructor(opts.errorStackTraces);
+  this._read = this._createReader();
+  this._skip = this._createSkipper();
+  this._write = this._createWriter();
+  this._check = this._createChecker();
+
+  opts.namespace = namespace;
+  Object.freeze(this);
+}
+util.inherits(RecordType, Type);
+
+RecordType.prototype._getConstructorName = function () {
+  return this.name ?
+    unqualify(this.name) :
+    this._isError ? 'Error$' : 'Record$';
+};
+
+RecordType.prototype._createConstructor = function (errorStackTraces) {
+  // jshint -W054
+  var outerArgs = [];
+  var innerArgs = [];
+  var ds = []; // Defaults.
+  var innerBody = '';
+  var i, l, field, name, defaultValue, hasDefault, stackField;
+  for (i = 0, l = this.fields.length; i < l; i++) {
+    field = this.fields[i];
+    defaultValue = field.defaultValue;
+    hasDefault = defaultValue() !== undefined;
+    name = field.name;
+    if (
+      errorStackTraces && this._isError && name === 'stack' &&
+      Type.isType(field.type, 'string') && !hasDefault
+    ) {
+      // We keep track of whether we've encountered a valid stack field (in
+      // particular, without a default) to populate a stack trace below.
+      stackField = field;
+    }
+    innerArgs.push('v' + i);
+    innerBody += '  ';
+    if (!hasDefault) {
+      innerBody += 'this.' + name + ' = v' + i + ';\n';
+    } else {
+      innerBody += 'if (v' + i + ' === undefined) { ';
+      innerBody += 'this.' + name + ' = d' + ds.length + '(); ';
+      innerBody += '} else { this.' + name + ' = v' + i + '; }\n';
+      outerArgs.push('d' + ds.length);
+      ds.push(defaultValue);
+    }
+  }
+  if (stackField) {
+    // We should populate a stack trace.
+    innerBody += '  if (this.stack === undefined) { ';
+    /* istanbul ignore else */
+    if (typeof Error.captureStackTrace == 'function') {
+      // v8 runtimes, the easy case.
+      innerBody += 'Error.captureStackTrace(this, this.constructor);';
+    } else {
+      // A few other runtimes (e.g. SpiderMonkey), might not work everywhere.
+      innerBody += 'this.stack = Error().stack;';
+    }
+    innerBody += ' }\n';
+  }
+  var outerBody = 'return function ' + this._getConstructorName() + '(';
+  outerBody += innerArgs.join() + ') {\n' + innerBody + '};';
+  var Record = new Function(outerArgs.join(), outerBody).apply(undefined, ds);
+
+  var self = this;
+  Record.getType = function () { return self; };
+  Record.type = self;
+  if (this._isError) {
+    util.inherits(Record, Error);
+    Record.prototype.name = this._getConstructorName();
+  }
+  Record.prototype.clone = function (o) { return self.clone(this, o); };
+  Record.prototype.compare = function (v) { return self.compare(this, v); };
+  Record.prototype.isValid = function (o) { return self.isValid(this, o); };
+  Record.prototype.toBuffer = function () { return self.toBuffer(this); };
+  Record.prototype.toString = function () { return self.toString(this); };
+  Record.prototype.wrap = function () { return self.wrap(this); };
+  Record.prototype.wrapped = Record.prototype.wrap; // Deprecated.
+  return Record;
+};
+
+RecordType.prototype._createChecker = function () {
+  // jshint -W054
+  var names = [];
+  var values = [];
+  var name = this._getConstructorName();
+  var body = 'return function check' + name + '(v, f, h, p) {\n';
+  body += '  if (\n';
+  body += '    v === null ||\n';
+  body += '    typeof v != \'object\' ||\n';
+  body += '    (f && !this._checkFields(v))\n';
+  body += '  ) {\n';
+  body += '    if (h) { h(v, this); }\n';
+  body += '    return false;\n';
+  body += '  }\n';
+  if (!this.fields.length) {
+    // Special case, empty record. We handle this directly.
+    body += '  return true;\n';
+  } else {
+    for (i = 0, l = this.fields.length; i < l; i++) {
+      field = this.fields[i];
+      names.push('t' + i);
+      values.push(field.type);
+      if (field.defaultValue() !== undefined) {
+        body += '  var v' + i + ' = v.' + field.name + ';\n';
+      }
+    }
+    body += '  if (h) {\n';
+    body += '    var b = 1;\n';
+    body += '    var j = p.length;\n';
+    body += '    p.push(\'\');\n';
+    var i, l, field;
+    for (i = 0, l = this.fields.length; i < l; i++) {
+      field = this.fields[i];
+      body += '    p[j] = \'' + field.name + '\';\n';
+      body += '    b &= ';
+      if (field.defaultValue() === undefined) {
+        body += 't' + i + '._check(v.' + field.name + ', f, h, p);\n';
+      } else {
+        body += 'v' + i + ' === undefined || ';
+        body += 't' + i + '._check(v' + i + ', f, h, p);\n';
+      }
+    }
+    body += '    p.pop();\n';
+    body += '    return !!b;\n';
+    body += '  } else {\n    return (\n      ';
+    body += this.fields.map(function (field, i) {
+      return field.defaultValue() === undefined ?
+        't' + i + '._check(v.' + field.name + ', f)' :
+        '(v' + i + ' === undefined || t' + i + '._check(v' + i + ', f))';
+    }).join(' &&\n      ');
+    body += '\n    );\n  }\n';
+  }
+  body += '};';
+  return new Function(names.join(), body).apply(undefined, values);
+};
+
+RecordType.prototype._createReader = function () {
+  // jshint -W054
+  var names = [];
+  var values = [this.recordConstructor];
+  var i, l;
+  for (i = 0, l = this.fields.length; i < l; i++) {
+    names.push('t' + i);
+    values.push(this.fields[i].type);
+  }
+  var name = this._getConstructorName();
+  var body = 'return function read' + name + '(t) {\n';
+  body += '  return new ' + name + '(\n    ';
+  body += names.map(function (s) { return s + '._read(t)'; }).join(',\n    ');
+  body += '\n  );\n};';
+  names.unshift(name);
+  // We can do this since the JS spec guarantees that function arguments are
+  // evaluated from left to right.
+  return new Function(names.join(), body).apply(undefined, values);
+};
+
+RecordType.prototype._createSkipper = function () {
+  // jshint -W054
+  var args = [];
+  var body = 'return function skip' + this._getConstructorName() + '(t) {\n';
+  var values = [];
+  var i, l;
+  for (i = 0, l = this.fields.length; i < l; i++) {
+    args.push('t' + i);
+    values.push(this.fields[i].type);
+    body += '  t' + i + '._skip(t);\n';
+  }
+  body += '}';
+  return new Function(args.join(), body).apply(undefined, values);
+};
+
+RecordType.prototype._createWriter = function () {
+  // jshint -W054
+  // We still do default handling here, in case a normal JS object is passed.
+  var args = [];
+  var name = this._getConstructorName();
+  var body = 'return function write' + name + '(t, v) {\n';
+  var values = [];
+  var i, l, field, value;
+  for (i = 0, l = this.fields.length; i < l; i++) {
+    field = this.fields[i];
+    args.push('t' + i);
+    values.push(field.type);
+    body += '  ';
+    if (field.defaultValue() === undefined) {
+      body += 't' + i + '._write(t, v.' + field.name + ');\n';
+    } else {
+      value = field.type.toBuffer(field.defaultValue()).toString('binary');
+      // Convert the default value to a binary string ahead of time. We aren't
+      // converting it to a buffer to avoid retaining too much memory. If we
+      // had our own buffer pool, this could be an idea in the future.
+      args.push('d' + i);
+      values.push(value);
+      body += 'var v' + i + ' = v.' + field.name + ';\n';
+      body += 'if (v' + i + ' === undefined) {\n';
+      body += '    t.writeBinary(d' + i + ', ' + value.length + ');\n';
+      body += '  } else {\n    t' + i + '._write(t, v' + i + ');\n  }\n';
+    }
+  }
+  body += '}';
+  return new Function(args.join(), body).apply(undefined, values);
+};
+
+RecordType.prototype._update = function (resolver, type, opts) {
+  // jshint -W054
+  if (type.name && !~getAliases(this).indexOf(type.name)) {
+    throw new Error(f('no alias found for %s', type.name));
+  }
+
+  var rFields = this.fields;
+  var wFields = type.fields;
+  var wFieldsMap = utils.toMap(wFields, function (f) { return f.name; });
+
+  var innerArgs = []; // Arguments for reader constructor.
+  var resolvers = {}; // Resolvers keyed by writer field name.
+  var i, j, field, name, names, matches, fieldResolver;
+  for (i = 0; i < rFields.length; i++) {
+    field = rFields[i];
+    names = getAliases(field);
+    matches = [];
+    for (j = 0; j < names.length; j++) {
+      name = names[j];
+      if (wFieldsMap[name]) {
+        matches.push(name);
+      }
+    }
+    if (matches.length > 1) {
+      throw new Error(
+        f('ambiguous aliasing for %s.%s (%s)', type.name, field.name, matches)
+      );
+    }
+    if (!matches.length) {
+      if (field.defaultValue() === undefined) {
+        throw new Error(
+          f('no matching field for default-less %s.%s', type.name, field.name)
+        );
+      }
+      innerArgs.push('undefined');
+    } else {
+      name = matches[0];
+      fieldResolver = {
+        resolver: field.type.createResolver(wFieldsMap[name].type, opts),
+        name: field.name, // Reader field name.
+      };
+      if (!resolvers[name]) {
+        resolvers[name] = [fieldResolver];
+      } else {
+        resolvers[name].push(fieldResolver);
+      }
+      innerArgs.push(field.name);
+    }
+  }
+
+  // See if we can add a bypass for unused fields at the end of the record.
+  var lazyIndex = -1;
+  i = wFields.length;
+  while (i && resolvers[wFields[--i].name] === undefined) {
+    lazyIndex = i;
+  }
+
+  var uname = this._getConstructorName();
+  var args = [uname];
+  var values = [this.recordConstructor];
+  var body = '  return function read' + uname + '(t, b) {\n';
+  for (i = 0; i < wFields.length; i++) {
+    if (i === lazyIndex) {
+      body += '  if (!b) {\n';
+    }
+    field = type.fields[i];
+    name = field.name;
+    if (resolvers[name] === undefined) {
+      body += (~lazyIndex && i >= lazyIndex) ? '    ' : '  ';
+      args.push('r' + i);
+      values.push(field.type);
+      body += 'r' + i + '._skip(t);\n';
+    } else {
+      j = resolvers[name].length;
+      while (j--) {
+        body += (~lazyIndex && i >= lazyIndex) ? '    ' : '  ';
+        args.push('r' + i + 'f' + j);
+        fieldResolver = resolvers[name][j];
+        values.push(fieldResolver.resolver);
+        body += 'var ' + fieldResolver.name + ' = ';
+        body += 'r' + i + 'f' + j + '._' + (j ? 'peek' : 'read') + '(t);\n';
+      }
+    }
+  }
+  if (~lazyIndex) {
+    body += '  }\n';
+  }
+  body += '  return new ' + uname + '(' + innerArgs.join() + ');\n};';
+
+  resolver._read = new Function(args.join(), body).apply(undefined, values);
+};
+
+RecordType.prototype._match = function (tap1, tap2) {
+  var fields = this.fields;
+  var i, l, field, order, type;
+  for (i = 0, l = fields.length; i < l; i++) {
+    field = fields[i];
+    order = field._order;
+    type = field.type;
+    if (order) {
+      order *= type._match(tap1, tap2);
+      if (order) {
+        return order;
+      }
+    } else {
+      type._skip(tap1);
+      type._skip(tap2);
+    }
+  }
+  return 0;
+};
+
+RecordType.prototype._checkFields = function (obj) {
+  var keys = Object.keys(obj);
+  var i, l;
+  for (i = 0, l = keys.length; i < l; i++) {
+    if (!this._fieldsByName[keys[i]]) {
+      return false;
+    }
+  }
+  return true;
+};
+
+RecordType.prototype._copy = function (val, opts) {
+  // jshint -W058
+  var hook = opts && opts.fieldHook;
+  var values = [undefined];
+  var i, l, field, value;
+  for (i = 0, l = this.fields.length; i < l; i++) {
+    field = this.fields[i];
+    value = val[field.name];
+    if (value === undefined && field.hasOwnProperty('defaultValue')) {
+      value = field.defaultValue();
+    } else if ((opts && !opts.skip) || value !== undefined) {
+      value = field.type._copy(value, opts);
+    }
+    if (hook) {
+      value = hook(field, value, this);
+    }
+    values.push(value);
+  }
+  var Record = this.recordConstructor;
+  return new (Record.bind.apply(Record, values))();
+};
+
+RecordType.prototype._deref = function (schema, opts) {
+  schema.fields = this.fields.map(function (field) {
+    var fieldType = field.type;
+    var fieldSchema = {
+      name: field.name,
+      type: fieldType._attrs(opts)
+    };
+    if (opts.exportAttrs) {
+      var val = field.defaultValue();
+      if (val !== undefined) {
+        // We must both unwrap all unions and coerce buffers to strings.
+        fieldSchema['default'] = fieldType._copy(val, {coerce: 3, wrap: 3});
+      }
+      var fieldOrder = field.order;
+      if (fieldOrder !== 'ascending') {
+        fieldSchema.order = fieldOrder;
+      }
+      var fieldAliases = field.aliases;
+      if (fieldAliases.length) {
+        fieldSchema.aliases = fieldAliases;
+      }
+      var fieldDoc = field.doc;
+      if (fieldDoc !== undefined) {
+        fieldSchema.doc = fieldDoc;
+      }
+    }
+    return fieldSchema;
+  });
+};
+
+RecordType.prototype.compare = function (val1, val2) {
+  var fields = this.fields;
+  var i, l, field, name, order, type;
+  for (i = 0, l = fields.length; i < l; i++) {
+    field = fields[i];
+    name = field.name;
+    order = field._order;
+    type = field.type;
+    if (order) {
+      order *= type.compare(val1[name], val2[name]);
+      if (order) {
+        return order;
+      }
+    }
+  }
+  return 0;
+};
+
+RecordType.prototype.random = function () {
+  // jshint -W058
+  var fields = this.fields.map(function (f) { return f.type.random(); });
+  fields.unshift(undefined);
+  var Record = this.recordConstructor;
+  return new (Record.bind.apply(Record, fields))();
+};
+
+RecordType.prototype.field = function (name) {
+  return this._fieldsByName[name];
+};
+
+RecordType.prototype.getField = RecordType.prototype.field;
+
+RecordType.prototype.getFields = function () { return this.fields; };
+
+RecordType.prototype.getRecordConstructor = function () {
+  return this.recordConstructor;
+};
+
+Object.defineProperty(RecordType.prototype, 'typeName', {
+  enumerable: true,
+  get: function () { return this._isError ? 'error' : 'record'; }
+});
+
+/** Derived type abstract class. */
+function LogicalType(schema, opts) {
+  this._logicalTypeName = schema.logicalType;
+  Type.call(this);
+  LOGICAL_TYPE = this;
+  this.underlyingType = Type.forSchema(schema, opts);
+  // We create a separate branch constructor for logical types to keep them
+  // monomorphic.
+  if (Type.isType(this.underlyingType, 'union')) {
+    this._branchConstructor = this.underlyingType._branchConstructor;
+  } else {
+    this._branchConstructor = this.underlyingType._createBranchConstructor();
+  }
+  // We don't freeze derived types to allow arbitrary properties. Implementors
+  // can still do so in the subclass' constructor at their convenience.
+}
+util.inherits(LogicalType, Type);
+
+Object.defineProperty(LogicalType.prototype, 'typeName', {
+  enumerable: true,
+  get: function () { return 'logical:' + this._logicalTypeName; }
+});
+
+LogicalType.prototype.getUnderlyingType = function () {
+  return this.underlyingType;
+};
+
+LogicalType.prototype._read = function (tap) {
+  return this._fromValue(this.underlyingType._read(tap));
+};
+
+LogicalType.prototype._write = function (tap, any) {
+  this.underlyingType._write(tap, this._toValue(any));
+};
+
+LogicalType.prototype._check = function (any, flags, hook, path) {
+  try {
+    var val = this._toValue(any);
+  } catch (err) {
+    // Handled below.
+  }
+  if (val === undefined) {
+    if (hook) {
+      hook(any, this);
+    }
+    return false;
+  }
+  return this.underlyingType._check(val, flags, hook, path);
+};
+
+LogicalType.prototype._copy = function (any, opts) {
+  var type = this.underlyingType;
+  switch (opts && opts.coerce) {
+    case 3: // To string.
+      return type._copy(this._toValue(any), opts);
+    case 2: // From string.
+      return this._fromValue(type._copy(any, opts));
+    default: // Normal copy.
+      return this._fromValue(type._copy(this._toValue(any), opts));
+  }
+};
+
+LogicalType.prototype._update = function (resolver, type, opts) {
+  var _fromValue = this._resolve(type, opts);
+  if (_fromValue) {
+    resolver._read = function (tap) { return _fromValue(type._read(tap)); };
+  }
+};
+
+LogicalType.prototype.compare = function (obj1, obj2) {
+  var val1 = this._toValue(obj1);
+  var val2 = this._toValue(obj2);
+  return this.underlyingType.compare(val1, val2);
+};
+
+LogicalType.prototype.random = function () {
+  return this._fromValue(this.underlyingType.random());
+};
+
+LogicalType.prototype._deref = function (schema, opts) {
+  var type = this.underlyingType;
+  var isVisited = type.name !== undefined && opts.derefed[type.name];
+  schema = type._attrs(opts);
+  if (!isVisited && opts.exportAttrs) {
+    if (typeof schema == 'string') {
+      schema = {type: schema};
+    }
+    schema.logicalType = this._logicalTypeName;
+    this._export(schema);
+  }
+  return schema;
+};
+
+// Unlike the other methods below, `_export` has a reasonable default which we
+// can provide (not exporting anything).
+LogicalType.prototype._export = function (/* schema */) {};
+
+// Methods to be implemented.
+LogicalType.prototype._fromValue = utils.abstractFunction;
+LogicalType.prototype._toValue = utils.abstractFunction;
+LogicalType.prototype._resolve = utils.abstractFunction;
+
+
+// General helpers.
+
+/**
+ * Customizable long.
+ * 
+ * This allows support of arbitrarily large long (e.g. larger than
+ * `Number.MAX_SAFE_INTEGER`). See `LongType.__with` method above. Note that we
+ * can't use a logical type because we need a "lower-level" hook here: passing
+ * through through the standard long would cause a loss of precision.
+ */
+function AbstractLongType(noUnpack) {
+  PrimitiveType.call(this, true);
+  // Note that this type "inherits" `LongType` (i.e. gain its prototype
+  // methods) but only "subclasses" `PrimitiveType` to avoid being prematurely
+  // frozen.
+  this._noUnpack = !!noUnpack;
+}
+util.inherits(AbstractLongType, LongType);
+
+AbstractLongType.prototype._check = function (val, flags, hook) {
+  var b = this._isValid(val);
+  if (!b && hook) {
+    hook(val, this);
+  }
+  return b;
+};
+
+AbstractLongType.prototype._read = function (tap) {
+  var buf, pos;
+  if (this._noUnpack) {
+    pos = tap.pos;
+    tap.skipLong();
+    buf = tap.buf.slice(pos, tap.pos);
+  } else {
+    buf = tap.unpackLongBytes(tap);
+  }
+  if (tap.isValid()) {
+    return this._fromBuffer(buf);
+  }
+};
+
+AbstractLongType.prototype._write = function (tap, val) {
+  if (!this._isValid(val)) {
+    throwInvalidError(val, this);
+  }
+  var buf = this._toBuffer(val);
+  if (this._noUnpack) {
+    tap.writeFixed(buf);
+  } else {
+    tap.packLongBytes(buf);
+  }
+};
+
+AbstractLongType.prototype._copy = function (val, opts) {
+  switch (opts && opts.coerce) {
+    case 3: // To string.
+      return this._toJSON(val);
+    case 2: // From string.
+      return this._fromJSON(val);
+    default: // Normal copy.
+      // Slow but guarantees most consistent results. Faster alternatives
+		// would
+      // require assumptions on the long class used (e.g. immutability).
+      return this._fromJSON(JSON.parse(JSON.stringify(this._toJSON(val))));
+  }
+};
+
+AbstractLongType.prototype.random = function () {
+  return this._fromJSON(LongType.prototype.random());
+};
+
+// Methods to be implemented by the user.
+AbstractLongType.prototype._fromBuffer = utils.abstractFunction;
+AbstractLongType.prototype._toBuffer = utils.abstractFunction;
+AbstractLongType.prototype._fromJSON = utils.abstractFunction;
+AbstractLongType.prototype._toJSON = utils.abstractFunction;
+AbstractLongType.prototype._isValid = utils.abstractFunction;
+AbstractLongType.prototype.compare = utils.abstractFunction;
+
+/** A record field. */
+function Field(schema, opts) {
+  var name = schema.name;
+  if (typeof name != 'string' || !isValidName(name)) {
+    throw new Error(f('invalid field name: %s', name));
+  }
+
+  this.name = name;
+  this.type = Type.forSchema(schema.type, opts);
+  this.aliases = schema.aliases || [];
+  this.doc = schema.doc !== undefined ? '' + schema.doc : undefined;
+
+  this._order = (function (order) {
+    switch (order) {
+      case 'ascending':
+        return 1;
+      case 'descending':
+        return -1;
+      case 'ignore':
+        return 0;
+      default:
+        throw new Error(f('invalid order: %j', order));
+    }
+  })(schema.order === undefined ? 'ascending' : schema.order);
+
+  var value = schema['default'];
+  if (value !== undefined) {
+    // We need to convert defaults back to a valid format (unions are
+    // disallowed in default definitions, only the first type of each union is
+    // allowed instead).
+    // http://apache-avro.679487.n3.nabble.com/field-union-default-in-Java-td1175327.html
+    var type = this.type;
+    var val = type._copy(value, {coerce: 2, wrap: 2});
+    // The clone call above will throw an error if the default is invalid.
+    if (isPrimitive(type.typeName) && type.typeName !== 'bytes') {
+      // These are immutable.
+      this.defaultValue = function () { return val; };
+    } else {
+      this.defaultValue = function () { return type._copy(val); };
+    }
+  }
+
+  Object.freeze(this);
+}
+
+Field.prototype.defaultValue = function () {}; // Undefined default.
+
+Object.defineProperty(Field.prototype, 'order', {
+  enumerable: true,
+  get: function () {
+    return ['descending', 'ignore', 'ascending'][this._order + 1];
+  }
+});
+
+Field.prototype.getAliases = function () { return this.aliases; };
+
+Field.prototype.getDefault = Field.prototype.defaultValue;
+
+Field.prototype.getName = function () { return this.name; };
+
+Field.prototype.getOrder = function () { return this.order; };
+
+Field.prototype.getType = function () { return this.type; };
+
+/**
+ * Resolver to read a writer's schema as a new schema.
+ * 
+ * @param readerType
+ *            {Type} The type to convert to.
+ */
+function Resolver(readerType) {
+  // Add all fields here so that all resolvers share the same hidden class.
+  this._readerType = readerType;
+  this._read = null;
+  this.itemsType = null;
+  this.size = 0;
+  this.symbols = null;
+  this.valuesType = null;
+}
+
+Resolver.prototype._peek = Type.prototype._peek;
+
+Resolver.prototype.inspect = function () { return '<Resolver>'; };
+
+/** Mutable hash container. */
+function Hash() {
+  this.str = undefined;
+}
+
+/**
+ * Read a value from a tap.
+ * 
+ * @param type
+ *            {Type} The type to decode.
+ * @param tap
+ *            {Tap} The tap to read from. No checks are performed here.
+ * @param resolver
+ *            {Resolver} Optional resolver. It must match the input type.
+ * @param lazy
+ *            {Boolean} Skip trailing fields when using a resolver.
+ */
+function readValue(type, tap, resolver, lazy) {
+  if (resolver) {
+    if (resolver._readerType !== type) {
+      throw new Error('invalid resolver');
+    }
+    return resolver._read(tap, lazy);
+  } else {
+    return type._read(tap);
+  }
+}
+
+/**
+ * Remove namespace from a name.
+ * 
+ * @param name
+ *            {String} Full or short name.
+ */
+function unqualify(name) {
+  var parts = name.split('.');
+  return parts[parts.length - 1];
+}
+
+/**
+ * Verify and return fully qualified name.
+ * 
+ * @param name
+ *            {String} Full or short name. It can be prefixed with a dot to
+ *            force global namespace.
+ * @param namespace
+ *            {String} Optional namespace.
+ */
+function qualify(name, namespace) {
+  if (~name.indexOf('.')) {
+    name = name.replace(/^\./, ''); // Allow absolute referencing.
+  } else if (namespace) {
+    name = namespace + '.' + name;
+  }
+  name.split('.').forEach(function (part) {
+    if (!isValidName(part)) {
+      throw new Error(f('invalid name: %j', name));
+    }
+  });
+  var tail = unqualify(name);
+  // Primitives are always in the global namespace.
+  return isPrimitive(tail) ? tail : name;
+}
+
+/**
+ * Get all aliases for a type (including its name).
+ * 
+ * @param obj
+ *            {Type|Object} Typically a type or a field. Its aliases property
+ *            must exist and be an array.
+ */
+function getAliases(obj) {
+  var names = {};
+  if (obj.name) {
+    names[obj.name] = true;
+  }
+  var aliases = obj.aliases;
+  var i, l;
+  for (i = 0, l = aliases.length; i < l; i++) {
+    names[aliases[i]] = true;
+  }
+  return Object.keys(names);
+}
+
+/**
+ * Check whether a type's name is a primitive.
+ * 
+ * @param name
+ *            {String} Type name (e.g. `'string'`, `'array'`).
+ */
+function isPrimitive(typeName) {
+  // Since we use this module's own `TYPES` object, we can use `instanceof`.
+  var type = TYPES[typeName];
+  return type && type.prototype instanceof PrimitiveType;
+}
+
+/**
+ * Return a type's class name from its Avro type name.
+ * 
+ * We can't simply use `constructor.name` since it isn't supported in all
+ * browsers.
+ * 
+ * @param typeName
+ *            {String} Type name.
+ */
+function getClassName(typeName) {
+  if (typeName === 'error') {
+    typeName = 'record';
+  } else {
+    var match = /^([^:]+):(.*)$/.exec(typeName);
+    if (match) {
+      if (match[1] === 'union') {
+        typeName = match[2] + 'Union';
+      } else {
+        // Logical type.
+        typeName = match[1];
+      }
+    }
+  }
+  return utils.capitalize(typeName) + 'Type';
+}
+
+/**
+ * Get the number of elements in an array block.
+ * 
+ * @param tap
+ *            {Tap} A tap positioned at the beginning of an array block.
+ */
+function readArraySize(tap) {
+  var n = tap.readLong();
+  if (n < 0) {
+    n = -n;
+    tap.skipLong(); // Skip size.
+  }
+  return n;
+}
+
+/**
+ * Check whether a long can be represented without precision loss.
+ * 
+ * @param n
+ *            {Number} The number.
+ * 
+ * Two things to note:
+ *  + We are not using the `Number` constants for compatibility with older
+ * browsers. + We must remove one from each bound because of rounding errors.
+ */
+function isSafeLong(n) {
+  return n >= -9007199254740990 && n <= 9007199254740990;
+}
+
+/**
+ * Check whether an object is the JSON representation of a buffer.
+ */
+function isJsonBuffer(obj) {
+  return obj && obj.type === 'Buffer' && Array.isArray(obj.data);
+}
+
+/**
+ * Check whether a string is a valid Avro identifier.
+ */
+function isValidName(str) { return NAME_PATTERN.test(str); }
+
+/**
+ * Throw a somewhat helpful error on invalid object.
+ * 
+ * @param path
+ *            {Array} Passed from hook, but unused (because empty where this
+ *            function is used, since we aren't keeping track of it for
+ *            effiency).
+ * @param val
+ *            {...} The object to reject.
+ * @param type
+ *            {Type} The type to check against.
+ * 
+ * This method is mostly used from `_write` to signal an invalid object for a
+ * given type. Note that this provides less information than calling `isValid`
+ * with a hook since the path is not propagated (for efficiency reasons).
+ */
+function throwInvalidError(val, type) {
+  throw new Error(f('invalid %s: %j', type, val));
+}
+
+/**
+ * Get a type's bucket when included inside an unwrapped union.
+ * 
+ * @param type
+ *            {Type} Any type.
+ */
+function getTypeBucket(type) {
+  var typeName = type.typeName;
+  switch (typeName) {
+    case 'double':
+    case 'float':
+    case 'int':
+    case 'long':
+      return 'number';
+    case 'bytes':
+    case 'fixed':
+      return 'buffer';
+    case 'enum':
+      return 'string';
+    case 'map':
+    case 'error':
+    case 'record':
+      return 'object';
+    default:
+      return typeName;
+  }
+}
+
+/**
+ * Infer a value's bucket (see unwrapped unions for more details).
+ * 
+ * @param val
+ *            {...} Any value.
+ */
+function getValueBucket(val) {
+  if (val === null) {
+    return 'null';
+  }
+  var bucket = typeof val;
+  if (bucket === 'object') {
+    // Could be bytes, fixed, array, map, or record.
+    if (Array.isArray(val)) {
+      return 'array';
+    } else if (Buffer.isBuffer(val)) {
+      return 'buffer';
+    }
+  }
+  return bucket;
+}
+
+/**
+ * Check whether a collection of types leads to an ambiguous union.
+ * 
+ * @param types
+ *            {Array} Array of types.
+ */
+function isAmbiguous(types) {
+  var buckets = {};
+  var i, l, bucket, type;
+  for (i = 0, l = types.length; i < l; i++) {
+    type = types[i];
+    if (!Type.isType(type, 'logical')) {
+      bucket = getTypeBucket(type);
+      if (buckets[bucket]) {
+        return true;
+      }
+      buckets[bucket] = true;
+    }
+  }
+  return false;
+}
+
+/**
+ * Combine number types.
+ * 
+ * Note that never have to create a new type here, we are guaranteed to be able
+ * to reuse one of the input types as super-type.
+ */
+function combineNumbers(types) {
+  var typeNames = ['int', 'long', 'float', 'double'];
+  var superIndex = -1;
+  var superType = null;
+  var i, l, type, index;
+  for (i = 0, l = types.length; i < l; i++) {
+    type = types[i];
+    index = typeNames.indexOf(type.typeName);
+    if (index > superIndex) {
+      superIndex = index;
+      superType = type;
+    }
+  }
+  return superType;
+}
+
+/**
+ * Combine enums and strings.
+ * 
+ * The order of the returned symbols is undefined and the returned enum is
+ * 
+ */
+function combineStrings(types, opts) {
+  var symbols = {};
+  var i, l, type, typeSymbols;
+  for (i = 0, l = types.length; i < l; i++) {
+    type = types[i];
+    if (type.typeName === 'string') {
+      // If at least one of the types is a string, it will be the supertype.
+      return type;
+    }
+    typeSymbols = type.symbols;
+    var j, m;
+    for (j = 0, m = typeSymbols.length; j < m; j++) {
+      symbols[typeSymbols[j]] = true;
+    }
+  }
+  return Type.forSchema({type: 'enum', symbols: Object.keys(symbols)}, opts);
+}
+
+/**
+ * Combine bytes and fixed.
+ * 
+ * This function is optimized to avoid creating new types when possible: in case
+ * of a size mismatch between fixed types, it will continue looking through the
+ * array to find an existing bytes type (rather than exit early by creating one
+ * eagerly).
+ */
+function combineBuffers(types, opts) {
+  var size = -1;
+  var i, l, type;
+  for (i = 0, l = types.length; i < l; i++) {
+    type = types[i];
+    if (type.typeName === 'bytes') {
+      return type;
+    }
+    if (size === -1) {
+      size = type.size;
+    } else if (type.size !== size) {
+      // Don't create a bytes type right away, we might be able to reuse one
+      // later on in the types array. Just mark this for now.
+      size = -2;
+    }
+  }
+  return size < 0 ? Type.forSchema('bytes', opts) : types[0];
+}
+
+/**
+ * Combine maps and records.
+ * 
+ * Field defaults are kept when possible (i.e. when no coercion to a map
+ * happens), with later definitions overriding previous ones.
+ */
+function combineObjects(types, opts) {
+  var allTypes = []; // Field and value types.
+  var fieldTypes = {}; // Record field types grouped by field name.
+  var fieldDefaults = {};
+  var isValidRecord = true;
+
+  // Check whether the final type will be a map or a record.
+  var i, l, type, fields;
+  for (i = 0, l = types.length; i < l; i++) {
+    type = types[i];
+    if (type.typeName === 'map') {
+      isValidRecord = false;
+      allTypes.push(type.valuesType);
+    } else {
+      fields = type.fields;
+      var j, m, field, fieldDefault, fieldName, fieldType;
+      for (j = 0, m = fields.length; j < m; j++) {
+        field = fields[j];
+        fieldName = field.name;
+        fieldType = field.type;
+        allTypes.push(fieldType);
+        if (isValidRecord) {
+          if (!fieldTypes[fieldName]) {
+            fieldTypes[fieldName] = [];
+          }
+          fieldTypes[fieldName].push(fieldType);
+          fieldDefault = field.defaultValue();
+          if (fieldDefault !== undefined) {
+            // Later defaults will override any previous ones.
+            fieldDefaults[fieldName] = fieldDefault;
+          }
+        }
+      }
+    }
+  }
+
+  if (isValidRecord) {
+    // Check that no fields are missing and that we have the approriate
+    // defaults for those which are.
+    var fieldNames = Object.keys(fieldTypes);
+    for (i = 0, l = fieldNames.length; i < l; i++) {
+      fieldName = fieldNames[i];
+      if (
+        fieldTypes[fieldName].length < types.length &&
+        fieldDefaults[fieldName] === undefined
+      ) {
+        // At least one of the records is missing a field with no default.
+        if (opts && opts.strictDefaults) {
+          isValidRecord = false;
+        } else {
+          fieldTypes[fieldName].unshift(Type.forSchema('null', opts));
+          fieldDefaults[fieldName] = null;
+        }
+      }
+    }
+  }
+
+  var schema;
+  if (isValidRecord) {
+    schema = {
+      type: 'record',
+      fields: fieldNames.map(function (s) {
+        var fieldType = Type.forTypes(fieldTypes[s], opts);
+        var fieldDefault = fieldDefaults[s];
+        if (
+          fieldDefault !== undefined &&
+          ~fieldType.typeName.indexOf('union')
+        ) {
+          // Ensure that the default's corresponding type is first.
+          var unionTypes = fieldType.types.slice();
+          var i, l;
+          for (i = 0, l = unionTypes.length; i < l; i++) {
+            if (unionTypes[i].isValid(fieldDefault)) {
+              break;
+            }
+          }
+          if (i > 0) {
+            var unionType = unionTypes[0];
+            unionTypes[0] = unionTypes[i];
+            unionTypes[i] = unionType;
+            fieldType = Type.forSchema(unionTypes, opts);
+          }
+        }
+        return {
+          name: s,
+          type: fieldType,
+          'default': fieldDefaults[s]
+        };
+      })
+    };
+  } else {
+    schema = {
+      type: 'map',
+      values: Type.forTypes(allTypes, opts)
+    };
+  }
+  return Type.forSchema(schema, opts);
+}
+
+
+module.exports = {
+  Type: Type,
+  getTypeBucket: getTypeBucket,
+  getValueBucket: getValueBucket,
+  isPrimitive: isPrimitive,
+  isValidName: isValidName,
+  qualify: qualify,
+  builtins: (function () {
+    var types = {
+      LogicalType: LogicalType,
+      UnwrappedUnionType: UnwrappedUnionType,
+      WrappedUnionType: WrappedUnionType
+    };
+    var typeNames = Object.keys(TYPES);
+    var i, l, typeName;
+    for (i = 0, l = typeNames.length; i < l; i++) {
+      typeName = typeNames[i];
+      types[getClassName(typeName)] = TYPES[typeName];
+    }
+    return types;
+  })()
+};
+
+}).call(this,require("buffer").Buffer)
+},{"./utils":56,"buffer":16,"util":47}],56:[function(require,module,exports){
+(function (Buffer){
+/* jshint node: true */
+
+// TODO: Make long comparison impervious to precision loss.
+// TODO: Optimize binary comparison methods.
+
+'use strict';
+
+/** Various utilities used across this library. */
+
+var crypto = require('crypto');
+var util = require('util');
+
+// Shared buffer pool for all taps.
+var POOL = new BufferPool(4096);
+
+
+/**
+ * Uppercase the first letter of a string.
+ * 
+ * @param s
+ *            {String} The string.
+ */
+function capitalize(s) { return s.charAt(0).toUpperCase() + s.slice(1); }
+
+/**
+ * Compare two numbers.
+ * 
+ * @param n1
+ *            {Number} The first one.
+ * @param n2
+ *            {Number} The second one.
+ */
+function compare(n1, n2) { return n1 === n2 ? 0 : (n1 < n2 ? -1 : 1); }
+
+/**
+ * Get option or default if undefined.
+ * 
+ * @param opts
+ *            {Object} Options.
+ * @param key
+ *            {String} Name of the option.
+ * @param def
+ *            {...} Default value.
+ * 
+ * This is useful mostly for true-ish defaults and false-ish values (where the
+ * usual `||` idiom breaks down).
+ */
+function getOption(opts, key, def) {
+  var value = opts[key];
+  return value === undefined ? def : value;
+}
+
+/**
+ * Compute a string's hash.
+ * 
+ * @param str
+ *            {String} The string to hash.
+ * @param algorithm
+ *            {String} The algorithm used. Defaults to MD5.
+ */
+function getHash(str, algorithm) {
+  algorithm = algorithm || 'md5';
+  var hash = crypto.createHash(algorithm);
+  hash.end(str);
+  return hash.read();
+}
+
+/**
+ * Find index of value in array.
+ * 
+ * @param arr
+ *            {Array} Can also be a false-ish value.
+ * @param v
+ *            {Object} Value to find.
+ * 
+ * Returns -1 if not found, -2 if found multiple times.
+ */
+function singleIndexOf(arr, v) {
+  var pos = -1;
+  var i, l;
+  if (!arr) {
+    return -1;
+  }
+  for (i = 0, l = arr.length; i < l; i++) {
+    if (arr[i] === v) {
+      if (pos >= 0) {
+        return -2;
+      }
+      pos = i;
+    }
+  }
+  return pos;
+}
+
+/**
+ * Convert array to map.
+ * 
+ * @param arr
+ *            {Array} Elements.
+ * @param fn
+ *            {Function} Function returning an element's key.
+ */
+function toMap(arr, fn) {
+  var obj = {};
+  var i, elem;
+  for (i = 0; i < arr.length; i++) {
+    elem = arr[i];
+    obj[fn(elem)] = elem;
+  }
+  return obj;
+}
+
+/**
+ * Convert map to array of values (polyfill for `Object.values`).
+ * 
+ * @param obj
+ *            {Object} Map.
+ */
+function objectValues(obj) {
+  return Object.keys(obj).map(function (key) { return obj[key]; });
+}
+
+/**
+ * Check whether an array has duplicates.
+ * 
+ * @param arr
+ *            {Array} The array.
+ * @param fn
+ *            {Function} Optional function to apply to each element.
+ */
+function hasDuplicates(arr, fn) {
+  var obj = {};
+  var i, l, elem;
+  for (i = 0, l = arr.length; i < l; i++) {
+    elem = arr[i];
+    if (fn) {
+      elem = fn(elem);
+    }
+    if (obj[elem]) {
+      return true;
+    }
+    obj[elem] = true;
+  }
+  return false;
+}
+
+/**
+ * Copy properties from one object to another.
+ * 
+ * @param src
+ *            {Object} The source object.
+ * @param dst
+ *            {Object} The destination object.
+ * @param overwrite
+ *            {Boolean} Whether to overwrite existing destination properties.
+ *            Defaults to false.
+ */
+function copyOwnProperties(src, dst, overwrite) {
+  var names = Object.getOwnPropertyNames(src);
+  var i, l, name;
+  for (i = 0, l = names.length; i < l; i++) {
+    name = names[i];
+    if (!dst.hasOwnProperty(name) || overwrite) {
+      var descriptor = Object.getOwnPropertyDescriptor(src, name);
+      Object.defineProperty(dst, name, descriptor);
+    }
+  }
+  return dst;
+}
+
+/**
+ * Returns offset in the string of the end of JSON object (-1 if past the end).
+ * 
+ * To keep the implementation simple, this function isn't a JSON validator. It
+ * will gladly return a result for invalid JSON (which is OK since that will be
+ * promptly rejected by the JSON parser). What matters is that it is guaranteed
+ * to return the correct end when presented with valid JSON.
+ * 
+ * @param str
+ *            {String} Input string containing serialized JSON..
+ * @param pos
+ *            {Number} Starting position.
+ */
+function jsonEnd(str, pos) {
+  pos = pos | 0;
+
+  // Handle the case of a simple literal separately.
+  var c = str.charAt(pos++);
+  if (/[\d-]/.test(c)) {
+    while (/[eE\d.+-]/.test(str.charAt(pos))) {
+      pos++;
+    }
+    return pos;
+  } else if (/true|null/.test(str.slice(pos - 1, pos + 3))) {
+    return pos + 3;
+  } else if (/false/.test(str.slice(pos - 1, pos + 4))) {
+    return pos + 4;
+  }
+
+  // String, object, or array.
+  var depth = 0;
+  var literal = false;
+  do {
+    switch (c) {
+    case '{':
+    case '[':
+      if (!literal) { depth++; }
+      break;
+    case '}':
+    case ']':
+      if (!literal && !--depth) {
+        return pos;
+      }
+      break;
+    case '"':
+      literal = !literal;
+      if (!depth && !literal) {
+        return pos;
+      }
+      break;
+    case '\\':
+      pos++; // Skip the next character.
+    }
+  } while ((c = str.charAt(pos++)));
+
+  return -1;
+}
+
+/** "Abstract" function to help with "subclassing". */
+function abstractFunction() { throw new Error('abstract'); }
+
+/** Batch-deprecate "getters" from an object's prototype. */
+function addDeprecatedGetters(obj, props) {
+  var proto = obj.prototype;
+  var i, l, prop, getter;
+  for (i = 0, l = props.length; i < l; i++) {
+    prop = props[i];
+    getter = 'get' + capitalize(prop);
+    proto[getter] = util.deprecate(
+      createGetter(prop),
+      'use `.' + prop + '` instead of `.' + getter + '()`'
+    );
+  }
+
+  function createGetter(prop) {
+    return function () {
+      var delegate = this[prop];
+      return typeof delegate == 'function' ?
+        delegate.apply(this, arguments) :
+        delegate;
+    };
+  }
+}
+
+/**
+ * Simple buffer pool to avoid allocating many small buffers.
+ * 
+ * This provides significant speedups in recent versions of node (6+).
+ */
+function BufferPool(len) {
+  this._len = len | 0;
+  this._pos = 0;
+  this._slab = new Buffer(this._len);
+}
+
+BufferPool.prototype.alloc = function (len) {
+  var maxLen = this._len;
+  if (len > maxLen) {
+    return new Buffer(len);
+  }
+  if (this._pos + len > maxLen) {
+    this._slab = new Buffer(maxLen);
+    this._pos = 0;
+  }
+  return this._slab.slice(this._pos, this._pos += len);
+};
+
+/**
+ * Generator of random things.
+ * 
+ * Inspired by: http://stackoverflow.com/a/424445/1062617
+ */
+function Lcg(seed) {
+  var a = 1103515245;
+  var c = 12345;
+  var m = Math.pow(2, 31);
+  var state = Math.floor(seed || Math.random() * (m - 1));
+
+  this._max = m;
+  this._nextInt = function () { return state = (a * state + c) % m; };
+}
+
+Lcg.prototype.nextBoolean = function () {
+  // jshint -W018
+  return !!(this._nextInt() % 2);
+};
+
+Lcg.prototype.nextInt = function (start, end) {
+  if (end === undefined) {
+    end = start;
+    start = 0;
+  }
+  end = end === undefined ? this._max : end;
+  return start + Math.floor(this.nextFloat() * (end - start));
+};
+
+Lcg.prototype.nextFloat = function (start, end) {
+  if (end === undefined) {
+    end = start;
+    start = 0;
+  }
+  end = end === undefined ? 1 : end;
+  return start + (end - start) * this._nextInt() / this._max;
+};
+
+Lcg.prototype.nextString = function(len, flags) {
+  len |= 0;
+  flags = flags || 'aA';
+  var mask = '';
+  if (flags.indexOf('a') > -1) {
+    mask += 'abcdefghijklmnopqrstuvwxyz';
+  }
+  if (flags.indexOf('A') > -1) {
+    mask += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
+  }
+  if (flags.indexOf('#') > -1) {
+    mask += '0123456789';
+  }
+  if (flags.indexOf('!') > -1) {
+    mask += '~`!@#$%^&*()_+-={}[]:";\'<>?,./|\\';
+  }
+  var result = [];
+  for (var i = 0; i < len; i++) {
+    result.push(this.choice(mask));
+  }
+  return result.join('');
+};
+
+Lcg.prototype.nextBuffer = function (len) {
+  var arr = [];
+  var i;
+  for (i = 0; i < len; i++) {
+    arr.push(this.nextInt(256));
+  }
+  return new Buffer(arr);
+};
+
+Lcg.prototype.choice = function (arr) {
+  var len = arr.length;
+  if (!len) {
+    throw new Error('choosing from empty array');
+  }
+  return arr[this.nextInt(len)];
+};
+
+/**
+ * Ordered queue which returns items consecutively.
+ * 
+ * This is actually a heap by index, with the added requirements that elements
+ * can only be retrieved consecutively.
+ */
+function OrderedQueue() {
+  this._index = 0;
+  this._items = [];
+}
+
+OrderedQueue.prototype.push = function (item) {
+  var items = this._items;
+  var i = items.length | 0;
+  var j;
+  items.push(item);
+  while (i > 0 && items[i].index < items[j = ((i - 1) >> 1)].index) {
+    item = items[i];
+    items[i] = items[j];
+    items[j] = item;
+    i = j;
+  }
+};
+
+OrderedQueue.prototype.pop = function () {
+  var items = this._items;
+  var len = (items.length - 1) | 0;
+  var first = items[0];
+  if (!first || first.index > this._index) {
+    return null;
+  }
+  this._index++;
+  if (!len) {
+    items.pop();
+    return first;
+  }
+  items[0] = items.pop();
+  var mid = len >> 1;
+  var i = 0;
+  var i1, i2, j, item, c, c1, c2;
+  while (i < mid) {
+    item = items[i];
+    i1 = (i << 1) + 1;
+    i2 = (i + 1) << 1;
+    c1 = items[i1];
+    c2 = items[i2];
+    if (!c2 || c1.index <= c2.index) {
+      c = c1;
+      j = i1;
+    } else {
+      c = c2;
+      j = i2;
+    }
+    if (c.index >= item.index) {
+      break;
+    }
+    items[j] = item;
+    items[i] = c;
+    i = j;
+  }
+  return first;
+};
+
+/**
+ * A tap is a buffer which remembers what has been already read.
+ * 
+ * It is optimized for performance, at the cost of failing silently when
+ * overflowing the buffer. This is a purposeful trade-off given the expected
+ * rarity of this case and the large performance hit necessary to enforce
+ * validity. See `isValid` below for more information.
+ */
+function Tap(buf, pos) {
+  this.buf = buf;
+  this.pos = pos | 0;
+  if (this.pos < 0) {
+    throw new Error('negative offset');
+  }
+}
+
+/**
+ * Check that the tap is in a valid state.
+ * 
+ * For efficiency reasons, none of the methods below will fail if an overflow
+ * occurs (either read, skip, or write). For this reason, it is up to the caller
+ * to always check that the read, skip, or write was valid by calling this
+ * method.
+ */
+Tap.prototype.isValid = function () { return this.pos <= this.buf.length; };
+
+// Read, skip, write methods.
+//
+// These should fail silently when the buffer overflows. Note this is only
+// required to be true when the functions are decoding valid objects. For
+// example errors will still be thrown if a bad count is read, leading to a
+// negative position offset (which will typically cause a failure in
+// `readFixed`).
+
+Tap.prototype.readBoolean = function () { return !!this.buf[this.pos++]; };
+
+Tap.prototype.skipBoolean = function () { this.pos++; };
+
+Tap.prototype.writeBoolean = function (b) { this.buf[this.pos++] = !!b; };
+
+Tap.prototype.readInt = Tap.prototype.readLong = function () {
+  var n = 0;
+  var k = 0;
+  var buf = this.buf;
+  var b, h, f, fk;
+
+  do {
+    b = buf[this.pos++];
+    h = b & 0x80;
+    n |= (b & 0x7f) << k;
+    k += 7;
+  } while (h && k < 28);
+
+  if (h) {
+    // Switch to float arithmetic, otherwise we might overflow.
+    f = n;
+    fk = 268435456; // 2 ** 28.
+    do {
+      b = buf[this.pos++];
+      f += (b & 0x7f) * fk;
+      fk *= 128;
+    } while (b & 0x80);
+    return (f % 2 ? -(f + 1) : f) / 2;
+  }
+
+  return (n >> 1) ^ -(n & 1);
+};
+
+Tap.prototype.skipInt = Tap.prototype.skipLong = function () {
+  var buf = this.buf;
+  while (buf[this.pos++] & 0x80) {}
+};
+
+Tap.prototype.writeInt = Tap.prototype.writeLong = function (n) {
+  var buf = this.buf;
+  var f, m;
+
+  if (n >= -1073741824 && n < 1073741824) {
+    // Won't overflow, we can use integer arithmetic.
+    m = n >= 0 ? n << 1 : (~n << 1) | 1;
+    do {
+      buf[this.pos] = m & 0x7f;
+      m >>= 7;
+    } while (m && (buf[this.pos++] |= 0x80));
+  } else {
+    // We have to use slower floating arithmetic.
+    f = n >= 0 ? n * 2 : (-n * 2) - 1;
+    do {
+      buf[this.pos] = f & 0x7f;
+      f /= 128;
+    } while (f >= 1 && (buf[this.pos++] |= 0x80));
+  }
+  this.pos++;
+};
+
+Tap.prototype.readFloat = function () {
+  var buf = this.buf;
+  var pos = this.pos;
+  this.pos += 4;
+  if (this.pos > buf.length) {
+    return;
+  }
+  return this.buf.readFloatLE(pos);
+};
+
+Tap.prototype.skipFloat = function () { this.pos += 4; };
+
+Tap.prototype.writeFloat = function (f) {
+  var buf = this.buf;
+  var pos = this.pos;
+  this.pos += 4;
+  if (this.pos > buf.length) {
+    return;
+  }
+  return this.buf.writeFloatLE(f, pos);
+};
+
+Tap.prototype.readDouble = function () {
+  var buf = this.buf;
+  var pos = this.pos;
+  this.pos += 8;
+  if (this.pos > buf.length) {
+    return;
+  }
+  return this.buf.readDoubleLE(pos);
+};
+
+Tap.prototype.skipDouble = function () { this.pos += 8; };
+
+Tap.prototype.writeDouble = function (d) {
+  var buf = this.buf;
+  var pos = this.pos;
+  this.pos += 8;
+  if (this.pos > buf.length) {
+    return;
+  }
+  return this.buf.writeDoubleLE(d, pos);
+};
+
+Tap.prototype.readFixed = function (len) {
+  var pos = this.pos;
+  this.pos += len;
+  if (this.pos > this.buf.length) {
+    return;
+  }
+  var fixed = POOL.alloc(len);
+  this.buf.copy(fixed, 0, pos, pos + len);
+  return fixed;
+};
+
+Tap.prototype.skipFixed = function (len) { this.pos += len; };
+
+Tap.prototype.writeFixed = function (buf, len) {
+  len = len || buf.length;
+  var pos = this.pos;
+  this.pos += len;
+  if (this.pos > this.buf.length) {
+    return;
+  }
+  buf.copy(this.buf, pos, 0, len);
+};
+
+Tap.prototype.readBytes = function () {
+  return this.readFixed(this.readLong());
+};
+
+Tap.prototype.skipBytes = function () {
+  var len = this.readLong();
+  this.pos += len;
+};
+
+Tap.prototype.writeBytes = function (buf) {
+  var len = buf.length;
+  this.writeLong(len);
+  this.writeFixed(buf, len);
+};
+
+/* istanbul ignore else */
+if (typeof Buffer.prototype.utf8Slice == 'function') {
+  // Use this optimized function when available.
+  Tap.prototype.readString = function () {
+    var len = this.readLong();
+    var pos = this.pos;
+    var buf = this.buf;
+    this.pos += len;
+    if (this.pos > buf.length) {
+      return;
+    }
+    return this.buf.utf8Slice(pos, pos + len);
+  };
+} else {
+  Tap.prototype.readString = function () {
+    var len = this.readLong();
+    var pos = this.pos;
+    var buf = this.buf;
+    this.pos += len;
+    if (this.pos > buf.length) {
+      return;
+    }
+    return this.buf.slice(pos, pos + len).toString();
+  };
+}
+
+Tap.prototype.skipString = function () {
+  var len = this.readLong();
+  this.pos += len;
+};
+
+Tap.prototype.writeString = function (s) {
+  var len = Buffer.byteLength(s);
+  var buf = this.buf;
+  this.writeLong(len);
+  var pos = this.pos;
+  this.pos += len;
+  if (this.pos > buf.length) {
+    return;
+  }
+  if (len > 64) {
+    this._writeUtf8(s, len);
+  } else {
+    var i, l, c1, c2;
+    for (i = 0, l = len; i < l; i++) {
+      c1 = s.charCodeAt(i);
+      if (c1 < 0x80) {
+        buf[pos++] = c1;
+      } else if (c1 < 0x800) {
+        buf[pos++] = c1 >> 6 | 0xc0;
+        buf[pos++] = c1 & 0x3f | 0x80;
+      } else if (
+        (c1 & 0xfc00) === 0xd800 &&
+        ((c2 = s.charCodeAt(i + 1)) & 0xfc00) === 0xdc00
+      ) {
+        c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff);
+        i++;
+        buf[pos++] = c1 >> 18 | 0xf0;
+        buf[pos++] = c1 >> 12 & 0x3f | 0x80;
+        buf[pos++] = c1 >> 6 & 0x3f | 0x80;
+        buf[pos++] = c1 & 0x3f | 0x80;
+      } else {
+        buf[pos++] = c1 >> 12 | 0xe0;
+        buf[pos++] = c1 >> 6 & 0x3f | 0x80;
+        buf[pos++] = c1 & 0x3f | 0x80;
+      }
+    }
+  }
+};
+
+/* istanbul ignore else */
+if (typeof Buffer.prototype.utf8Write == 'function') {
+  Tap.prototype._writeUtf8 = function (str, len) {
+    this.buf.utf8Write(str, this.pos - len, len);
+  };
+} else {
+  // `utf8Write` isn't available in the browser.
+  Tap.prototype._writeUtf8 = function (str, len) {
+    this.buf.write(str, this.pos - len, len, 'utf8');
+  };
+}
+
+/* istanbul ignore else */
+if (typeof Buffer.prototype.latin1Write == 'function') {
+  // `binaryWrite` has been renamed to `latin1Write` in Node v6.4.0, see
+  // https://github.com/nodejs/node/pull/7111. Note that the `'binary'`
+  // encoding argument still works however.
+  Tap.prototype.writeBinary = function (str, len) {
+    var pos = this.pos;
+    this.pos += len;
+    if (this.pos > this.buf.length) {
+      return;
+    }
+    this.buf.latin1Write(str, pos, len);
+  };
+} else if (typeof Buffer.prototype.binaryWrite == 'function') {
+  Tap.prototype.writeBinary = function (str, len) {
+    var pos = this.pos;
+    this.pos += len;
+    if (this.pos > this.buf.length) {
+      return;
+    }
+    this.buf.binaryWrite(str, pos, len);
+  };
+} else {
+  // Slowest implementation.
+  Tap.prototype.writeBinary = function (s, len) {
+    var pos = this.pos;
+    this.pos += len;
+    if (this.pos > this.buf.length) {
+      return;
+    }
+    this.buf.write(s, pos, len, 'binary');
+  };
+}
+
+// Binary comparison methods.
+//
+// These are not guaranteed to consume the objects they are comparing when
+// returning a non-zero result (allowing for performance benefits), so no other
+// operations should be done on either tap after a compare returns a non-zero
+// value. Also, these methods do not have the same silent failure requirement
+// as read, skip, and write since they are assumed to be called on valid
+// buffers.
+
+Tap.prototype.matchBoolean = function (tap) {
+  return this.buf[this.pos++] - tap.buf[tap.pos++];
+};
+
+Tap.prototype.matchInt = Tap.prototype.matchLong = function (tap) {
+  var n1 = this.readLong();
+  var n2 = tap.readLong();
+  return n1 === n2 ? 0 : (n1 < n2 ? -1 : 1);
+};
+
+Tap.prototype.matchFloat = function (tap) {
+  var n1 = this.readFloat();
+  var n2 = tap.readFloat();
+  return n1 === n2 ? 0 : (n1 < n2 ? -1 : 1);
+};
+
+Tap.prototype.matchDouble = function (tap) {
+  var n1 = this.readDouble();
+  var n2 = tap.readDouble();
+  return n1 === n2 ? 0 : (n1 < n2 ? -1 : 1);
+};
+
+Tap.prototype.matchFixed = function (tap, len) {
+  return this.readFixed(len).compare(tap.readFixed(len));
+};
+
+Tap.prototype.matchBytes = Tap.prototype.matchString = function (tap) {
+  var l1 = this.readLong();
+  var p1 = this.pos;
+  this.pos += l1;
+  var l2 = tap.readLong();
+  var p2 = tap.pos;
+  tap.pos += l2;
+  var b1 = this.buf.slice(p1, this.pos);
+  var b2 = tap.buf.slice(p2, tap.pos);
+  return b1.compare(b2);
+};
+
+// Functions for supporting custom long classes.
+//
+// The two following methods allow the long implementations to not have to
+// worry about Avro's zigzag encoding, we directly expose longs as unpacked.
+
+Tap.prototype.unpackLongBytes = function () {
+  var res = new Buffer(8);
+  var n = 0;
+  var i = 0; // Byte index in target buffer.
+  var j = 6; // Bit offset in current target buffer byte.
+  var buf = this.buf;
+  var b, neg;
+
+  b = buf[this.pos++];
+  neg = b & 1;
+  res.fill(0);
+
+  n |= (b & 0x7f) >> 1;
+  while (b & 0x80) {
+    b = buf[this.pos++];
+    n |= (b & 0x7f) << j;
+    j += 7;
+    if (j >= 8) {
+      // Flush byte.
+      j -= 8;
+      res[i++] = n;
+      n >>= 8;
+    }
+  }
+  res[i] = n;
+
+  if (neg) {
+    invert(res, 8);
+  }
+
+  return res;
+};
+
+Tap.prototype.packLongBytes = function (buf) {
+  var neg = (buf[7] & 0x80) >> 7;
+  var res = this.buf;
+  var j = 1;
+  var k = 0;
+  var m = 3;
+  var n;
+
+  if (neg) {
+    invert(buf, 8);
+    n = 1;
+  } else {
+    n = 0;
+  }
+
+  var parts = [
+    buf.readUIntLE(0, 3),
+    buf.readUIntLE(3, 3),
+    buf.readUIntLE(6, 2)
+  ];
+  // Not reading more than 24 bits because we need to be able to combine the
+  // "carry" bits from the previous part and JavaScript only supports bitwise
+  // operations on 32 bit integers.
+  while (m && !parts[--m]) {} // Skip trailing 0s.
+
+  // Leading parts (if any), we never bail early here since we need the
+  // continuation bit to be set.
+  while (k < m) {
+    n |= parts[k++] << j;
+    j += 24;
+    while (j > 7) {
+      res[this.pos++] = (n & 0x7f) | 0x80;
+      n >>= 7;
+      j -= 7;
+    }
+  }
+
+  // Final part, similar to normal packing aside from the initial offset.
+  n |= parts[m] << j;
+  do {
+    res[this.pos] = n & 0x7f;
+    n >>= 7;
+  } while (n && (res[this.pos++] |= 0x80));
+  this.pos++;
+
+  // Restore original buffer (could make this optional?).
+  if (neg) {
+    invert(buf, 8);
+  }
+};
+
+// Helpers.
+
+/**
+ * Invert all bits in a buffer.
+ * 
+ * @param buf
+ *            {Buffer} Non-empty buffer to invert.
+ * @param len
+ *            {Number} Buffer length (must be positive).
+ */
+function invert(buf, len) {
+  while (len--) {
+    buf[len] = ~buf[len];
+  }
+}
+
+
+module.exports = {
+  abstractFunction: abstractFunction,
+  addDeprecatedGetters: addDeprecatedGetters,
+  capitalize: capitalize,
+  copyOwnProperties: copyOwnProperties,
+  getHash: getHash,
+  compare: compare,
+  getOption: getOption,
+  jsonEnd: jsonEnd,
+  objectValues: objectValues,
+  toMap: toMap,
+  singleIndexOf: singleIndexOf,
+  hasDuplicates: hasDuplicates,
+  Lcg: Lcg,
+  OrderedQueue: OrderedQueue,
+  Tap: Tap
+};
+
+}).call(this,require("buffer").Buffer)
+},{"buffer":16,"crypto":50,"util":47}],"avsc":[function(require,module,exports){
+(function (Buffer){
+/* jshint browser: true, node: true */
+
+'use strict';
+
+/**
+ * Main browserify entry point.
+ * 
+ * This version of the entry point adds a couple browser-specific utilities to
+ * read and write blobs.
+ */
+
+var avroServices = require('./avsc-services'),
+    containers = require('../../lib/containers'),
+    utils = require('../../lib/utils'),
+    stream = require('stream'),
+    util = require('util');
+
+
+/** Transform stream which lazily reads a blob's contents. */
+function BlobReader(blob, opts) {
+  stream.Readable.call(this);
+  opts = opts || {};
+
+  this._batchSize = opts.batchSize || 65536;
+  this._blob = blob;
+  this._pos = 0;
+}
+util.inherits(BlobReader, stream.Readable);
+
+BlobReader.prototype._read = function () {
+  var pos = this._pos;
+  if (pos >= this._blob.size) {
+    this.push(null);
+    return;
+  }
+
+  this._pos += this._batchSize;
+  var blob = this._blob.slice(pos, this._pos, this._blob.type);
+  var reader = new FileReader();
+  var self = this;
+  reader.addEventListener('loadend', function cb(evt) {
+    reader.removeEventListener('loadend', cb, false);
+    if (evt.error) {
+      self.emit('error', evt.error);
+    } else {
+      self.push(new Buffer(reader.result));
+    }
+  }, false);
+  reader.readAsArrayBuffer(blob);
+};
+
+/** Transform stream which builds a blob from all data written to it. */
+function BlobWriter() {
+  stream.Transform.call(this, {readableObjectMode: true});
+  this._bufs = [];
+}
+util.inherits(BlobWriter, stream.Transform);
+
+BlobWriter.prototype._transform = function (buf, encoding, cb) {
+  this._bufs.push(buf);
+  cb();
+};
+
+BlobWriter.prototype._flush = function (cb) {
+  this.push(new Blob(this._bufs, {type: 'application/octet-binary'}));
+  cb();
+};
+
+/** Read an Avro-container stored as a blob. */
+function createBlobDecoder(blob, opts) {
+  return new BlobReader(blob).pipe(new containers.streams.BlockDecoder(opts));
+}
+
+/**
+ * Store Avro values into an Avro-container blob.
+ * 
+ * The returned stream will emit a single value, the blob, when ended.
+ */
+function createBlobEncoder(schema, opts) {
+  var encoder = new containers.streams.BlockEncoder(schema, opts);
+  var builder = new BlobWriter();
+  encoder.pipe(builder);
+  return new stream.Duplex({
+    objectMode: true,
+    read: function () {
+      // Not the fastest implementation, but it will only be called at most
+      // once (since the builder only ever emits a single value) so it'll do.
+      // It's also likely impractical to create very large blobs.
+      var val = builder.read();
+      if (val) {
+        done(val);
+      } else {
+        builder.once('readable', done);
+      }
+      var self = this;
+      function done(val) {
+        self.push(val || builder.read());
+        self.push(null);
+      }
+    },
+    write: function (val, encoding, cb) {
+      return encoder.write(val, encoding, cb);
+    }
+  }).on('finish', function () { encoder.end(); });
+}
+
+
+module.exports = {
+  createBlobDecoder: createBlobDecoder,
+  createBlobEncoder: createBlobEncoder,
+  streams: containers.streams
+};
+
+utils.copyOwnProperties(avroServices, module.exports);
+
+}).call(this,require("buffer").Buffer)
+},{"../../lib/containers":52,"../../lib/utils":56,"./avsc-services":48,"buffer":16,"stream":42,"util":47}]},{},[]);
diff --git a/client/client-monitoring/src/main/resources/webapp/js/d3/LICENSE b/client/client-monitoring/src/main/resources/webapp/js/d3/LICENSE
new file mode 100644
index 0000000..a626880
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/js/d3/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2010-2017 Mike Bostock
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+  this list of conditions and the following disclaimer in the documentation
+  and/or other materials provided with the distribution.
+
+* Neither the name of the author nor the names of contributors may be used to
+  endorse or promote products derived from this software without specific prior
+  written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
diff --git a/client/client-monitoring/src/main/resources/webapp/js/d3/d3.min.js b/client/client-monitoring/src/main/resources/webapp/js/d3/d3.min.js
new file mode 100644
index 0000000..1664873
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/js/d3/d3.min.js
@@ -0,0 +1,5 @@
+!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:NaN}function r(n){return null===n?NaN:+n}function i(n){return!isNaN(n)}function u(n){return{left:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)<0?r=u+1:i=u}return r},right:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)>0?i=u:r=u+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function l(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function c(){this._=Object.create(null)}function f(n){return(n+="")===bo||n[0]===_o?_o+n:n}function s(n){return(n+="")[0]===_o?n.slice(1):n}function h(n){return f(n)in this._}function p(n){return(n=f(n))in this._&&delete this._[n]}function g(){var n=[];for(var t in this._)n.push(s(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function y(){this._=Object.create(null)}function m(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=wo.length;r>e;++e){var i=wo[e]+t;if(i in n)return i}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,i=-1,u=r.length;++i<u;)(t=r[i].on)&&t.apply(this,arguments);return n}var e=[],r=new c;return t.on=function(t,i){var u,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,u=e.indexOf(o)).concat(e.slice(u+1)),r.remove(t)),i&&e.push(r.set(t,{on:i})),n)},t}function S(){ao.event.preventDefault()}function k(){for(var n,t=ao.event;n=t.sourceEvent;)t=n;return t}function N(n){for(var t=new _,e=0,r=arguments.length;++e<r;)t[arguments[e]]=w(t);return t.of=function(e,r){return function(i){try{var u=i.sourceEvent=ao.event;i.target=n,ao.event=i,t[i.type].apply(e,r)}finally{ao.event=u}}},t}function E(n){return ko(n,Co),n}function A(n){return"function"==typeof n?n:function(){return No(n,this)}}function C(n){return"function"==typeof n?n:function(){return Eo(n,this)}}function z(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function i(){this.setAttribute(n,t)}function u(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=ao.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?u:i}function L(n){return n.trim().replace(/\s+/g," ")}function q(n){return new RegExp("(?:^|\\s+)"+ao.requote(n)+"(?:\\s+|$)","g")}function T(n){return(n+"").trim().split(/^|\s+/)}function R(n,t){function e(){for(var e=-1;++e<i;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<i;)n[e](this,r)}n=T(n).map(D);var i=n.length;return"function"==typeof t?r:e}function D(n){var t=q(n);return function(e,r){if(i=e.classList)return r?i.add(n):i.remove(n);var i=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(i)||e.setAttribute("class",L(i+" "+n))):e.setAttribute("class",L(i.replace(t," ")))}}function P(n,t,e){function r(){this.style.removeProperty(n)}function i(){this.style.setProperty(n,t,e)}function u(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?u:i}function U(n,t){function e(){delete this[n]}function r(){this[n]=t}function i(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?i:r}function j(n){function t(){var t=this.ownerDocument,e=this.namespaceURI;return e===zo&&t.documentElement.namespaceURI===zo?t.createElement(n):t.createElementNS(e,n)}function e(){return this.ownerDocument.createElementNS(n.space,n.local)}return"function"==typeof n?n:(n=ao.ns.qualify(n)).local?e:t}function F(){var n=this.parentNode;n&&n.removeChild(this)}function H(n){return{__data__:n}}function O(n){return function(){return Ao(this,n)}}function I(n){return arguments.length||(n=e),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function Y(n,t){for(var e=0,r=n.length;r>e;e++)for(var i,u=n[e],o=0,a=u.length;a>o;o++)(i=u[o])&&t(i,o,e);return n}function Z(n){return ko(n,qo),n}function V(n){var t,e;return function(r,i,u){var o,a=n[u].update,l=a.length;for(u!=e&&(e=u,t=0),i>=t&&(t=i+1);!(o=a[t])&&++t<l;);return o}}function X(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function i(){var i=l(t,co(arguments));r.call(this),this.addEventListener(n,this[o]=i,i.$=e),i._=t}function u(){var t,e=new RegExp("^__on([^.]+)"+ao.requote(n)+"$");for(var r in this)if(t=r.match(e)){var i=this[r];this.removeEventListener(t[1],i,i.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),l=$;a>0&&(n=n.slice(0,a));var c=To.get(n);return c&&(n=c,l=B),a?t?i:r:t?b:u}function $(n,t){return function(e){var r=ao.event;ao.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ao.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Do,i="click"+r,u=ao.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ro&&(Ro="onselectstart"in e?!1:x(e.style,"userSelect")),Ro){var o=n(e).style,a=o[Ro];o[Ro]="none"}return function(n){if(u.on(r,null),Ro&&(o[Ro]=a),n){var t=function(){u.on(i,null)};u.on(i,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var i=r.createSVGPoint();if(0>Po){var u=t(n);if(u.scrollX||u.scrollY){r=ao.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Po=!(o.f||o.e),r.remove()}}return Po?(i.x=e.pageX,i.y=e.pageY):(i.x=e.clientX,i.y=e.clientY),i=i.matrixTransform(n.getScreenCTM().inverse()),[i.x,i.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ao.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nn(n){return n>1?0:-1>n?Fo:Math.acos(n)}function tn(n){return n>1?Io:-1>n?-Io:Math.asin(n)}function en(n){return((n=Math.exp(n))-1/n)/2}function rn(n){return((n=Math.exp(n))+1/n)/2}function un(n){return((n=Math.exp(2*n))-1)/(n+1)}function on(n){return(n=Math.sin(n/2))*n}function an(){}function ln(n,t,e){return this instanceof ln?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ln?new ln(n.h,n.s,n.l):_n(""+n,wn,ln):new ln(n,t,e)}function cn(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?u+(o-u)*n/60:180>n?o:240>n?u+(o-u)*(240-n)/60:u}function i(n){return Math.round(255*r(n))}var u,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,u=2*e-o,new mn(i(n+120),i(n),i(n-120))}function fn(n,t,e){return this instanceof fn?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof fn?new fn(n.h,n.c,n.l):n instanceof hn?gn(n.l,n.a,n.b):gn((n=Sn((n=ao.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new fn(n,t,e)}function sn(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new hn(e,Math.cos(n*=Yo)*t,Math.sin(n)*t)}function hn(n,t,e){return this instanceof hn?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof hn?new hn(n.l,n.a,n.b):n instanceof fn?sn(n.h,n.c,n.l):Sn((n=mn(n)).r,n.g,n.b):new hn(n,t,e)}function pn(n,t,e){var r=(n+16)/116,i=r+t/500,u=r-e/200;return i=vn(i)*na,r=vn(r)*ta,u=vn(u)*ea,new mn(yn(3.2404542*i-1.5371385*r-.4985314*u),yn(-.969266*i+1.8760108*r+.041556*u),yn(.0556434*i-.2040259*r+1.0572252*u))}function gn(n,t,e){return n>0?new fn(Math.atan2(e,t)*Zo,Math.sqrt(t*t+e*e),n):new fn(NaN,NaN,n)}function vn(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function dn(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function yn(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mn(n,t,e){return this instanceof mn?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mn?new mn(n.r,n.g,n.b):_n(""+n,mn,cn):new mn(n,t,e)}function Mn(n){return new mn(n>>16,n>>8&255,255&n)}function xn(n){return Mn(n)+""}function bn(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function _n(n,t,e){var r,i,u,o=0,a=0,l=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Nn(i[0]),Nn(i[1]),Nn(i[2]))}return(u=ua.get(n))?t(u.r,u.g,u.b):(null==n||"#"!==n.charAt(0)||isNaN(u=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&u)>>4,o=o>>4|o,a=240&u,a=a>>4|a,l=15&u,l=l<<4|l):7===n.length&&(o=(16711680&u)>>16,a=(65280&u)>>8,l=255&u)),t(o,a,l))}function wn(n,t,e){var r,i,u=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-u,l=(o+u)/2;return a?(i=.5>l?a/(o+u):a/(2-o-u),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=NaN,i=l>0&&1>l?0:r),new ln(r,i,l)}function Sn(n,t,e){n=kn(n),t=kn(t),e=kn(e);var r=dn((.4124564*n+.3575761*t+.1804375*e)/na),i=dn((.2126729*n+.7151522*t+.072175*e)/ta),u=dn((.0193339*n+.119192*t+.9503041*e)/ea);return hn(116*i-16,500*(r-i),200*(i-u))}function kn(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Nn(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function En(n){return"function"==typeof n?n:function(){return n}}function An(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Cn(t,e,n,r)}}function Cn(n,t,e,r){function i(){var n,t=l.status;if(!t&&Ln(l)||t>=200&&300>t||304===t){try{n=e.call(u,l)}catch(r){return void o.error.call(u,r)}o.load.call(u,n)}else o.error.call(u,l)}var u={},o=ao.dispatch("beforesend","progress","load","error"),a={},l=new XMLHttpRequest,c=null;return!this.XDomainRequest||"withCredentials"in l||!/^(http(s)?:)?\/\//.test(n)||(l=new XDomainRequest),"onload"in l?l.onload=l.onerror=i:l.onreadystatechange=function(){l.readyState>3&&i()},l.onprogress=function(n){var t=ao.event;ao.event=n;try{o.progress.call(u,l)}finally{ao.event=t}},u.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",u)},u.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",u):t},u.responseType=function(n){return arguments.length?(c=n,u):c},u.response=function(n){return e=n,u},["get","post"].forEach(function(n){u[n]=function(){return u.send.apply(u,[n].concat(co(arguments)))}}),u.send=function(e,r,i){if(2===arguments.length&&"function"==typeof r&&(i=r,r=null),l.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),l.setRequestHeader)for(var f in a)l.setRequestHeader(f,a[f]);return null!=t&&l.overrideMimeType&&l.overrideMimeType(t),null!=c&&(l.responseType=c),null!=i&&u.on("error",i).on("load",function(n){i(null,n)}),o.beforesend.call(u,l),l.send(null==r?null:r),u},u.abort=function(){return l.abort(),u},ao.rebind(u,o,"on"),null==r?u:u.get(zn(r))}function zn(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Ln(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qn(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var i=e+t,u={c:n,t:i,n:null};return aa?aa.n=u:oa=u,aa=u,la||(ca=clearTimeout(ca),la=1,fa(Tn)),u}function Tn(){var n=Rn(),t=Dn()-n;t>24?(isFinite(t)&&(clearTimeout(ca),ca=setTimeout(Tn,t)),la=0):(la=1,fa(Tn))}function Rn(){for(var n=Date.now(),t=oa;t;)n>=t.t&&t.c(n-t.t)&&(t.c=null),t=t.n;return n}function Dn(){for(var n,t=oa,e=1/0;t;)t.c?(t.t<e&&(e=t.t),t=(n=t).n):t=n?n.n=t.n:oa=t.n;return aa=n,e}function Pn(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Un(n,t){var e=Math.pow(10,3*xo(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function jn(n){var t=n.decimal,e=n.thousands,r=n.grouping,i=n.currency,u=r&&e?function(n,t){for(var i=n.length,u=[],o=0,a=r[0],l=0;i>0&&a>0&&(l+a+1>t&&(a=Math.max(1,t-l)),u.push(n.substring(i-=a,i+a)),!((l+=a+1)>t));)a=r[o=(o+1)%r.length];return u.reverse().join(e)}:m;return function(n){var e=ha.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",l=e[4]||"",c=e[5],f=+e[6],s=e[7],h=e[8],p=e[9],g=1,v="",d="",y=!1,m=!0;switch(h&&(h=+h.substring(1)),(c||"0"===r&&"="===o)&&(c=r="0",o="="),p){case"n":s=!0,p="g";break;case"%":g=100,d="%",p="f";break;case"p":g=100,d="%",p="r";break;case"b":case"o":case"x":case"X":"#"===l&&(v="0"+p.toLowerCase());case"c":m=!1;case"d":y=!0,h=0;break;case"s":g=-1,p="r"}"$"===l&&(v=i[0],d=i[1]),"r"!=p||h||(p="g"),null!=h&&("g"==p?h=Math.max(1,Math.min(21,h)):"e"!=p&&"f"!=p||(h=Math.max(0,Math.min(20,h)))),p=pa.get(p)||Fn;var M=c&&s;return function(n){var e=d;if(y&&n%1)return"";var i=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>g){var l=ao.formatPrefix(n,h);n=l.scale(n),e=l.symbol+d}else n*=g;n=p(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=m?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!c&&s&&(x=u(x,1/0));var S=v.length+x.length+b.length+(M?0:i.length),k=f>S?new Array(S=f-S+1).join(r):"";return M&&(x=u(k+x,k.length?f-b.length:1/0)),i+=v,n=x+b,("<"===o?i+n+k:">"===o?k+i+n:"^"===o?k.substring(0,S>>=1)+i+n+k.substring(S):i+(M?n:k+n))+e}}}function Fn(n){return n+""}function Hn(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function On(n,t,e){function r(t){var e=n(t),r=u(e,1);return r-t>t-e?e:r}function i(e){return t(e=n(new va(e-1)),1),e}function u(n,e){return t(n=new va(+n),e),n}function o(n,r,u){var o=i(n),a=[];if(u>1)for(;r>o;)e(o)%u||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{va=Hn;var r=new Hn;return r._=n,o(r,t,e)}finally{va=Date}}n.floor=n,n.round=r,n.ceil=i,n.offset=u,n.range=o;var l=n.utc=In(n);return l.floor=l,l.round=In(r),l.ceil=In(i),l.offset=In(u),l.range=a,n}function In(n){return function(t,e){try{va=Hn;var r=new Hn;return r._=t,n(r,e)._}finally{va=Date}}}function Yn(n){function t(n){function t(t){for(var e,i,u,o=[],a=-1,l=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.slice(l,a)),null!=(i=ya[e=n.charAt(++a)])&&(e=n.charAt(++a)),(u=A[e])&&(e=u(t,null==i?"e"===e?" ":"0":i)),o.push(e),l=a+1);return o.push(n.slice(l,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},i=e(r,n,t,0);if(i!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var u=null!=r.Z&&va!==Hn,o=new(u?Hn:va);return"j"in r?o.setFullYear(r.y,0,r.j):"W"in r||"U"in r?("w"in r||(r.w="W"in r?1:0),o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+(r.Z/100|0),r.M+r.Z%100,r.S,r.L),u?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var i,u,o,a=0,l=t.length,c=e.length;l>a;){if(r>=c)return-1;if(i=t.charCodeAt(a++),37===i){if(o=t.charAt(a++),u=C[o in ya?t.charAt(a++):o],!u||(r=u(n,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){N.lastIndex=0;var r=N.exec(t.slice(e));return r?(n.m=E.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,A.c.toString(),t,r)}function l(n,t,r){return e(n,A.x.toString(),t,r)}function c(n,t,r){return e(n,A.X.toString(),t,r)}function f(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var s=n.dateTime,h=n.date,p=n.time,g=n.periods,v=n.days,d=n.shortDays,y=n.months,m=n.shortMonths;t.utc=function(n){function e(n){try{va=Hn;var t=new va;return t._=n,r(t)}finally{va=Date}}var r=t(n);return e.parse=function(n){try{va=Hn;var t=r.parse(n);return t&&t._}finally{va=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ct;var M=ao.map(),x=Vn(v),b=Xn(v),_=Vn(d),w=Xn(d),S=Vn(y),k=Xn(y),N=Vn(m),E=Xn(m);g.forEach(function(n,t){M.set(n.toLowerCase(),t)});var A={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return m[n.getMonth()]},B:function(n){return y[n.getMonth()]},c:t(s),d:function(n,t){return Zn(n.getDate(),t,2)},e:function(n,t){return Zn(n.getDate(),t,2)},H:function(n,t){return Zn(n.getHours(),t,2)},I:function(n,t){return Zn(n.getHours()%12||12,t,2)},j:function(n,t){return Zn(1+ga.dayOfYear(n),t,3)},L:function(n,t){return Zn(n.getMilliseconds(),t,3)},m:function(n,t){return Zn(n.getMonth()+1,t,2)},M:function(n,t){return Zn(n.getMinutes(),t,2)},p:function(n){return g[+(n.getHours()>=12)]},S:function(n,t){return Zn(n.getSeconds(),t,2)},U:function(n,t){return Zn(ga.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Zn(ga.mondayOfYear(n),t,2)},x:t(h),X:t(p),y:function(n,t){return Zn(n.getFullYear()%100,t,2)},Y:function(n,t){return Zn(n.getFullYear()%1e4,t,4)},Z:at,"%":function(){return"%"}},C={a:r,A:i,b:u,B:o,c:a,d:tt,e:tt,H:rt,I:rt,j:et,L:ot,m:nt,M:it,p:f,S:ut,U:Bn,w:$n,W:Wn,x:l,X:c,y:Gn,Y:Jn,Z:Kn,"%":lt};return t}function Zn(n,t,e){var r=0>n?"-":"",i=(r?-n:n)+"",u=i.length;return r+(e>u?new Array(e-u+1).join(t)+i:i)}function Vn(n){return new RegExp("^(?:"+n.map(ao.requote).join("|")+")","i")}function Xn(n){for(var t=new c,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function $n(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Bn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e));return r?(n.U=+r[0],e+r[0].length):-1}function Wn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e));return r?(n.W=+r[0],e+r[0].length):-1}function Jn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Gn(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.y=Qn(+r[0]),e+r[0].length):-1}function Kn(n,t,e){return/^[+-]\d{4}$/.test(t=t.slice(e,e+5))?(n.Z=-t,e+5):-1}function Qn(n){return n+(n>68?1900:2e3)}function nt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function tt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function et(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function rt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function it(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function ut(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ot(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function at(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=xo(t)/60|0,i=xo(t)%60;return e+Zn(r,"0",2)+Zn(i,"0",2)}function lt(n,t,e){Ma.lastIndex=0;var r=Ma.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ct(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ft(){}function st(n,t,e){var r=e.s=n+t,i=r-n,u=r-i;e.t=n-u+(t-i)}function ht(n,t){n&&wa.hasOwnProperty(n.type)&&wa[n.type](n,t)}function pt(n,t,e){var r,i=-1,u=n.length-e;for(t.lineStart();++i<u;)r=n[i],t.point(r[0],r[1],r[2]);t.lineEnd()}function gt(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)pt(n[e],t,1);t.polygonEnd()}function vt(){function n(n,t){n*=Yo,t=t*Yo/2+Fo/4;var e=n-r,o=e>=0?1:-1,a=o*e,l=Math.cos(t),c=Math.sin(t),f=u*c,s=i*l+f*Math.cos(a),h=f*o*Math.sin(a);ka.add(Math.atan2(h,s)),r=n,i=l,u=c}var t,e,r,i,u;Na.point=function(o,a){Na.point=n,r=(t=o)*Yo,i=Math.cos(a=(e=a)*Yo/2+Fo/4),u=Math.sin(a)},Na.lineEnd=function(){n(t,e)}}function dt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function yt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function mt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Mt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function xt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function bt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function _t(n){return[Math.atan2(n[1],n[0]),tn(n[2])]}function wt(n,t){return xo(n[0]-t[0])<Uo&&xo(n[1]-t[1])<Uo}function St(n,t){n*=Yo;var e=Math.cos(t*=Yo);kt(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function kt(n,t,e){++Ea,Ca+=(n-Ca)/Ea,za+=(t-za)/Ea,La+=(e-La)/Ea}function Nt(){function n(n,i){n*=Yo;var u=Math.cos(i*=Yo),o=u*Math.cos(n),a=u*Math.sin(n),l=Math.sin(i),c=Math.atan2(Math.sqrt((c=e*l-r*a)*c+(c=r*o-t*l)*c+(c=t*a-e*o)*c),t*o+e*a+r*l);Aa+=c,qa+=c*(t+(t=o)),Ta+=c*(e+(e=a)),Ra+=c*(r+(r=l)),kt(t,e,r)}var t,e,r;ja.point=function(i,u){i*=Yo;var o=Math.cos(u*=Yo);t=o*Math.cos(i),e=o*Math.sin(i),r=Math.sin(u),ja.point=n,kt(t,e,r)}}function Et(){ja.point=St}function At(){function n(n,t){n*=Yo;var e=Math.cos(t*=Yo),o=e*Math.cos(n),a=e*Math.sin(n),l=Math.sin(t),c=i*l-u*a,f=u*o-r*l,s=r*a-i*o,h=Math.sqrt(c*c+f*f+s*s),p=r*o+i*a+u*l,g=h&&-nn(p)/h,v=Math.atan2(h,p);Da+=g*c,Pa+=g*f,Ua+=g*s,Aa+=v,qa+=v*(r+(r=o)),Ta+=v*(i+(i=a)),Ra+=v*(u+(u=l)),kt(r,i,u)}var t,e,r,i,u;ja.point=function(o,a){t=o,e=a,ja.point=n,o*=Yo;var l=Math.cos(a*=Yo);r=l*Math.cos(o),i=l*Math.sin(o),u=Math.sin(a),kt(r,i,u)},ja.lineEnd=function(){n(t,e),ja.lineEnd=Et,ja.point=St}}function Ct(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function zt(){return!0}function Lt(n,t,e,r,i){var u=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(wt(e,r)){i.lineStart();for(var a=0;t>a;++a)i.point((e=n[a])[0],e[1]);return void i.lineEnd()}var l=new Tt(e,n,null,!0),c=new Tt(e,null,l,!1);l.o=c,u.push(l),o.push(c),l=new Tt(r,n,null,!1),c=new Tt(r,null,l,!0),l.o=c,u.push(l),o.push(c)}}),o.sort(t),qt(u),qt(o),u.length){for(var a=0,l=e,c=o.length;c>a;++a)o[a].e=l=!l;for(var f,s,h=u[0];;){for(var p=h,g=!0;p.v;)if((p=p.n)===h)return;f=p.z,i.lineStart();do{if(p.v=p.o.v=!0,p.e){if(g)for(var a=0,c=f.length;c>a;++a)i.point((s=f[a])[0],s[1]);else r(p.x,p.n.x,1,i);p=p.n}else{if(g){f=p.p.z;for(var a=f.length-1;a>=0;--a)i.point((s=f[a])[0],s[1])}else r(p.x,p.p.x,-1,i);p=p.p}p=p.o,f=p.z,g=!g}while(!p.v);i.lineEnd()}}}function qt(n){if(t=n.length){for(var t,e,r=0,i=n[0];++r<t;)i.n=e=n[r],e.p=i,i=e;i.n=e=n[0],e.p=i}}function Tt(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Rt(n,t,e,r){return function(i,u){function o(t,e){var r=i(t,e);n(t=r[0],e=r[1])&&u.point(t,e)}function a(n,t){var e=i(n,t);d.point(e[0],e[1])}function l(){m.point=a,d.lineStart()}function c(){m.point=o,d.lineEnd()}function f(n,t){v.push([n,t]);var e=i(n,t);x.point(e[0],e[1])}function s(){x.lineStart(),v=[]}function h(){f(v[0][0],v[0][1]),x.lineEnd();var n,t=x.clean(),e=M.buffer(),r=e.length;if(v.pop(),g.push(v),v=null,r)if(1&t){n=e[0];var i,r=n.length-1,o=-1;if(r>0){for(b||(u.polygonStart(),b=!0),u.lineStart();++o<r;)u.point((i=n[o])[0],i[1]);u.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),p.push(e.filter(Dt))}var p,g,v,d=t(u),y=i.invert(r[0],r[1]),m={point:o,lineStart:l,lineEnd:c,polygonStart:function(){m.point=f,m.lineStart=s,m.lineEnd=h,p=[],g=[]},polygonEnd:function(){m.point=o,m.lineStart=l,m.lineEnd=c,p=ao.merge(p);var n=Ot(y,g);p.length?(b||(u.polygonStart(),b=!0),Lt(p,Ut,n,e,u)):n&&(b||(u.polygonStart(),b=!0),u.lineStart(),e(null,null,1,u),u.lineEnd()),b&&(u.polygonEnd(),b=!1),p=g=null},sphere:function(){u.polygonStart(),u.lineStart(),e(null,null,1,u),u.lineEnd(),u.polygonEnd()}},M=Pt(),x=t(M),b=!1;return m}}function Dt(n){return n.length>1}function Pt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ut(n,t){return((n=n.x)[0]<0?n[1]-Io-Uo:Io-n[1])-((t=t.x)[0]<0?t[1]-Io-Uo:Io-t[1])}function jt(n){var t,e=NaN,r=NaN,i=NaN;return{lineStart:function(){n.lineStart(),t=1},point:function(u,o){var a=u>0?Fo:-Fo,l=xo(u-e);xo(l-Fo)<Uo?(n.point(e,r=(r+o)/2>0?Io:-Io),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(u,r),t=0):i!==a&&l>=Fo&&(xo(e-i)<Uo&&(e-=i*Uo),xo(u-a)<Uo&&(u-=a*Uo),r=Ft(e,r,u,o),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=u,r=o),i=a},lineEnd:function(){n.lineEnd(),e=r=NaN},clean:function(){return 2-t}}}function Ft(n,t,e,r){var i,u,o=Math.sin(n-e);return xo(o)>Uo?Math.atan((Math.sin(t)*(u=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(t))*Math.sin(n))/(i*u*o)):(t+r)/2}function Ht(n,t,e,r){var i;if(null==n)i=e*Io,r.point(-Fo,i),r.point(0,i),r.point(Fo,i),r.point(Fo,0),r.point(Fo,-i),r.point(0,-i),r.point(-Fo,-i),r.point(-Fo,0),r.point(-Fo,i);else if(xo(n[0]-t[0])>Uo){var u=n[0]<t[0]?Fo:-Fo;i=e*u/2,r.point(-u,i),r.point(0,i),r.point(u,i)}else r.point(t[0],t[1])}function Ot(n,t){var e=n[0],r=n[1],i=[Math.sin(e),-Math.cos(e),0],u=0,o=0;ka.reset();for(var a=0,l=t.length;l>a;++a){var c=t[a],f=c.length;if(f)for(var s=c[0],h=s[0],p=s[1]/2+Fo/4,g=Math.sin(p),v=Math.cos(p),d=1;;){d===f&&(d=0),n=c[d];var y=n[0],m=n[1]/2+Fo/4,M=Math.sin(m),x=Math.cos(m),b=y-h,_=b>=0?1:-1,w=_*b,S=w>Fo,k=g*M;if(ka.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),u+=S?b+_*Ho:b,S^h>=e^y>=e){var N=mt(dt(s),dt(n));bt(N);var E=mt(i,N);bt(E);var A=(S^b>=0?-1:1)*tn(E[2]);(r>A||r===A&&(N[0]||N[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=y,g=M,v=x,s=n}}return(-Uo>u||Uo>u&&-Uo>ka)^1&o}function It(n){function t(n,t){return Math.cos(n)*Math.cos(t)>u}function e(n){var e,u,l,c,f;return{lineStart:function(){c=l=!1,f=1},point:function(s,h){var p,g=[s,h],v=t(s,h),d=o?v?0:i(s,h):v?i(s+(0>s?Fo:-Fo),h):0;if(!e&&(c=l=v)&&n.lineStart(),v!==l&&(p=r(e,g),(wt(e,p)||wt(g,p))&&(g[0]+=Uo,g[1]+=Uo,v=t(g[0],g[1]))),v!==l)f=0,v?(n.lineStart(),p=r(g,e),n.point(p[0],p[1])):(p=r(e,g),n.point(p[0],p[1]),n.lineEnd()),e=p;else if(a&&e&&o^v){var y;d&u||!(y=r(g,e,!0))||(f=0,o?(n.lineStart(),n.point(y[0][0],y[0][1]),n.point(y[1][0],y[1][1]),n.lineEnd()):(n.point(y[1][0],y[1][1]),n.lineEnd(),n.lineStart(),n.point(y[0][0],y[0][1])))}!v||e&&wt(e,g)||n.point(g[0],g[1]),e=g,l=v,u=d},lineEnd:function(){l&&n.lineEnd(),e=null},clean:function(){return f|(c&&l)<<1}}}function r(n,t,e){var r=dt(n),i=dt(t),o=[1,0,0],a=mt(r,i),l=yt(a,a),c=a[0],f=l-c*c;if(!f)return!e&&n;var s=u*l/f,h=-u*c/f,p=mt(o,a),g=xt(o,s),v=xt(a,h);Mt(g,v);var d=p,y=yt(g,d),m=yt(d,d),M=y*y-m*(yt(g,g)-1);if(!(0>M)){var x=Math.sqrt(M),b=xt(d,(-y-x)/m);if(Mt(b,g),b=_t(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],N=t[1];w>S&&(_=w,w=S,S=_);var E=S-w,A=xo(E-Fo)<Uo,C=A||Uo>E;if(!A&&k>N&&(_=k,k=N,N=_),C?A?k+N>0^b[1]<(xo(b[0]-w)<Uo?k:N):k<=b[1]&&b[1]<=N:E>Fo^(w<=b[0]&&b[0]<=S)){var z=xt(d,(-y+x)/m);return Mt(z,g),[b,_t(z)]}}}function i(t,e){var r=o?n:Fo-n,i=0;return-r>t?i|=1:t>r&&(i|=2),-r>e?i|=4:e>r&&(i|=8),i}var u=Math.cos(n),o=u>0,a=xo(u)>Uo,l=ve(n,6*Yo);return Rt(t,e,l,o?[0,-n]:[-Fo,n-Fo])}function Yt(n,t,e,r){return function(i){var u,o=i.a,a=i.b,l=o.x,c=o.y,f=a.x,s=a.y,h=0,p=1,g=f-l,v=s-c;if(u=n-l,g||!(u>0)){if(u/=g,0>g){if(h>u)return;p>u&&(p=u)}else if(g>0){if(u>p)return;u>h&&(h=u)}if(u=e-l,g||!(0>u)){if(u/=g,0>g){if(u>p)return;u>h&&(h=u)}else if(g>0){if(h>u)return;p>u&&(p=u)}if(u=t-c,v||!(u>0)){if(u/=v,0>v){if(h>u)return;p>u&&(p=u)}else if(v>0){if(u>p)return;u>h&&(h=u)}if(u=r-c,v||!(0>u)){if(u/=v,0>v){if(u>p)return;u>h&&(h=u)}else if(v>0){if(h>u)return;p>u&&(p=u)}return h>0&&(i.a={x:l+h*g,y:c+h*v}),1>p&&(i.b={x:l+p*g,y:c+p*v}),i}}}}}}function Zt(n,t,e,r){function i(r,i){return xo(r[0]-n)<Uo?i>0?0:3:xo(r[0]-e)<Uo?i>0?2:1:xo(r[1]-t)<Uo?i>0?1:0:i>0?3:2}function u(n,t){return o(n.x,t.x)}function o(n,t){var e=i(n,1),r=i(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function l(n){for(var t=0,e=d.length,r=n[1],i=0;e>i;++i)for(var u,o=1,a=d[i],l=a.length,c=a[0];l>o;++o)u=a[o],c[1]<=r?u[1]>r&&Q(c,u,n)>0&&++t:u[1]<=r&&Q(c,u,n)<0&&--t,c=u;return 0!==t}function c(u,a,l,c){var f=0,s=0;if(null==u||(f=i(u,l))!==(s=i(a,l))||o(u,a)<0^l>0){do c.point(0===f||3===f?n:e,f>1?r:t);while((f=(f+l+4)%4)!==s)}else c.point(a[0],a[1])}function f(i,u){return i>=n&&e>=i&&u>=t&&r>=u}function s(n,t){f(n,t)&&a.point(n,t)}function h(){C.point=g,d&&d.push(y=[]),S=!0,w=!1,b=_=NaN}function p(){v&&(g(m,M),x&&w&&E.rejoin(),v.push(E.buffer())),C.point=s,w&&a.lineEnd()}function g(n,t){n=Math.max(-Ha,Math.min(Ha,n)),t=Math.max(-Ha,Math.min(Ha,t));var e=f(n,t);if(d&&y.push([n,t]),S)m=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};A(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,y,m,M,x,b,_,w,S,k,N=a,E=Pt(),A=Yt(n,t,e,r),C={point:s,lineStart:h,lineEnd:p,polygonStart:function(){a=E,v=[],d=[],k=!0},polygonEnd:function(){a=N,v=ao.merge(v);var t=l([n,r]),e=k&&t,i=v.length;(e||i)&&(a.polygonStart(),e&&(a.lineStart(),c(null,null,1,a),a.lineEnd()),i&&Lt(v,u,t,c,a),a.polygonEnd()),v=d=y=null}};return C}}function Vt(n){var t=0,e=Fo/3,r=ae(n),i=r(t,e);return i.parallels=function(n){return arguments.length?r(t=n[0]*Fo/180,e=n[1]*Fo/180):[t/Fo*180,e/Fo*180]},i}function Xt(n,t){function e(n,t){var e=Math.sqrt(u-2*i*Math.sin(t))/i;return[e*Math.sin(n*=i),o-e*Math.cos(n)]}var r=Math.sin(n),i=(r+Math.sin(t))/2,u=1+r*(2*i-r),o=Math.sqrt(u)/i;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/i,tn((u-(n*n+e*e)*i*i)/(2*i))]},e}function $t(){function n(n,t){Ia+=i*n-r*t,r=n,i=t}var t,e,r,i;$a.point=function(u,o){$a.point=n,t=r=u,e=i=o},$a.lineEnd=function(){n(t,e)}}function Bt(n,t){Ya>n&&(Ya=n),n>Va&&(Va=n),Za>t&&(Za=t),t>Xa&&(Xa=t)}function Wt(){function n(n,t){o.push("M",n,",",t,u)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function i(){o.push("Z")}var u=Jt(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return u=Jt(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Jt(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Gt(n,t){Ca+=n,za+=t,++La}function Kt(){function n(n,r){var i=n-t,u=r-e,o=Math.sqrt(i*i+u*u);qa+=o*(t+n)/2,Ta+=o*(e+r)/2,Ra+=o,Gt(t=n,e=r)}var t,e;Wa.point=function(r,i){Wa.point=n,Gt(t=r,e=i)}}function Qt(){Wa.point=Gt}function ne(){function n(n,t){var e=n-r,u=t-i,o=Math.sqrt(e*e+u*u);qa+=o*(r+n)/2,Ta+=o*(i+t)/2,Ra+=o,o=i*n-r*t,Da+=o*(r+n),Pa+=o*(i+t),Ua+=3*o,Gt(r=n,i=t)}var t,e,r,i;Wa.point=function(u,o){Wa.point=n,Gt(t=r=u,e=i=o)},Wa.lineEnd=function(){n(t,e)}}function te(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Ho)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function i(){a.point=t}function u(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:i,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=i,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function ee(n){function t(n){return(a?r:e)(n)}function e(t){return ue(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=NaN,S.point=u,t.lineStart()}function u(e,r){var u=dt([e,r]),o=n(e,r);i(M,x,m,b,_,w,M=o[0],x=o[1],m=e,b=u[0],_=u[1],w=u[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function l(){
+r(),S.point=c,S.lineEnd=f}function c(n,t){u(s=n,h=t),p=M,g=x,v=b,d=_,y=w,S.point=u}function f(){i(M,x,m,b,_,w,p,g,s,v,d,y,a,t),S.lineEnd=o,o()}var s,h,p,g,v,d,y,m,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=l},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function i(t,e,r,a,l,c,f,s,h,p,g,v,d,y){var m=f-t,M=s-e,x=m*m+M*M;if(x>4*u&&d--){var b=a+p,_=l+g,w=c+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),N=xo(xo(w)-1)<Uo||xo(r-h)<Uo?(r+h)/2:Math.atan2(_,b),E=n(N,k),A=E[0],C=E[1],z=A-t,L=C-e,q=M*z-m*L;(q*q/x>u||xo((m*z+M*L)/x-.5)>.3||o>a*p+l*g+c*v)&&(i(t,e,r,a,l,c,A,C,N,b/=S,_/=S,w,d,y),y.point(A,C),i(A,C,N,b,_,w,f,s,h,p,g,v,d,y))}}var u=.5,o=Math.cos(30*Yo),a=16;return t.precision=function(n){return arguments.length?(a=(u=n*n)>0&&16,t):Math.sqrt(u)},t}function re(n){var t=ee(function(t,e){return n([t*Zo,e*Zo])});return function(n){return le(t(n))}}function ie(n){this.stream=n}function ue(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function oe(n){return ae(function(){return n})()}function ae(n){function t(n){return n=a(n[0]*Yo,n[1]*Yo),[n[0]*h+l,c-n[1]*h]}function e(n){return n=a.invert((n[0]-l)/h,(c-n[1])/h),n&&[n[0]*Zo,n[1]*Zo]}function r(){a=Ct(o=se(y,M,x),u);var n=u(v,d);return l=p-n[0]*h,c=g+n[1]*h,i()}function i(){return f&&(f.valid=!1,f=null),t}var u,o,a,l,c,f,s=ee(function(n,t){return n=u(n,t),[n[0]*h+l,c-n[1]*h]}),h=150,p=480,g=250,v=0,d=0,y=0,M=0,x=0,b=Fa,_=m,w=null,S=null;return t.stream=function(n){return f&&(f.valid=!1),f=le(b(o,s(_(n)))),f.valid=!0,f},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Fa):It((w=+n)*Yo),i()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Zt(n[0][0],n[0][1],n[1][0],n[1][1]):m,i()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(p=+n[0],g=+n[1],r()):[p,g]},t.center=function(n){return arguments.length?(v=n[0]%360*Yo,d=n[1]%360*Yo,r()):[v*Zo,d*Zo]},t.rotate=function(n){return arguments.length?(y=n[0]%360*Yo,M=n[1]%360*Yo,x=n.length>2?n[2]%360*Yo:0,r()):[y*Zo,M*Zo,x*Zo]},ao.rebind(t,s,"precision"),function(){return u=n.apply(this,arguments),t.invert=u.invert&&e,r()}}function le(n){return ue(n,function(t,e){n.point(t*Yo,e*Yo)})}function ce(n,t){return[n,t]}function fe(n,t){return[n>Fo?n-Ho:-Fo>n?n+Ho:n,t]}function se(n,t,e){return n?t||e?Ct(pe(n),ge(t,e)):pe(n):t||e?ge(t,e):fe}function he(n){return function(t,e){return t+=n,[t>Fo?t-Ho:-Fo>t?t+Ho:t,e]}}function pe(n){var t=he(n);return t.invert=he(-n),t}function ge(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*r+a*i;return[Math.atan2(l*u-f*o,a*r-c*i),tn(f*u+l*o)]}var r=Math.cos(n),i=Math.sin(n),u=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*u-l*o;return[Math.atan2(l*u+c*o,a*r+f*i),tn(f*r-a*i)]},e}function ve(n,t){var e=Math.cos(n),r=Math.sin(n);return function(i,u,o,a){var l=o*t;null!=i?(i=de(e,i),u=de(e,u),(o>0?u>i:i>u)&&(i+=o*Ho)):(i=n+o*Ho,u=n-.5*l);for(var c,f=i;o>0?f>u:u>f;f-=l)a.point((c=_t([e,-r*Math.cos(f),-r*Math.sin(f)]))[0],c[1])}}function de(n,t){var e=dt(t);e[0]-=n,bt(e);var r=nn(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Uo)%(2*Math.PI)}function ye(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function me(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function Me(n){return n.source}function xe(n){return n.target}function be(n,t,e,r){var i=Math.cos(t),u=Math.sin(t),o=Math.cos(r),a=Math.sin(r),l=i*Math.cos(n),c=i*Math.sin(n),f=o*Math.cos(e),s=o*Math.sin(e),h=2*Math.asin(Math.sqrt(on(r-t)+i*o*on(e-n))),p=1/Math.sin(h),g=h?function(n){var t=Math.sin(n*=h)*p,e=Math.sin(h-n)*p,r=e*l+t*f,i=e*c+t*s,o=e*u+t*a;return[Math.atan2(i,r)*Zo,Math.atan2(o,Math.sqrt(r*r+i*i))*Zo]}:function(){return[n*Zo,t*Zo]};return g.distance=h,g}function _e(){function n(n,i){var u=Math.sin(i*=Yo),o=Math.cos(i),a=xo((n*=Yo)-t),l=Math.cos(a);Ja+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*u-e*o*l)*a),e*u+r*o*l),t=n,e=u,r=o}var t,e,r;Ga.point=function(i,u){t=i*Yo,e=Math.sin(u*=Yo),r=Math.cos(u),Ga.point=n},Ga.lineEnd=function(){Ga.point=Ga.lineEnd=b}}function we(n,t){function e(t,e){var r=Math.cos(t),i=Math.cos(e),u=n(r*i);return[u*i*Math.sin(t),u*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),i=t(r),u=Math.sin(i),o=Math.cos(i);return[Math.atan2(n*u,r*o),Math.asin(r&&e*u/r)]},e}function Se(n,t){function e(n,t){o>0?-Io+Uo>t&&(t=-Io+Uo):t>Io-Uo&&(t=Io-Uo);var e=o/Math.pow(i(t),u);return[e*Math.sin(u*n),o-e*Math.cos(u*n)]}var r=Math.cos(n),i=function(n){return Math.tan(Fo/4+n/2)},u=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(i(t)/i(n)),o=r*Math.pow(i(n),u)/u;return u?(e.invert=function(n,t){var e=o-t,r=K(u)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/u,2*Math.atan(Math.pow(o/r,1/u))-Io]},e):Ne}function ke(n,t){function e(n,t){var e=u-t;return[e*Math.sin(i*n),u-e*Math.cos(i*n)]}var r=Math.cos(n),i=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),u=r/i+n;return xo(i)<Uo?ce:(e.invert=function(n,t){var e=u-t;return[Math.atan2(n,e)/i,u-K(i)*Math.sqrt(n*n+e*e)]},e)}function Ne(n,t){return[n,Math.log(Math.tan(Fo/4+t/2))]}function Ee(n){var t,e=oe(n),r=e.scale,i=e.translate,u=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=i.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=u.apply(e,arguments);if(o===e){if(t=null==n){var a=Fo*r(),l=i();u([[l[0]-a,l[1]-a],[l[0]+a,l[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function Ae(n,t){return[Math.log(Math.tan(Fo/4+t/2)),-n]}function Ce(n){return n[0]}function ze(n){return n[1]}function Le(n){for(var t=n.length,e=[0,1],r=2,i=2;t>i;i++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[i])<=0;)--r;e[r++]=i}return e.slice(0,r)}function qe(n,t){return n[0]-t[0]||n[1]-t[1]}function Te(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Re(n,t,e,r){var i=n[0],u=e[0],o=t[0]-i,a=r[0]-u,l=n[1],c=e[1],f=t[1]-l,s=r[1]-c,h=(a*(l-c)-s*(i-u))/(s*o-a*f);return[i+h*o,l+h*f]}function De(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Pe(){rr(this),this.edge=this.site=this.circle=null}function Ue(n){var t=cl.pop()||new Pe;return t.site=n,t}function je(n){Be(n),ol.remove(n),cl.push(n),rr(n)}function Fe(n){var t=n.circle,e=t.x,r=t.cy,i={x:e,y:r},u=n.P,o=n.N,a=[n];je(n);for(var l=u;l.circle&&xo(e-l.circle.x)<Uo&&xo(r-l.circle.cy)<Uo;)u=l.P,a.unshift(l),je(l),l=u;a.unshift(l),Be(l);for(var c=o;c.circle&&xo(e-c.circle.x)<Uo&&xo(r-c.circle.cy)<Uo;)o=c.N,a.push(c),je(c),c=o;a.push(c),Be(c);var f,s=a.length;for(f=1;s>f;++f)c=a[f],l=a[f-1],nr(c.edge,l.site,c.site,i);l=a[0],c=a[s-1],c.edge=Ke(l.site,c.site,null,i),$e(l),$e(c)}function He(n){for(var t,e,r,i,u=n.x,o=n.y,a=ol._;a;)if(r=Oe(a,o)-u,r>Uo)a=a.L;else{if(i=u-Ie(a,o),!(i>Uo)){r>-Uo?(t=a.P,e=a):i>-Uo?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var l=Ue(n);if(ol.insert(t,l),t||e){if(t===e)return Be(t),e=Ue(t.site),ol.insert(l,e),l.edge=e.edge=Ke(t.site,l.site),$e(t),void $e(e);if(!e)return void(l.edge=Ke(t.site,l.site));Be(t),Be(e);var c=t.site,f=c.x,s=c.y,h=n.x-f,p=n.y-s,g=e.site,v=g.x-f,d=g.y-s,y=2*(h*d-p*v),m=h*h+p*p,M=v*v+d*d,x={x:(d*m-p*M)/y+f,y:(h*M-v*m)/y+s};nr(e.edge,c,g,x),l.edge=Ke(c,n,null,x),e.edge=Ke(n,g,null,x),$e(t),$e(e)}}function Oe(n,t){var e=n.site,r=e.x,i=e.y,u=i-t;if(!u)return r;var o=n.P;if(!o)return-(1/0);e=o.site;var a=e.x,l=e.y,c=l-t;if(!c)return a;var f=a-r,s=1/u-1/c,h=f/c;return s?(-h+Math.sqrt(h*h-2*s*(f*f/(-2*c)-l+c/2+i-u/2)))/s+r:(r+a)/2}function Ie(n,t){var e=n.N;if(e)return Oe(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ye(n){this.site=n,this.edges=[]}function Ze(n){for(var t,e,r,i,u,o,a,l,c,f,s=n[0][0],h=n[1][0],p=n[0][1],g=n[1][1],v=ul,d=v.length;d--;)if(u=v[d],u&&u.prepare())for(a=u.edges,l=a.length,o=0;l>o;)f=a[o].end(),r=f.x,i=f.y,c=a[++o%l].start(),t=c.x,e=c.y,(xo(r-t)>Uo||xo(i-e)>Uo)&&(a.splice(o,0,new tr(Qe(u.site,f,xo(r-s)<Uo&&g-i>Uo?{x:s,y:xo(t-s)<Uo?e:g}:xo(i-g)<Uo&&h-r>Uo?{x:xo(e-g)<Uo?t:h,y:g}:xo(r-h)<Uo&&i-p>Uo?{x:h,y:xo(t-h)<Uo?e:p}:xo(i-p)<Uo&&r-s>Uo?{x:xo(e-p)<Uo?t:s,y:p}:null),u.site,null)),++l)}function Ve(n,t){return t.angle-n.angle}function Xe(){rr(this),this.x=this.y=this.arc=this.site=this.cy=null}function $e(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,i=n.site,u=e.site;if(r!==u){var o=i.x,a=i.y,l=r.x-o,c=r.y-a,f=u.x-o,s=u.y-a,h=2*(l*s-c*f);if(!(h>=-jo)){var p=l*l+c*c,g=f*f+s*s,v=(s*p-c*g)/h,d=(l*g-f*p)/h,s=d+a,y=fl.pop()||new Xe;y.arc=n,y.site=i,y.x=v+o,y.y=s+Math.sqrt(v*v+d*d),y.cy=s,n.circle=y;for(var m=null,M=ll._;M;)if(y.y<M.y||y.y===M.y&&y.x<=M.x){if(!M.L){m=M.P;break}M=M.L}else{if(!M.R){m=M;break}M=M.R}ll.insert(m,y),m||(al=y)}}}}function Be(n){var t=n.circle;t&&(t.P||(al=t.N),ll.remove(t),fl.push(t),rr(t),n.circle=null)}function We(n){for(var t,e=il,r=Yt(n[0][0],n[0][1],n[1][0],n[1][1]),i=e.length;i--;)t=e[i],(!Je(t,n)||!r(t)||xo(t.a.x-t.b.x)<Uo&&xo(t.a.y-t.b.y)<Uo)&&(t.a=t.b=null,e.splice(i,1))}function Je(n,t){var e=n.b;if(e)return!0;var r,i,u=n.a,o=t[0][0],a=t[1][0],l=t[0][1],c=t[1][1],f=n.l,s=n.r,h=f.x,p=f.y,g=s.x,v=s.y,d=(h+g)/2,y=(p+v)/2;if(v===p){if(o>d||d>=a)return;if(h>g){if(u){if(u.y>=c)return}else u={x:d,y:l};e={x:d,y:c}}else{if(u){if(u.y<l)return}else u={x:d,y:c};e={x:d,y:l}}}else if(r=(h-g)/(v-p),i=y-r*d,-1>r||r>1)if(h>g){if(u){if(u.y>=c)return}else u={x:(l-i)/r,y:l};e={x:(c-i)/r,y:c}}else{if(u){if(u.y<l)return}else u={x:(c-i)/r,y:c};e={x:(l-i)/r,y:l}}else if(v>p){if(u){if(u.x>=a)return}else u={x:o,y:r*o+i};e={x:a,y:r*a+i}}else{if(u){if(u.x<o)return}else u={x:a,y:r*a+i};e={x:o,y:r*o+i}}return n.a=u,n.b=e,!0}function Ge(n,t){this.l=n,this.r=t,this.a=this.b=null}function Ke(n,t,e,r){var i=new Ge(n,t);return il.push(i),e&&nr(i,n,t,e),r&&nr(i,t,n,r),ul[n.i].edges.push(new tr(i,n,t)),ul[t.i].edges.push(new tr(i,t,n)),i}function Qe(n,t,e){var r=new Ge(n,null);return r.a=t,r.b=e,il.push(r),r}function nr(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function tr(n,t,e){var r=n.a,i=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(i.x-r.x,r.y-i.y):Math.atan2(r.x-i.x,i.y-r.y)}function er(){this._=null}function rr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function ir(n,t){var e=t,r=t.R,i=e.U;i?i.L===e?i.L=r:i.R=r:n._=r,r.U=i,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function ur(n,t){var e=t,r=t.L,i=e.U;i?i.L===e?i.L=r:i.R=r:n._=r,r.U=i,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function or(n){for(;n.L;)n=n.L;return n}function ar(n,t){var e,r,i,u=n.sort(lr).pop();for(il=[],ul=new Array(n.length),ol=new er,ll=new er;;)if(i=al,u&&(!i||u.y<i.y||u.y===i.y&&u.x<i.x))u.x===e&&u.y===r||(ul[u.i]=new Ye(u),He(u),e=u.x,r=u.y),u=n.pop();else{if(!i)break;Fe(i.arc)}t&&(We(t),Ze(t));var o={cells:ul,edges:il};return ol=ll=il=ul=null,o}function lr(n,t){return t.y-n.y||t.x-n.x}function cr(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function fr(n){return n.x}function sr(n){return n.y}function hr(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function pr(n,t,e,r,i,u){if(!n(t,e,r,i,u)){var o=.5*(e+i),a=.5*(r+u),l=t.nodes;l[0]&&pr(n,l[0],e,r,o,a),l[1]&&pr(n,l[1],o,r,i,a),l[2]&&pr(n,l[2],e,a,o,u),l[3]&&pr(n,l[3],o,a,i,u)}}function gr(n,t,e,r,i,u,o){var a,l=1/0;return function c(n,f,s,h,p){if(!(f>u||s>o||r>h||i>p)){if(g=n.point){var g,v=t-n.x,d=e-n.y,y=v*v+d*d;if(l>y){var m=Math.sqrt(l=y);r=t-m,i=e-m,u=t+m,o=e+m,a=g}}for(var M=n.nodes,x=.5*(f+h),b=.5*(s+p),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:c(n,f,s,x,b);break;case 1:c(n,x,s,h,b);break;case 2:c(n,f,b,x,p);break;case 3:c(n,x,b,h,p)}}}(n,r,i,u,o),a}function vr(n,t){n=ao.rgb(n),t=ao.rgb(t);var e=n.r,r=n.g,i=n.b,u=t.r-e,o=t.g-r,a=t.b-i;return function(n){return"#"+bn(Math.round(e+u*n))+bn(Math.round(r+o*n))+bn(Math.round(i+a*n))}}function dr(n,t){var e,r={},i={};for(e in n)e in t?r[e]=Mr(n[e],t[e]):i[e]=n[e];for(e in t)e in n||(i[e]=t[e]);return function(n){for(e in r)i[e]=r[e](n);return i}}function yr(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function mr(n,t){var e,r,i,u=hl.lastIndex=pl.lastIndex=0,o=-1,a=[],l=[];for(n+="",t+="";(e=hl.exec(n))&&(r=pl.exec(t));)(i=r.index)>u&&(i=t.slice(u,i),a[o]?a[o]+=i:a[++o]=i),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,l.push({i:o,x:yr(e,r)})),u=pl.lastIndex;return u<t.length&&(i=t.slice(u),a[o]?a[o]+=i:a[++o]=i),a.length<2?l[0]?(t=l[0].x,function(n){return t(n)+""}):function(){return t}:(t=l.length,function(n){for(var e,r=0;t>r;++r)a[(e=l[r]).i]=e.x(n);return a.join("")})}function Mr(n,t){for(var e,r=ao.interpolators.length;--r>=0&&!(e=ao.interpolators[r](n,t)););return e}function xr(n,t){var e,r=[],i=[],u=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(Mr(n[e],t[e]));for(;u>e;++e)i[e]=n[e];for(;o>e;++e)i[e]=t[e];return function(n){for(e=0;a>e;++e)i[e]=r[e](n);return i}}function br(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function _r(n){return function(t){return 1-n(1-t)}}function wr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function Sr(n){return n*n}function kr(n){return n*n*n}function Nr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Er(n){return function(t){return Math.pow(t,n)}}function Ar(n){return 1-Math.cos(n*Io)}function Cr(n){return Math.pow(2,10*(n-1))}function zr(n){return 1-Math.sqrt(1-n*n)}function Lr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Ho*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Ho/t)}}function qr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Tr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Rr(n,t){n=ao.hcl(n),t=ao.hcl(t);var e=n.h,r=n.c,i=n.l,u=t.h-e,o=t.c-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return sn(e+u*n,r+o*n,i+a*n)+""}}function Dr(n,t){n=ao.hsl(n),t=ao.hsl(t);var e=n.h,r=n.s,i=n.l,u=t.h-e,o=t.s-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return cn(e+u*n,r+o*n,i+a*n)+""}}function Pr(n,t){n=ao.lab(n),t=ao.lab(t);var e=n.l,r=n.a,i=n.b,u=t.l-e,o=t.a-r,a=t.b-i;return function(n){return pn(e+u*n,r+o*n,i+a*n)+""}}function Ur(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function jr(n){var t=[n.a,n.b],e=[n.c,n.d],r=Hr(t),i=Fr(t,e),u=Hr(Or(e,t,-i))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,i*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Zo,this.translate=[n.e,n.f],this.scale=[r,u],this.skew=u?Math.atan2(i,u)*Zo:0}function Fr(n,t){return n[0]*t[0]+n[1]*t[1]}function Hr(n){var t=Math.sqrt(Fr(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Or(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Ir(n){return n.length?n.pop()+",":""}function Yr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push("translate(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else(t[0]||t[1])&&e.push("translate("+t+")")}function Zr(n,t,e,r){n!==t?(n-t>180?t+=360:t-n>180&&(n+=360),r.push({i:e.push(Ir(e)+"rotate(",null,")")-2,x:yr(n,t)})):t&&e.push(Ir(e)+"rotate("+t+")")}function Vr(n,t,e,r){n!==t?r.push({i:e.push(Ir(e)+"skewX(",null,")")-2,x:yr(n,t)}):t&&e.push(Ir(e)+"skewX("+t+")")}function Xr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push(Ir(e)+"scale(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else 1===t[0]&&1===t[1]||e.push(Ir(e)+"scale("+t+")")}function $r(n,t){var e=[],r=[];return n=ao.transform(n),t=ao.transform(t),Yr(n.translate,t.translate,e,r),Zr(n.rotate,t.rotate,e,r),Vr(n.skew,t.skew,e,r),Xr(n.scale,t.scale,e,r),n=t=null,function(n){for(var t,i=-1,u=r.length;++i<u;)e[(t=r[i]).i]=t.x(n);return e.join("")}}function Br(n,t){return t=(t-=n=+n)||1/t,function(e){return(e-n)/t}}function Wr(n,t){return t=(t-=n=+n)||1/t,function(e){return Math.max(0,Math.min(1,(e-n)/t))}}function Jr(n){for(var t=n.source,e=n.target,r=Kr(t,e),i=[t];t!==r;)t=t.parent,i.push(t);for(var u=i.length;e!==r;)i.splice(u,0,e),e=e.parent;return i}function Gr(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Kr(n,t){if(n===t)return n;for(var e=Gr(n),r=Gr(t),i=e.pop(),u=r.pop(),o=null;i===u;)o=i,i=e.pop(),u=r.pop();return o}function Qr(n){n.fixed|=2}function ni(n){n.fixed&=-7}function ti(n){n.fixed|=4,n.px=n.x,n.py=n.y}function ei(n){n.fixed&=-5}function ri(n,t,e){var r=0,i=0;if(n.charge=0,!n.leaf)for(var u,o=n.nodes,a=o.length,l=-1;++l<a;)u=o[l],null!=u&&(ri(u,t,e),n.charge+=u.charge,r+=u.charge*u.cx,i+=u.charge*u.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var c=t*e[n.point.index];n.charge+=n.pointCharge=c,r+=c*n.point.x,i+=c*n.point.y}n.cx=r/n.charge,n.cy=i/n.charge}function ii(n,t){return ao.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=fi,n}function ui(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(i=n.children)&&(r=i.length))for(var r,i;--r>=0;)e.push(i[r])}function oi(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(u=n.children)&&(i=u.length))for(var i,u,o=-1;++o<i;)e.push(u[o]);for(;null!=(n=r.pop());)t(n)}function ai(n){return n.children}function li(n){return n.value}function ci(n,t){return t.value-n.value}function fi(n){return ao.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function si(n){return n.x}function hi(n){return n.y}function pi(n,t,e){n.y0=t,n.y=e}function gi(n){return ao.range(n.length)}function vi(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function di(n){for(var t,e=1,r=0,i=n[0][1],u=n.length;u>e;++e)(t=n[e][1])>i&&(r=e,i=t);return r}function yi(n){return n.reduce(mi,0)}function mi(n,t){return n+t[1]}function Mi(n,t){return xi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function xi(n,t){for(var e=-1,r=+n[0],i=(n[1]-r)/t,u=[];++e<=t;)u[e]=i*e+r;return u}function bi(n){return[ao.min(n),ao.max(n)]}function _i(n,t){return n.value-t.value}function wi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Si(n,t){n._pack_next=t,t._pack_prev=n}function ki(n,t){var e=t.x-n.x,r=t.y-n.y,i=n.r+t.r;return.999*i*i>e*e+r*r}function Ni(n){function t(n){f=Math.min(n.x-n.r,f),s=Math.max(n.x+n.r,s),h=Math.min(n.y-n.r,h),p=Math.max(n.y+n.r,p)}if((e=n.children)&&(c=e.length)){var e,r,i,u,o,a,l,c,f=1/0,s=-(1/0),h=1/0,p=-(1/0);if(e.forEach(Ei),r=e[0],r.x=-r.r,r.y=0,t(r),c>1&&(i=e[1],i.x=i.r,i.y=0,t(i),c>2))for(u=e[2],zi(r,i,u),t(u),wi(r,u),r._pack_prev=u,wi(u,i),i=r._pack_next,o=3;c>o;o++){zi(r,i,u=e[o]);var g=0,v=1,d=1;for(a=i._pack_next;a!==i;a=a._pack_next,v++)if(ki(a,u)){g=1;break}if(1==g)for(l=r._pack_prev;l!==a._pack_prev&&!ki(l,u);l=l._pack_prev,d++);g?(d>v||v==d&&i.r<r.r?Si(r,i=a):Si(r=l,i),o--):(wi(r,u),i=u,t(u))}var y=(f+s)/2,m=(h+p)/2,M=0;for(o=0;c>o;o++)u=e[o],u.x-=y,u.y-=m,M=Math.max(M,u.r+Math.sqrt(u.x*u.x+u.y*u.y));n.r=M,e.forEach(Ai)}}function Ei(n){n._pack_next=n._pack_prev=n}function Ai(n){delete n._pack_next,delete n._pack_prev}function Ci(n,t,e,r){var i=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,i)for(var u=-1,o=i.length;++u<o;)Ci(i[u],t,e,r)}function zi(n,t,e){var r=n.r+e.r,i=t.x-n.x,u=t.y-n.y;if(r&&(i||u)){var o=t.r+e.r,a=i*i+u*u;o*=o,r*=r;var l=.5+(r-o)/(2*a),c=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+l*i+c*u,e.y=n.y+l*u-c*i}else e.x=n.x+r,e.y=n.y}function Li(n,t){return n.parent==t.parent?1:2}function qi(n){var t=n.children;return t.length?t[0]:n.t}function Ti(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function Ri(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function Di(n){for(var t,e=0,r=0,i=n.children,u=i.length;--u>=0;)t=i[u],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Pi(n,t,e){return n.a.parent===t.parent?n.a:e}function Ui(n){return 1+ao.max(n,function(n){return n.y})}function ji(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Fi(n){var t=n.children;return t&&t.length?Fi(t[0]):n}function Hi(n){var t,e=n.children;return e&&(t=e.length)?Hi(e[t-1]):n}function Oi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Ii(n,t){var e=n.x+t[3],r=n.y+t[0],i=n.dx-t[1]-t[3],u=n.dy-t[0]-t[2];return 0>i&&(e+=i/2,i=0),0>u&&(r+=u/2,u=0),{x:e,y:r,dx:i,dy:u}}function Yi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Zi(n){return n.rangeExtent?n.rangeExtent():Yi(n.range())}function Vi(n,t,e,r){var i=e(n[0],n[1]),u=r(t[0],t[1]);return function(n){return u(i(n))}}function Xi(n,t){var e,r=0,i=n.length-1,u=n[r],o=n[i];return u>o&&(e=r,r=i,i=e,e=u,u=o,o=e),n[r]=t.floor(u),n[i]=t.ceil(o),n}function $i(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:Sl}function Bi(n,t,e,r){var i=[],u=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)i.push(e(n[o-1],n[o])),u.push(r(t[o-1],t[o]));return function(t){var e=ao.bisect(n,t,1,a)-1;return u[e](i[e](t))}}function Wi(n,t,e,r){function i(){var i=Math.min(n.length,t.length)>2?Bi:Vi,l=r?Wr:Br;return o=i(n,t,l,e),a=i(t,n,l,Mr),u}function u(n){return o(n)}var o,a;return u.invert=function(n){return a(n)},u.domain=function(t){return arguments.length?(n=t.map(Number),i()):n},u.range=function(n){return arguments.length?(t=n,i()):t},u.rangeRound=function(n){return u.range(n).interpolate(Ur)},u.clamp=function(n){return arguments.length?(r=n,i()):r},u.interpolate=function(n){return arguments.length?(e=n,i()):e},u.ticks=function(t){return Qi(n,t)},u.tickFormat=function(t,e){return nu(n,t,e)},u.nice=function(t){return Gi(n,t),i()},u.copy=function(){return Wi(n,t,e,r)},i()}function Ji(n,t){return ao.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Gi(n,t){return Xi(n,$i(Ki(n,t)[2])),Xi(n,$i(Ki(n,t)[2])),n}function Ki(n,t){null==t&&(t=10);var e=Yi(n),r=e[1]-e[0],i=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),u=t/r*i;return.15>=u?i*=10:.35>=u?i*=5:.75>=u&&(i*=2),e[0]=Math.ceil(e[0]/i)*i,e[1]=Math.floor(e[1]/i)*i+.5*i,e[2]=i,e}function Qi(n,t){return ao.range.apply(ao,Ki(n,t))}function nu(n,t,e){var r=Ki(n,t);if(e){var i=ha.exec(e);if(i.shift(),"s"===i[8]){var u=ao.formatPrefix(Math.max(xo(r[0]),xo(r[1])));return i[7]||(i[7]="."+tu(u.scale(r[2]))),i[8]="f",e=ao.format(i.join("")),function(n){return e(u.scale(n))+u.symbol}}i[7]||(i[7]="."+eu(i[8],r)),e=i.join("")}else e=",."+tu(r[2])+"f";return ao.format(e)}function tu(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function eu(n,t){var e=tu(t[2]);return n in kl?Math.abs(e-tu(Math.max(xo(t[0]),xo(t[1]))))+ +("e"!==n):e-2*("%"===n)}function ru(n,t,e,r){function i(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function u(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(i(t))}return o.invert=function(t){return u(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(i)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(i)),o):t},o.nice=function(){var t=Xi(r.map(i),e?Math:El);return n.domain(t),r=t.map(u),o},o.ticks=function(){var n=Yi(r),o=[],a=n[0],l=n[1],c=Math.floor(i(a)),f=Math.ceil(i(l)),s=t%1?2:t;if(isFinite(f-c)){if(e){for(;f>c;c++)for(var h=1;s>h;h++)o.push(u(c)*h);o.push(u(c))}else for(o.push(u(c));c++<f;)for(var h=s-1;h>0;h--)o.push(u(c)*h);for(c=0;o[c]<a;c++);for(f=o.length;o[f-1]>l;f--);o=o.slice(c,f)}return o},o.tickFormat=function(n,e){if(!arguments.length)return Nl;arguments.length<2?e=Nl:"function"!=typeof e&&(e=ao.format(e));var r=Math.max(1,t*n/o.ticks().length);return function(n){var o=n/u(Math.round(i(n)));return t-.5>o*t&&(o*=t),r>=o?e(n):""}},o.copy=function(){return ru(n.copy(),t,e,r)},Ji(o,n)}function iu(n,t,e){function r(t){return n(i(t))}var i=uu(t),u=uu(1/t);return r.invert=function(t){return u(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(i)),r):e},r.ticks=function(n){return Qi(e,n)},r.tickFormat=function(n,t){return nu(e,n,t)},r.nice=function(n){return r.domain(Gi(e,n))},r.exponent=function(o){return arguments.length?(i=uu(t=o),u=uu(1/t),n.domain(e.map(i)),r):t},r.copy=function(){return iu(n.copy(),t,e)},Ji(r,n)}function uu(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function ou(n,t){function e(e){return u[((i.get(e)||("range"===t.t?i.set(e,n.push(e)):NaN))-1)%u.length]}function r(t,e){return ao.range(n.length).map(function(n){return t+e*n})}var i,u,o;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new c;for(var u,o=-1,a=r.length;++o<a;)i.has(u=r[o])||i.set(u,n.push(u));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(u=n,o=0,t={t:"range",a:arguments},e):u},e.rangePoints=function(i,a){arguments.length<2&&(a=0);var l=i[0],c=i[1],f=n.length<2?(l=(l+c)/2,0):(c-l)/(n.length-1+a);return u=r(l+f*a/2,f),o=0,t={t:"rangePoints",a:arguments},e},e.rangeRoundPoints=function(i,a){arguments.length<2&&(a=0);var l=i[0],c=i[1],f=n.length<2?(l=c=Math.round((l+c)/2),0):(c-l)/(n.length-1+a)|0;return u=r(l+Math.round(f*a/2+(c-l-(n.length-1+a)*f)/2),f),o=0,t={t:"rangeRoundPoints",a:arguments},e},e.rangeBands=function(i,a,l){arguments.length<2&&(a=0),arguments.length<3&&(l=a);var c=i[1]<i[0],f=i[c-0],s=i[1-c],h=(s-f)/(n.length-a+2*l);return u=r(f+h*l,h),c&&u.reverse(),o=h*(1-a),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(i,a,l){arguments.length<2&&(a=0),arguments.length<3&&(l=a);var c=i[1]<i[0],f=i[c-0],s=i[1-c],h=Math.floor((s-f)/(n.length-a+2*l));return u=r(f+Math.round((s-f-(n.length-a)*h)/2),h),c&&u.reverse(),o=Math.round(h*(1-a)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return o},e.rangeExtent=function(){return Yi(t.a[0])},e.copy=function(){return ou(n,t)},e.domain(n)}function au(n,t){function u(){var e=0,r=t.length;for(a=[];++e<r;)a[e-1]=ao.quantile(n,e/r);return o}function o(n){return isNaN(n=+n)?void 0:t[ao.bisect(a,n)]}var a;return o.domain=function(t){return arguments.length?(n=t.map(r).filter(i).sort(e),u()):n},o.range=function(n){return arguments.length?(t=n,u()):t},o.quantiles=function(){return a},o.invertExtent=function(e){return e=t.indexOf(e),0>e?[NaN,NaN]:[e>0?a[e-1]:n[0],e<a.length?a[e]:n[n.length-1]]},o.copy=function(){return au(n,t)},u()}function lu(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(u*(t-n))))]}function i(){return u=e.length/(t-n),o=e.length-1,r}var u,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],i()):[n,t]},r.range=function(n){return arguments.length?(e=n,i()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?NaN:t/u+n,[t,t+1/u]},r.copy=function(){return lu(n,t,e)},i()}function cu(n,t){function e(e){return e>=e?t[ao.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return cu(n,t)},e}function fu(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Qi(n,t)},t.tickFormat=function(t,e){return nu(n,t,e)},t.copy=function(){return fu(n)},t}function su(){return 0}function hu(n){return n.innerRadius}function pu(n){return n.outerRadius}function gu(n){return n.startAngle}function vu(n){return n.endAngle}function du(n){return n&&n.padAngle}function yu(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function mu(n,t,e,r,i){var u=n[0]-t[0],o=n[1]-t[1],a=(i?r:-r)/Math.sqrt(u*u+o*o),l=a*o,c=-a*u,f=n[0]+l,s=n[1]+c,h=t[0]+l,p=t[1]+c,g=(f+h)/2,v=(s+p)/2,d=h-f,y=p-s,m=d*d+y*y,M=e-r,x=f*p-h*s,b=(0>y?-1:1)*Math.sqrt(Math.max(0,M*M*m-x*x)),_=(x*y-d*b)/m,w=(-x*d-y*b)/m,S=(x*y+d*b)/m,k=(-x*d+y*b)/m,N=_-g,E=w-v,A=S-g,C=k-v;return N*N+E*E>A*A+C*C&&(_=S,w=k),[[_-l,w-c],[_*e/M,w*e/M]]}function Mu(n){function t(t){function o(){c.push("M",u(n(f),a))}for(var l,c=[],f=[],s=-1,h=t.length,p=En(e),g=En(r);++s<h;)i.call(this,l=t[s],s)?f.push([+p.call(this,l,s),+g.call(this,l,s)]):f.length&&(o(),f=[]);return f.length&&o(),c.length?c.join(""):null}var e=Ce,r=ze,i=zt,u=xu,o=u.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(i=n,t):i},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?u=n:(u=Tl.get(n)||xu).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function xu(n){return n.length>1?n.join("L"):n+"Z"}function bu(n){return n.join("L")+"Z"}function _u(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&i.push("H",r[0]),i.join("")}function wu(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("V",(r=n[t])[1],"H",r[0]);return i.join("")}function Su(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t<e;)i.push("H",(r=n[t])[0],"V",r[1]);return i.join("")}function ku(n,t){return n.length<4?xu(n):n[1]+Au(n.slice(1,-1),Cu(n,t))}function Nu(n,t){return n.length<3?bu(n):n[0]+Au((n.push(n[0]),n),Cu([n[n.length-2]].concat(n,[n[1]]),t))}function Eu(n,t){return n.length<3?xu(n):n[0]+Au(n,Cu(n,t))}function Au(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return xu(n);var e=n.length!=t.length,r="",i=n[0],u=n[1],o=t[0],a=o,l=1;if(e&&(r+="Q"+(u[0]-2*o[0]/3)+","+(u[1]-2*o[1]/3)+","+u[0]+","+u[1],i=n[1],l=2),t.length>1){a=t[1],u=n[l],l++,r+="C"+(i[0]+o[0])+","+(i[1]+o[1])+","+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1];for(var c=2;c<t.length;c++,l++)u=n[l],a=t[c],r+="S"+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1]}if(e){var f=n[l];r+="Q"+(u[0]+2*a[0]/3)+","+(u[1]+2*a[1]/3)+","+f[0]+","+f[1]}return r}function Cu(n,t){for(var e,r=[],i=(1-t)/2,u=n[0],o=n[1],a=1,l=n.length;++a<l;)e=u,u=o,o=n[a],r.push([i*(o[0]-e[0]),i*(o[1]-e[1])]);return r}function zu(n){if(n.length<3)return xu(n);var t=1,e=n.length,r=n[0],i=r[0],u=r[1],o=[i,i,i,(r=n[1])[0]],a=[u,u,u,r[1]],l=[i,",",u,"L",Ru(Pl,o),",",Ru(Pl,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Du(l,o,a);return n.pop(),l.push("L",r),l.join("")}function Lu(n){if(n.length<4)return xu(n);for(var t,e=[],r=-1,i=n.length,u=[0],o=[0];++r<3;)t=n[r],u.push(t[0]),o.push(t[1]);for(e.push(Ru(Pl,u)+","+Ru(Pl,o)),--r;++r<i;)t=n[r],u.shift(),u.push(t[0]),o.shift(),o.push(t[1]),Du(e,u,o);return e.join("")}function qu(n){for(var t,e,r=-1,i=n.length,u=i+4,o=[],a=[];++r<4;)e=n[r%i],o.push(e[0]),a.push(e[1]);for(t=[Ru(Pl,o),",",Ru(Pl,a)],--r;++r<u;)e=n[r%i],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Du(t,o,a);return t.join("")}function Tu(n,t){var e=n.length-1;if(e)for(var r,i,u=n[0][0],o=n[0][1],a=n[e][0]-u,l=n[e][1]-o,c=-1;++c<=e;)r=n[c],i=c/e,r[0]=t*r[0]+(1-t)*(u+i*a),r[1]=t*r[1]+(1-t)*(o+i*l);return zu(n)}function Ru(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Du(n,t,e){n.push("C",Ru(Rl,t),",",Ru(Rl,e),",",Ru(Dl,t),",",Ru(Dl,e),",",Ru(Pl,t),",",Ru(Pl,e))}function Pu(n,t){return(t[1]-n[1])/(t[0]-n[0])}function Uu(n){for(var t=0,e=n.length-1,r=[],i=n[0],u=n[1],o=r[0]=Pu(i,u);++t<e;)r[t]=(o+(o=Pu(i=u,u=n[t+1])))/2;return r[t]=o,r}function ju(n){for(var t,e,r,i,u=[],o=Uu(n),a=-1,l=n.length-1;++a<l;)t=Pu(n[a],n[a+1]),xo(t)<Uo?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,i=e*e+r*r,i>9&&(i=3*t/Math.sqrt(i),o[a]=i*e,o[a+1]=i*r));for(a=-1;++a<=l;)i=(n[Math.min(l,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),u.push([i||0,o[a]*i||0]);return u}function Fu(n){return n.length<3?xu(n):n[0]+Au(n,ju(n))}function Hu(n){for(var t,e,r,i=-1,u=n.length;++i<u;)t=n[i],e=t[0],r=t[1]-Io,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Ou(n){function t(t){function l(){v.push("M",a(n(y),s),f,c(n(d.reverse()),s),"Z")}for(var h,p,g,v=[],d=[],y=[],m=-1,M=t.length,x=En(e),b=En(i),_=e===r?function(){
+return p}:En(r),w=i===u?function(){return g}:En(u);++m<M;)o.call(this,h=t[m],m)?(d.push([p=+x.call(this,h,m),g=+b.call(this,h,m)]),y.push([+_.call(this,h,m),+w.call(this,h,m)])):d.length&&(l(),d=[],y=[]);return d.length&&l(),v.length?v.join(""):null}var e=Ce,r=Ce,i=0,u=ze,o=zt,a=xu,l=a.key,c=a,f="L",s=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(i=u=n,t):u},t.y0=function(n){return arguments.length?(i=n,t):i},t.y1=function(n){return arguments.length?(u=n,t):u},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(l="function"==typeof n?a=n:(a=Tl.get(n)||xu).key,c=a.reverse||a,f=a.closed?"M":"L",t):l},t.tension=function(n){return arguments.length?(s=n,t):s},t}function Iu(n){return n.radius}function Yu(n){return[n.x,n.y]}function Zu(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]-Io;return[e*Math.cos(r),e*Math.sin(r)]}}function Vu(){return 64}function Xu(){return"circle"}function $u(n){var t=Math.sqrt(n/Fo);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Bu(n){return function(){var t,e,r;(t=this[n])&&(r=t[e=t.active])&&(r.timer.c=null,r.timer.t=NaN,--t.count?delete t[e]:delete this[n],t.active+=.5,r.event&&r.event.interrupt.call(this,this.__data__,r.index))}}function Wu(n,t,e){return ko(n,Yl),n.namespace=t,n.id=e,n}function Ju(n,t,e,r){var i=n.id,u=n.namespace;return Y(n,"function"==typeof e?function(n,o,a){n[u][i].tween.set(t,r(e.call(n,n.__data__,o,a)))}:(e=r(e),function(n){n[u][i].tween.set(t,e)}))}function Gu(n){return null==n&&(n=""),function(){this.textContent=n}}function Ku(n){return null==n?"__transition__":"__transition_"+n+"__"}function Qu(n,t,e,r,i){function u(n){var t=v.delay;return f.t=t+l,n>=t?o(n-t):void(f.c=o)}function o(e){var i=g.active,u=g[i];u&&(u.timer.c=null,u.timer.t=NaN,--g.count,delete g[i],u.event&&u.event.interrupt.call(n,n.__data__,u.index));for(var o in g)if(r>+o){var c=g[o];c.timer.c=null,c.timer.t=NaN,--g.count,delete g[o]}f.c=a,qn(function(){return f.c&&a(e||1)&&(f.c=null,f.t=NaN),1},0,l),g.active=r,v.event&&v.event.start.call(n,n.__data__,t),p=[],v.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&p.push(r)}),h=v.ease,s=v.duration}function a(i){for(var u=i/s,o=h(u),a=p.length;a>0;)p[--a].call(n,o);return u>=1?(v.event&&v.event.end.call(n,n.__data__,t),--g.count?delete g[r]:delete n[e],1):void 0}var l,f,s,h,p,g=n[e]||(n[e]={active:0,count:0}),v=g[r];v||(l=i.time,f=qn(u,0,l),v=g[r]={tween:new c,time:l,timer:f,delay:i.delay,duration:i.duration,ease:i.ease,index:t},i=null,++g.count)}function no(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function to(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function eo(n){return n.toISOString()}function ro(n,t,e){function r(t){return n(t)}function i(n,e){var r=n[1]-n[0],i=r/e,u=ao.bisect(Kl,i);return u==Kl.length?[t.year,Ki(n.map(function(n){return n/31536e6}),e)[2]]:u?t[i/Kl[u-1]<Kl[u]/i?u-1:u]:[tc,Ki(n,e)[2]]}return r.invert=function(t){return io(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(io)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,io(+e+1),t).length}var u=r.domain(),o=Yi(u),a=null==n?i(o,10):"number"==typeof n&&i(o,n);return a&&(n=a[0],t=a[1]),r.domain(Xi(u,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Yi(r.domain()),u=null==n?i(e,10):"number"==typeof n?i(e,n):!n.range&&[{range:n},t];return u&&(n=u[0],t=u[1]),n.range(e[0],io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return ro(n.copy(),t,e)},Ji(r,n)}function io(n){return new Date(n)}function uo(n){return JSON.parse(n.responseText)}function oo(n){var t=fo.createRange();return t.selectNode(fo.body),t.createContextualFragment(n.responseText)}var ao={version:"3.5.17"},lo=[].slice,co=function(n){return lo.call(n)},fo=this.document;if(fo)try{co(fo.documentElement.childNodes)[0].nodeType}catch(so){co=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),fo)try{fo.createElement("DIV").style.setProperty("opacity",0,"")}catch(ho){var po=this.Element.prototype,go=po.setAttribute,vo=po.setAttributeNS,yo=this.CSSStyleDeclaration.prototype,mo=yo.setProperty;po.setAttribute=function(n,t){go.call(this,n,t+"")},po.setAttributeNS=function(n,t,e){vo.call(this,n,t,e+"")},yo.setProperty=function(n,t,e){mo.call(this,n,t+"",e)}}ao.ascending=e,ao.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:NaN},ao.min=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i<u;)if(null!=(r=n[i])&&r>=r){e=r;break}for(;++i<u;)null!=(r=n[i])&&e>r&&(e=r)}else{for(;++i<u;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=r;break}for(;++i<u;)null!=(r=t.call(n,n[i],i))&&e>r&&(e=r)}return e},ao.max=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i<u;)if(null!=(r=n[i])&&r>=r){e=r;break}for(;++i<u;)null!=(r=n[i])&&r>e&&(e=r)}else{for(;++i<u;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=r;break}for(;++i<u;)null!=(r=t.call(n,n[i],i))&&r>e&&(e=r)}return e},ao.extent=function(n,t){var e,r,i,u=-1,o=n.length;if(1===arguments.length){for(;++u<o;)if(null!=(r=n[u])&&r>=r){e=i=r;break}for(;++u<o;)null!=(r=n[u])&&(e>r&&(e=r),r>i&&(i=r))}else{for(;++u<o;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=i=r;break}for(;++u<o;)null!=(r=t.call(n,n[u],u))&&(e>r&&(e=r),r>i&&(i=r))}return[e,i]},ao.sum=function(n,t){var e,r=0,u=n.length,o=-1;if(1===arguments.length)for(;++o<u;)i(e=+n[o])&&(r+=e);else for(;++o<u;)i(e=+t.call(n,n[o],o))&&(r+=e);return r},ao.mean=function(n,t){var e,u=0,o=n.length,a=-1,l=o;if(1===arguments.length)for(;++a<o;)i(e=r(n[a]))?u+=e:--l;else for(;++a<o;)i(e=r(t.call(n,n[a],a)))?u+=e:--l;return l?u/l:void 0},ao.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),i=+n[r-1],u=e-r;return u?i+u*(n[r]-i):i},ao.median=function(n,t){var u,o=[],a=n.length,l=-1;if(1===arguments.length)for(;++l<a;)i(u=r(n[l]))&&o.push(u);else for(;++l<a;)i(u=r(t.call(n,n[l],l)))&&o.push(u);return o.length?ao.quantile(o.sort(e),.5):void 0},ao.variance=function(n,t){var e,u,o=n.length,a=0,l=0,c=-1,f=0;if(1===arguments.length)for(;++c<o;)i(e=r(n[c]))&&(u=e-a,a+=u/++f,l+=u*(e-a));else for(;++c<o;)i(e=r(t.call(n,n[c],c)))&&(u=e-a,a+=u/++f,l+=u*(e-a));return f>1?l/(f-1):void 0},ao.deviation=function(){var n=ao.variance.apply(this,arguments);return n?Math.sqrt(n):n};var Mo=u(e);ao.bisectLeft=Mo.left,ao.bisect=ao.bisectRight=Mo.right,ao.bisector=function(n){return u(1===n.length?function(t,r){return e(n(t),r)}:n)},ao.shuffle=function(n,t,e){(u=arguments.length)<3&&(e=n.length,2>u&&(t=0));for(var r,i,u=e-t;u;)i=Math.random()*u--|0,r=n[u+t],n[u+t]=n[i+t],n[i+t]=r;return n},ao.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ao.pairs=function(n){for(var t,e=0,r=n.length-1,i=n[0],u=new Array(0>r?0:r);r>e;)u[e]=[t=i,i=n[++e]];return u},ao.transpose=function(n){if(!(i=n.length))return[];for(var t=-1,e=ao.min(n,o),r=new Array(e);++t<e;)for(var i,u=-1,a=r[t]=new Array(i);++u<i;)a[u]=n[u][t];return r},ao.zip=function(){return ao.transpose(arguments)},ao.keys=function(n){var t=[];for(var e in n)t.push(e);return t},ao.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},ao.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},ao.merge=function(n){for(var t,e,r,i=n.length,u=-1,o=0;++u<i;)o+=n[u].length;for(e=new Array(o);--i>=0;)for(r=n[i],t=r.length;--t>=0;)e[--o]=r[t];return e};var xo=Math.abs;ao.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,i=[],u=a(xo(e)),o=-1;if(n*=u,t*=u,e*=u,0>e)for(;(r=n+e*++o)>t;)i.push(r/u);else for(;(r=n+e*++o)<t;)i.push(r/u);return i},ao.map=function(n,t){var e=new c;if(n instanceof c)n.forEach(function(n,t){e.set(n,t)});else if(Array.isArray(n)){var r,i=-1,u=n.length;if(1===arguments.length)for(;++i<u;)e.set(i,n[i]);else for(;++i<u;)e.set(t.call(n,r=n[i],i),r)}else for(var o in n)e.set(o,n[o]);return e};var bo="__proto__",_o="\x00";l(c,{has:h,get:function(n){return this._[f(n)]},set:function(n,t){return this._[f(n)]=t},remove:p,keys:g,values:function(){var n=[];for(var t in this._)n.push(this._[t]);return n},entries:function(){var n=[];for(var t in this._)n.push({key:s(t),value:this._[t]});return n},size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t),this._[t])}}),ao.nest=function(){function n(t,o,a){if(a>=u.length)return r?r.call(i,o):e?o.sort(e):o;for(var l,f,s,h,p=-1,g=o.length,v=u[a++],d=new c;++p<g;)(h=d.get(l=v(f=o[p])))?h.push(f):d.set(l,[f]);return t?(f=t(),s=function(e,r){f.set(e,n(t,r,a))}):(f={},s=function(e,r){f[e]=n(t,r,a)}),d.forEach(s),f}function t(n,e){if(e>=u.length)return n;var r=[],i=o[e++];return n.forEach(function(n,i){r.push({key:n,values:t(i,e)})}),i?r.sort(function(n,t){return i(n.key,t.key)}):r}var e,r,i={},u=[],o=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(ao.map,e,0),0)},i.key=function(n){return u.push(n),i},i.sortKeys=function(n){return o[u.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},ao.set=function(n){var t=new y;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},l(y,{has:h,add:function(n){return this._[f(n+="")]=!0,n},remove:p,values:g,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t))}}),ao.behavior={},ao.rebind=function(n,t){for(var e,r=1,i=arguments.length;++r<i;)n[e=arguments[r]]=M(n,t,t[e]);return n};var wo=["webkit","ms","moz","Moz","o","O"];ao.dispatch=function(){for(var n=new _,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=w(n);return n},_.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ao.event=null,ao.requote=function(n){return n.replace(So,"\\$&")};var So=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ko={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},No=function(n,t){return t.querySelector(n)},Eo=function(n,t){return t.querySelectorAll(n)},Ao=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(Ao=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(No=function(n,t){return Sizzle(n,t)[0]||null},Eo=Sizzle,Ao=Sizzle.matchesSelector),ao.selection=function(){return ao.select(fo.documentElement)};var Co=ao.selection.prototype=[];Co.select=function(n){var t,e,r,i,u=[];n=A(n);for(var o=-1,a=this.length;++o<a;){u.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var l=-1,c=r.length;++l<c;)(i=r[l])?(t.push(e=n.call(i,i.__data__,l,o)),e&&"__data__"in i&&(e.__data__=i.__data__)):t.push(null)}return E(u)},Co.selectAll=function(n){var t,e,r=[];n=C(n);for(var i=-1,u=this.length;++i<u;)for(var o=this[i],a=-1,l=o.length;++a<l;)(e=o[a])&&(r.push(t=co(n.call(e,e.__data__,a,i))),t.parentNode=e);return E(r)};var zo="http://www.w3.org/1999/xhtml",Lo={svg:"http://www.w3.org/2000/svg",xhtml:zo,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};ao.ns={prefix:Lo,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&"xmlns"!==(e=n.slice(0,t))&&(n=n.slice(t+1)),Lo.hasOwnProperty(e)?{space:Lo[e],local:n}:n}},Co.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ao.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},Co.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,i=-1;if(t=e.classList){for(;++i<r;)if(!t.contains(n[i]))return!1}else for(t=e.getAttribute("class");++i<r;)if(!q(n[i]).test(t))return!1;return!0}for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},Co.style=function(n,e,r){var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>i){var u=this.node();return t(u).getComputedStyle(u,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},Co.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},Co.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Co.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Co.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Co.insert=function(n,t){return n=j(n),t=A(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},Co.remove=function(){return this.each(F)},Co.data=function(n,t){function e(n,e){var r,i,u,o=n.length,s=e.length,h=Math.min(o,s),p=new Array(s),g=new Array(s),v=new Array(o);if(t){var d,y=new c,m=new Array(o);for(r=-1;++r<o;)(i=n[r])&&(y.has(d=t.call(i,i.__data__,r))?v[r]=i:y.set(d,i),m[r]=d);for(r=-1;++r<s;)(i=y.get(d=t.call(e,u=e[r],r)))?i!==!0&&(p[r]=i,i.__data__=u):g[r]=H(u),y.set(d,!0);for(r=-1;++r<o;)r in m&&y.get(m[r])!==!0&&(v[r]=n[r])}else{for(r=-1;++r<h;)i=n[r],u=e[r],i?(i.__data__=u,p[r]=i):g[r]=H(u);for(;s>r;++r)g[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}g.update=p,g.parentNode=p.parentNode=v.parentNode=n.parentNode,a.push(g),l.push(p),f.push(v)}var r,i,u=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++u<o;)(i=r[u])&&(n[u]=i.__data__);return n}var a=Z([]),l=E([]),f=E([]);if("function"==typeof n)for(;++u<o;)e(r=this[u],n.call(r,r.parentNode.__data__,u));else for(;++u<o;)e(r=this[u],n);return l.enter=function(){return a},l.exit=function(){return f},l},Co.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},Co.filter=function(n){var t,e,r,i=[];"function"!=typeof n&&(n=O(n));for(var u=0,o=this.length;o>u;u++){i.push(t=[]),t.parentNode=(e=this[u]).parentNode;for(var a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return E(i)},Co.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],i=r.length-1,u=r[i];--i>=0;)(e=r[i])&&(u&&u!==e.nextSibling&&u.parentNode.insertBefore(e,u),u=e);return this},Co.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},Co.each=function(n){return Y(this,function(t,e,r){n.call(t,t.__data__,e,r)})},Co.call=function(n){var t=co(arguments);return n.apply(t[0]=this,t),this},Co.empty=function(){return!this.node()},Co.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,i=e.length;i>r;r++){var u=e[r];if(u)return u}return null},Co.size=function(){var n=0;return Y(this,function(){++n}),n};var qo=[];ao.selection.enter=Z,ao.selection.enter.prototype=qo,qo.append=Co.append,qo.empty=Co.empty,qo.node=Co.node,qo.call=Co.call,qo.size=Co.size,qo.select=function(n){for(var t,e,r,i,u,o=[],a=-1,l=this.length;++a<l;){r=(i=this[a]).update,o.push(t=[]),t.parentNode=i.parentNode;for(var c=-1,f=i.length;++c<f;)(u=i[c])?(t.push(r[c]=e=n.call(i.parentNode,u.__data__,c,a)),e.__data__=u.__data__):t.push(null)}return E(o)},qo.insert=function(n,t){return arguments.length<2&&(t=V(this)),Co.insert.call(this,n,t)},ao.select=function(t){var e;return"string"==typeof t?(e=[No(t,fo)],e.parentNode=fo.documentElement):(e=[t],e.parentNode=n(t)),E([e])},ao.selectAll=function(n){var t;return"string"==typeof n?(t=co(Eo(n,fo)),t.parentNode=fo.documentElement):(t=co(n),t.parentNode=null),E([t])},Co.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var To=ao.map({mouseenter:"mouseover",mouseleave:"mouseout"});fo&&To.forEach(function(n){"on"+n in fo&&To.remove(n)});var Ro,Do=0;ao.mouse=function(n){return J(n,k())};var Po=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ao.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,i=0,u=t.length;u>i;++i)if((r=t[i]).identifier===e)return J(n,r)},ao.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",o)}function e(n,t,e,u,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],g|=n|e,M=r,p({type:"drag",x:r[0]+c[0],y:r[1]+c[1],dx:n,dy:e}))}function l(){t(h,v)&&(y.on(u+d,null).on(o+d,null),m(g),p({type:"dragend"}))}var c,f=this,s=ao.event.target.correspondingElement||ao.event.target,h=f.parentNode,p=r.of(f,arguments),g=0,v=n(),d=".drag"+(null==v?"":"-"+v),y=ao.select(e(s)).on(u+d,a).on(o+d,l),m=W(s),M=t(h,v);i?(c=i.apply(f,arguments),c=[c.x-M[0],c.y-M[1]]):c=[0,0],p({type:"dragstart"})}}var r=N(n,"drag","dragstart","dragend"),i=null,u=e(b,ao.mouse,t,"mousemove","mouseup"),o=e(G,ao.touch,m,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},ao.rebind(n,r,"on")},ao.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?co(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Uo=1e-6,jo=Uo*Uo,Fo=Math.PI,Ho=2*Fo,Oo=Ho-Uo,Io=Fo/2,Yo=Fo/180,Zo=180/Fo,Vo=Math.SQRT2,Xo=2,$o=4;ao.interpolateZoom=function(n,t){var e,r,i=n[0],u=n[1],o=n[2],a=t[0],l=t[1],c=t[2],f=a-i,s=l-u,h=f*f+s*s;if(jo>h)r=Math.log(c/o)/Vo,e=function(n){return[i+n*f,u+n*s,o*Math.exp(Vo*n*r)]};else{var p=Math.sqrt(h),g=(c*c-o*o+$o*h)/(2*o*Xo*p),v=(c*c-o*o-$o*h)/(2*c*Xo*p),d=Math.log(Math.sqrt(g*g+1)-g),y=Math.log(Math.sqrt(v*v+1)-v);r=(y-d)/Vo,e=function(n){var t=n*r,e=rn(d),a=o/(Xo*p)*(e*un(Vo*t+d)-en(d));return[i+a*f,u+a*s,o*e/rn(Vo*t+d)]}}return e.duration=1e3*r,e},ao.behavior.zoom=function(){function n(n){n.on(L,s).on(Wo+".zoom",p).on("dblclick.zoom",g).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function i(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},i(Math.pow(2,o)),u(d=e,r),t=ao.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function l(n){z++||n({type:"zoomstart"})}function c(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function f(n){--z||(n({type:"zoomend"}),d=null)}function s(){function n(){a=1,u(ao.mouse(i),h),c(o)}function r(){s.on(q,null).on(T,null),p(a),f(o)}var i=this,o=D.of(i,arguments),a=0,s=ao.select(t(i)).on(q,n).on(T,r),h=e(ao.mouse(i)),p=W(i);Il.call(i),l(o)}function h(){function n(){var n=ao.touches(g);return p=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ao.event.target;ao.select(t).on(x,r).on(b,a),_.push(t);for(var e=ao.event.changedTouches,i=0,u=e.length;u>i;++i)d[e[i].identifier]=null;var l=n(),c=Date.now();if(1===l.length){if(500>c-M){var f=l[0];o(g,f,d[f.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=c}else if(l.length>1){var f=l[0],s=l[1],h=f[0]-s[0],p=f[1]-s[1];y=h*h+p*p}}function r(){var n,t,e,r,o=ao.touches(g);Il.call(g);for(var a=0,l=o.length;l>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var f=(f=e[0]-n[0])*f+(f=e[1]-n[1])*f,s=y&&Math.sqrt(f/y);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],i(s*p)}M=null,u(n,t),c(v)}function a(){if(ao.event.touches.length){for(var t=ao.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var i in d)return void n()}ao.selectAll(_).on(m,null),w.on(L,s).on(R,h),N(),f(v)}var p,g=this,v=D.of(g,arguments),d={},y=0,m=".zoom-"+ao.event.changedTouches[0].identifier,x="touchmove"+m,b="touchend"+m,_=[],w=ao.select(g),N=W(g);t(),l(v),w.on(L,null).on(R,t)}function p(){var n=D.of(this,arguments);m?clearTimeout(m):(Il.call(this),v=e(d=y||ao.mouse(this)),l(n)),m=setTimeout(function(){m=null,f(n)},50),S(),i(Math.pow(2,.002*Bo())*k.k),u(d,v),c(n)}function g(){var n=ao.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ao.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,y,m,M,x,b,_,w,k={x:0,y:0,k:1},E=[960,500],A=Jo,C=250,z=0,L="mousedown.zoom",q="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=N(n,"zoomstart","zoom","zoomend");return Wo||(Wo="onwheel"in fo?(Bo=function(){return-ao.event.deltaY*(ao.event.deltaMode?120:1)},"wheel"):"onmousewheel"in fo?(Bo=function(){return ao.event.wheelDelta},"mousewheel"):(Bo=function(){return-ao.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Hl?ao.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},l(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],i=d?d[0]:e/2,u=d?d[1]:r/2,o=ao.interpolateZoom([(i-k.x)/k.k,(u-k.y)/k.k,e/k.k],[(i-t.x)/t.k,(u-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:i-r[0]*a,y:u-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){f(n)}).each("end.zoom",function(){f(n)}):(this.__chart__=k,l(n),c(n),f(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:null},i(+t),a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Jo:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(y=t&&[+t[0],+t[1]],n):y},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ao.rebind(n,D,"on")};var Bo,Wo,Jo=[0,1/0];ao.color=an,an.prototype.toString=function(){return this.rgb()+""},ao.hsl=ln;var Go=ln.prototype=new an;Go.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,this.l/n)},Go.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,n*this.l)},Go.rgb=function(){return cn(this.h,this.s,this.l)},ao.hcl=fn;var Ko=fn.prototype=new an;Ko.brighter=function(n){return new fn(this.h,this.c,Math.min(100,this.l+Qo*(arguments.length?n:1)))},Ko.darker=function(n){return new fn(this.h,this.c,Math.max(0,this.l-Qo*(arguments.length?n:1)))},Ko.rgb=function(){return sn(this.h,this.c,this.l).rgb()},ao.lab=hn;var Qo=18,na=.95047,ta=1,ea=1.08883,ra=hn.prototype=new an;ra.brighter=function(n){return new hn(Math.min(100,this.l+Qo*(arguments.length?n:1)),this.a,this.b)},ra.darker=function(n){return new hn(Math.max(0,this.l-Qo*(arguments.length?n:1)),this.a,this.b)},ra.rgb=function(){return pn(this.l,this.a,this.b)},ao.rgb=mn;var ia=mn.prototype=new an;ia.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,i=30;return t||e||r?(t&&i>t&&(t=i),e&&i>e&&(e=i),r&&i>r&&(r=i),new mn(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mn(i,i,i)},ia.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mn(n*this.r,n*this.g,n*this.b)},ia.hsl=function(){return wn(this.r,this.g,this.b)},ia.toString=function(){return"#"+bn(this.r)+bn(this.g)+bn(this.b)};var ua=ao.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});ua.forEach(function(n,t){ua.set(n,Mn(t))}),ao.functor=En,ao.xhr=An(m),ao.dsv=function(n,t){function e(n,e,u){arguments.length<3&&(u=e,e=null);var o=Cn(n,t,null==e?r:i(e),u);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:i(n)):e},o}function r(n){return e.parse(n.responseText)}function i(n){return function(t){return e.parse(t.responseText,n)}}function u(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var i=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(i(n),e)}:i})},e.parseRows=function(n,t){function e(){if(f>=c)return o;if(i)return i=!1,u;var t=f;if(34===n.charCodeAt(t)){for(var e=t;e++<c;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}f=e+2;var r=n.charCodeAt(e+1);return 13===r?(i=!0,10===n.charCodeAt(e+2)&&++f):10===r&&(i=!0),n.slice(t+1,e).replace(/""/g,'"')}for(;c>f;){var r=n.charCodeAt(f++),a=1;if(10===r)i=!0;else if(13===r)i=!0,10===n.charCodeAt(f)&&(++f,++a);else if(r!==l)continue;return n.slice(t,f-a)}return n.slice(t)}for(var r,i,u={},o={},a=[],c=n.length,f=0,s=0;(r=e())!==o;){for(var h=[];r!==u&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,s++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new y,i=[];return t.forEach(function(n){for(var t in n)r.has(t)||i.push(r.add(t))}),[i.map(o).join(n)].concat(t.map(function(t){return i.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(u).join("\n")},e},ao.csv=ao.dsv(",","text/csv"),ao.tsv=ao.dsv("	","text/tab-separated-values");var oa,aa,la,ca,fa=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ao.timer=function(){qn.apply(this,arguments)},ao.timer.flush=function(){Rn(),Dn()},ao.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var sa=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Un);ao.formatPrefix=function(n,t){var e=0;return(n=+n)&&(0>n&&(n*=-1),t&&(n=ao.round(n,Pn(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),sa[8+e/3]};var ha=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,pa=ao.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ao.round(n,Pn(n,t))).toFixed(Math.max(0,Math.min(20,Pn(n*(1+1e-15),t))))}}),ga=ao.time={},va=Date;Hn.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){da.setUTCDate.apply(this._,arguments)},setDay:function(){da.setUTCDay.apply(this._,arguments)},setFullYear:function(){da.setUTCFullYear.apply(this._,arguments)},setHours:function(){da.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){da.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){da.setUTCMinutes.apply(this._,arguments)},setMonth:function(){da.setUTCMonth.apply(this._,arguments)},setSeconds:function(){da.setUTCSeconds.apply(this._,arguments)},setTime:function(){da.setTime.apply(this._,arguments)}};var da=Date.prototype;ga.year=On(function(n){return n=ga.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ga.years=ga.year.range,ga.years.utc=ga.year.utc.range,ga.day=On(function(n){var t=new va(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ga.days=ga.day.range,ga.days.utc=ga.day.utc.range,ga.dayOfYear=function(n){var t=ga.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ga[n]=On(function(n){return(n=ga.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ga[n+"s"]=e.range,ga[n+"s"].utc=e.utc.range,ga[n+"OfYear"]=function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)}}),ga.week=ga.sunday,ga.weeks=ga.sunday.range,ga.weeks.utc=ga.sunday.utc.range,ga.weekOfYear=ga.sundayOfYear;var ya={"-":"",_:" ",0:"0"},ma=/^\s*\d+/,Ma=/^%/;ao.locale=function(n){return{numberFormat:jn(n),timeFormat:Yn(n)}};var xa=ao.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],
+shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ao.format=xa.numberFormat,ao.geo={},ft.prototype={s:0,t:0,add:function(n){st(n,this.t,ba),st(ba.s,this.s,this),this.s?this.t+=ba.t:this.s=ba.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var ba=new ft;ao.geo.stream=function(n,t){n&&_a.hasOwnProperty(n.type)?_a[n.type](n,t):ht(n,t)};var _a={Feature:function(n,t){ht(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,i=e.length;++r<i;)ht(e[r].geometry,t)}},wa={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){pt(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)pt(e[r],t,0)},Polygon:function(n,t){gt(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,i=e.length;++r<i;)gt(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,i=e.length;++r<i;)ht(e[r],t)}};ao.geo.area=function(n){return Sa=0,ao.geo.stream(n,Na),Sa};var Sa,ka=new ft,Na={sphere:function(){Sa+=4*Fo},point:b,lineStart:b,lineEnd:b,polygonStart:function(){ka.reset(),Na.lineStart=vt},polygonEnd:function(){var n=2*ka;Sa+=0>n?4*Fo+n:n,Na.lineStart=Na.lineEnd=Na.point=b}};ao.geo.bounds=function(){function n(n,t){M.push(x=[f=n,h=n]),s>t&&(s=t),t>p&&(p=t)}function t(t,e){var r=dt([t*Yo,e*Yo]);if(y){var i=mt(y,r),u=[i[1],-i[0],0],o=mt(u,i);bt(o),o=_t(o);var l=t-g,c=l>0?1:-1,v=o[0]*Zo*c,d=xo(l)>180;if(d^(v>c*g&&c*t>v)){var m=o[1]*Zo;m>p&&(p=m)}else if(v=(v+360)%360-180,d^(v>c*g&&c*t>v)){var m=-o[1]*Zo;s>m&&(s=m)}else s>e&&(s=e),e>p&&(p=e);d?g>t?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t):h>=f?(f>t&&(f=t),t>h&&(h=t)):t>g?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t)}else n(t,e);y=r,g=t}function e(){b.point=t}function r(){x[0]=f,x[1]=h,b.point=n,y=null}function i(n,e){if(y){var r=n-g;m+=xo(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Na.point(n,e),t(n,e)}function u(){Na.lineStart()}function o(){i(v,d),Na.lineEnd(),xo(m)>Uo&&(f=-(h=180)),x[0]=f,x[1]=h,y=null}function a(n,t){return(t-=n)<0?t+360:t}function l(n,t){return n[0]-t[0]}function c(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var f,s,h,p,g,v,d,y,m,M,x,b={point:n,lineStart:e,lineEnd:r,polygonStart:function(){b.point=i,b.lineStart=u,b.lineEnd=o,m=0,Na.polygonStart()},polygonEnd:function(){Na.polygonEnd(),b.point=n,b.lineStart=e,b.lineEnd=r,0>ka?(f=-(h=180),s=-(p=90)):m>Uo?p=90:-Uo>m&&(s=-90),x[0]=f,x[1]=h}};return function(n){p=h=-(f=s=1/0),M=[],ao.geo.stream(n,b);var t=M.length;if(t){M.sort(l);for(var e,r=1,i=M[0],u=[i];t>r;++r)e=M[r],c(e[0],i)||c(e[1],i)?(a(i[0],e[1])>a(i[0],i[1])&&(i[1]=e[1]),a(e[0],i[1])>a(i[0],i[1])&&(i[0]=e[0])):u.push(i=e);for(var o,e,g=-(1/0),t=u.length-1,r=0,i=u[t];t>=r;i=e,++r)e=u[r],(o=a(i[1],e[0]))>g&&(g=o,f=e[0],h=i[1])}return M=x=null,f===1/0||s===1/0?[[NaN,NaN],[NaN,NaN]]:[[f,s],[h,p]]}}(),ao.geo.centroid=function(n){Ea=Aa=Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,ja);var t=Da,e=Pa,r=Ua,i=t*t+e*e+r*r;return jo>i&&(t=qa,e=Ta,r=Ra,Uo>Aa&&(t=Ca,e=za,r=La),i=t*t+e*e+r*r,jo>i)?[NaN,NaN]:[Math.atan2(e,t)*Zo,tn(r/Math.sqrt(i))*Zo]};var Ea,Aa,Ca,za,La,qa,Ta,Ra,Da,Pa,Ua,ja={sphere:b,point:St,lineStart:Nt,lineEnd:Et,polygonStart:function(){ja.lineStart=At},polygonEnd:function(){ja.lineStart=Nt}},Fa=Rt(zt,jt,Ht,[-Fo,-Fo/2]),Ha=1e9;ao.geo.clipExtent=function(){var n,t,e,r,i,u,o={stream:function(n){return i&&(i.valid=!1),i=u(n),i.valid=!0,i},extent:function(a){return arguments.length?(u=Zt(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),i&&(i.valid=!1,i=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ao.geo.conicEqualArea=function(){return Vt(Xt)}).raw=Xt,ao.geo.albers=function(){return ao.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ao.geo.albersUsa=function(){function n(n){var u=n[0],o=n[1];return t=null,e(u,o),t||(r(u,o),t)||i(u,o),t}var t,e,r,i,u=ao.geo.albers(),o=ao.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ao.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=u.scale(),e=u.translate(),r=(n[0]-e[0])/t,i=(n[1]-e[1])/t;return(i>=.12&&.234>i&&r>=-.425&&-.214>r?o:i>=.166&&.234>i&&r>=-.214&&-.115>r?a:u).invert(n)},n.stream=function(n){var t=u.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,i){t.point(n,i),e.point(n,i),r.point(n,i)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(u.precision(t),o.precision(t),a.precision(t),n):u.precision()},n.scale=function(t){return arguments.length?(u.scale(t),o.scale(.35*t),a.scale(t),n.translate(u.translate())):u.scale()},n.translate=function(t){if(!arguments.length)return u.translate();var c=u.scale(),f=+t[0],s=+t[1];return e=u.translate(t).clipExtent([[f-.455*c,s-.238*c],[f+.455*c,s+.238*c]]).stream(l).point,r=o.translate([f-.307*c,s+.201*c]).clipExtent([[f-.425*c+Uo,s+.12*c+Uo],[f-.214*c-Uo,s+.234*c-Uo]]).stream(l).point,i=a.translate([f-.205*c,s+.212*c]).clipExtent([[f-.214*c+Uo,s+.166*c+Uo],[f-.115*c-Uo,s+.234*c-Uo]]).stream(l).point,n},n.scale(1070)};var Oa,Ia,Ya,Za,Va,Xa,$a={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Ia=0,$a.lineStart=$t},polygonEnd:function(){$a.lineStart=$a.lineEnd=$a.point=b,Oa+=xo(Ia/2)}},Ba={point:Bt,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Wa={point:Gt,lineStart:Kt,lineEnd:Qt,polygonStart:function(){Wa.lineStart=ne},polygonEnd:function(){Wa.point=Gt,Wa.lineStart=Kt,Wa.lineEnd=Qt}};ao.geo.path=function(){function n(n){return n&&("function"==typeof a&&u.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=i(u)),ao.geo.stream(n,o)),u.result()}function t(){return o=null,n}var e,r,i,u,o,a=4.5;return n.area=function(n){return Oa=0,ao.geo.stream(n,i($a)),Oa},n.centroid=function(n){return Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,i(Wa)),Ua?[Da/Ua,Pa/Ua]:Ra?[qa/Ra,Ta/Ra]:La?[Ca/La,za/La]:[NaN,NaN]},n.bounds=function(n){return Va=Xa=-(Ya=Za=1/0),ao.geo.stream(n,i(Ba)),[[Ya,Za],[Va,Xa]]},n.projection=function(n){return arguments.length?(i=(e=n)?n.stream||re(n):m,t()):e},n.context=function(n){return arguments.length?(u=null==(r=n)?new Wt:new te(n),"function"!=typeof a&&u.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(u.pointRadius(+t),+t),n):a},n.projection(ao.geo.albersUsa()).context(null)},ao.geo.transform=function(n){return{stream:function(t){var e=new ie(t);for(var r in n)e[r]=n[r];return e}}},ie.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ao.geo.projection=oe,ao.geo.projectionMutator=ae,(ao.geo.equirectangular=function(){return oe(ce)}).raw=ce.invert=ce,ao.geo.rotation=function(n){function t(t){return t=n(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t}return n=se(n[0]%360*Yo,n[1]*Yo,n.length>2?n[2]*Yo:0),t.invert=function(t){return t=n.invert(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t},t},fe.invert=ce,ao.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=se(-n[0]*Yo,-n[1]*Yo,0).invert,i=[];return e(null,null,1,{point:function(n,e){i.push(n=t(n,e)),n[0]*=Zo,n[1]*=Zo}}),{type:"Polygon",coordinates:[i]}}var t,e,r=[0,0],i=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=ve((t=+r)*Yo,i*Yo),n):t},n.precision=function(r){return arguments.length?(e=ve(t*Yo,(i=+r)*Yo),n):i},n.angle(90)},ao.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Yo,i=n[1]*Yo,u=t[1]*Yo,o=Math.sin(r),a=Math.cos(r),l=Math.sin(i),c=Math.cos(i),f=Math.sin(u),s=Math.cos(u);return Math.atan2(Math.sqrt((e=s*o)*e+(e=c*f-l*s*a)*e),l*f+c*s*a)},ao.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ao.range(Math.ceil(u/d)*d,i,d).map(h).concat(ao.range(Math.ceil(c/y)*y,l,y).map(p)).concat(ao.range(Math.ceil(r/g)*g,e,g).filter(function(n){return xo(n%d)>Uo}).map(f)).concat(ao.range(Math.ceil(a/v)*v,o,v).filter(function(n){return xo(n%y)>Uo}).map(s))}var e,r,i,u,o,a,l,c,f,s,h,p,g=10,v=g,d=90,y=360,m=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(u).concat(p(l).slice(1),h(i).reverse().slice(1),p(c).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(u=+t[0][0],i=+t[1][0],c=+t[0][1],l=+t[1][1],u>i&&(t=u,u=i,i=t),c>l&&(t=c,c=l,l=t),n.precision(m)):[[u,c],[i,l]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(m)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],y=+t[1],n):[d,y]},n.minorStep=function(t){return arguments.length?(g=+t[0],v=+t[1],n):[g,v]},n.precision=function(t){return arguments.length?(m=+t,f=ye(a,o,90),s=me(r,e,m),h=ye(c,l,90),p=me(u,i,m),n):m},n.majorExtent([[-180,-90+Uo],[180,90-Uo]]).minorExtent([[-180,-80-Uo],[180,80+Uo]])},ao.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||i.apply(this,arguments)]}}var t,e,r=Me,i=xe;return n.distance=function(){return ao.geo.distance(t||r.apply(this,arguments),e||i.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(i=t,e="function"==typeof t?null:t,n):i},n.precision=function(){return arguments.length?n:0},n},ao.geo.interpolate=function(n,t){return be(n[0]*Yo,n[1]*Yo,t[0]*Yo,t[1]*Yo)},ao.geo.length=function(n){return Ja=0,ao.geo.stream(n,Ga),Ja};var Ja,Ga={sphere:b,point:b,lineStart:_e,lineEnd:b,polygonStart:b,polygonEnd:b},Ka=we(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ao.geo.azimuthalEqualArea=function(){return oe(Ka)}).raw=Ka;var Qa=we(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},m);(ao.geo.azimuthalEquidistant=function(){return oe(Qa)}).raw=Qa,(ao.geo.conicConformal=function(){return Vt(Se)}).raw=Se,(ao.geo.conicEquidistant=function(){return Vt(ke)}).raw=ke;var nl=we(function(n){return 1/n},Math.atan);(ao.geo.gnomonic=function(){return oe(nl)}).raw=nl,Ne.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Io]},(ao.geo.mercator=function(){return Ee(Ne)}).raw=Ne;var tl=we(function(){return 1},Math.asin);(ao.geo.orthographic=function(){return oe(tl)}).raw=tl;var el=we(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ao.geo.stereographic=function(){return oe(el)}).raw=el,Ae.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Io]},(ao.geo.transverseMercator=function(){var n=Ee(Ae),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Ae,ao.geom={},ao.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,i=En(e),u=En(r),o=n.length,a=[],l=[];for(t=0;o>t;t++)a.push([+i.call(this,n[t],t),+u.call(this,n[t],t),t]);for(a.sort(qe),t=0;o>t;t++)l.push([a[t][0],-a[t][1]]);var c=Le(a),f=Le(l),s=f[0]===c[0],h=f[f.length-1]===c[c.length-1],p=[];for(t=c.length-1;t>=0;--t)p.push(n[a[c[t]][2]]);for(t=+s;t<f.length-h;++t)p.push(n[a[f[t]][2]]);return p}var e=Ce,r=ze;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},ao.geom.polygon=function(n){return ko(n,rl),n};var rl=ao.geom.polygon.prototype=[];rl.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],i=0;++t<e;)n=r,r=this[t],i+=n[1]*r[0]-n[0]*r[1];return.5*i},rl.centroid=function(n){var t,e,r=-1,i=this.length,u=0,o=0,a=this[i-1];for(arguments.length||(n=-1/(6*this.area()));++r<i;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],u+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[u*n,o*n]},rl.clip=function(n){for(var t,e,r,i,u,o,a=De(n),l=-1,c=this.length-De(this),f=this[c-1];++l<c;){for(t=n.slice(),n.length=0,i=this[l],u=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Te(o,f,i)?(Te(u,f,i)||n.push(Re(u,o,f,i)),n.push(o)):Te(u,f,i)&&n.push(Re(u,o,f,i)),u=o;a&&n.push(n[0]),f=i}return n};var il,ul,ol,al,ll,cl=[],fl=[];Ye.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Ve),t.length},tr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},er.prototype={insert:function(n,t){var e,r,i;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=or(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(i=r.R,i&&i.C?(e.C=i.C=!1,r.C=!0,n=r):(n===e.R&&(ir(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ur(this,r))):(i=r.L,i&&i.C?(e.C=i.C=!1,r.C=!0,n=r):(n===e.L&&(ur(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ir(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,i=n.U,u=n.L,o=n.R;if(e=u?o?or(o):u:o,i?i.L===n?i.L=e:i.R=e:this._=e,u&&o?(r=e.C,e.C=n.C,e.L=u,u.U=e,e!==o?(i=e.U,e.U=n.U,n=e.R,i.L=n,e.R=o,o.U=e):(e.U=i,i=e,n=e.R)):(r=n.C,n=e),n&&(n.U=i),!r){if(n&&n.C)return void(n.C=!1);do{if(n===this._)break;if(n===i.L){if(t=i.R,t.C&&(t.C=!1,i.C=!0,ir(this,i),t=i.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,ur(this,t),t=i.R),t.C=i.C,i.C=t.R.C=!1,ir(this,i),n=this._;break}}else if(t=i.L,t.C&&(t.C=!1,i.C=!0,ur(this,i),t=i.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,ir(this,t),t=i.L),t.C=i.C,i.C=t.L.C=!1,ur(this,i),n=this._;break}t.C=!0,n=i,i=i.U}while(!n.C);n&&(n.C=!1)}}},ao.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],i=a[0][1],u=a[1][0],o=a[1][1];return ar(e(n),a).cells.forEach(function(e,a){var l=e.edges,c=e.site,f=t[a]=l.length?l.map(function(n){var t=n.start();return[t.x,t.y]}):c.x>=r&&c.x<=u&&c.y>=i&&c.y<=o?[[r,o],[u,o],[u,i],[r,i]]:[];f.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(u(n,t)/Uo)*Uo,y:Math.round(o(n,t)/Uo)*Uo,i:t}})}var r=Ce,i=ze,u=r,o=i,a=sl;return n?t(n):(t.links=function(n){return ar(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return ar(e(n)).cells.forEach(function(e,r){for(var i,u,o=e.site,a=e.edges.sort(Ve),l=-1,c=a.length,f=a[c-1].edge,s=f.l===o?f.r:f.l;++l<c;)i=f,u=s,f=a[l].edge,s=f.l===o?f.r:f.l,r<u.i&&r<s.i&&cr(o,u,s)<0&&t.push([n[r],n[u.i],n[s.i]])}),t},t.x=function(n){return arguments.length?(u=En(r=n),t):r},t.y=function(n){return arguments.length?(o=En(i=n),t):i},t.clipExtent=function(n){return arguments.length?(a=null==n?sl:n,t):a===sl?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===sl?null:a&&a[1]},t)};var sl=[[-1e6,-1e6],[1e6,1e6]];ao.geom.delaunay=function(n){return ao.geom.voronoi().triangles(n)},ao.geom.quadtree=function(n,t,e,r,i){function u(n){function u(n,t,e,r,i,u,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var l=n.x,f=n.y;if(null!=l)if(xo(l-e)+xo(f-r)<.01)c(n,t,e,r,i,u,o,a);else{var s=n.point;n.x=n.y=n.point=null,c(n,s,l,f,i,u,o,a),c(n,t,e,r,i,u,o,a)}else n.x=e,n.y=r,n.point=t}else c(n,t,e,r,i,u,o,a)}function c(n,t,e,r,i,o,a,l){var c=.5*(i+a),f=.5*(o+l),s=e>=c,h=r>=f,p=h<<1|s;n.leaf=!1,n=n.nodes[p]||(n.nodes[p]=hr()),s?i=c:a=c,h?o=f:l=f,u(n,t,e,r,i,o,a,l)}var f,s,h,p,g,v,d,y,m,M=En(a),x=En(l);if(null!=t)v=t,d=e,y=r,m=i;else if(y=m=-(v=d=1/0),s=[],h=[],g=n.length,o)for(p=0;g>p;++p)f=n[p],f.x<v&&(v=f.x),f.y<d&&(d=f.y),f.x>y&&(y=f.x),f.y>m&&(m=f.y),s.push(f.x),h.push(f.y);else for(p=0;g>p;++p){var b=+M(f=n[p],p),_=+x(f,p);v>b&&(v=b),d>_&&(d=_),b>y&&(y=b),_>m&&(m=_),s.push(b),h.push(_)}var w=y-v,S=m-d;w>S?m=d+w:y=v+S;var k=hr();if(k.add=function(n){u(k,n,+M(n,++p),+x(n,p),v,d,y,m)},k.visit=function(n){pr(n,k,v,d,y,m)},k.find=function(n){return gr(k,n[0],n[1],v,d,y,m)},p=-1,null==t){for(;++p<g;)u(k,n[p],s[p],h[p],v,d,y,m);--p}else n.forEach(k.add);return s=h=n=f=null,k}var o,a=Ce,l=ze;return(o=arguments.length)?(a=fr,l=sr,3===o&&(i=e,r=t,e=t=0),u(n)):(u.x=function(n){return arguments.length?(a=n,u):a},u.y=function(n){return arguments.length?(l=n,u):l},u.extent=function(n){return arguments.length?(null==n?t=e=r=i=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],i=+n[1][1]),u):null==t?null:[[t,e],[r,i]]},u.size=function(n){return arguments.length?(null==n?t=e=r=i=null:(t=e=0,r=+n[0],i=+n[1]),u):null==t?null:[r-t,i-e]},u)},ao.interpolateRgb=vr,ao.interpolateObject=dr,ao.interpolateNumber=yr,ao.interpolateString=mr;var hl=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,pl=new RegExp(hl.source,"g");ao.interpolate=Mr,ao.interpolators=[function(n,t){var e=typeof t;return("string"===e?ua.has(t.toLowerCase())||/^(#|rgb\(|hsl\()/i.test(t)?vr:mr:t instanceof an?vr:Array.isArray(t)?xr:"object"===e&&isNaN(t)?dr:yr)(n,t)}],ao.interpolateArray=xr;var gl=function(){return m},vl=ao.map({linear:gl,poly:Er,quad:function(){return Sr},cubic:function(){return kr},sin:function(){return Ar},exp:function(){return Cr},circle:function(){return zr},elastic:Lr,back:qr,bounce:function(){return Tr}}),dl=ao.map({"in":m,out:_r,"in-out":wr,"out-in":function(n){return wr(_r(n))}});ao.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=vl.get(e)||gl,r=dl.get(r)||m,br(r(e.apply(null,lo.call(arguments,1))))},ao.interpolateHcl=Rr,ao.interpolateHsl=Dr,ao.interpolateLab=Pr,ao.interpolateRound=Ur,ao.transform=function(n){var t=fo.createElementNS(ao.ns.prefix.svg,"g");return(ao.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new jr(e?e.matrix:yl)})(n)},jr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var yl={a:1,b:0,c:0,d:1,e:0,f:0};ao.interpolateTransform=$r,ao.layout={},ao.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Jr(n[e]));return t}},ao.layout.chord=function(){function n(){var n,c,s,h,p,g={},v=[],d=ao.range(u),y=[];for(e=[],r=[],n=0,h=-1;++h<u;){for(c=0,p=-1;++p<u;)c+=i[h][p];v.push(c),y.push(ao.range(u)),n+=c}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&y.forEach(function(n,t){n.sort(function(n,e){return a(i[t][n],i[t][e])})}),n=(Ho-f*u)/n,c=0,h=-1;++h<u;){for(s=c,p=-1;++p<u;){var m=d[h],M=y[m][p],x=i[m][M],b=c,_=c+=x*n;g[m+"-"+M]={index:m,subindex:M,startAngle:b,endAngle:_,value:x}}r[m]={index:m,startAngle:s,endAngle:c,value:v[m]},c+=f}for(h=-1;++h<u;)for(p=h-1;++p<u;){var w=g[h+"-"+p],S=g[p+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}l&&t()}function t(){e.sort(function(n,t){return l((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,i,u,o,a,l,c={},f=0;return c.matrix=function(n){return arguments.length?(u=(i=n)&&i.length,e=r=null,c):i},c.padding=function(n){return arguments.length?(f=n,e=r=null,c):f},c.sortGroups=function(n){return arguments.length?(o=n,e=r=null,c):o},c.sortSubgroups=function(n){return arguments.length?(a=n,e=null,c):a},c.sortChords=function(n){return arguments.length?(l=n,e&&t(),c):l},c.chords=function(){return e||n(),e},c.groups=function(){return r||n(),r},c},ao.layout.force=function(){function n(n){return function(t,e,r,i){if(t.point!==n){var u=t.cx-n.x,o=t.cy-n.y,a=i-e,l=u*u+o*o;if(l>a*a/y){if(v>l){var c=t.charge/l;n.px-=u*c,n.py-=o*c}return!0}if(t.point&&l&&v>l){var c=t.pointCharge/l;n.px-=u*c,n.py-=o*c}}return!t.charge}}function t(n){n.px=ao.event.x,n.py=ao.event.y,l.resume()}var e,r,i,u,o,a,l={},c=ao.dispatch("start","tick","end"),f=[1,1],s=.9,h=ml,p=Ml,g=-30,v=xl,d=.1,y=.64,M=[],x=[];return l.tick=function(){if((i*=.99)<.005)return e=null,c.end({type:"end",alpha:i=0}),!0;var t,r,l,h,p,v,y,m,b,_=M.length,w=x.length;for(r=0;w>r;++r)l=x[r],h=l.source,p=l.target,m=p.x-h.x,b=p.y-h.y,(v=m*m+b*b)&&(v=i*o[r]*((v=Math.sqrt(v))-u[r])/v,m*=v,b*=v,p.x-=m*(y=h.weight+p.weight?h.weight/(h.weight+p.weight):.5),p.y-=b*y,h.x+=m*(y=1-y),h.y+=b*y);if((y=i*d)&&(m=f[0]/2,b=f[1]/2,r=-1,y))for(;++r<_;)l=M[r],l.x+=(m-l.x)*y,l.y+=(b-l.y)*y;if(g)for(ri(t=ao.geom.quadtree(M),i,a),r=-1;++r<_;)(l=M[r]).fixed||t.visit(n(l));for(r=-1;++r<_;)l=M[r],l.fixed?(l.x=l.px,l.y=l.py):(l.x-=(l.px-(l.px=l.x))*s,l.y-=(l.py-(l.py=l.y))*s);c.tick({type:"tick",alpha:i})},l.nodes=function(n){return arguments.length?(M=n,l):M},l.links=function(n){return arguments.length?(x=n,l):x},l.size=function(n){return arguments.length?(f=n,l):f},l.linkDistance=function(n){return arguments.length?(h="function"==typeof n?n:+n,l):h},l.distance=l.linkDistance,l.linkStrength=function(n){return arguments.length?(p="function"==typeof n?n:+n,l):p},l.friction=function(n){return arguments.length?(s=+n,l):s},l.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,l):g},l.chargeDistance=function(n){return arguments.length?(v=n*n,l):Math.sqrt(v)},l.gravity=function(n){return arguments.length?(d=+n,l):d},l.theta=function(n){return arguments.length?(y=n*n,l):Math.sqrt(y)},l.alpha=function(n){return arguments.length?(n=+n,i?n>0?i=n:(e.c=null,e.t=NaN,e=null,c.end({type:"end",alpha:i=0})):n>0&&(c.start({type:"start",alpha:i=n}),e=qn(l.tick)),l):i},l.start=function(){function n(n,r){if(!e){for(e=new Array(i),l=0;i>l;++l)e[l]=[];for(l=0;c>l;++l){var u=x[l];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var o,a=e[t],l=-1,f=a.length;++l<f;)if(!isNaN(o=a[l][n]))return o;return Math.random()*r}var t,e,r,i=M.length,c=x.length,s=f[0],v=f[1];for(t=0;i>t;++t)(r=M[t]).index=t,r.weight=0;for(t=0;c>t;++t)r=x[t],"number"==typeof r.source&&(r.source=M[r.source]),"number"==typeof r.target&&(r.target=M[r.target]),++r.source.weight,++r.target.weight;for(t=0;i>t;++t)r=M[t],isNaN(r.x)&&(r.x=n("x",s)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof h)for(t=0;c>t;++t)u[t]=+h.call(this,x[t],t);else for(t=0;c>t;++t)u[t]=h;if(o=[],"function"==typeof p)for(t=0;c>t;++t)o[t]=+p.call(this,x[t],t);else for(t=0;c>t;++t)o[t]=p;if(a=[],"function"==typeof g)for(t=0;i>t;++t)a[t]=+g.call(this,M[t],t);else for(t=0;i>t;++t)a[t]=g;return l.resume()},l.resume=function(){return l.alpha(.1)},l.stop=function(){return l.alpha(0)},l.drag=function(){return r||(r=ao.behavior.drag().origin(m).on("dragstart.force",Qr).on("drag.force",t).on("dragend.force",ni)),arguments.length?void this.on("mouseover.force",ti).on("mouseout.force",ei).call(r):r},ao.rebind(l,c,"on")};var ml=20,Ml=1,xl=1/0;ao.layout.hierarchy=function(){function n(i){var u,o=[i],a=[];for(i.depth=0;null!=(u=o.pop());)if(a.push(u),(c=e.call(n,u,u.depth))&&(l=c.length)){for(var l,c,f;--l>=0;)o.push(f=c[l]),f.parent=u,f.depth=u.depth+1;r&&(u.value=0),u.children=c}else r&&(u.value=+r.call(n,u,u.depth)||0),delete u.children;return oi(i,function(n){var e,i;t&&(e=n.children)&&e.sort(t),r&&(i=n.parent)&&(i.value+=n.value)}),a}var t=ci,e=ai,r=li;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(ui(t,function(n){n.children&&(n.value=0)}),oi(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ao.layout.partition=function(){function n(t,e,r,i){var u=t.children;if(t.x=e,t.y=t.depth*i,t.dx=r,t.dy=i,u&&(o=u.length)){var o,a,l,c=-1;for(r=t.value?r/t.value:0;++c<o;)n(a=u[c],e,l=a.value*r,i),e+=l}}function t(n){var e=n.children,r=0;if(e&&(i=e.length))for(var i,u=-1;++u<i;)r=Math.max(r,t(e[u]));return 1+r}function e(e,u){var o=r.call(this,e,u);return n(o[0],0,i[0],i[1]/t(o[0])),o}var r=ao.layout.hierarchy(),i=[1,1];return e.size=function(n){return arguments.length?(i=n,e):i},ii(e,r)},ao.layout.pie=function(){function n(o){var a,l=o.length,c=o.map(function(e,r){return+t.call(n,e,r)}),f=+("function"==typeof r?r.apply(this,arguments):r),s=("function"==typeof i?i.apply(this,arguments):i)-f,h=Math.min(Math.abs(s)/l,+("function"==typeof u?u.apply(this,arguments):u)),p=h*(0>s?-1:1),g=ao.sum(c),v=g?(s-l*p)/g:0,d=ao.range(l),y=[];return null!=e&&d.sort(e===bl?function(n,t){return c[t]-c[n]}:function(n,t){return e(o[n],o[t])}),d.forEach(function(n){y[n]={data:o[n],value:a=c[n],startAngle:f,endAngle:f+=a*v+p,padAngle:h}}),y}var t=Number,e=bl,r=0,i=Ho,u=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(i=t,n):i},n.padAngle=function(t){return arguments.length?(u=t,n):u},n};var bl={};ao.layout.stack=function(){function n(a,l){if(!(h=a.length))return a;var c=a.map(function(e,r){return t.call(n,e,r)}),f=c.map(function(t){return t.map(function(t,e){return[u.call(n,t,e),o.call(n,t,e)]})}),s=e.call(n,f,l);c=ao.permute(c,s),f=ao.permute(f,s);var h,p,g,v,d=r.call(n,f,l),y=c[0].length;for(g=0;y>g;++g)for(i.call(n,c[0][g],v=d[g],f[0][g][1]),p=1;h>p;++p)i.call(n,c[p][g],v+=f[p-1][g][1],f[p][g][1]);return a}var t=m,e=gi,r=vi,i=pi,u=si,o=hi;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:_l.get(t)||gi,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:wl.get(t)||vi,n):r},n.x=function(t){return arguments.length?(u=t,n):u},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(i=t,n):i},n};var _l=ao.map({"inside-out":function(n){var t,e,r=n.length,i=n.map(di),u=n.map(yi),o=ao.range(r).sort(function(n,t){return i[n]-i[t]}),a=0,l=0,c=[],f=[];for(t=0;r>t;++t)e=o[t],l>a?(a+=u[e],c.push(e)):(l+=u[e],f.push(e));return f.reverse().concat(c)},reverse:function(n){return ao.range(n.length).reverse()},"default":gi}),wl=ao.map({silhouette:function(n){var t,e,r,i=n.length,u=n[0].length,o=[],a=0,l=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;u>e;++e)l[e]=(a-o[e])/2;return l},wiggle:function(n){var t,e,r,i,u,o,a,l,c,f=n.length,s=n[0],h=s.length,p=[];for(p[0]=l=c=0,e=1;h>e;++e){for(t=0,i=0;f>t;++t)i+=n[t][e][1];for(t=0,u=0,a=s[e][0]-s[e-1][0];f>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;u+=o*n[t][e][1]}p[e]=l-=i?u/i*a:0,c>l&&(c=l)}for(e=0;h>e;++e)p[e]-=c;return p},expand:function(n){var t,e,r,i=n.length,u=n[0].length,o=1/i,a=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];if(r)for(t=0;i>t;t++)n[t][e][1]/=r;else for(t=0;i>t;t++)n[t][e][1]=o}for(e=0;u>e;++e)a[e]=0;return a},zero:vi});ao.layout.histogram=function(){function n(n,u){for(var o,a,l=[],c=n.map(e,this),f=r.call(this,c,u),s=i.call(this,f,c,u),u=-1,h=c.length,p=s.length-1,g=t?1:1/h;++u<p;)o=l[u]=[],o.dx=s[u+1]-(o.x=s[u]),o.y=0;if(p>0)for(u=-1;++u<h;)a=c[u],a>=f[0]&&a<=f[1]&&(o=l[ao.bisect(s,a,1,p)-1],o.y+=g,o.push(n[u]));return l}var t=!0,e=Number,r=bi,i=Mi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=En(t),n):r},n.bins=function(t){return arguments.length?(i="number"==typeof t?function(n){return xi(n,t)}:En(t),n):i},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ao.layout.pack=function(){function n(n,u){var o=e.call(this,n,u),a=o[0],l=i[0],c=i[1],f=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,oi(a,function(n){n.r=+f(n.value)}),oi(a,Ni),r){var s=r*(t?1:Math.max(2*a.r/l,2*a.r/c))/2;oi(a,function(n){n.r+=s}),oi(a,Ni),oi(a,function(n){n.r-=s})}return Ci(a,l/2,c/2,t?1:1/Math.max(2*a.r/l,2*a.r/c)),o}var t,e=ao.layout.hierarchy().sort(_i),r=0,i=[1,1];return n.size=function(t){return arguments.length?(i=t,n):i},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},ii(n,e)},ao.layout.tree=function(){function n(n,i){var f=o.call(this,n,i),s=f[0],h=t(s);if(oi(h,e),h.parent.m=-h.z,ui(h,r),c)ui(s,u);else{var p=s,g=s,v=s;ui(s,function(n){n.x<p.x&&(p=n),n.x>g.x&&(g=n),n.depth>v.depth&&(v=n)});var d=a(p,g)/2-p.x,y=l[0]/(g.x+a(g,p)/2+d),m=l[1]/(v.depth||1);ui(s,function(n){n.x=(n.x+d)*y,n.y=n.depth*m})}return f}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var i,u=t.children,o=0,a=u.length;a>o;++o)r.push((u[o]=i={_:u[o],parent:t,children:(i=u[o].children)&&i.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=i);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Di(n);var u=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-u):n.z=u}else r&&(n.z=r.z+a(n._,r._));n.parent.A=i(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function i(n,t,e){if(t){for(var r,i=n,u=n,o=t,l=i.parent.children[0],c=i.m,f=u.m,s=o.m,h=l.m;o=Ti(o),i=qi(i),o&&i;)l=qi(l),u=Ti(u),u.a=n,r=o.z+s-i.z-c+a(o._,i._),r>0&&(Ri(Pi(o,n,e),n,r),c+=r,f+=r),s+=o.m,c+=i.m,h+=l.m,f+=u.m;o&&!Ti(u)&&(u.t=o,u.m+=s-f),i&&!qi(l)&&(l.t=i,l.m+=c-h,e=n)}return e}function u(n){n.x*=l[0],n.y=n.depth*l[1]}var o=ao.layout.hierarchy().sort(null).value(null),a=Li,l=[1,1],c=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(c=null==(l=t)?u:null,n):c?null:l},n.nodeSize=function(t){return arguments.length?(c=null==(l=t)?null:u,n):c?l:null},ii(n,o)},ao.layout.cluster=function(){function n(n,u){var o,a=t.call(this,n,u),l=a[0],c=0;oi(l,function(n){var t=n.children;t&&t.length?(n.x=ji(t),n.y=Ui(t)):(n.x=o?c+=e(n,o):0,n.y=0,o=n)});var f=Fi(l),s=Hi(l),h=f.x-e(f,s)/2,p=s.x+e(s,f)/2;return oi(l,i?function(n){n.x=(n.x-l.x)*r[0],n.y=(l.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(p-h)*r[0],n.y=(1-(l.y?n.y/l.y:1))*r[1]}),a}var t=ao.layout.hierarchy().sort(null).value(null),e=Li,r=[1,1],i=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(i=null==(r=t),n):i?null:r},n.nodeSize=function(t){return arguments.length?(i=null!=(r=t),n):i?r:null},ii(n,t)},ao.layout.treemap=function(){function n(n,t){for(var e,r,i=-1,u=n.length;++i<u;)r=(e=n[i]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var u=e.children;if(u&&u.length){var o,a,l,c=s(e),f=[],h=u.slice(),g=1/0,v="slice"===p?c.dx:"dice"===p?c.dy:"slice-dice"===p?1&e.depth?c.dy:c.dx:Math.min(c.dx,c.dy);for(n(h,c.dx*c.dy/e.value),f.area=0;(l=h.length)>0;)f.push(o=h[l-1]),f.area+=o.area,"squarify"!==p||(a=r(f,v))<=g?(h.pop(),g=a):(f.area-=f.pop().area,i(f,v,c,!1),v=Math.min(c.dx,c.dy),f.length=f.area=0,g=1/0);f.length&&(i(f,v,c,!0),f.length=f.area=0),u.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var u,o=s(t),a=r.slice(),l=[];for(n(a,o.dx*o.dy/t.value),l.area=0;u=a.pop();)l.push(u),l.area+=u.area,null!=u.z&&(i(l,u.z?o.dx:o.dy,o,!a.length),l.length=l.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,i=0,u=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(u>e&&(u=e),e>i&&(i=e));return r*=r,t*=t,r?Math.max(t*i*g/r,r/(t*u*g)):1/0}function i(n,t,e,r){var i,u=-1,o=n.length,a=e.x,c=e.y,f=t?l(n.area/t):0;
+if(t==e.dx){for((r||f>e.dy)&&(f=e.dy);++u<o;)i=n[u],i.x=a,i.y=c,i.dy=f,a+=i.dx=Math.min(e.x+e.dx-a,f?l(i.area/f):0);i.z=!0,i.dx+=e.x+e.dx-a,e.y+=f,e.dy-=f}else{for((r||f>e.dx)&&(f=e.dx);++u<o;)i=n[u],i.x=a,i.y=c,i.dx=f,c+=i.dy=Math.min(e.y+e.dy-c,f?l(i.area/f):0);i.z=!1,i.dy+=e.y+e.dy-c,e.x+=f,e.dx-=f}}function u(r){var i=o||a(r),u=i[0];return u.x=u.y=0,u.value?(u.dx=c[0],u.dy=c[1]):u.dx=u.dy=0,o&&a.revalue(u),n([u],u.dx*u.dy/u.value),(o?e:t)(u),h&&(o=i),i}var o,a=ao.layout.hierarchy(),l=Math.round,c=[1,1],f=null,s=Oi,h=!1,p="squarify",g=.5*(1+Math.sqrt(5));return u.size=function(n){return arguments.length?(c=n,u):c},u.padding=function(n){function t(t){var e=n.call(u,t,t.depth);return null==e?Oi(t):Ii(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return Ii(t,n)}if(!arguments.length)return f;var r;return s=null==(f=n)?Oi:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,u},u.round=function(n){return arguments.length?(l=n?Math.round:Number,u):l!=Number},u.sticky=function(n){return arguments.length?(h=n,o=null,u):h},u.ratio=function(n){return arguments.length?(g=n,u):g},u.mode=function(n){return arguments.length?(p=n+"",u):p},ii(u,a)},ao.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,i;do e=2*Math.random()-1,r=2*Math.random()-1,i=e*e+r*r;while(!i||i>1);return n+t*e*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(){var n=ao.random.normal.apply(ao,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ao.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ao.scale={};var Sl={floor:m,ceil:m};ao.scale.linear=function(){return Wi([0,1],[0,1],Mr,!1)};var kl={s:1,g:1,p:1,r:1,e:1};ao.scale.log=function(){return ru(ao.scale.linear().domain([0,1]),10,!0,[1,10])};var Nl=ao.format(".0e"),El={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ao.scale.pow=function(){return iu(ao.scale.linear(),1,[0,1])},ao.scale.sqrt=function(){return ao.scale.pow().exponent(.5)},ao.scale.ordinal=function(){return ou([],{t:"range",a:[[]]})},ao.scale.category10=function(){return ao.scale.ordinal().range(Al)},ao.scale.category20=function(){return ao.scale.ordinal().range(Cl)},ao.scale.category20b=function(){return ao.scale.ordinal().range(zl)},ao.scale.category20c=function(){return ao.scale.ordinal().range(Ll)};var Al=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(xn),Cl=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(xn),zl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(xn),Ll=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(xn);ao.scale.quantile=function(){return au([],[])},ao.scale.quantize=function(){return lu(0,1,[0,1])},ao.scale.threshold=function(){return cu([.5],[0,1])},ao.scale.identity=function(){return fu([0,1])},ao.svg={},ao.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),c=Math.max(0,+r.apply(this,arguments)),f=o.apply(this,arguments)-Io,s=a.apply(this,arguments)-Io,h=Math.abs(s-f),p=f>s?0:1;if(n>c&&(g=c,c=n,n=g),h>=Oo)return t(c,p)+(n?t(n,1-p):"")+"Z";var g,v,d,y,m,M,x,b,_,w,S,k,N=0,E=0,A=[];if((y=(+l.apply(this,arguments)||0)/2)&&(d=u===ql?Math.sqrt(n*n+c*c):+u.apply(this,arguments),p||(E*=-1),c&&(E=tn(d/c*Math.sin(y))),n&&(N=tn(d/n*Math.sin(y)))),c){m=c*Math.cos(f+E),M=c*Math.sin(f+E),x=c*Math.cos(s-E),b=c*Math.sin(s-E);var C=Math.abs(s-f-2*E)<=Fo?0:1;if(E&&yu(m,M,x,b)===p^C){var z=(f+s)/2;m=c*Math.cos(z),M=c*Math.sin(z),x=b=null}}else m=M=0;if(n){_=n*Math.cos(s-N),w=n*Math.sin(s-N),S=n*Math.cos(f+N),k=n*Math.sin(f+N);var L=Math.abs(f-s+2*N)<=Fo?0:1;if(N&&yu(_,w,S,k)===1-p^L){var q=(f+s)/2;_=n*Math.cos(q),w=n*Math.sin(q),S=k=null}}else _=w=0;if(h>Uo&&(g=Math.min(Math.abs(c-n)/2,+i.apply(this,arguments)))>.001){v=c>n^p?0:1;var T=g,R=g;if(Fo>h){var D=null==S?[_,w]:null==x?[m,M]:Re([m,M],[S,k],[x,b],[_,w]),P=m-D[0],U=M-D[1],j=x-D[0],F=b-D[1],H=1/Math.sin(Math.acos((P*j+U*F)/(Math.sqrt(P*P+U*U)*Math.sqrt(j*j+F*F)))/2),O=Math.sqrt(D[0]*D[0]+D[1]*D[1]);R=Math.min(g,(n-O)/(H-1)),T=Math.min(g,(c-O)/(H+1))}if(null!=x){var I=mu(null==S?[_,w]:[S,k],[m,M],c,T,p),Y=mu([x,b],[_,w],c,T,p);g===T?A.push("M",I[0],"A",T,",",T," 0 0,",v," ",I[1],"A",c,",",c," 0 ",1-p^yu(I[1][0],I[1][1],Y[1][0],Y[1][1]),",",p," ",Y[1],"A",T,",",T," 0 0,",v," ",Y[0]):A.push("M",I[0],"A",T,",",T," 0 1,",v," ",Y[0])}else A.push("M",m,",",M);if(null!=S){var Z=mu([m,M],[S,k],n,-R,p),V=mu([_,w],null==x?[m,M]:[x,b],n,-R,p);g===R?A.push("L",V[0],"A",R,",",R," 0 0,",v," ",V[1],"A",n,",",n," 0 ",p^yu(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-p," ",Z[1],"A",R,",",R," 0 0,",v," ",Z[0]):A.push("L",V[0],"A",R,",",R," 0 0,",v," ",Z[0])}else A.push("L",_,",",w)}else A.push("M",m,",",M),null!=x&&A.push("A",c,",",c," 0 ",C,",",p," ",x,",",b),A.push("L",_,",",w),null!=S&&A.push("A",n,",",n," 0 ",L,",",1-p," ",S,",",k);return A.push("Z"),A.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=hu,r=pu,i=su,u=ql,o=gu,a=vu,l=du;return n.innerRadius=function(t){return arguments.length?(e=En(t),n):e},n.outerRadius=function(t){return arguments.length?(r=En(t),n):r},n.cornerRadius=function(t){return arguments.length?(i=En(t),n):i},n.padRadius=function(t){return arguments.length?(u=t==ql?ql:En(t),n):u},n.startAngle=function(t){return arguments.length?(o=En(t),n):o},n.endAngle=function(t){return arguments.length?(a=En(t),n):a},n.padAngle=function(t){return arguments.length?(l=En(t),n):l},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Io;return[Math.cos(t)*n,Math.sin(t)*n]},n};var ql="auto";ao.svg.line=function(){return Mu(m)};var Tl=ao.map({linear:xu,"linear-closed":bu,step:_u,"step-before":wu,"step-after":Su,basis:zu,"basis-open":Lu,"basis-closed":qu,bundle:Tu,cardinal:Eu,"cardinal-open":ku,"cardinal-closed":Nu,monotone:Fu});Tl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Rl=[0,2/3,1/3,0],Dl=[0,1/3,2/3,0],Pl=[0,1/6,2/3,1/6];ao.svg.line.radial=function(){var n=Mu(Hu);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},wu.reverse=Su,Su.reverse=wu,ao.svg.area=function(){return Ou(m)},ao.svg.area.radial=function(){var n=Ou(Hu);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ao.svg.chord=function(){function n(n,a){var l=t(this,u,n,a),c=t(this,o,n,a);return"M"+l.p0+r(l.r,l.p1,l.a1-l.a0)+(e(l,c)?i(l.r,l.p1,l.r,l.p0):i(l.r,l.p1,c.r,c.p0)+r(c.r,c.p1,c.a1-c.a0)+i(c.r,c.p1,l.r,l.p0))+"Z"}function t(n,t,e,r){var i=t.call(n,e,r),u=a.call(n,i,r),o=l.call(n,i,r)-Io,f=c.call(n,i,r)-Io;return{r:u,a0:o,a1:f,p0:[u*Math.cos(o),u*Math.sin(o)],p1:[u*Math.cos(f),u*Math.sin(f)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Fo)+",1 "+t}function i(n,t,e,r){return"Q 0,0 "+r}var u=Me,o=xe,a=Iu,l=gu,c=vu;return n.radius=function(t){return arguments.length?(a=En(t),n):a},n.source=function(t){return arguments.length?(u=En(t),n):u},n.target=function(t){return arguments.length?(o=En(t),n):o},n.startAngle=function(t){return arguments.length?(l=En(t),n):l},n.endAngle=function(t){return arguments.length?(c=En(t),n):c},n},ao.svg.diagonal=function(){function n(n,i){var u=t.call(this,n,i),o=e.call(this,n,i),a=(u.y+o.y)/2,l=[u,{x:u.x,y:a},{x:o.x,y:a},o];return l=l.map(r),"M"+l[0]+"C"+l[1]+" "+l[2]+" "+l[3]}var t=Me,e=xe,r=Yu;return n.source=function(e){return arguments.length?(t=En(e),n):t},n.target=function(t){return arguments.length?(e=En(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ao.svg.diagonal.radial=function(){var n=ao.svg.diagonal(),t=Yu,e=n.projection;return n.projection=function(n){return arguments.length?e(Zu(t=n)):t},n},ao.svg.symbol=function(){function n(n,r){return(Ul.get(t.call(this,n,r))||$u)(e.call(this,n,r))}var t=Xu,e=Vu;return n.type=function(e){return arguments.length?(t=En(e),n):t},n.size=function(t){return arguments.length?(e=En(t),n):e},n};var Ul=ao.map({circle:$u,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Fl)),e=t*Fl;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ao.svg.symbolTypes=Ul.keys();var jl=Math.sqrt(3),Fl=Math.tan(30*Yo);Co.transition=function(n){for(var t,e,r=Hl||++Zl,i=Ku(n),u=[],o=Ol||{time:Date.now(),ease:Nr,delay:0,duration:250},a=-1,l=this.length;++a<l;){u.push(t=[]);for(var c=this[a],f=-1,s=c.length;++f<s;)(e=c[f])&&Qu(e,f,i,r,o),t.push(e)}return Wu(u,i,r)},Co.interrupt=function(n){return this.each(null==n?Il:Bu(Ku(n)))};var Hl,Ol,Il=Bu(Ku()),Yl=[],Zl=0;Yl.call=Co.call,Yl.empty=Co.empty,Yl.node=Co.node,Yl.size=Co.size,ao.transition=function(n,t){return n&&n.transition?Hl?n.transition(t):n:ao.selection().transition(n)},ao.transition.prototype=Yl,Yl.select=function(n){var t,e,r,i=this.id,u=this.namespace,o=[];n=A(n);for(var a=-1,l=this.length;++a<l;){o.push(t=[]);for(var c=this[a],f=-1,s=c.length;++f<s;)(r=c[f])&&(e=n.call(r,r.__data__,f,a))?("__data__"in r&&(e.__data__=r.__data__),Qu(e,f,u,i,r[u][i]),t.push(e)):t.push(null)}return Wu(o,u,i)},Yl.selectAll=function(n){var t,e,r,i,u,o=this.id,a=this.namespace,l=[];n=C(n);for(var c=-1,f=this.length;++c<f;)for(var s=this[c],h=-1,p=s.length;++h<p;)if(r=s[h]){u=r[a][o],e=n.call(r,r.__data__,h,c),l.push(t=[]);for(var g=-1,v=e.length;++g<v;)(i=e[g])&&Qu(i,g,a,o,u),t.push(i)}return Wu(l,a,o)},Yl.filter=function(n){var t,e,r,i=[];"function"!=typeof n&&(n=O(n));for(var u=0,o=this.length;o>u;u++){i.push(t=[]);for(var e=this[u],a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return Wu(i,this.namespace,this.id)},Yl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(i){i[r][e].tween.set(n,t)})},Yl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function i(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function u(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?$r:Mr,a=ao.ns.qualify(n);return Ju(this,"attr."+n,t,a.local?u:i)},Yl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(i));return r&&function(n){this.setAttribute(i,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(i.space,i.local));return r&&function(n){this.setAttributeNS(i.space,i.local,r(n))}}var i=ao.ns.qualify(n);return this.tween("attr."+n,i.local?r:e)},Yl.style=function(n,e,r){function i(){this.style.removeProperty(n)}function u(e){return null==e?i:(e+="",function(){var i,u=t(this).getComputedStyle(this,null).getPropertyValue(n);return u!==e&&(i=Mr(u,e),function(t){this.style.setProperty(n,i(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Ju(this,"style."+n,e,u)},Yl.styleTween=function(n,e,r){function i(i,u){var o=e.call(this,i,u,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,i)},Yl.text=function(n){return Ju(this,"text",n,Gu)},Yl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Yl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ao.ease.apply(ao,arguments)),Y(this,function(r){r[e][t].ease=n}))},Yl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,i,u){r[e][t].delay=+n.call(r,r.__data__,i,u)}:(n=+n,function(r){r[e][t].delay=n}))},Yl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,i,u){r[e][t].duration=Math.max(1,n.call(r,r.__data__,i,u))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Yl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var i=Ol,u=Hl;try{Hl=e,Y(this,function(t,i,u){Ol=t[r][e],n.call(t,t.__data__,i,u)})}finally{Ol=i,Hl=u}}else Y(this,function(i){var u=i[r][e];(u.event||(u.event=ao.dispatch("start","end","interrupt"))).on(n,t)});return this},Yl.transition=function(){for(var n,t,e,r,i=this.id,u=++Zl,o=this.namespace,a=[],l=0,c=this.length;c>l;l++){a.push(n=[]);for(var t=this[l],f=0,s=t.length;s>f;f++)(e=t[f])&&(r=e[o][i],Qu(e,f,o,u,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Wu(a,o,u)},ao.svg.axis=function(){function n(n){n.each(function(){var n,c=ao.select(this),f=this.__chart__||e,s=this.__chart__=e.copy(),h=null==l?s.ticks?s.ticks.apply(s,a):s.domain():l,p=null==t?s.tickFormat?s.tickFormat.apply(s,a):m:t,g=c.selectAll(".tick").data(h,s),v=g.enter().insert("g",".domain").attr("class","tick").style("opacity",Uo),d=ao.transition(g.exit()).style("opacity",Uo).remove(),y=ao.transition(g.order()).style("opacity",1),M=Math.max(i,0)+o,x=Zi(s),b=c.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ao.transition(b));v.append("line"),v.append("text");var w,S,k,N,E=v.select("line"),A=y.select("line"),C=g.select("text").text(p),z=v.select("text"),L=y.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=no,w="x",k="y",S="x2",N="y2",C.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+q*u+"V0H"+x[1]+"V"+q*u)):(n=to,w="y",k="x",S="y2",N="x2",C.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),_.attr("d","M"+q*u+","+x[0]+"H0V"+x[1]+"H"+q*u)),E.attr(N,q*i),z.attr(k,q*M),A.attr(S,0).attr(N,q*i),L.attr(w,0).attr(k,q*M),s.rangeBand){var T=s,R=T.rangeBand()/2;f=s=function(n){return T(n)+R}}else f.rangeBand?f=s:d.call(n,s,f);v.call(n,f,s),y.call(n,s,s)})}var t,e=ao.scale.linear(),r=Vl,i=6,u=6,o=3,a=[10],l=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Xl?t+"":Vl,n):r},n.ticks=function(){return arguments.length?(a=co(arguments),n):a},n.tickValues=function(t){return arguments.length?(l=t,n):l},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(i=+t,u=+arguments[e-1],n):i},n.innerTickSize=function(t){return arguments.length?(i=+t,n):i},n.outerTickSize=function(t){return arguments.length?(u=+t,n):u},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Vl="bottom",Xl={top:1,right:1,bottom:1,left:1};ao.svg.brush=function(){function n(t){t.each(function(){var t=ao.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,m);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return $l[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,s=ao.transition(t),h=ao.transition(o);c&&(l=Zi(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),r(s)),f&&(l=Zi(f),h.attr("y",l[0]).attr("height",l[1]-l[0]),i(s)),e(s)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function i(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function u(){function u(){32==ao.event.keyCode&&(C||(M=null,L[0]-=s[1],L[1]-=h[1],C=2),S())}function v(){32==ao.event.keyCode&&2==C&&(L[0]+=s[1],L[1]+=h[1],C=0,S())}function d(){var n=ao.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ao.event.altKey?(M||(M=[(s[0]+s[1])/2,(h[0]+h[1])/2]),L[0]=s[+(n[0]<M[0])],L[1]=h[+(n[1]<M[1])]):M=null),E&&y(n,c,0)&&(r(k),t=!0),A&&y(n,f,1)&&(i(k),t=!0),t&&(e(k),w({type:"brush",mode:C?"move":"resize"}))}function y(n,t,e){var r,i,u=Zi(t),l=u[0],c=u[1],f=L[e],v=e?h:s,d=v[1]-v[0];return C&&(l-=f,c-=d+f),r=(e?g:p)?Math.max(l,Math.min(c,n[e])):n[e],C?i=(r+=f)+d:(M&&(f=Math.max(l,Math.min(c,2*M[e]-r))),r>f?(i=r,r=f):i=f),v[0]!=r||v[1]!=i?(e?a=null:o=null,v[0]=r,v[1]=i,!0):void 0}function m(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ao.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ao.select(ao.event.target),w=l.of(b,arguments),k=ao.select(b),N=_.datum(),E=!/^(n|s)$/.test(N)&&c,A=!/^(e|w)$/.test(N)&&f,C=_.classed("extent"),z=W(b),L=ao.mouse(b),q=ao.select(t(b)).on("keydown.brush",u).on("keyup.brush",v);if(ao.event.changedTouches?q.on("touchmove.brush",d).on("touchend.brush",m):q.on("mousemove.brush",d).on("mouseup.brush",m),k.interrupt().selectAll("*").interrupt(),C)L[0]=s[0]-L[0],L[1]=h[0]-L[1];else if(N){var T=+/w$/.test(N),R=+/^n/.test(N);x=[s[1-T]-L[0],h[1-R]-L[1]],L[0]=s[T],L[1]=h[R]}else ao.event.altKey&&(M=L.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ao.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,l=N(n,"brushstart","brush","brushend"),c=null,f=null,s=[0,0],h=[0,0],p=!0,g=!0,v=Bl[0];return n.event=function(n){n.each(function(){var n=l.of(this,arguments),t={x:s,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Hl?ao.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,s=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=xr(s,t.x),r=xr(h,t.y);return o=a=null,function(i){s=t.x=e(i),h=t.y=r(i),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,v=Bl[!c<<1|!f],n):c},n.y=function(t){return arguments.length?(f=t,v=Bl[!c<<1|!f],n):f},n.clamp=function(t){return arguments.length?(c&&f?(p=!!t[0],g=!!t[1]):c?p=!!t:f&&(g=!!t),n):c&&f?[p,g]:c?p:f?g:null},n.extent=function(t){var e,r,i,u,l;return arguments.length?(c&&(e=t[0],r=t[1],f&&(e=e[0],r=r[0]),o=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(l=e,e=r,r=l),e==s[0]&&r==s[1]||(s=[e,r])),f&&(i=t[0],u=t[1],c&&(i=i[1],u=u[1]),a=[i,u],f.invert&&(i=f(i),u=f(u)),i>u&&(l=i,i=u,u=l),i==h[0]&&u==h[1]||(h=[i,u])),n):(c&&(o?(e=o[0],r=o[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(l=e,e=r,r=l))),f&&(a?(i=a[0],u=a[1]):(i=h[0],u=h[1],f.invert&&(i=f.invert(i),u=f.invert(u)),i>u&&(l=i,i=u,u=l))),c&&f?[[e,i],[r,u]]:c?[e,r]:f&&[i,u])},n.clear=function(){return n.empty()||(s=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!f&&h[0]==h[1]},ao.rebind(n,l,"on")};var $l={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Bl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Wl=ga.format=xa.timeFormat,Jl=Wl.utc,Gl=Jl("%Y-%m-%dT%H:%M:%S.%LZ");Wl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?eo:Gl,eo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},eo.toString=Gl.toString,ga.second=On(function(n){return new va(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ga.seconds=ga.second.range,ga.seconds.utc=ga.second.utc.range,ga.minute=On(function(n){return new va(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ga.minutes=ga.minute.range,ga.minutes.utc=ga.minute.utc.range,ga.hour=On(function(n){var t=n.getTimezoneOffset()/60;return new va(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ga.hours=ga.hour.range,ga.hours.utc=ga.hour.utc.range,ga.month=On(function(n){return n=ga.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ga.months=ga.month.range,ga.months.utc=ga.month.utc.range;var Kl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Ql=[[ga.second,1],[ga.second,5],[ga.second,15],[ga.second,30],[ga.minute,1],[ga.minute,5],[ga.minute,15],[ga.minute,30],[ga.hour,1],[ga.hour,3],[ga.hour,6],[ga.hour,12],[ga.day,1],[ga.day,2],[ga.week,1],[ga.month,1],[ga.month,3],[ga.year,1]],nc=Wl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",zt]]),tc={range:function(n,t,e){return ao.range(Math.ceil(n/e)*e,+t,e).map(io)},floor:m,ceil:m};Ql.year=ga.year,ga.scale=function(){return ro(ao.scale.linear(),Ql,nc)};var ec=Ql.map(function(n){return[n[0].utc,n[1]]}),rc=Jl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",zt]]);ec.year=ga.year.utc,ga.scale.utc=function(){return ro(ao.scale.linear(),ec,rc)},ao.text=An(function(n){return n.responseText}),ao.json=function(n,t){return Cn(n,"application/json",uo,t)},ao.html=function(n,t){return Cn(n,"text/html",oo,t)},ao.xml=An(function(n){return n.responseXML}),"function"==typeof define&&define.amd?(this.d3=ao,define(ao)):"object"==typeof module&&module.exports?module.exports=ao:this.d3=ao}();
\ No newline at end of file
diff --git a/client/client-monitoring/src/main/resources/webapp/js/jquery/jquery-1.12.4.js b/client/client-monitoring/src/main/resources/webapp/js/jquery/jquery-1.12.4.js
new file mode 100644
index 0000000..13ca477
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/js/jquery/jquery-1.12.4.js
@@ -0,0 +1,13201 @@
+/*!
+ * jQuery JavaScript Library v1.12.4
+ * http://jquery.com/
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2016-05-20T17:17Z
+ */
+
+(function(global, factory) {
+
+	if (typeof module === "object" && typeof module.exports === "object") {
+		// For CommonJS and CommonJS-like environments where a proper `window`
+		// is present, execute the factory and get jQuery.
+		// For environments that do not have a `window` with a `document`
+		// (such as Node.js), expose a factory as module.exports.
+		// This accentuates the need for the creation of a real `window`.
+		// e.g. var jQuery = require("jquery")(window);
+		// See ticket #14549 for more info.
+		module.exports = global.document ? factory(global, true) : function(w) {
+			if (!w.document) {
+				throw new Error("jQuery requires a window with a document");
+			}
+			return factory(w);
+		};
+	} else {
+		factory(global);
+	}
+
+	// Pass this if window is not defined yet
+}
+		(
+				typeof window !== "undefined" ? window : this,
+				function(window, noGlobal) {
+
+					// Support: Firefox 18+
+					// Can't be in strict mode, several libs including ASP.NET
+					// trace
+					// the stack via arguments.caller.callee and Firefox dies if
+					// you try to trace through "use strict" call chains.
+					// (#13335)
+					// "use strict";
+					var deletedIds = [];
+
+					var document = window.document;
+
+					var slice = deletedIds.slice;
+
+					var concat = deletedIds.concat;
+
+					var push = deletedIds.push;
+
+					var indexOf = deletedIds.indexOf;
+
+					var class2type = {};
+
+					var toString = class2type.toString;
+
+					var hasOwn = class2type.hasOwnProperty;
+
+					var support = {};
+
+					var version = "1.12.4",
+
+					// Define a local copy of jQuery
+					jQuery = function(selector, context) {
+
+						// The jQuery object is actually just the init
+						// constructor 'enhanced'
+						// Need init if jQuery is called (just allow error to be
+						// thrown if not included)
+						return new jQuery.fn.init(selector, context);
+					},
+
+					// Support: Android<4.1, IE<9
+					// Make sure we trim BOM and NBSP
+					rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
+
+					// Matches dashed string for camelizing
+					rmsPrefix = /^-ms-/, rdashAlpha = /-([\da-z])/gi,
+
+					// Used by jQuery.camelCase as callback to replace()
+					fcamelCase = function(all, letter) {
+						return letter.toUpperCase();
+					};
+
+					jQuery.fn = jQuery.prototype = {
+
+						// The current version of jQuery being used
+						jquery : version,
+
+						constructor : jQuery,
+
+						// Start with an empty selector
+						selector : "",
+
+						// The default length of a jQuery object is 0
+						length : 0,
+
+						toArray : function() {
+							return slice.call(this);
+						},
+
+						// Get the Nth element in the matched element set OR
+						// Get the whole matched element set as a clean array
+						get : function(num) {
+							return num != null ?
+
+							// Return just the one element from the set
+							(num < 0 ? this[num + this.length] : this[num]) :
+
+							// Return all the elements in a clean array
+							slice.call(this);
+						},
+
+						// Take an array of elements and push it onto the stack
+						// (returning the new matched element set)
+						pushStack : function(elems) {
+
+							// Build a new jQuery matched element set
+							var ret = jQuery.merge(this.constructor(), elems);
+
+							// Add the old object onto the stack (as a
+							// reference)
+							ret.prevObject = this;
+							ret.context = this.context;
+
+							// Return the newly-formed element set
+							return ret;
+						},
+
+						// Execute a callback for every element in the matched
+						// set.
+						each : function(callback) {
+							return jQuery.each(this, callback);
+						},
+
+						map : function(callback) {
+							return this.pushStack(jQuery.map(this, function(
+									elem, i) {
+								return callback.call(elem, i, elem);
+							}));
+						},
+
+						slice : function() {
+							return this.pushStack(slice.apply(this, arguments));
+						},
+
+						first : function() {
+							return this.eq(0);
+						},
+
+						last : function() {
+							return this.eq(-1);
+						},
+
+						eq : function(i) {
+							var len = this.length, j = +i + (i < 0 ? len : 0);
+							return this
+									.pushStack(j >= 0 && j < len ? [ this[j] ]
+											: []);
+						},
+
+						end : function() {
+							return this.prevObject || this.constructor();
+						},
+
+						// For internal use only.
+						// Behaves like an Array's method, not like a jQuery
+						// method.
+						push : push,
+						sort : deletedIds.sort,
+						splice : deletedIds.splice
+					};
+
+					jQuery.extend = jQuery.fn.extend = function() {
+						var src, copyIsArray, copy, name, options, clone, target = arguments[0]
+								|| {}, i = 1, length = arguments.length, deep = false;
+
+						// Handle a deep copy situation
+						if (typeof target === "boolean") {
+							deep = target;
+
+							// skip the boolean and the target
+							target = arguments[i] || {};
+							i++;
+						}
+
+						// Handle case when target is a string or something
+						// (possible in deep copy)
+						if (typeof target !== "object"
+								&& !jQuery.isFunction(target)) {
+							target = {};
+						}
+
+						// extend jQuery itself if only one argument is passed
+						if (i === length) {
+							target = this;
+							i--;
+						}
+
+						for (; i < length; i++) {
+
+							// Only deal with non-null/undefined values
+							if ((options = arguments[i]) != null) {
+
+								// Extend the base object
+								for (name in options) {
+									src = target[name];
+									copy = options[name];
+
+									// Prevent never-ending loop
+									if (target === copy) {
+										continue;
+									}
+
+									// Recurse if we're merging plain objects or
+									// arrays
+									if (deep
+											&& copy
+											&& (jQuery.isPlainObject(copy) || (copyIsArray = jQuery
+													.isArray(copy)))) {
+
+										if (copyIsArray) {
+											copyIsArray = false;
+											clone = src && jQuery.isArray(src) ? src
+													: [];
+
+										} else {
+											clone = src
+													&& jQuery
+															.isPlainObject(src) ? src
+													: {};
+										}
+
+										// Never move original objects, clone
+										// them
+										target[name] = jQuery.extend(deep,
+												clone, copy);
+
+										// Don't bring in undefined values
+									} else if (copy !== undefined) {
+										target[name] = copy;
+									}
+								}
+							}
+						}
+
+						// Return the modified object
+						return target;
+					};
+
+					jQuery
+							.extend({
+
+								// Unique for each copy of jQuery on the page
+								expando : "jQuery"
+										+ (version + Math.random()).replace(
+												/\D/g, ""),
+
+								// Assume jQuery is ready without the ready
+								// module
+								isReady : true,
+
+								error : function(msg) {
+									throw new Error(msg);
+								},
+
+								noop : function() {
+								},
+
+								// See test/unit/core.js for details concerning
+								// isFunction.
+								// Since version 1.3, DOM methods and functions
+								// like alert
+								// aren't supported. They return false on IE
+								// (#2968).
+								isFunction : function(obj) {
+									return jQuery.type(obj) === "function";
+								},
+
+								isArray : Array.isArray || function(obj) {
+									return jQuery.type(obj) === "array";
+								},
+
+								isWindow : function(obj) {
+									/* jshint eqeqeq: false */
+									return obj != null && obj == obj.window;
+								},
+
+								isNumeric : function(obj) {
+
+									// parseFloat NaNs numeric-cast false
+									// positives (null|true|false|"")
+									// ...but misinterprets leading-number
+									// strings, particularly hex literals
+									// ("0x...")
+									// subtraction forces infinities to NaN
+									// adding 1 corrects loss of precision from
+									// parseFloat (#15100)
+									var realStringObj = obj && obj.toString();
+									return !jQuery.isArray(obj)
+											&& (realStringObj
+													- parseFloat(realStringObj) + 1) >= 0;
+								},
+
+								isEmptyObject : function(obj) {
+									var name;
+									for (name in obj) {
+										return false;
+									}
+									return true;
+								},
+
+								isPlainObject : function(obj) {
+									var key;
+
+									// Must be an Object.
+									// Because of IE, we also have to check the
+									// presence of the constructor property.
+									// Make sure that DOM nodes and window
+									// objects don't pass through, as well
+									if (!obj || jQuery.type(obj) !== "object"
+											|| obj.nodeType
+											|| jQuery.isWindow(obj)) {
+										return false;
+									}
+
+									try {
+
+										// Not own constructor property must be
+										// Object
+										if (obj.constructor
+												&& !hasOwn.call(obj,
+														"constructor")
+												&& !hasOwn
+														.call(
+																obj.constructor.prototype,
+																"isPrototypeOf")) {
+											return false;
+										}
+									} catch (e) {
+
+										// IE8,9 Will throw exceptions on
+										// certain host objects #9897
+										return false;
+									}
+
+									// Support: IE<9
+									// Handle iteration over inherited
+									// properties before own properties.
+									if (!support.ownFirst) {
+										for (key in obj) {
+											return hasOwn.call(obj, key);
+										}
+									}
+
+									// Own properties are enumerated firstly, so
+									// to speed up,
+									// if last one is own, then all properties
+									// are own.
+									for (key in obj) {
+									}
+
+									return key === undefined
+											|| hasOwn.call(obj, key);
+								},
+
+								type : function(obj) {
+									if (obj == null) {
+										return obj + "";
+									}
+									return typeof obj === "object"
+											|| typeof obj === "function" ? class2type[toString
+											.call(obj)]
+											|| "object"
+											: typeof obj;
+								},
+
+								// Workarounds based on findings by Jim Driscoll
+								// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
+								globalEval : function(data) {
+									if (data && jQuery.trim(data)) {
+
+										// We use execScript on Internet
+										// Explorer
+										// We use an anonymous function so that
+										// context is window
+										// rather than jQuery in Firefox
+										(window.execScript || function(data) {
+											window["eval"].call(window, data); // jscs:ignore
+																				// requireDotNotation
+										})(data);
+									}
+								},
+
+								// Convert dashed to camelCase; used by the css
+								// and data modules
+								// Microsoft forgot to hump their vendor prefix
+								// (#9572)
+								camelCase : function(string) {
+									return string.replace(rmsPrefix, "ms-")
+											.replace(rdashAlpha, fcamelCase);
+								},
+
+								nodeName : function(elem, name) {
+									return elem.nodeName
+											&& elem.nodeName.toLowerCase() === name
+													.toLowerCase();
+								},
+
+								each : function(obj, callback) {
+									var length, i = 0;
+
+									if (isArrayLike(obj)) {
+										length = obj.length;
+										for (; i < length; i++) {
+											if (callback
+													.call(obj[i], i, obj[i]) === false) {
+												break;
+											}
+										}
+									} else {
+										for (i in obj) {
+											if (callback
+													.call(obj[i], i, obj[i]) === false) {
+												break;
+											}
+										}
+									}
+
+									return obj;
+								},
+
+								// Support: Android<4.1, IE<9
+								trim : function(text) {
+									return text == null ? "" : (text + "")
+											.replace(rtrim, "");
+								},
+
+								// results is for internal usage only
+								makeArray : function(arr, results) {
+									var ret = results || [];
+
+									if (arr != null) {
+										if (isArrayLike(Object(arr))) {
+											jQuery
+													.merge(
+															ret,
+															typeof arr === "string" ? [ arr ]
+																	: arr);
+										} else {
+											push.call(ret, arr);
+										}
+									}
+
+									return ret;
+								},
+
+								inArray : function(elem, arr, i) {
+									var len;
+
+									if (arr) {
+										if (indexOf) {
+											return indexOf.call(arr, elem, i);
+										}
+
+										len = arr.length;
+										i = i ? i < 0 ? Math.max(0, len + i)
+												: i : 0;
+
+										for (; i < len; i++) {
+
+											// Skip accessing in sparse arrays
+											if (i in arr && arr[i] === elem) {
+												return i;
+											}
+										}
+									}
+
+									return -1;
+								},
+
+								merge : function(first, second) {
+									var len = +second.length, j = 0, i = first.length;
+
+									while (j < len) {
+										first[i++] = second[j++];
+									}
+
+									// Support: IE<9
+									// Workaround casting of .length to NaN on
+									// otherwise arraylike objects (e.g.,
+									// NodeLists)
+									if (len !== len) {
+										while (second[j] !== undefined) {
+											first[i++] = second[j++];
+										}
+									}
+
+									first.length = i;
+
+									return first;
+								},
+
+								grep : function(elems, callback, invert) {
+									var callbackInverse, matches = [], i = 0, length = elems.length, callbackExpect = !invert;
+
+									// Go through the array, only saving the
+									// items
+									// that pass the validator function
+									for (; i < length; i++) {
+										callbackInverse = !callback(elems[i], i);
+										if (callbackInverse !== callbackExpect) {
+											matches.push(elems[i]);
+										}
+									}
+
+									return matches;
+								},
+
+								// arg is for internal usage only
+								map : function(elems, callback, arg) {
+									var length, value, i = 0, ret = [];
+
+									// Go through the array, translating each of
+									// the items to their new values
+									if (isArrayLike(elems)) {
+										length = elems.length;
+										for (; i < length; i++) {
+											value = callback(elems[i], i, arg);
+
+											if (value != null) {
+												ret.push(value);
+											}
+										}
+
+										// Go through every key on the object,
+									} else {
+										for (i in elems) {
+											value = callback(elems[i], i, arg);
+
+											if (value != null) {
+												ret.push(value);
+											}
+										}
+									}
+
+									// Flatten any nested arrays
+									return concat.apply([], ret);
+								},
+
+								// A global GUID counter for objects
+								guid : 1,
+
+								// Bind a function to a context, optionally
+								// partially applying any
+								// arguments.
+								proxy : function(fn, context) {
+									var args, proxy, tmp;
+
+									if (typeof context === "string") {
+										tmp = fn[context];
+										context = fn;
+										fn = tmp;
+									}
+
+									// Quick check to determine if target is
+									// callable, in the spec
+									// this throws a TypeError, but we will just
+									// return undefined.
+									if (!jQuery.isFunction(fn)) {
+										return undefined;
+									}
+
+									// Simulated bind
+									args = slice.call(arguments, 2);
+									proxy = function() {
+										return fn.apply(context || this, args
+												.concat(slice.call(arguments)));
+									};
+
+									// Set the guid of unique handler to the
+									// same of original handler, so it can be
+									// removed
+									proxy.guid = fn.guid = fn.guid
+											|| jQuery.guid++;
+
+									return proxy;
+								},
+
+								now : function() {
+									return +(new Date());
+								},
+
+								// jQuery.support is not used in Core but other
+								// projects attach their
+								// properties to it so it needs to exist.
+								support : support
+							});
+
+					// JSHint would error on this code due to the Symbol not
+					// being defined in ES5.
+					// Defining this global in .jshintrc would create a danger
+					// of using the global
+					// unguarded in another place, it seems safer to just
+					// disable JSHint for these
+					// three lines.
+					/* jshint ignore: start */
+					if (typeof Symbol === "function") {
+						jQuery.fn[Symbol.iterator] = deletedIds[Symbol.iterator];
+					}
+					/* jshint ignore: end */
+
+					// Populate the class2type map
+					jQuery.each(
+							"Boolean Number String Function Array Date RegExp Object Error Symbol"
+									.split(" "), function(i, name) {
+								class2type["[object " + name + "]"] = name
+										.toLowerCase();
+							});
+
+					function isArrayLike(obj) {
+
+						// Support: iOS 8.2 (not reproducible in simulator)
+						// `in` check used to prevent JIT error (gh-2145)
+						// hasOwn isn't used here due to false negatives
+						// regarding Nodelist length in IE
+						var length = !!obj && "length" in obj && obj.length, type = jQuery
+								.type(obj);
+
+						if (type === "function" || jQuery.isWindow(obj)) {
+							return false;
+						}
+
+						return type === "array" || length === 0
+								|| typeof length === "number" && length > 0
+								&& (length - 1) in obj;
+					}
+					var Sizzle =
+					/*
+					 * ! Sizzle CSS Selector Engine v2.2.1 http://sizzlejs.com/
+					 * 
+					 * Copyright jQuery Foundation and other contributors
+					 * Released under the MIT license http://jquery.org/license
+					 * 
+					 * Date: 2015-10-17
+					 */
+					(function(window) {
+
+						var i, support, Expr, getText, isXML, tokenize, compile, select, outermostContext, sortInput, hasDuplicate,
+
+						// Local document vars
+						setDocument, document, docElem, documentIsHTML, rbuggyQSA, rbuggyMatches, matches, contains,
+
+						// Instance-specific data
+						expando = "sizzle" + 1 * new Date(), preferredDoc = window.document, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), sortOrder = function(
+								a, b) {
+							if (a === b) {
+								hasDuplicate = true;
+							}
+							return 0;
+						},
+
+						// General-purpose constants
+						MAX_NEGATIVE = 1 << 31,
+
+						// Instance methods
+						hasOwn = ({}).hasOwnProperty, arr = [], pop = arr.pop, push_native = arr.push, push = arr.push, slice = arr.slice,
+						// Use a stripped-down indexOf as it's faster than
+						// native
+						// http://jsperf.com/thor-indexof-vs-for/5
+						indexOf = function(list, elem) {
+							var i = 0, len = list.length;
+							for (; i < len; i++) {
+								if (list[i] === elem) {
+									return i;
+								}
+							}
+							return -1;
+						},
+
+						booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
+
+						// Regular expressions
+
+						// http://www.w3.org/TR/css3-selectors/#whitespace
+						whitespace = "[\\x20\\t\\r\\n\\f]",
+
+						// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+						identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
+
+						// Attribute selectors:
+						// http://www.w3.org/TR/selectors/#attribute-selectors
+						attributes = "\\[" + whitespace + "*(" + identifier
+								+ ")(?:" + whitespace +
+								// Operator (capture 2)
+								"*([*^$|!~]?=)" + whitespace +
+								// "Attribute values must be CSS identifiers
+								// [capture 5] or strings [capture 3 or capture
+								// 4]"
+								"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("
+								+ identifier + "))|)" + whitespace + "*\\]",
+
+						pseudos = ":(" + identifier + ")(?:\\((" +
+						// To reduce the number of selectors needing tokenize in
+						// the preFilter, prefer arguments:
+						// 1. quoted (capture 3; capture 4 or capture 5)
+						"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|"
+								+
+								// 2. simple (capture 6)
+								"((?:\\\\.|[^\\\\()[\\]]|" + attributes
+								+ ")*)|" +
+								// 3. anything else (capture 2)
+								".*" + ")\\)|)",
+
+						// Leading and non-escaped trailing whitespace,
+						// capturing some non-whitespace characters preceding
+						// the latter
+						rwhitespace = new RegExp(whitespace + "+", "g"), rtrim = new RegExp(
+								"^" + whitespace
+										+ "+|((?:^|[^\\\\])(?:\\\\.)*)"
+										+ whitespace + "+$", "g"),
+
+						rcomma = new RegExp("^" + whitespace + "*,"
+								+ whitespace + "*"), rcombinators = new RegExp(
+								"^" + whitespace + "*([>+~]|" + whitespace
+										+ ")" + whitespace + "*"),
+
+						rattributeQuotes = new RegExp("=" + whitespace
+								+ "*([^\\]'\"]*?)" + whitespace + "*\\]", "g"),
+
+						rpseudo = new RegExp(pseudos), ridentifier = new RegExp(
+								"^" + identifier + "$"),
+
+						matchExpr = {
+							"ID" : new RegExp("^#(" + identifier + ")"),
+							"CLASS" : new RegExp("^\\.(" + identifier + ")"),
+							"TAG" : new RegExp("^(" + identifier + "|[*])"),
+							"ATTR" : new RegExp("^" + attributes),
+							"PSEUDO" : new RegExp("^" + pseudos),
+							"CHILD" : new RegExp(
+									"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("
+											+ whitespace
+											+ "*(even|odd|(([+-]|)(\\d*)n|)"
+											+ whitespace + "*(?:([+-]|)"
+											+ whitespace + "*(\\d+)|))"
+											+ whitespace + "*\\)|)", "i"),
+							"bool" : new RegExp("^(?:" + booleans + ")$", "i"),
+							// For use in libraries implementing .is()
+							// We use this for POS matching in `select`
+							"needsContext" : new RegExp(
+									"^"
+											+ whitespace
+											+ "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("
+											+ whitespace + "*((?:-\\d)?\\d*)"
+											+ whitespace + "*\\)|)(?=[^-]|$)",
+									"i")
+						},
+
+						rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i,
+
+						rnative = /^[^{]+\{\s*\[native \w/,
+
+						// Easily-parseable/retrievable ID or TAG or CLASS
+						// selectors
+						rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+						rsibling = /[+~]/, rescape = /'|\\/g,
+
+						// CSS escapes
+						// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+						runescape = new RegExp("\\\\([\\da-f]{1,6}"
+								+ whitespace + "?|(" + whitespace + ")|.)",
+								"ig"), funescape = function(_, escaped,
+								escapedWhitespace) {
+							var high = "0x" + escaped - 0x10000;
+							// NaN means non-codepoint
+							// Support: Firefox<24
+							// Workaround erroneous numeric interpretation of
+							// +"0x"
+							return high !== high || escapedWhitespace ? escaped
+									: high < 0 ?
+									// BMP codepoint
+									String.fromCharCode(high + 0x10000) :
+									// Supplemental Plane codepoint (surrogate
+									// pair)
+									String.fromCharCode(high >> 10 | 0xD800,
+											high & 0x3FF | 0xDC00);
+						},
+
+						// Used for iframes
+						// See setDocument()
+						// Removing the function wrapper causes a "Permission
+						// Denied"
+						// error in IE
+						unloadHandler = function() {
+							setDocument();
+						};
+
+						// Optimize for push.apply( _, NodeList )
+						try {
+							push.apply((arr = slice
+									.call(preferredDoc.childNodes)),
+									preferredDoc.childNodes);
+							// Support: Android<4.0
+							// Detect silently failing push.apply
+							arr[preferredDoc.childNodes.length].nodeType;
+						} catch (e) {
+							push = {
+								apply : arr.length ?
+
+								// Leverage slice if possible
+								function(target, els) {
+									push_native.apply(target, slice.call(els));
+								} :
+
+								// Support: IE<9
+								// Otherwise append directly
+								function(target, els) {
+									var j = target.length, i = 0;
+									// Can't trust NodeList.length
+									while ((target[j++] = els[i++])) {
+									}
+									target.length = j - 1;
+								}
+							};
+						}
+
+						function Sizzle(selector, context, results, seed) {
+							var m, i, elem, nid, nidselect, match, groups, newSelector, newContext = context
+									&& context.ownerDocument,
+
+							// nodeType defaults to 9, since context defaults to
+							// document
+							nodeType = context ? context.nodeType : 9;
+
+							results = results || [];
+
+							// Return early from calls with invalid selector or
+							// context
+							if (typeof selector !== "string" || !selector
+									|| nodeType !== 1 && nodeType !== 9
+									&& nodeType !== 11) {
+
+								return results;
+							}
+
+							// Try to shortcut find operations (as opposed to
+							// filters) in HTML documents
+							if (!seed) {
+
+								if ((context ? context.ownerDocument || context
+										: preferredDoc) !== document) {
+									setDocument(context);
+								}
+								context = context || document;
+
+								if (documentIsHTML) {
+
+									// If the selector is sufficiently simple,
+									// try using a "get*By*" DOM method
+									// (excepting DocumentFragment context,
+									// where the methods don't exist)
+									if (nodeType !== 11
+											&& (match = rquickExpr
+													.exec(selector))) {
+
+										// ID selector
+										if ((m = match[1])) {
+
+											// Document context
+											if (nodeType === 9) {
+												if ((elem = context
+														.getElementById(m))) {
+
+													// Support: IE, Opera,
+													// Webkit
+													// TODO: identify versions
+													// getElementById can match
+													// elements by name instead
+													// of ID
+													if (elem.id === m) {
+														results.push(elem);
+														return results;
+													}
+												} else {
+													return results;
+												}
+
+												// Element context
+											} else {
+
+												// Support: IE, Opera, Webkit
+												// TODO: identify versions
+												// getElementById can match
+												// elements by name instead of
+												// ID
+												if (newContext
+														&& (elem = newContext
+																.getElementById(m))
+														&& contains(context,
+																elem)
+														&& elem.id === m) {
+
+													results.push(elem);
+													return results;
+												}
+											}
+
+											// Type selector
+										} else if (match[2]) {
+											push
+													.apply(
+															results,
+															context
+																	.getElementsByTagName(selector));
+											return results;
+
+											// Class selector
+										} else if ((m = match[3])
+												&& support.getElementsByClassName
+												&& context.getElementsByClassName) {
+
+											push.apply(results, context
+													.getElementsByClassName(m));
+											return results;
+										}
+									}
+
+									// Take advantage of querySelectorAll
+									if (support.qsa
+											&& !compilerCache[selector + " "]
+											&& (!rbuggyQSA || !rbuggyQSA
+													.test(selector))) {
+
+										if (nodeType !== 1) {
+											newContext = context;
+											newSelector = selector;
+
+											// qSA looks outside Element
+											// context, which is not what we
+											// want
+											// Thanks to Andrew Dupont for this
+											// workaround technique
+											// Support: IE <=8
+											// Exclude object elements
+										} else if (context.nodeName
+												.toLowerCase() !== "object") {
+
+											// Capture the context ID, setting
+											// it first if necessary
+											if ((nid = context
+													.getAttribute("id"))) {
+												nid = nid.replace(rescape,
+														"\\$&");
+											} else {
+												context.setAttribute("id",
+														(nid = expando));
+											}
+
+											// Prefix every selector in the list
+											groups = tokenize(selector);
+											i = groups.length;
+											nidselect = ridentifier.test(nid) ? "#"
+													+ nid
+													: "[id='" + nid + "']";
+											while (i--) {
+												groups[i] = nidselect + " "
+														+ toSelector(groups[i]);
+											}
+											newSelector = groups.join(",");
+
+											// Expand context for sibling
+											// selectors
+											newContext = rsibling
+													.test(selector)
+													&& testContext(context.parentNode)
+													|| context;
+										}
+
+										if (newSelector) {
+											try {
+												push
+														.apply(
+																results,
+																newContext
+																		.querySelectorAll(newSelector));
+												return results;
+											} catch (qsaError) {
+											} finally {
+												if (nid === expando) {
+													context
+															.removeAttribute("id");
+												}
+											}
+										}
+									}
+								}
+							}
+
+							// All others
+							return select(selector.replace(rtrim, "$1"),
+									context, results, seed);
+						}
+
+						/**
+						 * Create key-value caches of limited size
+						 * 
+						 * @returns {function(string, object)} Returns the
+						 *          Object data after storing it on itself with
+						 *          property name the (space-suffixed) string
+						 *          and (if the cache is larger than
+						 *          Expr.cacheLength) deleting the oldest entry
+						 */
+						function createCache() {
+							var keys = [];
+
+							function cache(key, value) {
+								// Use (key + " ") to avoid collision with
+								// native prototype properties (see Issue #157)
+								if (keys.push(key + " ") > Expr.cacheLength) {
+									// Only keep the most recent entries
+									delete cache[keys.shift()];
+								}
+								return (cache[key + " "] = value);
+							}
+							return cache;
+						}
+
+						/**
+						 * Mark a function for special use by Sizzle
+						 * 
+						 * @param {Function}
+						 *            fn The function to mark
+						 */
+						function markFunction(fn) {
+							fn[expando] = true;
+							return fn;
+						}
+
+						/**
+						 * Support testing using an element
+						 * 
+						 * @param {Function}
+						 *            fn Passed the created div and expects a
+						 *            boolean result
+						 */
+						function assert(fn) {
+							var div = document.createElement("div");
+
+							try {
+								return !!fn(div);
+							} catch (e) {
+								return false;
+							} finally {
+								// Remove from its parent by default
+								if (div.parentNode) {
+									div.parentNode.removeChild(div);
+								}
+								// release memory in IE
+								div = null;
+							}
+						}
+
+						/**
+						 * Adds the same handler for all of the specified attrs
+						 * 
+						 * @param {String}
+						 *            attrs Pipe-separated list of attributes
+						 * @param {Function}
+						 *            handler The method that will be applied
+						 */
+						function addHandle(attrs, handler) {
+							var arr = attrs.split("|"), i = arr.length;
+
+							while (i--) {
+								Expr.attrHandle[arr[i]] = handler;
+							}
+						}
+
+						/**
+						 * Checks document order of two siblings
+						 * 
+						 * @param {Element}
+						 *            a
+						 * @param {Element}
+						 *            b
+						 * @returns {Number} Returns less than 0 if a precedes
+						 *          b, greater than 0 if a follows b
+						 */
+						function siblingCheck(a, b) {
+							var cur = b && a, diff = cur && a.nodeType === 1
+									&& b.nodeType === 1
+									&& (~b.sourceIndex || MAX_NEGATIVE)
+									- (~a.sourceIndex || MAX_NEGATIVE);
+
+							// Use IE sourceIndex if available on both nodes
+							if (diff) {
+								return diff;
+							}
+
+							// Check if b follows a
+							if (cur) {
+								while ((cur = cur.nextSibling)) {
+									if (cur === b) {
+										return -1;
+									}
+								}
+							}
+
+							return a ? 1 : -1;
+						}
+
+						/**
+						 * Returns a function to use in pseudos for input types
+						 * 
+						 * @param {String}
+						 *            type
+						 */
+						function createInputPseudo(type) {
+							return function(elem) {
+								var name = elem.nodeName.toLowerCase();
+								return name === "input" && elem.type === type;
+							};
+						}
+
+						/**
+						 * Returns a function to use in pseudos for buttons
+						 * 
+						 * @param {String}
+						 *            type
+						 */
+						function createButtonPseudo(type) {
+							return function(elem) {
+								var name = elem.nodeName.toLowerCase();
+								return (name === "input" || name === "button")
+										&& elem.type === type;
+							};
+						}
+
+						/**
+						 * Returns a function to use in pseudos for positionals
+						 * 
+						 * @param {Function}
+						 *            fn
+						 */
+						function createPositionalPseudo(fn) {
+							return markFunction(function(argument) {
+								argument = +argument;
+								return markFunction(function(seed, matches) {
+									var j, matchIndexes = fn([], seed.length,
+											argument), i = matchIndexes.length;
+
+									// Match elements found at the specified
+									// indexes
+									while (i--) {
+										if (seed[(j = matchIndexes[i])]) {
+											seed[j] = !(matches[j] = seed[j]);
+										}
+									}
+								});
+							});
+						}
+
+						/**
+						 * Checks a node for validity as a Sizzle context
+						 * 
+						 * @param {Element|Object=}
+						 *            context
+						 * @returns {Element|Object|Boolean} The input node if
+						 *          acceptable, otherwise a falsy value
+						 */
+						function testContext(context) {
+							return context
+									&& typeof context.getElementsByTagName !== "undefined"
+									&& context;
+						}
+
+						// Expose support vars for convenience
+						support = Sizzle.support = {};
+
+						/**
+						 * Detects XML nodes
+						 * 
+						 * @param {Element|Object}
+						 *            elem An element or a document
+						 * @returns {Boolean} True iff elem is a non-HTML XML
+						 *          node
+						 */
+						isXML = Sizzle.isXML = function(elem) {
+							// documentElement is verified for cases where it
+							// doesn't yet exist
+							// (such as loading iframes in IE - #4833)
+							var documentElement = elem
+									&& (elem.ownerDocument || elem).documentElement;
+							return documentElement ? documentElement.nodeName !== "HTML"
+									: false;
+						};
+
+						/**
+						 * Sets document-related variables once based on the
+						 * current document
+						 * 
+						 * @param {Element|Object}
+						 *            [doc] An element or document object to use
+						 *            to set the document
+						 * @returns {Object} Returns the current document
+						 */
+						setDocument = Sizzle.setDocument = function(node) {
+							var hasCompare, parent, doc = node ? node.ownerDocument
+									|| node
+									: preferredDoc;
+
+							// Return early if doc is invalid or already
+							// selected
+							if (doc === document || doc.nodeType !== 9
+									|| !doc.documentElement) {
+								return document;
+							}
+
+							// Update global variables
+							document = doc;
+							docElem = document.documentElement;
+							documentIsHTML = !isXML(document);
+
+							// Support: IE 9-11, Edge
+							// Accessing iframe documents after unload throws
+							// "permission denied" errors (jQuery #13936)
+							if ((parent = document.defaultView)
+									&& parent.top !== parent) {
+								// Support: IE 11
+								if (parent.addEventListener) {
+									parent.addEventListener("unload",
+											unloadHandler, false);
+
+									// Support: IE 9 - 10 only
+								} else if (parent.attachEvent) {
+									parent.attachEvent("onunload",
+											unloadHandler);
+								}
+							}
+
+							/*
+							 * Attributes
+							 * ----------------------------------------------------------------------
+							 */
+
+							// Support: IE<8
+							// Verify that getAttribute really returns
+							// attributes and not properties
+							// (excepting IE8 booleans)
+							support.attributes = assert(function(div) {
+								div.className = "i";
+								return !div.getAttribute("className");
+							});
+
+							/***************************************************
+							 * getElement(s)By
+							 * ----------------------------------------------------------------------
+							 */
+
+							// Check if getElementsByTagName("*") returns only
+							// elements
+							support.getElementsByTagName = assert(function(div) {
+								div.appendChild(document.createComment(""));
+								return !div.getElementsByTagName("*").length;
+							});
+
+							// Support: IE<9
+							support.getElementsByClassName = rnative
+									.test(document.getElementsByClassName);
+
+							// Support: IE<10
+							// Check if getElementById returns elements by name
+							// The broken getElementById methods don't pick up
+							// programatically-set names,
+							// so use a roundabout getElementsByName test
+							support.getById = assert(function(div) {
+								docElem.appendChild(div).id = expando;
+								return !document.getElementsByName
+										|| !document.getElementsByName(expando).length;
+							});
+
+							// ID find and filter
+							if (support.getById) {
+								Expr.find["ID"] = function(id, context) {
+									if (typeof context.getElementById !== "undefined"
+											&& documentIsHTML) {
+										var m = context.getElementById(id);
+										return m ? [ m ] : [];
+									}
+								};
+								Expr.filter["ID"] = function(id) {
+									var attrId = id.replace(runescape,
+											funescape);
+									return function(elem) {
+										return elem.getAttribute("id") === attrId;
+									};
+								};
+							} else {
+								// Support: IE6/7
+								// getElementById is not reliable as a find
+								// shortcut
+								delete Expr.find["ID"];
+
+								Expr.filter["ID"] = function(id) {
+									var attrId = id.replace(runescape,
+											funescape);
+									return function(elem) {
+										var node = typeof elem.getAttributeNode !== "undefined"
+												&& elem.getAttributeNode("id");
+										return node && node.value === attrId;
+									};
+								};
+							}
+
+							// Tag
+							Expr.find["TAG"] = support.getElementsByTagName ? function(
+									tag, context) {
+								if (typeof context.getElementsByTagName !== "undefined") {
+									return context.getElementsByTagName(tag);
+
+									// DocumentFragment nodes don't have gEBTN
+								} else if (support.qsa) {
+									return context.querySelectorAll(tag);
+								}
+							}
+									:
+
+									function(tag, context) {
+										var elem, tmp = [], i = 0,
+										// By happy coincidence, a (broken)
+										// gEBTN appears on DocumentFragment
+										// nodes too
+										results = context
+												.getElementsByTagName(tag);
+
+										// Filter out possible comments
+										if (tag === "*") {
+											while ((elem = results[i++])) {
+												if (elem.nodeType === 1) {
+													tmp.push(elem);
+												}
+											}
+
+											return tmp;
+										}
+										return results;
+									};
+
+							// Class
+							Expr.find["CLASS"] = support.getElementsByClassName
+									&& function(className, context) {
+										if (typeof context.getElementsByClassName !== "undefined"
+												&& documentIsHTML) {
+											return context
+													.getElementsByClassName(className);
+										}
+									};
+
+							/*
+							 * QSA/matchesSelector
+							 * ----------------------------------------------------------------------
+							 */
+
+							// QSA and matchesSelector support
+							// matchesSelector(:active) reports false when true
+							// (IE9/Opera 11.5)
+							rbuggyMatches = [];
+
+							// qSa(:focus) reports false when true (Chrome 21)
+							// We allow this because of a bug in IE8/9 that
+							// throws an error
+							// whenever `document.activeElement` is accessed on
+							// an iframe
+							// So, we allow :focus to pass through QSA all the
+							// time to avoid the IE error
+							// See http://bugs.jquery.com/ticket/13378
+							rbuggyQSA = [];
+
+							if ((support.qsa = rnative
+									.test(document.querySelectorAll))) {
+								// Build QSA regex
+								// Regex strategy adopted from Diego Perini
+								assert(function(div) {
+									// Select is set to empty string on purpose
+									// This is to test IE's treatment of not
+									// explicitly
+									// setting a boolean content attribute,
+									// since its presence should be enough
+									// http://bugs.jquery.com/ticket/12359
+									docElem.appendChild(div).innerHTML = "<a id='"
+											+ expando
+											+ "'></a>"
+											+ "<select id='"
+											+ expando
+											+ "-\r\\' msallowcapture=''>"
+											+ "<option selected=''></option></select>";
+
+									// Support: IE8, Opera 11-12.16
+									// Nothing should be selected when empty
+									// strings follow ^= or $= or *=
+									// The test attribute must be unknown in
+									// Opera but "safe" for WinRT
+									// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
+									if (div
+											.querySelectorAll("[msallowcapture^='']").length) {
+										rbuggyQSA.push("[*^$]=" + whitespace
+												+ "*(?:''|\"\")");
+									}
+
+									// Support: IE8
+									// Boolean attributes and "value" are not
+									// treated correctly
+									if (!div.querySelectorAll("[selected]").length) {
+										rbuggyQSA
+												.push("\\[" + whitespace
+														+ "*(?:value|"
+														+ booleans + ")");
+									}
+
+									// Support: Chrome<29, Android<4.4,
+									// Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
+									if (!div.querySelectorAll("[id~=" + expando
+											+ "-]").length) {
+										rbuggyQSA.push("~=");
+									}
+
+									// Webkit/Opera - :checked should return
+									// selected option elements
+									// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+									// IE8 throws error here and will not see
+									// later tests
+									if (!div.querySelectorAll(":checked").length) {
+										rbuggyQSA.push(":checked");
+									}
+
+									// Support: Safari 8+, iOS 8+
+									// https://bugs.webkit.org/show_bug.cgi?id=136851
+									// In-page `selector#id sibing-combinator
+									// selector` fails
+									if (!div.querySelectorAll("a#" + expando
+											+ "+*").length) {
+										rbuggyQSA.push(".#.+[+~]");
+									}
+								});
+
+								assert(function(div) {
+									// Support: Windows 8 Native Apps
+									// The type and name attributes are
+									// restricted during .innerHTML assignment
+									var input = document.createElement("input");
+									input.setAttribute("type", "hidden");
+									div.appendChild(input).setAttribute("name",
+											"D");
+
+									// Support: IE8
+									// Enforce case-sensitivity of name
+									// attribute
+									if (div.querySelectorAll("[name=d]").length) {
+										rbuggyQSA.push("name" + whitespace
+												+ "*[*^$|!~]?=");
+									}
+
+									// FF 3.5 - :enabled/:disabled and hidden
+									// elements (hidden elements are still
+									// enabled)
+									// IE8 throws error here and will not see
+									// later tests
+									if (!div.querySelectorAll(":enabled").length) {
+										rbuggyQSA.push(":enabled", ":disabled");
+									}
+
+									// Opera 10-11 does not throw on post-comma
+									// invalid pseudos
+									div.querySelectorAll("*,:x");
+									rbuggyQSA.push(",.*:");
+								});
+							}
+
+							if ((support.matchesSelector = rnative
+									.test((matches = docElem.matches
+											|| docElem.webkitMatchesSelector
+											|| docElem.mozMatchesSelector
+											|| docElem.oMatchesSelector
+											|| docElem.msMatchesSelector)))) {
+
+								assert(function(div) {
+									// Check to see if it's possible to do
+									// matchesSelector
+									// on a disconnected node (IE 9)
+									support.disconnectedMatch = matches.call(
+											div, "div");
+
+									// This should fail with an exception
+									// Gecko does not error, returns false
+									// instead
+									matches.call(div, "[s!='']:x");
+									rbuggyMatches.push("!=", pseudos);
+								});
+							}
+
+							rbuggyQSA = rbuggyQSA.length
+									&& new RegExp(rbuggyQSA.join("|"));
+							rbuggyMatches = rbuggyMatches.length
+									&& new RegExp(rbuggyMatches.join("|"));
+
+							/*
+							 * Contains
+							 * ----------------------------------------------------------------------
+							 */
+							hasCompare = rnative
+									.test(docElem.compareDocumentPosition);
+
+							// Element contains another
+							// Purposefully self-exclusive
+							// As in, an element does not contain itself
+							contains = hasCompare
+									|| rnative.test(docElem.contains) ? function(
+									a, b) {
+								var adown = a.nodeType === 9 ? a.documentElement
+										: a, bup = b && b.parentNode;
+								return a === bup
+										|| !!(bup && bup.nodeType === 1 && (adown.contains ? adown
+												.contains(bup)
+												: a.compareDocumentPosition
+														&& a
+																.compareDocumentPosition(bup)
+														& 16));
+							}
+									: function(a, b) {
+										if (b) {
+											while ((b = b.parentNode)) {
+												if (b === a) {
+													return true;
+												}
+											}
+										}
+										return false;
+									};
+
+							/*
+							 * Sorting
+							 * ----------------------------------------------------------------------
+							 */
+
+							// Document order sorting
+							sortOrder = hasCompare ? function(a, b) {
+
+								// Flag for duplicate removal
+								if (a === b) {
+									hasDuplicate = true;
+									return 0;
+								}
+
+								// Sort on method existence if only one input
+								// has compareDocumentPosition
+								var compare = !a.compareDocumentPosition
+										- !b.compareDocumentPosition;
+								if (compare) {
+									return compare;
+								}
+
+								// Calculate position if both inputs belong to
+								// the same document
+								compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? a
+										.compareDocumentPosition(b)
+										:
+
+										// Otherwise we know they are
+										// disconnected
+										1;
+
+								// Disconnected nodes
+								if (compare
+										& 1
+										|| (!support.sortDetached && b
+												.compareDocumentPosition(a) === compare)) {
+
+									// Choose the first element that is related
+									// to our preferred document
+									if (a === document
+											|| a.ownerDocument === preferredDoc
+											&& contains(preferredDoc, a)) {
+										return -1;
+									}
+									if (b === document
+											|| b.ownerDocument === preferredDoc
+											&& contains(preferredDoc, b)) {
+										return 1;
+									}
+
+									// Maintain original order
+									return sortInput ? (indexOf(sortInput, a) - indexOf(
+											sortInput, b))
+											: 0;
+								}
+
+								return compare & 4 ? -1 : 1;
+							}
+									: function(a, b) {
+										// Exit early if the nodes are identical
+										if (a === b) {
+											hasDuplicate = true;
+											return 0;
+										}
+
+										var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [ a ], bp = [ b ];
+
+										// Parentless nodes are either documents
+										// or disconnected
+										if (!aup || !bup) {
+											return a === document ? -1
+													: b === document ? 1
+															: aup ? -1
+																	: bup ? 1
+																			: sortInput ? (indexOf(
+																					sortInput,
+																					a) - indexOf(
+																					sortInput,
+																					b))
+																					: 0;
+
+											// If the nodes are siblings, we can
+											// do a quick check
+										} else if (aup === bup) {
+											return siblingCheck(a, b);
+										}
+
+										// Otherwise we need full lists of their
+										// ancestors for comparison
+										cur = a;
+										while ((cur = cur.parentNode)) {
+											ap.unshift(cur);
+										}
+										cur = b;
+										while ((cur = cur.parentNode)) {
+											bp.unshift(cur);
+										}
+
+										// Walk down the tree looking for a
+										// discrepancy
+										while (ap[i] === bp[i]) {
+											i++;
+										}
+
+										return i ?
+										// Do a sibling check if the nodes have
+										// a common ancestor
+										siblingCheck(ap[i], bp[i]) :
+
+										// Otherwise nodes in our document sort
+										// first
+										ap[i] === preferredDoc ? -1
+												: bp[i] === preferredDoc ? 1
+														: 0;
+									};
+
+							return document;
+						};
+
+						Sizzle.matches = function(expr, elements) {
+							return Sizzle(expr, null, null, elements);
+						};
+
+						Sizzle.matchesSelector = function(elem, expr) {
+							// Set document vars if needed
+							if ((elem.ownerDocument || elem) !== document) {
+								setDocument(elem);
+							}
+
+							// Make sure that attribute selectors are quoted
+							expr = expr.replace(rattributeQuotes, "='$1']");
+
+							if (support.matchesSelector
+									&& documentIsHTML
+									&& !compilerCache[expr + " "]
+									&& (!rbuggyMatches || !rbuggyMatches
+											.test(expr))
+									&& (!rbuggyQSA || !rbuggyQSA.test(expr))) {
+
+								try {
+									var ret = matches.call(elem, expr);
+
+									// IE 9's matchesSelector returns false on
+									// disconnected nodes
+									if (ret || support.disconnectedMatch ||
+									// As well, disconnected nodes are said to
+									// be in a document
+									// fragment in IE 9
+									elem.document
+											&& elem.document.nodeType !== 11) {
+										return ret;
+									}
+								} catch (e) {
+								}
+							}
+
+							return Sizzle(expr, document, null, [ elem ]).length > 0;
+						};
+
+						Sizzle.contains = function(context, elem) {
+							// Set document vars if needed
+							if ((context.ownerDocument || context) !== document) {
+								setDocument(context);
+							}
+							return contains(context, elem);
+						};
+
+						Sizzle.attr = function(elem, name) {
+							// Set document vars if needed
+							if ((elem.ownerDocument || elem) !== document) {
+								setDocument(elem);
+							}
+
+							var fn = Expr.attrHandle[name.toLowerCase()],
+							// Don't get fooled by Object.prototype properties
+							// (jQuery #13807)
+							val = fn
+									&& hasOwn.call(Expr.attrHandle, name
+											.toLowerCase()) ? fn(elem, name,
+									!documentIsHTML) : undefined;
+
+							return val !== undefined ? val : support.attributes
+									|| !documentIsHTML ? elem
+									.getAttribute(name) : (val = elem
+									.getAttributeNode(name))
+									&& val.specified ? val.value : null;
+						};
+
+						Sizzle.error = function(msg) {
+							throw new Error(
+									"Syntax error, unrecognized expression: "
+											+ msg);
+						};
+
+						/**
+						 * Document sorting and removing duplicates
+						 * 
+						 * @param {ArrayLike}
+						 *            results
+						 */
+						Sizzle.uniqueSort = function(results) {
+							var elem, duplicates = [], j = 0, i = 0;
+
+							// Unless we *know* we can detect duplicates, assume
+							// their presence
+							hasDuplicate = !support.detectDuplicates;
+							sortInput = !support.sortStable && results.slice(0);
+							results.sort(sortOrder);
+
+							if (hasDuplicate) {
+								while ((elem = results[i++])) {
+									if (elem === results[i]) {
+										j = duplicates.push(i);
+									}
+								}
+								while (j--) {
+									results.splice(duplicates[j], 1);
+								}
+							}
+
+							// Clear input after sorting to release objects
+							// See https://github.com/jquery/sizzle/pull/225
+							sortInput = null;
+
+							return results;
+						};
+
+						/**
+						 * Utility function for retrieving the text value of an
+						 * array of DOM nodes
+						 * 
+						 * @param {Array|Element}
+						 *            elem
+						 */
+						getText = Sizzle.getText = function(elem) {
+							var node, ret = "", i = 0, nodeType = elem.nodeType;
+
+							if (!nodeType) {
+								// If no nodeType, this is expected to be an
+								// array
+								while ((node = elem[i++])) {
+									// Do not traverse comment nodes
+									ret += getText(node);
+								}
+							} else if (nodeType === 1 || nodeType === 9
+									|| nodeType === 11) {
+								// Use textContent for elements
+								// innerText usage removed for consistency of
+								// new lines (jQuery #11153)
+								if (typeof elem.textContent === "string") {
+									return elem.textContent;
+								} else {
+									// Traverse its children
+									for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
+										ret += getText(elem);
+									}
+								}
+							} else if (nodeType === 3 || nodeType === 4) {
+								return elem.nodeValue;
+							}
+							// Do not include comment or processing instruction
+							// nodes
+
+							return ret;
+						};
+
+						Expr = Sizzle.selectors = {
+
+							// Can be adjusted by the user
+							cacheLength : 50,
+
+							createPseudo : markFunction,
+
+							match : matchExpr,
+
+							attrHandle : {},
+
+							find : {},
+
+							relative : {
+								">" : {
+									dir : "parentNode",
+									first : true
+								},
+								" " : {
+									dir : "parentNode"
+								},
+								"+" : {
+									dir : "previousSibling",
+									first : true
+								},
+								"~" : {
+									dir : "previousSibling"
+								}
+							},
+
+							preFilter : {
+								"ATTR" : function(match) {
+									match[1] = match[1].replace(runescape,
+											funescape);
+
+									// Move the given value to match[3] whether
+									// quoted or unquoted
+									match[3] = (match[3] || match[4]
+											|| match[5] || "").replace(
+											runescape, funescape);
+
+									if (match[2] === "~=") {
+										match[3] = " " + match[3] + " ";
+									}
+
+									return match.slice(0, 4);
+								},
+
+								"CHILD" : function(match) {
+									/*
+									 * matches from matchExpr["CHILD"] 1 type
+									 * (only|nth|...) 2 what (child|of-type) 3
+									 * argument
+									 * (even|odd|\d*|\d*n([+-]\d+)?|...) 4
+									 * xn-component of xn+y argument
+									 * ([+-]?\d*n|) 5 sign of xn-component 6 x
+									 * of xn-component 7 sign of y-component 8 y
+									 * of y-component
+									 */
+									match[1] = match[1].toLowerCase();
+
+									if (match[1].slice(0, 3) === "nth") {
+										// nth-* requires argument
+										if (!match[3]) {
+											Sizzle.error(match[0]);
+										}
+
+										// numeric x and y parameters for
+										// Expr.filter.CHILD
+										// remember that false/true cast
+										// respectively to 0/1
+										match[4] = +(match[4] ? match[5]
+												+ (match[6] || 1)
+												: 2 * (match[3] === "even" || match[3] === "odd"));
+										match[5] = +((match[7] + match[8]) || match[3] === "odd");
+
+										// other types prohibit arguments
+									} else if (match[3]) {
+										Sizzle.error(match[0]);
+									}
+
+									return match;
+								},
+
+								"PSEUDO" : function(match) {
+									var excess, unquoted = !match[6]
+											&& match[2];
+
+									if (matchExpr["CHILD"].test(match[0])) {
+										return null;
+									}
+
+									// Accept quoted arguments as-is
+									if (match[3]) {
+										match[2] = match[4] || match[5] || "";
+
+										// Strip excess characters from unquoted
+										// arguments
+									} else if (unquoted
+											&& rpseudo.test(unquoted)
+											&&
+											// Get excess from tokenize
+											// (recursively)
+											(excess = tokenize(unquoted, true))
+											&&
+											// advance to the next closing
+											// parenthesis
+											(excess = unquoted.indexOf(")",
+													unquoted.length - excess)
+													- unquoted.length)) {
+
+										// excess is a negative index
+										match[0] = match[0].slice(0, excess);
+										match[2] = unquoted.slice(0, excess);
+									}
+
+									// Return only captures needed by the pseudo
+									// filter method (type and argument)
+									return match.slice(0, 3);
+								}
+							},
+
+							filter : {
+
+								"TAG" : function(nodeNameSelector) {
+									var nodeName = nodeNameSelector.replace(
+											runescape, funescape).toLowerCase();
+									return nodeNameSelector === "*" ? function() {
+										return true;
+									}
+											: function(elem) {
+												return elem.nodeName
+														&& elem.nodeName
+																.toLowerCase() === nodeName;
+											};
+								},
+
+								"CLASS" : function(className) {
+									var pattern = classCache[className + " "];
+
+									return pattern
+											|| (pattern = new RegExp("(^|"
+													+ whitespace + ")"
+													+ className + "("
+													+ whitespace + "|$)"))
+											&& classCache(
+													className,
+													function(elem) {
+														return pattern
+																.test(typeof elem.className === "string"
+																		&& elem.className
+																		|| typeof elem.getAttribute !== "undefined"
+																		&& elem
+																				.getAttribute("class")
+																		|| "");
+													});
+								},
+
+								"ATTR" : function(name, operator, check) {
+									return function(elem) {
+										var result = Sizzle.attr(elem, name);
+
+										if (result == null) {
+											return operator === "!=";
+										}
+										if (!operator) {
+											return true;
+										}
+
+										result += "";
+
+										return operator === "=" ? result === check
+												: operator === "!=" ? result !== check
+														: operator === "^=" ? check
+																&& result
+																		.indexOf(check) === 0
+																: operator === "*=" ? check
+																		&& result
+																				.indexOf(check) > -1
+																		: operator === "$=" ? check
+																				&& result
+																						.slice(-check.length) === check
+																				: operator === "~=" ? (" "
+																						+ result
+																								.replace(
+																										rwhitespace,
+																										" ") + " ")
+																						.indexOf(check) > -1
+																						: operator === "|=" ? result === check
+																								|| result
+																										.slice(
+																												0,
+																												check.length + 1) === check
+																										+ "-"
+																								: false;
+									};
+								},
+
+								"CHILD" : function(type, what, argument, first,
+										last) {
+									var simple = type.slice(0, 3) !== "nth", forward = type
+											.slice(-4) !== "last", ofType = what === "of-type";
+
+									return first === 1 && last === 0 ?
+
+									// Shortcut for :nth-*(n)
+									function(elem) {
+										return !!elem.parentNode;
+									}
+											:
+
+											function(elem, context, xml) {
+												var cache, uniqueCache, outerCache, node, nodeIndex, start, dir = simple !== forward ? "nextSibling"
+														: "previousSibling", parent = elem.parentNode, name = ofType
+														&& elem.nodeName
+																.toLowerCase(), useCache = !xml
+														&& !ofType, diff = false;
+
+												if (parent) {
+
+													// :(first|last|only)-(child|of-type)
+													if (simple) {
+														while (dir) {
+															node = elem;
+															while ((node = node[dir])) {
+																if (ofType ? node.nodeName
+																		.toLowerCase() === name
+																		: node.nodeType === 1) {
+
+																	return false;
+																}
+															}
+															// Reverse direction
+															// for :only-* (if
+															// we haven't yet
+															// done so)
+															start = dir = type === "only"
+																	&& !start
+																	&& "nextSibling";
+														}
+														return true;
+													}
+
+													start = [ forward ? parent.firstChild
+															: parent.lastChild ];
+
+													// non-xml :nth-child(...)
+													// stores cache data on
+													// `parent`
+													if (forward && useCache) {
+
+														// Seek `elem` from a
+														// previously-cached
+														// index
+
+														// ...in a gzip-friendly
+														// way
+														node = parent;
+														outerCache = node[expando]
+																|| (node[expando] = {});
+
+														// Support: IE <9 only
+														// Defend against cloned
+														// attroperties (jQuery
+														// gh-1709)
+														uniqueCache = outerCache[node.uniqueID]
+																|| (outerCache[node.uniqueID] = {});
+
+														cache = uniqueCache[type]
+																|| [];
+														nodeIndex = cache[0] === dirruns
+																&& cache[1];
+														diff = nodeIndex
+																&& cache[2];
+														node = nodeIndex
+																&& parent.childNodes[nodeIndex];
+
+														while ((node = ++nodeIndex
+																&& node
+																&& node[dir]
+																||
+
+																// Fallback to
+																// seeking
+																// `elem` from
+																// the start
+																(diff = nodeIndex = 0)
+																|| start.pop())) {
+
+															// When found, cache
+															// indexes on
+															// `parent` and
+															// break
+															if (node.nodeType === 1
+																	&& ++diff
+																	&& node === elem) {
+																uniqueCache[type] = [
+																		dirruns,
+																		nodeIndex,
+																		diff ];
+																break;
+															}
+														}
+
+													} else {
+														// Use previously-cached
+														// element index if
+														// available
+														if (useCache) {
+															// ...in a
+															// gzip-friendly way
+															node = elem;
+															outerCache = node[expando]
+																	|| (node[expando] = {});
+
+															// Support: IE <9
+															// only
+															// Defend against
+															// cloned
+															// attroperties
+															// (jQuery gh-1709)
+															uniqueCache = outerCache[node.uniqueID]
+																	|| (outerCache[node.uniqueID] = {});
+
+															cache = uniqueCache[type]
+																	|| [];
+															nodeIndex = cache[0] === dirruns
+																	&& cache[1];
+															diff = nodeIndex;
+														}
+
+														// xml :nth-child(...)
+														// or
+														// :nth-last-child(...)
+														// or
+														// :nth(-last)?-of-type(...)
+														if (diff === false) {
+															// Use the same loop
+															// as above to seek
+															// `elem` from the
+															// start
+															while ((node = ++nodeIndex
+																	&& node
+																	&& node[dir]
+																	|| (diff = nodeIndex = 0)
+																	|| start
+																			.pop())) {
+
+																if ((ofType ? node.nodeName
+																		.toLowerCase() === name
+																		: node.nodeType === 1)
+																		&& ++diff) {
+
+																	// Cache the
+																	// index of
+																	// each
+																	// encountered
+																	// element
+																	if (useCache) {
+																		outerCache = node[expando]
+																				|| (node[expando] = {});
+
+																		// Support:
+																		// IE <9
+																		// only
+																		// Defend
+																		// against
+																		// cloned
+																		// attroperties
+																		// (jQuery
+																		// gh-1709)
+																		uniqueCache = outerCache[node.uniqueID]
+																				|| (outerCache[node.uniqueID] = {});
+
+																		uniqueCache[type] = [
+																				dirruns,
+																				diff ];
+																	}
+
+																	if (node === elem) {
+																		break;
+																	}
+																}
+															}
+														}
+													}
+
+													// Incorporate the offset,
+													// then check against cycle
+													// size
+													diff -= last;
+													return diff === first
+															|| (diff % first === 0 && diff
+																	/ first >= 0);
+												}
+											};
+								},
+
+								"PSEUDO" : function(pseudo, argument) {
+									// pseudo-class names are case-insensitive
+									// http://www.w3.org/TR/selectors/#pseudo-classes
+									// Prioritize by case sensitivity in case
+									// custom pseudos are added with uppercase
+									// letters
+									// Remember that setFilters inherits from
+									// pseudos
+									var args, fn = Expr.pseudos[pseudo]
+											|| Expr.setFilters[pseudo
+													.toLowerCase()]
+											|| Sizzle
+													.error("unsupported pseudo: "
+															+ pseudo);
+
+									// The user may use createPseudo to indicate
+									// that
+									// arguments are needed to create the filter
+									// function
+									// just as Sizzle does
+									if (fn[expando]) {
+										return fn(argument);
+									}
+
+									// But maintain support for old signatures
+									if (fn.length > 1) {
+										args = [ pseudo, pseudo, "", argument ];
+										return Expr.setFilters
+												.hasOwnProperty(pseudo
+														.toLowerCase()) ? markFunction(function(
+												seed, matches) {
+											var idx, matched = fn(seed,
+													argument), i = matched.length;
+											while (i--) {
+												idx = indexOf(seed, matched[i]);
+												seed[idx] = !(matches[idx] = matched[i]);
+											}
+										})
+												: function(elem) {
+													return fn(elem, 0, args);
+												};
+									}
+
+									return fn;
+								}
+							},
+
+							pseudos : {
+								// Potentially complex pseudos
+								"not" : markFunction(function(selector) {
+									// Trim the selector passed to compile
+									// to avoid treating leading and trailing
+									// spaces as combinators
+									var input = [], results = [], matcher = compile(selector
+											.replace(rtrim, "$1"));
+
+									return matcher[expando] ? markFunction(function(
+											seed, matches, context, xml) {
+										var elem, unmatched = matcher(seed,
+												null, xml, []), i = seed.length;
+
+										// Match elements unmatched by `matcher`
+										while (i--) {
+											if ((elem = unmatched[i])) {
+												seed[i] = !(matches[i] = elem);
+											}
+										}
+									})
+											: function(elem, context, xml) {
+												input[0] = elem;
+												matcher(input, null, xml,
+														results);
+												// Don't keep the element (issue
+												// #299)
+												input[0] = null;
+												return !results.pop();
+											};
+								}),
+
+								"has" : markFunction(function(selector) {
+									return function(elem) {
+										return Sizzle(selector, elem).length > 0;
+									};
+								}),
+
+								"contains" : markFunction(function(text) {
+									text = text.replace(runescape, funescape);
+									return function(elem) {
+										return (elem.textContent
+												|| elem.innerText || getText(elem))
+												.indexOf(text) > -1;
+									};
+								}),
+
+								// "Whether an element is represented by a
+								// :lang() selector
+								// is based solely on the element's language
+								// value
+								// being equal to the identifier C,
+								// or beginning with the identifier C
+								// immediately followed by "-".
+								// The matching of C against the element's
+								// language value is performed
+								// case-insensitively.
+								// The identifier C does not have to be a valid
+								// language name."
+								// http://www.w3.org/TR/selectors/#lang-pseudo
+								"lang" : markFunction(function(lang) {
+									// lang value must be a valid identifier
+									if (!ridentifier.test(lang || "")) {
+										Sizzle.error("unsupported lang: "
+												+ lang);
+									}
+									lang = lang.replace(runescape, funescape)
+											.toLowerCase();
+									return function(elem) {
+										var elemLang;
+										do {
+											if ((elemLang = documentIsHTML ? elem.lang
+													: elem
+															.getAttribute("xml:lang")
+															|| elem
+																	.getAttribute("lang"))) {
+
+												elemLang = elemLang
+														.toLowerCase();
+												return elemLang === lang
+														|| elemLang
+																.indexOf(lang
+																		+ "-") === 0;
+											}
+										} while ((elem = elem.parentNode)
+												&& elem.nodeType === 1);
+										return false;
+									};
+								}),
+
+								// Miscellaneous
+								"target" : function(elem) {
+									var hash = window.location
+											&& window.location.hash;
+									return hash && hash.slice(1) === elem.id;
+								},
+
+								"root" : function(elem) {
+									return elem === docElem;
+								},
+
+								"focus" : function(elem) {
+									return elem === document.activeElement
+											&& (!document.hasFocus || document
+													.hasFocus())
+											&& !!(elem.type || elem.href || ~elem.tabIndex);
+								},
+
+								// Boolean properties
+								"enabled" : function(elem) {
+									return elem.disabled === false;
+								},
+
+								"disabled" : function(elem) {
+									return elem.disabled === true;
+								},
+
+								"checked" : function(elem) {
+									// In CSS3, :checked should return both
+									// checked and selected elements
+									// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+									var nodeName = elem.nodeName.toLowerCase();
+									return (nodeName === "input" && !!elem.checked)
+											|| (nodeName === "option" && !!elem.selected);
+								},
+
+								"selected" : function(elem) {
+									// Accessing this property makes
+									// selected-by-default
+									// options in Safari work properly
+									if (elem.parentNode) {
+										elem.parentNode.selectedIndex;
+									}
+
+									return elem.selected === true;
+								},
+
+								// Contents
+								"empty" : function(elem) {
+									// http://www.w3.org/TR/selectors/#empty-pseudo
+									// :empty is negated by element (1) or
+									// content nodes (text: 3; cdata: 4; entity
+									// ref: 5),
+									// but not by others (comment: 8; processing
+									// instruction: 7; etc.)
+									// nodeType < 6 works because attributes (2)
+									// do not appear as children
+									for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
+										if (elem.nodeType < 6) {
+											return false;
+										}
+									}
+									return true;
+								},
+
+								"parent" : function(elem) {
+									return !Expr.pseudos["empty"](elem);
+								},
+
+								// Element/input types
+								"header" : function(elem) {
+									return rheader.test(elem.nodeName);
+								},
+
+								"input" : function(elem) {
+									return rinputs.test(elem.nodeName);
+								},
+
+								"button" : function(elem) {
+									var name = elem.nodeName.toLowerCase();
+									return name === "input"
+											&& elem.type === "button"
+											|| name === "button";
+								},
+
+								"text" : function(elem) {
+									var attr;
+									return elem.nodeName.toLowerCase() === "input"
+											&& elem.type === "text"
+											&&
+
+											// Support: IE<8
+											// New HTML5 attribute values (e.g.,
+											// "search") appear with elem.type
+											// === "text"
+											((attr = elem.getAttribute("type")) == null || attr
+													.toLowerCase() === "text");
+								},
+
+								// Position-in-collection
+								"first" : createPositionalPseudo(function() {
+									return [ 0 ];
+								}),
+
+								"last" : createPositionalPseudo(function(
+										matchIndexes, length) {
+									return [ length - 1 ];
+								}),
+
+								"eq" : createPositionalPseudo(function(
+										matchIndexes, length, argument) {
+									return [ argument < 0 ? argument + length
+											: argument ];
+								}),
+
+								"even" : createPositionalPseudo(function(
+										matchIndexes, length) {
+									var i = 0;
+									for (; i < length; i += 2) {
+										matchIndexes.push(i);
+									}
+									return matchIndexes;
+								}),
+
+								"odd" : createPositionalPseudo(function(
+										matchIndexes, length) {
+									var i = 1;
+									for (; i < length; i += 2) {
+										matchIndexes.push(i);
+									}
+									return matchIndexes;
+								}),
+
+								"lt" : createPositionalPseudo(function(
+										matchIndexes, length, argument) {
+									var i = argument < 0 ? argument + length
+											: argument;
+									for (; --i >= 0;) {
+										matchIndexes.push(i);
+									}
+									return matchIndexes;
+								}),
+
+								"gt" : createPositionalPseudo(function(
+										matchIndexes, length, argument) {
+									var i = argument < 0 ? argument + length
+											: argument;
+									for (; ++i < length;) {
+										matchIndexes.push(i);
+									}
+									return matchIndexes;
+								})
+							}
+						};
+
+						Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+						// Add button/input type pseudos
+						for (i in {
+							radio : true,
+							checkbox : true,
+							file : true,
+							password : true,
+							image : true
+						}) {
+							Expr.pseudos[i] = createInputPseudo(i);
+						}
+						for (i in {
+							submit : true,
+							reset : true
+						}) {
+							Expr.pseudos[i] = createButtonPseudo(i);
+						}
+
+						// Easy API for creating new setFilters
+						function setFilters() {
+						}
+						setFilters.prototype = Expr.filters = Expr.pseudos;
+						Expr.setFilters = new setFilters();
+
+						tokenize = Sizzle.tokenize = function(selector,
+								parseOnly) {
+							var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[selector
+									+ " "];
+
+							if (cached) {
+								return parseOnly ? 0 : cached.slice(0);
+							}
+
+							soFar = selector;
+							groups = [];
+							preFilters = Expr.preFilter;
+
+							while (soFar) {
+
+								// Comma and first run
+								if (!matched || (match = rcomma.exec(soFar))) {
+									if (match) {
+										// Don't consume trailing commas as
+										// valid
+										soFar = soFar.slice(match[0].length)
+												|| soFar;
+									}
+									groups.push((tokens = []));
+								}
+
+								matched = false;
+
+								// Combinators
+								if ((match = rcombinators.exec(soFar))) {
+									matched = match.shift();
+									tokens.push({
+										value : matched,
+										// Cast descendant combinators to space
+										type : match[0].replace(rtrim, " ")
+									});
+									soFar = soFar.slice(matched.length);
+								}
+
+								// Filters
+								for (type in Expr.filter) {
+									if ((match = matchExpr[type].exec(soFar))
+											&& (!preFilters[type] || (match = preFilters[type]
+													(match)))) {
+										matched = match.shift();
+										tokens.push({
+											value : matched,
+											type : type,
+											matches : match
+										});
+										soFar = soFar.slice(matched.length);
+									}
+								}
+
+								if (!matched) {
+									break;
+								}
+							}
+
+							// Return the length of the invalid excess
+							// if we're just parsing
+							// Otherwise, throw an error or return tokens
+							return parseOnly ? soFar.length : soFar ? Sizzle
+									.error(selector) :
+							// Cache the tokens
+							tokenCache(selector, groups).slice(0);
+						};
+
+						function toSelector(tokens) {
+							var i = 0, len = tokens.length, selector = "";
+							for (; i < len; i++) {
+								selector += tokens[i].value;
+							}
+							return selector;
+						}
+
+						function addCombinator(matcher, combinator, base) {
+							var dir = combinator.dir, checkNonElements = base
+									&& dir === "parentNode", doneName = done++;
+
+							return combinator.first ?
+							// Check against closest ancestor/preceding element
+							function(elem, context, xml) {
+								while ((elem = elem[dir])) {
+									if (elem.nodeType === 1 || checkNonElements) {
+										return matcher(elem, context, xml);
+									}
+								}
+							}
+									:
+
+									// Check against all ancestor/preceding
+									// elements
+									function(elem, context, xml) {
+										var oldCache, uniqueCache, outerCache, newCache = [
+												dirruns, doneName ];
+
+										// We can't set arbitrary data on XML
+										// nodes, so they don't benefit from
+										// combinator caching
+										if (xml) {
+											while ((elem = elem[dir])) {
+												if (elem.nodeType === 1
+														|| checkNonElements) {
+													if (matcher(elem, context,
+															xml)) {
+														return true;
+													}
+												}
+											}
+										} else {
+											while ((elem = elem[dir])) {
+												if (elem.nodeType === 1
+														|| checkNonElements) {
+													outerCache = elem[expando]
+															|| (elem[expando] = {});
+
+													// Support: IE <9 only
+													// Defend against cloned
+													// attroperties (jQuery
+													// gh-1709)
+													uniqueCache = outerCache[elem.uniqueID]
+															|| (outerCache[elem.uniqueID] = {});
+
+													if ((oldCache = uniqueCache[dir])
+															&& oldCache[0] === dirruns
+															&& oldCache[1] === doneName) {
+
+														// Assign to newCache so
+														// results
+														// back-propagate to
+														// previous elements
+														return (newCache[2] = oldCache[2]);
+													} else {
+														// Reuse newcache so
+														// results
+														// back-propagate to
+														// previous elements
+														uniqueCache[dir] = newCache;
+
+														// A match means we're
+														// done; a fail means we
+														// have to keep checking
+														if ((newCache[2] = matcher(
+																elem, context,
+																xml))) {
+															return true;
+														}
+													}
+												}
+											}
+										}
+									};
+						}
+
+						function elementMatcher(matchers) {
+							return matchers.length > 1 ? function(elem,
+									context, xml) {
+								var i = matchers.length;
+								while (i--) {
+									if (!matchers[i](elem, context, xml)) {
+										return false;
+									}
+								}
+								return true;
+							} : matchers[0];
+						}
+
+						function multipleContexts(selector, contexts, results) {
+							var i = 0, len = contexts.length;
+							for (; i < len; i++) {
+								Sizzle(selector, contexts[i], results);
+							}
+							return results;
+						}
+
+						function condense(unmatched, map, filter, context, xml) {
+							var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null;
+
+							for (; i < len; i++) {
+								if ((elem = unmatched[i])) {
+									if (!filter || filter(elem, context, xml)) {
+										newUnmatched.push(elem);
+										if (mapped) {
+											map.push(i);
+										}
+									}
+								}
+							}
+
+							return newUnmatched;
+						}
+
+						function setMatcher(preFilter, selector, matcher,
+								postFilter, postFinder, postSelector) {
+							if (postFilter && !postFilter[expando]) {
+								postFilter = setMatcher(postFilter);
+							}
+							if (postFinder && !postFinder[expando]) {
+								postFinder = setMatcher(postFinder,
+										postSelector);
+							}
+							return markFunction(function(seed, results,
+									context, xml) {
+								var temp, i, elem, preMap = [], postMap = [], preexisting = results.length,
+
+								// Get initial elements from seed or context
+								elems = seed
+										|| multipleContexts(selector || "*",
+												context.nodeType ? [ context ]
+														: context, []),
+
+								// Prefilter to get matcher input, preserving a
+								// map for seed-results synchronization
+								matcherIn = preFilter && (seed || !selector) ? condense(
+										elems, preMap, preFilter, context, xml)
+										: elems,
+
+								matcherOut = matcher ?
+								// If we have a postFinder, or filtered seed, or
+								// non-seed postFilter or preexisting results,
+								postFinder
+										|| (seed ? preFilter : preexisting
+												|| postFilter) ?
+
+								// ...intermediate processing is necessary
+								[] :
+
+								// ...otherwise use results directly
+								results : matcherIn;
+
+								// Find primary matches
+								if (matcher) {
+									matcher(matcherIn, matcherOut, context, xml);
+								}
+
+								// Apply postFilter
+								if (postFilter) {
+									temp = condense(matcherOut, postMap);
+									postFilter(temp, [], context, xml);
+
+									// Un-match failing elements by moving them
+									// back to matcherIn
+									i = temp.length;
+									while (i--) {
+										if ((elem = temp[i])) {
+											matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);
+										}
+									}
+								}
+
+								if (seed) {
+									if (postFinder || preFilter) {
+										if (postFinder) {
+											// Get the final matcherOut by
+											// condensing this intermediate into
+											// postFinder contexts
+											temp = [];
+											i = matcherOut.length;
+											while (i--) {
+												if ((elem = matcherOut[i])) {
+													// Restore matcherIn since
+													// elem is not yet a final
+													// match
+													temp
+															.push((matcherIn[i] = elem));
+												}
+											}
+											postFinder(null, (matcherOut = []),
+													temp, xml);
+										}
+
+										// Move matched elements from seed to
+										// results to keep them synchronized
+										i = matcherOut.length;
+										while (i--) {
+											if ((elem = matcherOut[i])
+													&& (temp = postFinder ? indexOf(
+															seed, elem)
+															: preMap[i]) > -1) {
+
+												seed[temp] = !(results[temp] = elem);
+											}
+										}
+									}
+
+									// Add elements to results, through
+									// postFinder if defined
+								} else {
+									matcherOut = condense(matcherOut === results ? matcherOut
+											.splice(preexisting,
+													matcherOut.length)
+											: matcherOut);
+									if (postFinder) {
+										postFinder(null, results, matcherOut,
+												xml);
+									} else {
+										push.apply(results, matcherOut);
+									}
+								}
+							});
+						}
+
+						function matcherFromTokens(tokens) {
+							var checkContext, matcher, j, len = tokens.length, leadingRelative = Expr.relative[tokens[0].type], implicitRelative = leadingRelative
+									|| Expr.relative[" "], i = leadingRelative ? 1
+									: 0,
+
+							// The foundational matcher ensures that elements
+							// are reachable from top-level context(s)
+							matchContext = addCombinator(function(elem) {
+								return elem === checkContext;
+							}, implicitRelative, true), matchAnyContext = addCombinator(
+									function(elem) {
+										return indexOf(checkContext, elem) > -1;
+									}, implicitRelative, true), matchers = [ function(
+									elem, context, xml) {
+								var ret = (!leadingRelative && (xml || context !== outermostContext))
+										|| ((checkContext = context).nodeType ? matchContext(
+												elem, context, xml)
+												: matchAnyContext(elem,
+														context, xml));
+								// Avoid hanging onto element (issue #299)
+								checkContext = null;
+								return ret;
+							} ];
+
+							for (; i < len; i++) {
+								if ((matcher = Expr.relative[tokens[i].type])) {
+									matchers = [ addCombinator(
+											elementMatcher(matchers), matcher) ];
+								} else {
+									matcher = Expr.filter[tokens[i].type]
+											.apply(null, tokens[i].matches);
+
+									// Return special upon seeing a positional
+									// matcher
+									if (matcher[expando]) {
+										// Find the next relative operator (if
+										// any) for proper handling
+										j = ++i;
+										for (; j < len; j++) {
+											if (Expr.relative[tokens[j].type]) {
+												break;
+											}
+										}
+										return setMatcher(
+												i > 1
+														&& elementMatcher(matchers),
+												i > 1
+														&& toSelector(
+																// If the
+																// preceding
+																// token was a
+																// descendant
+																// combinator,
+																// insert an
+																// implicit
+																// any-element
+																// `*`
+																tokens
+																		.slice(
+																				0,
+																				i - 1)
+																		.concat(
+																				{
+																					value : tokens[i - 2].type === " " ? "*"
+																							: ""
+																				}))
+																.replace(rtrim,
+																		"$1"),
+												matcher,
+												i < j
+														&& matcherFromTokens(tokens
+																.slice(i, j)),
+												j < len
+														&& matcherFromTokens((tokens = tokens
+																.slice(j))),
+												j < len && toSelector(tokens));
+									}
+									matchers.push(matcher);
+								}
+							}
+
+							return elementMatcher(matchers);
+						}
+
+						function matcherFromGroupMatchers(elementMatchers,
+								setMatchers) {
+							var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function(
+									seed, context, xml, results, outermost) {
+								var elem, j, matcher, matchedCount = 0, i = "0", unmatched = seed
+										&& [], setMatched = [], contextBackup = outermostContext,
+								// We must always have either seed elements or
+								// outermost context
+								elems = seed || byElement
+										&& Expr.find["TAG"]("*", outermost),
+								// Use integer dirruns iff this is the outermost
+								// matcher
+								dirrunsUnique = (dirruns += contextBackup == null ? 1
+										: Math.random() || 0.1), len = elems.length;
+
+								if (outermost) {
+									outermostContext = context === document
+											|| context || outermost;
+								}
+
+								// Add elements passing elementMatchers directly
+								// to results
+								// Support: IE<9, Safari
+								// Tolerate NodeList properties (IE: "length";
+								// Safari: <number>) matching elements by id
+								for (; i !== len && (elem = elems[i]) != null; i++) {
+									if (byElement && elem) {
+										j = 0;
+										if (!context
+												&& elem.ownerDocument !== document) {
+											setDocument(elem);
+											xml = !documentIsHTML;
+										}
+										while ((matcher = elementMatchers[j++])) {
+											if (matcher(elem, context
+													|| document, xml)) {
+												results.push(elem);
+												break;
+											}
+										}
+										if (outermost) {
+											dirruns = dirrunsUnique;
+										}
+									}
+
+									// Track unmatched elements for set filters
+									if (bySet) {
+										// They will have gone through all
+										// possible matchers
+										if ((elem = !matcher && elem)) {
+											matchedCount--;
+										}
+
+										// Lengthen the array for every element,
+										// matched or not
+										if (seed) {
+											unmatched.push(elem);
+										}
+									}
+								}
+
+								// `i` is now the count of elements visited
+								// above, and adding it to `matchedCount`
+								// makes the latter nonnegative.
+								matchedCount += i;
+
+								// Apply set filters to unmatched elements
+								// NOTE: This can be skipped if there are no
+								// unmatched elements (i.e., `matchedCount`
+								// equals `i`), unless we didn't visit _any_
+								// elements in the above loop because we have
+								// no element matchers and no seed.
+								// Incrementing an initially-string "0" `i`
+								// allows `i` to remain a string only in that
+								// case, which will result in a "00"
+								// `matchedCount` that differs from `i` but is
+								// also
+								// numerically zero.
+								if (bySet && i !== matchedCount) {
+									j = 0;
+									while ((matcher = setMatchers[j++])) {
+										matcher(unmatched, setMatched, context,
+												xml);
+									}
+
+									if (seed) {
+										// Reintegrate element matches to
+										// eliminate the need for sorting
+										if (matchedCount > 0) {
+											while (i--) {
+												if (!(unmatched[i] || setMatched[i])) {
+													setMatched[i] = pop
+															.call(results);
+												}
+											}
+										}
+
+										// Discard index placeholder values to
+										// get only actual matches
+										setMatched = condense(setMatched);
+									}
+
+									// Add matches to results
+									push.apply(results, setMatched);
+
+									// Seedless set matches succeeding multiple
+									// successful matchers stipulate sorting
+									if (outermost
+											&& !seed
+											&& setMatched.length > 0
+											&& (matchedCount + setMatchers.length) > 1) {
+
+										Sizzle.uniqueSort(results);
+									}
+								}
+
+								// Override manipulation of globals by nested
+								// matchers
+								if (outermost) {
+									dirruns = dirrunsUnique;
+									outermostContext = contextBackup;
+								}
+
+								return unmatched;
+							};
+
+							return bySet ? markFunction(superMatcher)
+									: superMatcher;
+						}
+
+						compile = Sizzle.compile = function(selector, match /*
+																			 * Internal
+																			 * Use
+																			 * Only
+																			 */) {
+							var i, setMatchers = [], elementMatchers = [], cached = compilerCache[selector
+									+ " "];
+
+							if (!cached) {
+								// Generate a function of recursive functions
+								// that can be used to check each element
+								if (!match) {
+									match = tokenize(selector);
+								}
+								i = match.length;
+								while (i--) {
+									cached = matcherFromTokens(match[i]);
+									if (cached[expando]) {
+										setMatchers.push(cached);
+									} else {
+										elementMatchers.push(cached);
+									}
+								}
+
+								// Cache the compiled function
+								cached = compilerCache(selector,
+										matcherFromGroupMatchers(
+												elementMatchers, setMatchers));
+
+								// Save selector and tokenization
+								cached.selector = selector;
+							}
+							return cached;
+						};
+
+						/**
+						 * A low-level selection function that works with
+						 * Sizzle's compiled selector functions
+						 * 
+						 * @param {String|Function}
+						 *            selector A selector or a pre-compiled
+						 *            selector function built with
+						 *            Sizzle.compile
+						 * @param {Element}
+						 *            context
+						 * @param {Array}
+						 *            [results]
+						 * @param {Array}
+						 *            [seed] A set of elements to match against
+						 */
+						select = Sizzle.select = function(selector, context,
+								results, seed) {
+							var i, tokens, token, type, find, compiled = typeof selector === "function"
+									&& selector, match = !seed
+									&& tokenize((selector = compiled.selector
+											|| selector));
+
+							results = results || [];
+
+							// Try to minimize operations if there is only one
+							// selector in the list and no seed
+							// (the latter of which guarantees us context)
+							if (match.length === 1) {
+
+								// Reduce context if the leading compound
+								// selector is an ID
+								tokens = match[0] = match[0].slice(0);
+								if (tokens.length > 2
+										&& (token = tokens[0]).type === "ID"
+										&& support.getById
+										&& context.nodeType === 9
+										&& documentIsHTML
+										&& Expr.relative[tokens[1].type]) {
+
+									context = (Expr.find["ID"](token.matches[0]
+											.replace(runescape, funescape),
+											context) || [])[0];
+									if (!context) {
+										return results;
+
+										// Precompiled matchers will still
+										// verify ancestry, so step up a level
+									} else if (compiled) {
+										context = context.parentNode;
+									}
+
+									selector = selector
+											.slice(tokens.shift().value.length);
+								}
+
+								// Fetch a seed set for right-to-left matching
+								i = matchExpr["needsContext"].test(selector) ? 0
+										: tokens.length;
+								while (i--) {
+									token = tokens[i];
+
+									// Abort if we hit a combinator
+									if (Expr.relative[(type = token.type)]) {
+										break;
+									}
+									if ((find = Expr.find[type])) {
+										// Search, expanding context for leading
+										// sibling combinators
+										if ((seed = find(
+												token.matches[0].replace(
+														runescape, funescape),
+												rsibling.test(tokens[0].type)
+														&& testContext(context.parentNode)
+														|| context))) {
+
+											// If seed is empty or no tokens
+											// remain, we can return early
+											tokens.splice(i, 1);
+											selector = seed.length
+													&& toSelector(tokens);
+											if (!selector) {
+												push.apply(results, seed);
+												return results;
+											}
+
+											break;
+										}
+									}
+								}
+							}
+
+							// Compile and execute a filtering function if one
+							// is not provided
+							// Provide `match` to avoid retokenization if we
+							// modified the selector above
+							(compiled || compile(selector, match))(seed,
+									context, !documentIsHTML, results, !context
+											|| rsibling.test(selector)
+											&& testContext(context.parentNode)
+											|| context);
+							return results;
+						};
+
+						// One-time assignments
+
+						// Sort stability
+						support.sortStable = expando.split("").sort(sortOrder)
+								.join("") === expando;
+
+						// Support: Chrome 14-35+
+						// Always assume duplicates if they aren't passed to the
+						// comparison function
+						support.detectDuplicates = !!hasDuplicate;
+
+						// Initialize against the default document
+						setDocument();
+
+						// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25
+						// (fixed in Chrome 27)
+						// Detached nodes confoundingly follow *each other*
+						support.sortDetached = assert(function(div1) {
+							// Should return 1, but returns 4 (following)
+							return div1.compareDocumentPosition(document
+									.createElement("div")) & 1;
+						});
+
+						// Support: IE<8
+						// Prevent attribute/property "interpolation"
+						// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+						if (!assert(function(div) {
+							div.innerHTML = "<a href='#'></a>";
+							return div.firstChild.getAttribute("href") === "#";
+						})) {
+							addHandle("type|href|height|width", function(elem,
+									name, isXML) {
+								if (!isXML) {
+									return elem.getAttribute(name, name
+											.toLowerCase() === "type" ? 1 : 2);
+								}
+							});
+						}
+
+						// Support: IE<9
+						// Use defaultValue in place of getAttribute("value")
+						if (!support.attributes || !assert(function(div) {
+							div.innerHTML = "<input/>";
+							div.firstChild.setAttribute("value", "");
+							return div.firstChild.getAttribute("value") === "";
+						})) {
+							addHandle(
+									"value",
+									function(elem, name, isXML) {
+										if (!isXML
+												&& elem.nodeName.toLowerCase() === "input") {
+											return elem.defaultValue;
+										}
+									});
+						}
+
+						// Support: IE<9
+						// Use getAttributeNode to fetch booleans when
+						// getAttribute lies
+						if (!assert(function(div) {
+							return div.getAttribute("disabled") == null;
+						})) {
+							addHandle(
+									booleans,
+									function(elem, name, isXML) {
+										var val;
+										if (!isXML) {
+											return elem[name] === true ? name
+													.toLowerCase()
+													: (val = elem
+															.getAttributeNode(name))
+															&& val.specified ? val.value
+															: null;
+										}
+									});
+						}
+
+						return Sizzle;
+
+					})(window);
+
+					jQuery.find = Sizzle;
+					jQuery.expr = Sizzle.selectors;
+					jQuery.expr[":"] = jQuery.expr.pseudos;
+					jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
+					jQuery.text = Sizzle.getText;
+					jQuery.isXMLDoc = Sizzle.isXML;
+					jQuery.contains = Sizzle.contains;
+
+					var dir = function(elem, dir, until) {
+						var matched = [], truncate = until !== undefined;
+
+						while ((elem = elem[dir]) && elem.nodeType !== 9) {
+							if (elem.nodeType === 1) {
+								if (truncate && jQuery(elem).is(until)) {
+									break;
+								}
+								matched.push(elem);
+							}
+						}
+						return matched;
+					};
+
+					var siblings = function(n, elem) {
+						var matched = [];
+
+						for (; n; n = n.nextSibling) {
+							if (n.nodeType === 1 && n !== elem) {
+								matched.push(n);
+							}
+						}
+
+						return matched;
+					};
+
+					var rneedsContext = jQuery.expr.match.needsContext;
+
+					var rsingleTag = (/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/);
+
+					var risSimple = /^.[^:#\[\.,]*$/;
+
+					// Implement the identical functionality for filter and not
+					function winnow(elements, qualifier, not) {
+						if (jQuery.isFunction(qualifier)) {
+							return jQuery.grep(elements, function(elem, i) {
+								/* jshint -W018 */
+								return !!qualifier.call(elem, i, elem) !== not;
+							});
+
+						}
+
+						if (qualifier.nodeType) {
+							return jQuery.grep(elements, function(elem) {
+								return (elem === qualifier) !== not;
+							});
+
+						}
+
+						if (typeof qualifier === "string") {
+							if (risSimple.test(qualifier)) {
+								return jQuery.filter(qualifier, elements, not);
+							}
+
+							qualifier = jQuery.filter(qualifier, elements);
+						}
+
+						return jQuery
+								.grep(elements,
+										function(elem) {
+											return (jQuery.inArray(elem,
+													qualifier) > -1) !== not;
+										});
+					}
+
+					jQuery.filter = function(expr, elems, not) {
+						var elem = elems[0];
+
+						if (not) {
+							expr = ":not(" + expr + ")";
+						}
+
+						return elems.length === 1 && elem.nodeType === 1 ? jQuery.find
+								.matchesSelector(elem, expr) ? [ elem ] : []
+								: jQuery.find.matches(expr, jQuery.grep(elems,
+										function(elem) {
+											return elem.nodeType === 1;
+										}));
+					};
+
+					jQuery.fn
+							.extend({
+								find : function(selector) {
+									var i, ret = [], self = this, len = self.length;
+
+									if (typeof selector !== "string") {
+										return this
+												.pushStack(jQuery(selector)
+														.filter(
+																function() {
+																	for (i = 0; i < len; i++) {
+																		if (jQuery
+																				.contains(
+																						self[i],
+																						this)) {
+																			return true;
+																		}
+																	}
+																}));
+									}
+
+									for (i = 0; i < len; i++) {
+										jQuery.find(selector, self[i], ret);
+									}
+
+									// Needed because $( selector, context )
+									// becomes $( context ).find( selector )
+									ret = this.pushStack(len > 1 ? jQuery
+											.unique(ret) : ret);
+									ret.selector = this.selector ? this.selector
+											+ " " + selector
+											: selector;
+									return ret;
+								},
+								filter : function(selector) {
+									return this.pushStack(winnow(this, selector
+											|| [], false));
+								},
+								not : function(selector) {
+									return this.pushStack(winnow(this, selector
+											|| [], true));
+								},
+								is : function(selector) {
+									return !!winnow(
+											this,
+
+											// If this is a positional/relative
+											// selector, check membership in the
+											// returned set
+											// so $("p:first").is("p:last")
+											// won't return true for a doc with
+											// two "p".
+											typeof selector === "string"
+													&& rneedsContext
+															.test(selector) ? jQuery(selector)
+													: selector || [], false).length;
+								}
+							});
+
+					// Initialize a jQuery object
+
+					// A central reference to the root jQuery(document)
+					var rootjQuery,
+
+					// A simple way to check for HTML strings
+					// Prioritize #id over <tag> to avoid XSS via location.hash
+					// (#9521)
+					// Strict HTML recognition (#11290: must start with <)
+					rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
+
+					init = jQuery.fn.init = function(selector, context, root) {
+						var match, elem;
+
+						// HANDLE: $(""), $(null), $(undefined), $(false)
+						if (!selector) {
+							return this;
+						}
+
+						// init accepts an alternate rootjQuery
+						// so migrate can support jQuery.sub (gh-2101)
+						root = root || rootjQuery;
+
+						// Handle HTML strings
+						if (typeof selector === "string") {
+							if (selector.charAt(0) === "<"
+									&& selector.charAt(selector.length - 1) === ">"
+									&& selector.length >= 3) {
+
+								// Assume that strings that start and end with
+								// <> are HTML and skip the regex check
+								match = [ null, selector, null ];
+
+							} else {
+								match = rquickExpr.exec(selector);
+							}
+
+							// Match html or make sure no context is specified
+							// for #id
+							if (match && (match[1] || !context)) {
+
+								// HANDLE: $(html) -> $(array)
+								if (match[1]) {
+									context = context instanceof jQuery ? context[0]
+											: context;
+
+									// scripts is true for back-compat
+									// Intentionally let the error be thrown if
+									// parseHTML is not present
+									jQuery
+											.merge(
+													this,
+													jQuery
+															.parseHTML(
+																	match[1],
+																	context
+																			&& context.nodeType ? context.ownerDocument
+																			|| context
+																			: document,
+																	true));
+
+									// HANDLE: $(html, props)
+									if (rsingleTag.test(match[1])
+											&& jQuery.isPlainObject(context)) {
+										for (match in context) {
+
+											// Properties of context are called
+											// as methods if possible
+											if (jQuery.isFunction(this[match])) {
+												this[match](context[match]);
+
+												// ...and otherwise set as
+												// attributes
+											} else {
+												this
+														.attr(match,
+																context[match]);
+											}
+										}
+									}
+
+									return this;
+
+									// HANDLE: $(#id)
+								} else {
+									elem = document.getElementById(match[2]);
+
+									// Check parentNode to catch when Blackberry
+									// 4.6 returns
+									// nodes that are no longer in the document
+									// #6963
+									if (elem && elem.parentNode) {
+
+										// Handle the case where IE and Opera
+										// return items
+										// by name instead of ID
+										if (elem.id !== match[2]) {
+											return rootjQuery.find(selector);
+										}
+
+										// Otherwise, we inject the element
+										// directly into the jQuery object
+										this.length = 1;
+										this[0] = elem;
+									}
+
+									this.context = document;
+									this.selector = selector;
+									return this;
+								}
+
+								// HANDLE: $(expr, $(...))
+							} else if (!context || context.jquery) {
+								return (context || root).find(selector);
+
+								// HANDLE: $(expr, context)
+								// (which is just equivalent to:
+								// $(context).find(expr)
+							} else {
+								return this.constructor(context).find(selector);
+							}
+
+							// HANDLE: $(DOMElement)
+						} else if (selector.nodeType) {
+							this.context = this[0] = selector;
+							this.length = 1;
+							return this;
+
+							// HANDLE: $(function)
+							// Shortcut for document ready
+						} else if (jQuery.isFunction(selector)) {
+							return typeof root.ready !== "undefined" ? root
+									.ready(selector) :
+
+							// Execute immediately if ready is not present
+							selector(jQuery);
+						}
+
+						if (selector.selector !== undefined) {
+							this.selector = selector.selector;
+							this.context = selector.context;
+						}
+
+						return jQuery.makeArray(selector, this);
+					};
+
+					// Give the init function the jQuery prototype for later
+					// instantiation
+					init.prototype = jQuery.fn;
+
+					// Initialize central reference
+					rootjQuery = jQuery(document);
+
+					var rparentsprev = /^(?:parents|prev(?:Until|All))/,
+
+					// methods guaranteed to produce a unique set when starting
+					// from a unique set
+					guaranteedUnique = {
+						children : true,
+						contents : true,
+						next : true,
+						prev : true
+					};
+
+					jQuery.fn
+							.extend({
+								has : function(target) {
+									var i, targets = jQuery(target, this), len = targets.length;
+
+									return this.filter(function() {
+										for (i = 0; i < len; i++) {
+											if (jQuery.contains(this,
+													targets[i])) {
+												return true;
+											}
+										}
+									});
+								},
+
+								closest : function(selectors, context) {
+									var cur, i = 0, l = this.length, matched = [], pos = rneedsContext
+											.test(selectors)
+											|| typeof selectors !== "string" ? jQuery(
+											selectors, context || this.context)
+											: 0;
+
+									for (; i < l; i++) {
+										for (cur = this[i]; cur
+												&& cur !== context; cur = cur.parentNode) {
+
+											// Always skip document fragments
+											if (cur.nodeType < 11
+													&& (pos ? pos.index(cur) > -1
+															:
+
+															// Don't pass
+															// non-elements to
+															// Sizzle
+															cur.nodeType === 1
+																	&& jQuery.find
+																			.matchesSelector(
+																					cur,
+																					selectors))) {
+
+												matched.push(cur);
+												break;
+											}
+										}
+									}
+
+									return this
+											.pushStack(matched.length > 1 ? jQuery
+													.uniqueSort(matched)
+													: matched);
+								},
+
+								// Determine the position of an element within
+								// the matched set of elements
+								index : function(elem) {
+
+									// No argument, return index in parent
+									if (!elem) {
+										return (this[0] && this[0].parentNode) ? this
+												.first().prevAll().length
+												: -1;
+									}
+
+									// index in selector
+									if (typeof elem === "string") {
+										return jQuery.inArray(this[0],
+												jQuery(elem));
+									}
+
+									// Locate the position of the desired
+									// element
+									return jQuery.inArray(
+
+									// If it receives a jQuery object, the first
+									// element is used
+									elem.jquery ? elem[0] : elem, this);
+								},
+
+								add : function(selector, context) {
+									return this
+											.pushStack(jQuery
+													.uniqueSort(jQuery.merge(
+															this.get(), jQuery(
+																	selector,
+																	context))));
+								},
+
+								addBack : function(selector) {
+									return this
+											.add(selector == null ? this.prevObject
+													: this.prevObject
+															.filter(selector));
+								}
+							});
+
+					function sibling(cur, dir) {
+						do {
+							cur = cur[dir];
+						} while (cur && cur.nodeType !== 1);
+
+						return cur;
+					}
+
+					jQuery
+							.each(
+									{
+										parent : function(elem) {
+											var parent = elem.parentNode;
+											return parent
+													&& parent.nodeType !== 11 ? parent
+													: null;
+										},
+										parents : function(elem) {
+											return dir(elem, "parentNode");
+										},
+										parentsUntil : function(elem, i, until) {
+											return dir(elem, "parentNode",
+													until);
+										},
+										next : function(elem) {
+											return sibling(elem, "nextSibling");
+										},
+										prev : function(elem) {
+											return sibling(elem,
+													"previousSibling");
+										},
+										nextAll : function(elem) {
+											return dir(elem, "nextSibling");
+										},
+										prevAll : function(elem) {
+											return dir(elem, "previousSibling");
+										},
+										nextUntil : function(elem, i, until) {
+											return dir(elem, "nextSibling",
+													until);
+										},
+										prevUntil : function(elem, i, until) {
+											return dir(elem, "previousSibling",
+													until);
+										},
+										siblings : function(elem) {
+											return siblings(
+													(elem.parentNode || {}).firstChild,
+													elem);
+										},
+										children : function(elem) {
+											return siblings(elem.firstChild);
+										},
+										contents : function(elem) {
+											return jQuery.nodeName(elem,
+													"iframe") ? elem.contentDocument
+													|| elem.contentWindow.document
+													: jQuery.merge([],
+															elem.childNodes);
+										}
+									},
+									function(name, fn) {
+										jQuery.fn[name] = function(until,
+												selector) {
+											var ret = jQuery.map(this, fn,
+													until);
+
+											if (name.slice(-5) !== "Until") {
+												selector = until;
+											}
+
+											if (selector
+													&& typeof selector === "string") {
+												ret = jQuery.filter(selector,
+														ret);
+											}
+
+											if (this.length > 1) {
+
+												// Remove duplicates
+												if (!guaranteedUnique[name]) {
+													ret = jQuery
+															.uniqueSort(ret);
+												}
+
+												// Reverse order for parents*
+												// and prev-derivatives
+												if (rparentsprev.test(name)) {
+													ret = ret.reverse();
+												}
+											}
+
+											return this.pushStack(ret);
+										};
+									});
+					var rnotwhite = (/\S+/g);
+
+					// Convert String-formatted options into Object-formatted
+					// ones
+					function createOptions(options) {
+						var object = {};
+						jQuery.each(options.match(rnotwhite) || [], function(_,
+								flag) {
+							object[flag] = true;
+						});
+						return object;
+					}
+
+					/*
+					 * Create a callback list using the following parameters:
+					 * 
+					 * options: an optional list of space-separated options that
+					 * will change how the callback list behaves or a more
+					 * traditional option object
+					 * 
+					 * By default a callback list will act like an event
+					 * callback list and can be "fired" multiple times.
+					 * 
+					 * Possible options:
+					 * 
+					 * once: will ensure the callback list can only be fired
+					 * once (like a Deferred)
+					 * 
+					 * memory: will keep track of previous values and will call
+					 * any callback added after the list has been fired right
+					 * away with the latest "memorized" values (like a Deferred)
+					 * 
+					 * unique: will ensure a callback can only be added once (no
+					 * duplicate in the list)
+					 * 
+					 * stopOnFalse: interrupt callings when a callback returns
+					 * false
+					 * 
+					 */
+					jQuery.Callbacks = function(options) {
+
+						// Convert options from String-formatted to
+						// Object-formatted if needed
+						// (we check in cache first)
+						options = typeof options === "string" ? createOptions(options)
+								: jQuery.extend({}, options);
+
+						var // Flag to know if list is currently firing
+						firing,
+
+						// Last fire value for non-forgettable lists
+						memory,
+
+						// Flag to know if list was already fired
+						fired,
+
+						// Flag to prevent firing
+						locked,
+
+						// Actual callback list
+						list = [],
+
+						// Queue of execution data for repeatable lists
+						queue = [],
+
+						// Index of currently firing callback (modified by
+						// add/remove as needed)
+						firingIndex = -1,
+
+						// Fire callbacks
+						fire = function() {
+
+							// Enforce single-firing
+							locked = options.once;
+
+							// Execute callbacks for all pending executions,
+							// respecting firingIndex overrides and runtime
+							// changes
+							fired = firing = true;
+							for (; queue.length; firingIndex = -1) {
+								memory = queue.shift();
+								while (++firingIndex < list.length) {
+
+									// Run callback and check for early
+									// termination
+									if (list[firingIndex].apply(memory[0],
+											memory[1]) === false
+											&& options.stopOnFalse) {
+
+										// Jump to end and forget the data so
+										// .add doesn't re-fire
+										firingIndex = list.length;
+										memory = false;
+									}
+								}
+							}
+
+							// Forget the data if we're done with it
+							if (!options.memory) {
+								memory = false;
+							}
+
+							firing = false;
+
+							// Clean up if we're done firing for good
+							if (locked) {
+
+								// Keep an empty list if we have data for future
+								// add calls
+								if (memory) {
+									list = [];
+
+									// Otherwise, this object is spent
+								} else {
+									list = "";
+								}
+							}
+						},
+
+						// Actual Callbacks object
+						self = {
+
+							// Add a callback or a collection of callbacks to
+							// the list
+							add : function() {
+								if (list) {
+
+									// If we have memory from a past run, we
+									// should fire after adding
+									if (memory && !firing) {
+										firingIndex = list.length - 1;
+										queue.push(memory);
+									}
+
+									(function add(args) {
+										jQuery
+												.each(
+														args,
+														function(_, arg) {
+															if (jQuery
+																	.isFunction(arg)) {
+																if (!options.unique
+																		|| !self
+																				.has(arg)) {
+																	list
+																			.push(arg);
+																}
+															} else if (arg
+																	&& arg.length
+																	&& jQuery
+																			.type(arg) !== "string") {
+
+																// Inspect
+																// recursively
+																add(arg);
+															}
+														});
+									})(arguments);
+
+									if (memory && !firing) {
+										fire();
+									}
+								}
+								return this;
+							},
+
+							// Remove a callback from the list
+							remove : function() {
+								jQuery.each(arguments, function(_, arg) {
+									var index;
+									while ((index = jQuery.inArray(arg, list,
+											index)) > -1) {
+										list.splice(index, 1);
+
+										// Handle firing indexes
+										if (index <= firingIndex) {
+											firingIndex--;
+										}
+									}
+								});
+								return this;
+							},
+
+							// Check if a given callback is in the list.
+							// If no argument is given, return whether or not
+							// list has callbacks attached.
+							has : function(fn) {
+								return fn ? jQuery.inArray(fn, list) > -1
+										: list.length > 0;
+							},
+
+							// Remove all callbacks from the list
+							empty : function() {
+								if (list) {
+									list = [];
+								}
+								return this;
+							},
+
+							// Disable .fire and .add
+							// Abort any current/pending executions
+							// Clear all callbacks and values
+							disable : function() {
+								locked = queue = [];
+								list = memory = "";
+								return this;
+							},
+							disabled : function() {
+								return !list;
+							},
+
+							// Disable .fire
+							// Also disable .add unless we have memory (since it
+							// would have no effect)
+							// Abort any pending executions
+							lock : function() {
+								locked = true;
+								if (!memory) {
+									self.disable();
+								}
+								return this;
+							},
+							locked : function() {
+								return !!locked;
+							},
+
+							// Call all callbacks with the given context and
+							// arguments
+							fireWith : function(context, args) {
+								if (!locked) {
+									args = args || [];
+									args = [ context,
+											args.slice ? args.slice() : args ];
+									queue.push(args);
+									if (!firing) {
+										fire();
+									}
+								}
+								return this;
+							},
+
+							// Call all the callbacks with the given arguments
+							fire : function() {
+								self.fireWith(this, arguments);
+								return this;
+							},
+
+							// To know if the callbacks have already been called
+							// at least once
+							fired : function() {
+								return !!fired;
+							}
+						};
+
+						return self;
+					};
+
+					jQuery
+							.extend({
+
+								Deferred : function(func) {
+									var tuples = [
+
+											// action, add listener, listener
+											// list, final state
+											[
+													"resolve",
+													"done",
+													jQuery
+															.Callbacks("once memory"),
+													"resolved" ],
+											[
+													"reject",
+													"fail",
+													jQuery
+															.Callbacks("once memory"),
+													"rejected" ],
+											[ "notify", "progress",
+													jQuery.Callbacks("memory") ] ], state = "pending", promise = {
+										state : function() {
+											return state;
+										},
+										always : function() {
+											deferred.done(arguments).fail(
+													arguments);
+											return this;
+										},
+										then : function( /*
+															 * fnDone, fnFail,
+															 * fnProgress
+															 */) {
+											var fns = arguments;
+											return jQuery
+													.Deferred(
+															function(newDefer) {
+																jQuery
+																		.each(
+																				tuples,
+																				function(
+																						i,
+																						tuple) {
+																					var fn = jQuery
+																							.isFunction(fns[i])
+																							&& fns[i];
+
+																					// deferred[
+																					// done
+																					// |
+																					// fail
+																					// |
+																					// progress
+																					// ]
+																					// for
+																					// forwarding
+																					// actions
+																					// to
+																					// newDefer
+																					deferred[tuple[1]]
+																							(function() {
+																								var returned = fn
+																										&& fn
+																												.apply(
+																														this,
+																														arguments);
+																								if (returned
+																										&& jQuery
+																												.isFunction(returned.promise)) {
+																									returned
+																											.promise()
+																											.progress(
+																													newDefer.notify)
+																											.done(
+																													newDefer.resolve)
+																											.fail(
+																													newDefer.reject);
+																								} else {
+																									newDefer[tuple[0]
+																											+ "With"]
+																											(
+																													this === promise ? newDefer
+																															.promise()
+																															: this,
+																													fn ? [ returned ]
+																															: arguments);
+																								}
+																							});
+																				});
+																fns = null;
+															}).promise();
+										},
+
+										// Get a promise for this deferred
+										// If obj is provided, the promise
+										// aspect is added to the object
+										promise : function(obj) {
+											return obj != null ? jQuery.extend(
+													obj, promise) : promise;
+										}
+									}, deferred = {};
+
+									// Keep pipe for back-compat
+									promise.pipe = promise.then;
+
+									// Add list-specific methods
+									jQuery
+											.each(
+													tuples,
+													function(i, tuple) {
+														var list = tuple[2], stateString = tuple[3];
+
+														// promise[ done | fail
+														// | progress ] =
+														// list.add
+														promise[tuple[1]] = list.add;
+
+														// Handle state
+														if (stateString) {
+															list
+																	.add(
+																			function() {
+
+																				// state
+																				// = [
+																				// resolved
+																				// |
+																				// rejected
+																				// ]
+																				state = stateString;
+
+																				// [
+																				// reject_list
+																				// |
+																				// resolve_list
+																				// ].disable;
+																				// progress_list.lock
+																			},
+																			tuples[i ^ 1][2].disable,
+																			tuples[2][2].lock);
+														}
+
+														// deferred[ resolve |
+														// reject | notify ]
+														deferred[tuple[0]] = function() {
+															deferred[tuple[0]
+																	+ "With"]
+																	(
+																			this === deferred ? promise
+																					: this,
+																			arguments);
+															return this;
+														};
+														deferred[tuple[0]
+																+ "With"] = list.fireWith;
+													});
+
+									// Make the deferred a promise
+									promise.promise(deferred);
+
+									// Call given func if any
+									if (func) {
+										func.call(deferred, deferred);
+									}
+
+									// All done!
+									return deferred;
+								},
+
+								// Deferred helper
+								when : function(subordinate /*
+															 * , ...,
+															 * subordinateN
+															 */) {
+									var i = 0, resolveValues = slice
+											.call(arguments), length = resolveValues.length,
+
+									// the count of uncompleted subordinates
+									remaining = length !== 1
+											|| (subordinate && jQuery
+													.isFunction(subordinate.promise)) ? length
+											: 0,
+
+									// the master Deferred.
+									// If resolveValues consist of only a single
+									// Deferred, just use that.
+									deferred = remaining === 1 ? subordinate
+											: jQuery.Deferred(),
+
+									// Update function for both resolve and
+									// progress values
+									updateFunc = function(i, contexts, values) {
+										return function(value) {
+											contexts[i] = this;
+											values[i] = arguments.length > 1 ? slice
+													.call(arguments)
+													: value;
+											if (values === progressValues) {
+												deferred.notifyWith(contexts,
+														values);
+
+											} else if (!(--remaining)) {
+												deferred.resolveWith(contexts,
+														values);
+											}
+										};
+									},
+
+									progressValues, progressContexts, resolveContexts;
+
+									// add listeners to Deferred subordinates;
+									// treat others as resolved
+									if (length > 1) {
+										progressValues = new Array(length);
+										progressContexts = new Array(length);
+										resolveContexts = new Array(length);
+										for (; i < length; i++) {
+											if (resolveValues[i]
+													&& jQuery
+															.isFunction(resolveValues[i].promise)) {
+												resolveValues[i]
+														.promise()
+														.progress(
+																updateFunc(
+																		i,
+																		progressContexts,
+																		progressValues))
+														.done(
+																updateFunc(
+																		i,
+																		resolveContexts,
+																		resolveValues))
+														.fail(deferred.reject);
+											} else {
+												--remaining;
+											}
+										}
+									}
+
+									// if we're not waiting on anything, resolve
+									// the master
+									if (!remaining) {
+										deferred.resolveWith(resolveContexts,
+												resolveValues);
+									}
+
+									return deferred.promise();
+								}
+							});
+
+					// The deferred used on DOM ready
+					var readyList;
+
+					jQuery.fn.ready = function(fn) {
+
+						// Add the callback
+						jQuery.ready.promise().done(fn);
+
+						return this;
+					};
+
+					jQuery.extend({
+
+						// Is the DOM ready to be used? Set to true once it
+						// occurs.
+						isReady : false,
+
+						// A counter to track how many items to wait for before
+						// the ready event fires. See #6781
+						readyWait : 1,
+
+						// Hold (or release) the ready event
+						holdReady : function(hold) {
+							if (hold) {
+								jQuery.readyWait++;
+							} else {
+								jQuery.ready(true);
+							}
+						},
+
+						// Handle when the DOM is ready
+						ready : function(wait) {
+
+							// Abort if there are pending holds or we're already
+							// ready
+							if (wait === true ? --jQuery.readyWait
+									: jQuery.isReady) {
+								return;
+							}
+
+							// Remember that the DOM is ready
+							jQuery.isReady = true;
+
+							// If a normal DOM Ready event fired, decrement, and
+							// wait if need be
+							if (wait !== true && --jQuery.readyWait > 0) {
+								return;
+							}
+
+							// If there are functions bound, to execute
+							readyList.resolveWith(document, [ jQuery ]);
+
+							// Trigger any bound ready events
+							if (jQuery.fn.triggerHandler) {
+								jQuery(document).triggerHandler("ready");
+								jQuery(document).off("ready");
+							}
+						}
+					});
+
+					/**
+					 * Clean-up method for dom ready events
+					 */
+					function detach() {
+						if (document.addEventListener) {
+							document.removeEventListener("DOMContentLoaded",
+									completed);
+							window.removeEventListener("load", completed);
+
+						} else {
+							document.detachEvent("onreadystatechange",
+									completed);
+							window.detachEvent("onload", completed);
+						}
+					}
+
+					/**
+					 * The ready event handler and self cleanup method
+					 */
+					function completed() {
+
+						// readyState === "complete" is good enough for us to
+						// call the dom ready in oldIE
+						if (document.addEventListener
+								|| window.event.type === "load"
+								|| document.readyState === "complete") {
+
+							detach();
+							jQuery.ready();
+						}
+					}
+
+					jQuery.ready.promise = function(obj) {
+						if (!readyList) {
+
+							readyList = jQuery.Deferred();
+
+							// Catch cases where $(document).ready() is called
+							// after the browser event has already occurred.
+							// Support: IE6-10
+							// Older IE sometimes signals "interactive" too soon
+							if (document.readyState === "complete"
+									|| (document.readyState !== "loading" && !document.documentElement.doScroll)) {
+
+								// Handle it asynchronously to allow scripts the
+								// opportunity to delay ready
+								window.setTimeout(jQuery.ready);
+
+								// Standards-based browsers support
+								// DOMContentLoaded
+							} else if (document.addEventListener) {
+
+								// Use the handy event callback
+								document.addEventListener("DOMContentLoaded",
+										completed);
+
+								// A fallback to window.onload, that will always
+								// work
+								window.addEventListener("load", completed);
+
+								// If IE event model is used
+							} else {
+
+								// Ensure firing before onload, maybe late but
+								// safe also for iframes
+								document.attachEvent("onreadystatechange",
+										completed);
+
+								// A fallback to window.onload, that will always
+								// work
+								window.attachEvent("onload", completed);
+
+								// If IE and not a frame
+								// continually check to see if the document is
+								// ready
+								var top = false;
+
+								try {
+									top = window.frameElement == null
+											&& document.documentElement;
+								} catch (e) {
+								}
+
+								if (top && top.doScroll) {
+									(function doScrollCheck() {
+										if (!jQuery.isReady) {
+
+											try {
+
+												// Use the trick by Diego Perini
+												// http://javascript.nwbox.com/IEContentLoaded/
+												top.doScroll("left");
+											} catch (e) {
+												return window.setTimeout(
+														doScrollCheck, 50);
+											}
+
+											// detach all dom ready events
+											detach();
+
+											// and execute any waiting functions
+											jQuery.ready();
+										}
+									})();
+								}
+							}
+						}
+						return readyList.promise(obj);
+					};
+
+					// Kick off the DOM ready check even if the user does not
+					jQuery.ready.promise();
+
+					// Support: IE<9
+					// Iteration over object's inherited properties before its
+					// own
+					var i;
+					for (i in jQuery(support)) {
+						break;
+					}
+					support.ownFirst = i === "0";
+
+					// Note: most support tests are defined in their respective
+					// modules.
+					// false until the test is run
+					support.inlineBlockNeedsLayout = false;
+
+					// Execute ASAP in case we need to set body.style.zoom
+					jQuery(function() {
+
+						// Minified: var a,b,c,d
+						var val, div, body, container;
+
+						body = document.getElementsByTagName("body")[0];
+						if (!body || !body.style) {
+
+							// Return for frameset docs that don't have a body
+							return;
+						}
+
+						// Setup
+						div = document.createElement("div");
+						container = document.createElement("div");
+						container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
+						body.appendChild(container).appendChild(div);
+
+						if (typeof div.style.zoom !== "undefined") {
+
+							// Support: IE<8
+							// Check if natively block-level elements act like
+							// inline-block
+							// elements when setting their display to 'inline'
+							// and giving
+							// them layout
+							div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1";
+
+							support.inlineBlockNeedsLayout = val = div.offsetWidth === 3;
+							if (val) {
+
+								// Prevent IE 6 from affecting layout for
+								// positioned elements #11048
+								// Prevent IE from shrinking the body in IE 7
+								// mode #12869
+								// Support: IE<8
+								body.style.zoom = 1;
+							}
+						}
+
+						body.removeChild(container);
+					});
+
+					(function() {
+						var div = document.createElement("div");
+
+						// Support: IE<9
+						support.deleteExpando = true;
+						try {
+							delete div.test;
+						} catch (e) {
+							support.deleteExpando = false;
+						}
+
+						// Null elements to avoid leaks in IE.
+						div = null;
+					})();
+					var acceptData = function(elem) {
+						var noData = jQuery.noData[(elem.nodeName + " ")
+								.toLowerCase()], nodeType = +elem.nodeType || 1;
+
+						// Do not set data on non-element DOM nodes because it
+						// will not be cleared (#8335).
+						return nodeType !== 1 && nodeType !== 9 ? false :
+
+						// Nodes accept data unless otherwise specified;
+						// rejection can be conditional
+						!noData || noData !== true
+								&& elem.getAttribute("classid") === noData;
+					};
+
+					var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, rmultiDash = /([A-Z])/g;
+
+					function dataAttr(elem, key, data) {
+
+						// If nothing was found internally, try to fetch any
+						// data from the HTML5 data-* attribute
+						if (data === undefined && elem.nodeType === 1) {
+
+							var name = "data-"
+									+ key.replace(rmultiDash, "-$1")
+											.toLowerCase();
+
+							data = elem.getAttribute(name);
+
+							if (typeof data === "string") {
+								try {
+									data = data === "true" ? true
+											: data === "false" ? false
+													: data === "null" ? null
+															:
+
+															// Only convert to a
+															// number if it
+															// doesn't change
+															// the string
+															+data + "" === data ? +data
+																	: rbrace
+																			.test(data) ? jQuery
+																			.parseJSON(data)
+																			: data;
+								} catch (e) {
+								}
+
+								// Make sure we set the data so it isn't changed
+								// later
+								jQuery.data(elem, key, data);
+
+							} else {
+								data = undefined;
+							}
+						}
+
+						return data;
+					}
+
+					// checks a cache object for emptiness
+					function isEmptyDataObject(obj) {
+						var name;
+						for (name in obj) {
+
+							// if the public data object is empty, the private
+							// is still empty
+							if (name === "data"
+									&& jQuery.isEmptyObject(obj[name])) {
+								continue;
+							}
+							if (name !== "toJSON") {
+								return false;
+							}
+						}
+
+						return true;
+					}
+
+					function internalData(elem, name, data, pvt /*
+																 * Internal Use
+																 * Only
+																 */) {
+						if (!acceptData(elem)) {
+							return;
+						}
+
+						var ret, thisCache, internalKey = jQuery.expando,
+
+						// We have to handle DOM nodes and JS objects
+						// differently because IE6-7
+						// can't GC object references properly across the DOM-JS
+						// boundary
+						isNode = elem.nodeType,
+
+						// Only DOM nodes need the global jQuery cache; JS
+						// object data is
+						// attached directly to the object so GC can occur
+						// automatically
+						cache = isNode ? jQuery.cache : elem,
+
+						// Only defining an ID for JS objects if its cache
+						// already exists allows
+						// the code to shortcut on the same path as a DOM node
+						// with no cache
+						id = isNode ? elem[internalKey] : elem[internalKey]
+								&& internalKey;
+
+						// Avoid doing any more work than we need to when trying
+						// to get data on an
+						// object that has no data at all
+						if ((!id || !cache[id] || (!pvt && !cache[id].data))
+								&& data === undefined
+								&& typeof name === "string") {
+							return;
+						}
+
+						if (!id) {
+
+							// Only DOM nodes need a new unique ID for each
+							// element since their data
+							// ends up in the global cache
+							if (isNode) {
+								id = elem[internalKey] = deletedIds.pop()
+										|| jQuery.guid++;
+							} else {
+								id = internalKey;
+							}
+						}
+
+						if (!cache[id]) {
+
+							// Avoid exposing jQuery metadata on plain JS
+							// objects when the object
+							// is serialized using JSON.stringify
+							cache[id] = isNode ? {} : {
+								toJSON : jQuery.noop
+							};
+						}
+
+						// An object can be passed to jQuery.data instead of a
+						// key/value pair; this gets
+						// shallow copied over onto the existing cache
+						if (typeof name === "object"
+								|| typeof name === "function") {
+							if (pvt) {
+								cache[id] = jQuery.extend(cache[id], name);
+							} else {
+								cache[id].data = jQuery.extend(cache[id].data,
+										name);
+							}
+						}
+
+						thisCache = cache[id];
+
+						// jQuery data() is stored in a separate object inside
+						// the object's internal data
+						// cache in order to avoid key collisions between
+						// internal data and user-defined
+						// data.
+						if (!pvt) {
+							if (!thisCache.data) {
+								thisCache.data = {};
+							}
+
+							thisCache = thisCache.data;
+						}
+
+						if (data !== undefined) {
+							thisCache[jQuery.camelCase(name)] = data;
+						}
+
+						// Check for both converted-to-camel and non-converted
+						// data property names
+						// If a data property was specified
+						if (typeof name === "string") {
+
+							// First Try to find as-is property data
+							ret = thisCache[name];
+
+							// Test for null|undefined property data
+							if (ret == null) {
+
+								// Try to find the camelCased property
+								ret = thisCache[jQuery.camelCase(name)];
+							}
+						} else {
+							ret = thisCache;
+						}
+
+						return ret;
+					}
+
+					function internalRemoveData(elem, name, pvt) {
+						if (!acceptData(elem)) {
+							return;
+						}
+
+						var thisCache, i, isNode = elem.nodeType,
+
+						// See jQuery.data for more information
+						cache = isNode ? jQuery.cache : elem, id = isNode ? elem[jQuery.expando]
+								: jQuery.expando;
+
+						// If there is already no cache entry for this object,
+						// there is no
+						// purpose in continuing
+						if (!cache[id]) {
+							return;
+						}
+
+						if (name) {
+
+							thisCache = pvt ? cache[id] : cache[id].data;
+
+							if (thisCache) {
+
+								// Support array or space separated string names
+								// for data keys
+								if (!jQuery.isArray(name)) {
+
+									// try the string as a key before any
+									// manipulation
+									if (name in thisCache) {
+										name = [ name ];
+									} else {
+
+										// split the camel cased version by
+										// spaces unless a key with the spaces
+										// exists
+										name = jQuery.camelCase(name);
+										if (name in thisCache) {
+											name = [ name ];
+										} else {
+											name = name.split(" ");
+										}
+									}
+								} else {
+
+									// If "name" is an array of keys...
+									// When data is initially created, via
+									// ("key", "val") signature,
+									// keys will be converted to camelCase.
+									// Since there is no way to tell _how_ a key
+									// was added, remove
+									// both plain key and camelCase key. #12786
+									// This will only penalize the array
+									// argument path.
+									name = name.concat(jQuery.map(name,
+											jQuery.camelCase));
+								}
+
+								i = name.length;
+								while (i--) {
+									delete thisCache[name[i]];
+								}
+
+								// If there is no data left in the cache, we
+								// want to continue
+								// and let the cache object itself get destroyed
+								if (pvt ? !isEmptyDataObject(thisCache)
+										: !jQuery.isEmptyObject(thisCache)) {
+									return;
+								}
+							}
+						}
+
+						// See jQuery.data for more information
+						if (!pvt) {
+							delete cache[id].data;
+
+							// Don't destroy the parent cache unless the
+							// internal data object
+							// had been the only thing left in it
+							if (!isEmptyDataObject(cache[id])) {
+								return;
+							}
+						}
+
+						// Destroy the cache
+						if (isNode) {
+							jQuery.cleanData([ elem ], true);
+
+							// Use delete when supported for expandos or `cache`
+							// is not a window per isWindow (#10080)
+							/* jshint eqeqeq: false */
+						} else if (support.deleteExpando
+								|| cache != cache.window) {
+							/* jshint eqeqeq: true */
+							delete cache[id];
+
+							// When all else fails, undefined
+						} else {
+							cache[id] = undefined;
+						}
+					}
+
+					jQuery
+							.extend({
+								cache : {},
+
+								// The following elements (space-suffixed to
+								// avoid Object.prototype collisions)
+								// throw uncatchable exceptions if you attempt
+								// to set expando properties
+								noData : {
+									"applet " : true,
+									"embed " : true,
+
+									// ...but Flash objects (which have this
+									// classid) *can* handle expandos
+									"object " : "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
+								},
+
+								hasData : function(elem) {
+									elem = elem.nodeType ? jQuery.cache[elem[jQuery.expando]]
+											: elem[jQuery.expando];
+									return !!elem && !isEmptyDataObject(elem);
+								},
+
+								data : function(elem, name, data) {
+									return internalData(elem, name, data);
+								},
+
+								removeData : function(elem, name) {
+									return internalRemoveData(elem, name);
+								},
+
+								// For internal use only.
+								_data : function(elem, name, data) {
+									return internalData(elem, name, data, true);
+								},
+
+								_removeData : function(elem, name) {
+									return internalRemoveData(elem, name, true);
+								}
+							});
+
+					jQuery.fn
+							.extend({
+								data : function(key, value) {
+									var i, name, data, elem = this[0], attrs = elem
+											&& elem.attributes;
+
+									// Special expections of .data basically
+									// thwart jQuery.access,
+									// so implement the relevant behavior
+									// ourselves
+
+									// Gets all values
+									if (key === undefined) {
+										if (this.length) {
+											data = jQuery.data(elem);
+
+											if (elem.nodeType === 1
+													&& !jQuery._data(elem,
+															"parsedAttrs")) {
+												i = attrs.length;
+												while (i--) {
+
+													// Support: IE11+
+													// The attrs elements can be
+													// null (#14894)
+													if (attrs[i]) {
+														name = attrs[i].name;
+														if (name
+																.indexOf("data-") === 0) {
+															name = jQuery
+																	.camelCase(name
+																			.slice(5));
+															dataAttr(elem,
+																	name,
+																	data[name]);
+														}
+													}
+												}
+												jQuery._data(elem,
+														"parsedAttrs", true);
+											}
+										}
+
+										return data;
+									}
+
+									// Sets multiple values
+									if (typeof key === "object") {
+										return this.each(function() {
+											jQuery.data(this, key);
+										});
+									}
+
+									return arguments.length > 1 ?
+
+									// Sets one value
+									this.each(function() {
+										jQuery.data(this, key, value);
+									}) :
+
+									// Gets one value
+									// Try to fetch any internally stored data
+									// first
+									elem ? dataAttr(elem, key, jQuery.data(
+											elem, key)) : undefined;
+								},
+
+								removeData : function(key) {
+									return this.each(function() {
+										jQuery.removeData(this, key);
+									});
+								}
+							});
+
+					jQuery
+							.extend({
+								queue : function(elem, type, data) {
+									var queue;
+
+									if (elem) {
+										type = (type || "fx") + "queue";
+										queue = jQuery._data(elem, type);
+
+										// Speed up dequeue by getting out
+										// quickly if this is just a lookup
+										if (data) {
+											if (!queue || jQuery.isArray(data)) {
+												queue = jQuery._data(elem,
+														type,
+														jQuery.makeArray(data));
+											} else {
+												queue.push(data);
+											}
+										}
+										return queue || [];
+									}
+								},
+
+								dequeue : function(elem, type) {
+									type = type || "fx";
+
+									var queue = jQuery.queue(elem, type), startLength = queue.length, fn = queue
+											.shift(), hooks = jQuery
+											._queueHooks(elem, type), next = function() {
+										jQuery.dequeue(elem, type);
+									};
+
+									// If the fx queue is dequeued, always
+									// remove the progress sentinel
+									if (fn === "inprogress") {
+										fn = queue.shift();
+										startLength--;
+									}
+
+									if (fn) {
+
+										// Add a progress sentinel to prevent
+										// the fx queue from being
+										// automatically dequeued
+										if (type === "fx") {
+											queue.unshift("inprogress");
+										}
+
+										// clear up the last queue stop function
+										delete hooks.stop;
+										fn.call(elem, next, hooks);
+									}
+
+									if (!startLength && hooks) {
+										hooks.empty.fire();
+									}
+								},
+
+								// not intended for public consumption -
+								// generates a queueHooks object,
+								// or returns the current one
+								_queueHooks : function(elem, type) {
+									var key = type + "queueHooks";
+									return jQuery._data(elem, key)
+											|| jQuery
+													._data(
+															elem,
+															key,
+															{
+																empty : jQuery
+																		.Callbacks(
+																				"once memory")
+																		.add(
+																				function() {
+																					jQuery
+																							._removeData(
+																									elem,
+																									type
+																											+ "queue");
+																					jQuery
+																							._removeData(
+																									elem,
+																									key);
+																				})
+															});
+								}
+							});
+
+					jQuery.fn
+							.extend({
+								queue : function(type, data) {
+									var setter = 2;
+
+									if (typeof type !== "string") {
+										data = type;
+										type = "fx";
+										setter--;
+									}
+
+									if (arguments.length < setter) {
+										return jQuery.queue(this[0], type);
+									}
+
+									return data === undefined ? this
+											: this
+													.each(function() {
+														var queue = jQuery
+																.queue(this,
+																		type,
+																		data);
+
+														// ensure a hooks for
+														// this queue
+														jQuery._queueHooks(
+																this, type);
+
+														if (type === "fx"
+																&& queue[0] !== "inprogress") {
+															jQuery.dequeue(
+																	this, type);
+														}
+													});
+								},
+								dequeue : function(type) {
+									return this.each(function() {
+										jQuery.dequeue(this, type);
+									});
+								},
+								clearQueue : function(type) {
+									return this.queue(type || "fx", []);
+								},
+
+								// Get a promise resolved when queues of a
+								// certain type
+								// are emptied (fx is the type by default)
+								promise : function(type, obj) {
+									var tmp, count = 1, defer = jQuery
+											.Deferred(), elements = this, i = this.length, resolve = function() {
+										if (!(--count)) {
+											defer.resolveWith(elements,
+													[ elements ]);
+										}
+									};
+
+									if (typeof type !== "string") {
+										obj = type;
+										type = undefined;
+									}
+									type = type || "fx";
+
+									while (i--) {
+										tmp = jQuery._data(elements[i], type
+												+ "queueHooks");
+										if (tmp && tmp.empty) {
+											count++;
+											tmp.empty.add(resolve);
+										}
+									}
+									resolve();
+									return defer.promise(obj);
+								}
+							});
+
+					(function() {
+						var shrinkWrapBlocksVal;
+
+						support.shrinkWrapBlocks = function() {
+							if (shrinkWrapBlocksVal != null) {
+								return shrinkWrapBlocksVal;
+							}
+
+							// Will be changed later if needed.
+							shrinkWrapBlocksVal = false;
+
+							// Minified: var b,c,d
+							var div, body, container;
+
+							body = document.getElementsByTagName("body")[0];
+							if (!body || !body.style) {
+
+								// Test fired too early or in an unsupported
+								// environment, exit.
+								return;
+							}
+
+							// Setup
+							div = document.createElement("div");
+							container = document.createElement("div");
+							container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
+							body.appendChild(container).appendChild(div);
+
+							// Support: IE6
+							// Check if elements with layout shrink-wrap their
+							// children
+							if (typeof div.style.zoom !== "undefined") {
+
+								// Reset CSS: box-sizing; display; margin;
+								// border
+								div.style.cssText =
+
+								// Support: Firefox<29, Android 2.3
+								// Vendor-prefix box-sizing
+								"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;"
+										+ "box-sizing:content-box;display:block;margin:0;border:0;"
+										+ "padding:1px;width:1px;zoom:1";
+								div.appendChild(document.createElement("div")).style.width = "5px";
+								shrinkWrapBlocksVal = div.offsetWidth !== 3;
+							}
+
+							body.removeChild(container);
+
+							return shrinkWrapBlocksVal;
+						};
+
+					})();
+					var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
+
+					var rcssNum = new RegExp("^(?:([+-])=|)(" + pnum
+							+ ")([a-z%]*)$", "i");
+
+					var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
+
+					var isHidden = function(elem, el) {
+
+						// isHidden might be called from jQuery#filter function;
+						// in that case, element will be second argument
+						elem = el || elem;
+						return jQuery.css(elem, "display") === "none"
+								|| !jQuery.contains(elem.ownerDocument, elem);
+					};
+
+					function adjustCSS(elem, prop, valueParts, tween) {
+						var adjusted, scale = 1, maxIterations = 20, currentValue = tween ? function() {
+							return tween.cur();
+						}
+								: function() {
+									return jQuery.css(elem, prop, "");
+								}, initial = currentValue(), unit = valueParts
+								&& valueParts[3]
+								|| (jQuery.cssNumber[prop] ? "" : "px"),
+
+						// Starting value computation is required for potential
+						// unit mismatches
+						initialInUnit = (jQuery.cssNumber[prop] || unit !== "px"
+								&& +initial)
+								&& rcssNum.exec(jQuery.css(elem, prop));
+
+						if (initialInUnit && initialInUnit[3] !== unit) {
+
+							// Trust units reported by jQuery.css
+							unit = unit || initialInUnit[3];
+
+							// Make sure we update the tween properties later on
+							valueParts = valueParts || [];
+
+							// Iteratively approximate from a nonzero starting
+							// point
+							initialInUnit = +initial || 1;
+
+							do {
+
+								// If previous iteration zeroed out, double
+								// until we get *something*.
+								// Use string for doubling so we don't
+								// accidentally see scale as unchanged below
+								scale = scale || ".5";
+
+								// Adjust and apply
+								initialInUnit = initialInUnit / scale;
+								jQuery.style(elem, prop, initialInUnit + unit);
+
+								// Update scale, tolerating zero or NaN from
+								// tween.cur()
+								// Break the loop if scale is unchanged or
+								// perfect, or if we've just had enough.
+							} while (scale !== (scale = currentValue()
+									/ initial)
+									&& scale !== 1 && --maxIterations);
+						}
+
+						if (valueParts) {
+							initialInUnit = +initialInUnit || +initial || 0;
+
+							// Apply relative offset (+=/-=) if specified
+							adjusted = valueParts[1] ? initialInUnit
+									+ (valueParts[1] + 1) * valueParts[2]
+									: +valueParts[2];
+							if (tween) {
+								tween.unit = unit;
+								tween.start = initialInUnit;
+								tween.end = adjusted;
+							}
+						}
+						return adjusted;
+					}
+
+					// Multifunctional method to get and set values of a
+					// collection
+					// The value/s can optionally be executed if it's a function
+					var access = function(elems, fn, key, value, chainable,
+							emptyGet, raw) {
+						var i = 0, length = elems.length, bulk = key == null;
+
+						// Sets many values
+						if (jQuery.type(key) === "object") {
+							chainable = true;
+							for (i in key) {
+								access(elems, fn, i, key[i], true, emptyGet,
+										raw);
+							}
+
+							// Sets one value
+						} else if (value !== undefined) {
+							chainable = true;
+
+							if (!jQuery.isFunction(value)) {
+								raw = true;
+							}
+
+							if (bulk) {
+
+								// Bulk operations run against the entire set
+								if (raw) {
+									fn.call(elems, value);
+									fn = null;
+
+									// ...except when executing function values
+								} else {
+									bulk = fn;
+									fn = function(elem, key, value) {
+										return bulk.call(jQuery(elem), value);
+									};
+								}
+							}
+
+							if (fn) {
+								for (; i < length; i++) {
+									fn(elems[i], key, raw ? value : value.call(
+											elems[i], i, fn(elems[i], key)));
+								}
+							}
+						}
+
+						return chainable ? elems :
+
+						// Gets
+						bulk ? fn.call(elems) : length ? fn(elems[0], key)
+								: emptyGet;
+					};
+					var rcheckableType = (/^(?:checkbox|radio)$/i);
+
+					var rtagName = (/<([\w:-]+)/);
+
+					var rscriptType = (/^$|\/(?:java|ecma)script/i);
+
+					var rleadingWhitespace = (/^\s+/);
+
+					var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|"
+							+ "details|dialog|figcaption|figure|footer|header|hgroup|main|"
+							+ "mark|meter|nav|output|picture|progress|section|summary|template|time|video";
+
+					function createSafeFragment(document) {
+						var list = nodeNames.split("|"), safeFrag = document
+								.createDocumentFragment();
+
+						if (safeFrag.createElement) {
+							while (list.length) {
+								safeFrag.createElement(list.pop());
+							}
+						}
+						return safeFrag;
+					}
+
+					(function() {
+						var div = document.createElement("div"), fragment = document
+								.createDocumentFragment(), input = document
+								.createElement("input");
+
+						// Setup
+						div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
+
+						// IE strips leading whitespace when .innerHTML is used
+						support.leadingWhitespace = div.firstChild.nodeType === 3;
+
+						// Make sure that tbody elements aren't automatically
+						// inserted
+						// IE will insert them into empty tables
+						support.tbody = !div.getElementsByTagName("tbody").length;
+
+						// Make sure that link elements get serialized correctly
+						// by innerHTML
+						// This requires a wrapper element in IE
+						support.htmlSerialize = !!div
+								.getElementsByTagName("link").length;
+
+						// Makes sure cloning an html5 element does not cause
+						// problems
+						// Where outerHTML is undefined, this still works
+						support.html5Clone = document.createElement("nav")
+								.cloneNode(true).outerHTML !== "<:nav></:nav>";
+
+						// Check if a disconnected checkbox will retain its
+						// checked
+						// value of true after appended to the DOM (IE6/7)
+						input.type = "checkbox";
+						input.checked = true;
+						fragment.appendChild(input);
+						support.appendChecked = input.checked;
+
+						// Make sure textarea (and checkbox) defaultValue is
+						// properly cloned
+						// Support: IE6-IE11+
+						div.innerHTML = "<textarea>x</textarea>";
+						support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue;
+
+						// #11217 - WebKit loses check when the name is after
+						// the checked attribute
+						fragment.appendChild(div);
+
+						// Support: Windows Web Apps (WWA)
+						// `name` and `type` must use .setAttribute for WWA
+						// (#14901)
+						input = document.createElement("input");
+						input.setAttribute("type", "radio");
+						input.setAttribute("checked", "checked");
+						input.setAttribute("name", "t");
+
+						div.appendChild(input);
+
+						// Support: Safari 5.1, iOS 5.1, Android 4.x, Android
+						// 2.3
+						// old WebKit doesn't clone checked state correctly in
+						// fragments
+						support.checkClone = div.cloneNode(true)
+								.cloneNode(true).lastChild.checked;
+
+						// Support: IE<9
+						// Cloned elements keep attachEvent handlers, we use
+						// addEventListener on IE9+
+						support.noCloneEvent = !!div.addEventListener;
+
+						// Support: IE<9
+						// Since attributes and properties are the same in IE,
+						// cleanData must set properties to undefined rather
+						// than use removeAttribute
+						div[jQuery.expando] = 1;
+						support.attributes = !div.getAttribute(jQuery.expando);
+					})();
+
+					// We have to close these tags to support XHTML (#13200)
+					var wrapMap = {
+						option : [ 1, "<select multiple='multiple'>",
+								"</select>" ],
+						legend : [ 1, "<fieldset>", "</fieldset>" ],
+						area : [ 1, "<map>", "</map>" ],
+
+						// Support: IE8
+						param : [ 1, "<object>", "</object>" ],
+						thead : [ 1, "<table>", "</table>" ],
+						tr : [ 2, "<table><tbody>", "</tbody></table>" ],
+						col : [ 2, "<table><tbody></tbody><colgroup>",
+								"</colgroup></table>" ],
+						td : [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+
+						// IE6-8 can't serialize link, script, style, or any
+						// html5 (NoScope) tags,
+						// unless wrapped in a div with non-breaking characters
+						// in front of it.
+						_default : support.htmlSerialize ? [ 0, "", "" ] : [ 1,
+								"X<div>", "</div>" ]
+					};
+
+					// Support: IE8-IE9
+					wrapMap.optgroup = wrapMap.option;
+
+					wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+					wrapMap.th = wrapMap.td;
+
+					function getAll(context, tag) {
+						var elems, elem, i = 0, found = typeof context.getElementsByTagName !== "undefined" ? context
+								.getElementsByTagName(tag || "*")
+								: typeof context.querySelectorAll !== "undefined" ? context
+										.querySelectorAll(tag || "*")
+										: undefined;
+
+						if (!found) {
+							for (found = [], elems = context.childNodes
+									|| context; (elem = elems[i]) != null; i++) {
+								if (!tag || jQuery.nodeName(elem, tag)) {
+									found.push(elem);
+								} else {
+									jQuery.merge(found, getAll(elem, tag));
+								}
+							}
+						}
+
+						return tag === undefined || tag
+								&& jQuery.nodeName(context, tag) ? jQuery
+								.merge([ context ], found) : found;
+					}
+
+					// Mark scripts as having already been evaluated
+					function setGlobalEval(elems, refElements) {
+						var elem, i = 0;
+						for (; (elem = elems[i]) != null; i++) {
+							jQuery._data(elem, "globalEval", !refElements
+									|| jQuery._data(refElements[i],
+											"globalEval"));
+						}
+					}
+
+					var rhtml = /<|&#?\w+;/, rtbody = /<tbody/i;
+
+					function fixDefaultChecked(elem) {
+						if (rcheckableType.test(elem.type)) {
+							elem.defaultChecked = elem.checked;
+						}
+					}
+
+					function buildFragment(elems, context, scripts, selection,
+							ignored) {
+						var j, elem, contains, tmp, tag, tbody, wrap, l = elems.length,
+
+						// Ensure a safe fragment
+						safe = createSafeFragment(context),
+
+						nodes = [], i = 0;
+
+						for (; i < l; i++) {
+							elem = elems[i];
+
+							if (elem || elem === 0) {
+
+								// Add nodes directly
+								if (jQuery.type(elem) === "object") {
+									jQuery.merge(nodes,
+											elem.nodeType ? [ elem ] : elem);
+
+									// Convert non-html into a text node
+								} else if (!rhtml.test(elem)) {
+									nodes.push(context.createTextNode(elem));
+
+									// Convert html into DOM nodes
+								} else {
+									tmp = tmp
+											|| safe.appendChild(context
+													.createElement("div"));
+
+									// Deserialize a standard representation
+									tag = (rtagName.exec(elem) || [ "", "" ])[1]
+											.toLowerCase();
+									wrap = wrapMap[tag] || wrapMap._default;
+
+									tmp.innerHTML = wrap[1]
+											+ jQuery.htmlPrefilter(elem)
+											+ wrap[2];
+
+									// Descend through wrappers to the right
+									// content
+									j = wrap[0];
+									while (j--) {
+										tmp = tmp.lastChild;
+									}
+
+									// Manually add leading whitespace removed
+									// by IE
+									if (!support.leadingWhitespace
+											&& rleadingWhitespace.test(elem)) {
+										nodes
+												.push(context
+														.createTextNode(rleadingWhitespace
+																.exec(elem)[0]));
+									}
+
+									// Remove IE's autoinserted <tbody> from
+									// table fragments
+									if (!support.tbody) {
+
+										// String was a <table>, *may* have
+										// spurious <tbody>
+										elem = tag === "table"
+												&& !rtbody.test(elem) ? tmp.firstChild
+												:
+
+												// String was a bare <thead> or
+												// <tfoot>
+												wrap[1] === "<table>"
+														&& !rtbody.test(elem) ? tmp
+														: 0;
+
+										j = elem && elem.childNodes.length;
+										while (j--) {
+											if (jQuery
+													.nodeName(
+															(tbody = elem.childNodes[j]),
+															"tbody")
+													&& !tbody.childNodes.length) {
+
+												elem.removeChild(tbody);
+											}
+										}
+									}
+
+									jQuery.merge(nodes, tmp.childNodes);
+
+									// Fix #12392 for WebKit and IE > 9
+									tmp.textContent = "";
+
+									// Fix #12392 for oldIE
+									while (tmp.firstChild) {
+										tmp.removeChild(tmp.firstChild);
+									}
+
+									// Remember the top-level container for
+									// proper cleanup
+									tmp = safe.lastChild;
+								}
+							}
+						}
+
+						// Fix #11356: Clear elements from fragment
+						if (tmp) {
+							safe.removeChild(tmp);
+						}
+
+						// Reset defaultChecked for any radios and checkboxes
+						// about to be appended to the DOM in IE 6/7 (#8060)
+						if (!support.appendChecked) {
+							jQuery.grep(getAll(nodes, "input"),
+									fixDefaultChecked);
+						}
+
+						i = 0;
+						while ((elem = nodes[i++])) {
+
+							// Skip elements already in the context collection
+							// (trac-4087)
+							if (selection
+									&& jQuery.inArray(elem, selection) > -1) {
+								if (ignored) {
+									ignored.push(elem);
+								}
+
+								continue;
+							}
+
+							contains = jQuery
+									.contains(elem.ownerDocument, elem);
+
+							// Append to fragment
+							tmp = getAll(safe.appendChild(elem), "script");
+
+							// Preserve script evaluation history
+							if (contains) {
+								setGlobalEval(tmp);
+							}
+
+							// Capture executables
+							if (scripts) {
+								j = 0;
+								while ((elem = tmp[j++])) {
+									if (rscriptType.test(elem.type || "")) {
+										scripts.push(elem);
+									}
+								}
+							}
+						}
+
+						tmp = null;
+
+						return safe;
+					}
+
+					(function() {
+						var i, eventName, div = document.createElement("div");
+
+						// Support: IE<9 (lack submit/change bubble), Firefox
+						// (lack focus(in | out) events)
+						for (i in {
+							submit : true,
+							change : true,
+							focusin : true
+						}) {
+							eventName = "on" + i;
+
+							if (!(support[i] = eventName in window)) {
+
+								// Beware of CSP restrictions
+								// (https://developer.mozilla.org/en/Security/CSP)
+								div.setAttribute(eventName, "t");
+								support[i] = div.attributes[eventName].expando === false;
+							}
+						}
+
+						// Null elements to avoid leaks in IE.
+						div = null;
+					})();
+
+					var rformElems = /^(?:input|select|textarea)$/i, rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
+
+					function returnTrue() {
+						return true;
+					}
+
+					function returnFalse() {
+						return false;
+					}
+
+					// Support: IE9
+					// See #13393 for more info
+					function safeActiveElement() {
+						try {
+							return document.activeElement;
+						} catch (err) {
+						}
+					}
+
+					function on(elem, types, selector, data, fn, one) {
+						var origFn, type;
+
+						// Types can be a map of types/handlers
+						if (typeof types === "object") {
+
+							// ( types-Object, selector, data )
+							if (typeof selector !== "string") {
+
+								// ( types-Object, data )
+								data = data || selector;
+								selector = undefined;
+							}
+							for (type in types) {
+								on(elem, type, selector, data, types[type], one);
+							}
+							return elem;
+						}
+
+						if (data == null && fn == null) {
+
+							// ( types, fn )
+							fn = selector;
+							data = selector = undefined;
+						} else if (fn == null) {
+							if (typeof selector === "string") {
+
+								// ( types, selector, fn )
+								fn = data;
+								data = undefined;
+							} else {
+
+								// ( types, data, fn )
+								fn = data;
+								data = selector;
+								selector = undefined;
+							}
+						}
+						if (fn === false) {
+							fn = returnFalse;
+						} else if (!fn) {
+							return elem;
+						}
+
+						if (one === 1) {
+							origFn = fn;
+							fn = function(event) {
+
+								// Can use an empty set, since event contains
+								// the info
+								jQuery().off(event);
+								return origFn.apply(this, arguments);
+							};
+
+							// Use same guid so caller can remove using origFn
+							fn.guid = origFn.guid
+									|| (origFn.guid = jQuery.guid++);
+						}
+						return elem.each(function() {
+							jQuery.event.add(this, types, fn, data, selector);
+						});
+					}
+
+					/*
+					 * Helper functions for managing events -- not part of the
+					 * public interface. Props to Dean Edwards' addEvent library
+					 * for many of the ideas.
+					 */
+					jQuery.event = {
+
+						global : {},
+
+						add : function(elem, types, handler, data, selector) {
+							var tmp, events, t, handleObjIn, special, eventHandle, handleObj, handlers, type, namespaces, origType, elemData = jQuery
+									._data(elem);
+
+							// Don't attach events to noData or text/comment
+							// nodes (but allow plain objects)
+							if (!elemData) {
+								return;
+							}
+
+							// Caller can pass in an object of custom data in
+							// lieu of the handler
+							if (handler.handler) {
+								handleObjIn = handler;
+								handler = handleObjIn.handler;
+								selector = handleObjIn.selector;
+							}
+
+							// Make sure that the handler has a unique ID, used
+							// to find/remove it later
+							if (!handler.guid) {
+								handler.guid = jQuery.guid++;
+							}
+
+							// Init the element's event structure and main
+							// handler, if this is the first
+							if (!(events = elemData.events)) {
+								events = elemData.events = {};
+							}
+							if (!(eventHandle = elemData.handle)) {
+								eventHandle = elemData.handle = function(e) {
+
+									// Discard the second event of a
+									// jQuery.event.trigger() and
+									// when an event is called after a page has
+									// unloaded
+									return typeof jQuery !== "undefined"
+											&& (!e || jQuery.event.triggered !== e.type) ? jQuery.event.dispatch
+											.apply(eventHandle.elem, arguments)
+											: undefined;
+								};
+
+								// Add elem as a property of the handle fn to
+								// prevent a memory leak
+								// with IE non-native events
+								eventHandle.elem = elem;
+							}
+
+							// Handle multiple events separated by a space
+							types = (types || "").match(rnotwhite) || [ "" ];
+							t = types.length;
+							while (t--) {
+								tmp = rtypenamespace.exec(types[t]) || [];
+								type = origType = tmp[1];
+								namespaces = (tmp[2] || "").split(".").sort();
+
+								// There *must* be a type, no attaching
+								// namespace-only handlers
+								if (!type) {
+									continue;
+								}
+
+								// If event changes its type, use the special
+								// event handlers for the changed type
+								special = jQuery.event.special[type] || {};
+
+								// If selector defined, determine special event
+								// api type, otherwise given type
+								type = (selector ? special.delegateType
+										: special.bindType)
+										|| type;
+
+								// Update special based on newly reset type
+								special = jQuery.event.special[type] || {};
+
+								// handleObj is passed to all event handlers
+								handleObj = jQuery.extend({
+									type : type,
+									origType : origType,
+									data : data,
+									handler : handler,
+									guid : handler.guid,
+									selector : selector,
+									needsContext : selector
+											&& jQuery.expr.match.needsContext
+													.test(selector),
+									namespace : namespaces.join(".")
+								}, handleObjIn);
+
+								// Init the event handler queue if we're the
+								// first
+								if (!(handlers = events[type])) {
+									handlers = events[type] = [];
+									handlers.delegateCount = 0;
+
+									// Only use addEventListener/attachEvent if
+									// the special events handler returns false
+									if (!special.setup
+											|| special.setup.call(elem, data,
+													namespaces, eventHandle) === false) {
+
+										// Bind the global event handler to the
+										// element
+										if (elem.addEventListener) {
+											elem.addEventListener(type,
+													eventHandle, false);
+
+										} else if (elem.attachEvent) {
+											elem.attachEvent("on" + type,
+													eventHandle);
+										}
+									}
+								}
+
+								if (special.add) {
+									special.add.call(elem, handleObj);
+
+									if (!handleObj.handler.guid) {
+										handleObj.handler.guid = handler.guid;
+									}
+								}
+
+								// Add to the element's handler list, delegates
+								// in front
+								if (selector) {
+									handlers.splice(handlers.delegateCount++,
+											0, handleObj);
+								} else {
+									handlers.push(handleObj);
+								}
+
+								// Keep track of which events have ever been
+								// used, for event optimization
+								jQuery.event.global[type] = true;
+							}
+
+							// Nullify elem to prevent memory leaks in IE
+							elem = null;
+						},
+
+						// Detach an event or set of events from an element
+						remove : function(elem, types, handler, selector,
+								mappedTypes) {
+							var j, handleObj, tmp, origCount, t, events, special, handlers, type, namespaces, origType, elemData = jQuery
+									.hasData(elem)
+									&& jQuery._data(elem);
+
+							if (!elemData || !(events = elemData.events)) {
+								return;
+							}
+
+							// Once for each type.namespace in types; type may
+							// be omitted
+							types = (types || "").match(rnotwhite) || [ "" ];
+							t = types.length;
+							while (t--) {
+								tmp = rtypenamespace.exec(types[t]) || [];
+								type = origType = tmp[1];
+								namespaces = (tmp[2] || "").split(".").sort();
+
+								// Unbind all events (on this namespace, if
+								// provided) for the element
+								if (!type) {
+									for (type in events) {
+										jQuery.event.remove(elem, type
+												+ types[t], handler, selector,
+												true);
+									}
+									continue;
+								}
+
+								special = jQuery.event.special[type] || {};
+								type = (selector ? special.delegateType
+										: special.bindType)
+										|| type;
+								handlers = events[type] || [];
+								tmp = tmp[2]
+										&& new RegExp("(^|\\.)"
+												+ namespaces
+														.join("\\.(?:.*\\.|)")
+												+ "(\\.|$)");
+
+								// Remove matching events
+								origCount = j = handlers.length;
+								while (j--) {
+									handleObj = handlers[j];
+
+									if ((mappedTypes || origType === handleObj.origType)
+											&& (!handler || handler.guid === handleObj.guid)
+											&& (!tmp || tmp
+													.test(handleObj.namespace))
+											&& (!selector
+													|| selector === handleObj.selector || selector === "**"
+													&& handleObj.selector)) {
+										handlers.splice(j, 1);
+
+										if (handleObj.selector) {
+											handlers.delegateCount--;
+										}
+										if (special.remove) {
+											special.remove
+													.call(elem, handleObj);
+										}
+									}
+								}
+
+								// Remove generic event handler if we removed
+								// something and no more handlers exist
+								// (avoids potential for endless recursion
+								// during removal of special event handlers)
+								if (origCount && !handlers.length) {
+									if (!special.teardown
+											|| special.teardown
+													.call(elem, namespaces,
+															elemData.handle) === false) {
+
+										jQuery.removeEvent(elem, type,
+												elemData.handle);
+									}
+
+									delete events[type];
+								}
+							}
+
+							// Remove the expando if it's no longer used
+							if (jQuery.isEmptyObject(events)) {
+								delete elemData.handle;
+
+								// removeData also checks for emptiness and
+								// clears the expando if empty
+								// so use it instead of delete
+								jQuery._removeData(elem, "events");
+							}
+						},
+
+						trigger : function(event, data, elem, onlyHandlers) {
+							var handle, ontype, cur, bubbleType, special, tmp, i, eventPath = [ elem
+									|| document ], type = hasOwn.call(event,
+									"type") ? event.type : event, namespaces = hasOwn
+									.call(event, "namespace") ? event.namespace
+									.split(".") : [];
+
+							cur = tmp = elem = elem || document;
+
+							// Don't do events on text and comment nodes
+							if (elem.nodeType === 3 || elem.nodeType === 8) {
+								return;
+							}
+
+							// focus/blur morphs to focusin/out; ensure we're
+							// not firing them right now
+							if (rfocusMorph.test(type + jQuery.event.triggered)) {
+								return;
+							}
+
+							if (type.indexOf(".") > -1) {
+
+								// Namespaced trigger; create a regexp to match
+								// event type in handle()
+								namespaces = type.split(".");
+								type = namespaces.shift();
+								namespaces.sort();
+							}
+							ontype = type.indexOf(":") < 0 && "on" + type;
+
+							// Caller can pass in a jQuery.Event object, Object,
+							// or just an event type string
+							event = event[jQuery.expando] ? event
+									: new jQuery.Event(type,
+											typeof event === "object" && event);
+
+							// Trigger bitmask: & 1 for native handlers; & 2 for
+							// jQuery (always true)
+							event.isTrigger = onlyHandlers ? 2 : 3;
+							event.namespace = namespaces.join(".");
+							event.rnamespace = event.namespace ? new RegExp(
+									"(^|\\.)"
+											+ namespaces.join("\\.(?:.*\\.|)")
+											+ "(\\.|$)") : null;
+
+							// Clean up the event in case it is being reused
+							event.result = undefined;
+							if (!event.target) {
+								event.target = elem;
+							}
+
+							// Clone any incoming data and prepend the event,
+							// creating the handler arg list
+							data = data == null ? [ event ] : jQuery.makeArray(
+									data, [ event ]);
+
+							// Allow special events to draw outside the lines
+							special = jQuery.event.special[type] || {};
+							if (!onlyHandlers
+									&& special.trigger
+									&& special.trigger.apply(elem, data) === false) {
+								return;
+							}
+
+							// Determine event propagation path in advance, per
+							// W3C events spec (#9951)
+							// Bubble up to document, then to window; watch for
+							// a global ownerDocument var (#9724)
+							if (!onlyHandlers && !special.noBubble
+									&& !jQuery.isWindow(elem)) {
+
+								bubbleType = special.delegateType || type;
+								if (!rfocusMorph.test(bubbleType + type)) {
+									cur = cur.parentNode;
+								}
+								for (; cur; cur = cur.parentNode) {
+									eventPath.push(cur);
+									tmp = cur;
+								}
+
+								// Only add window if we got to document (e.g.,
+								// not plain obj or detached DOM)
+								if (tmp === (elem.ownerDocument || document)) {
+									eventPath.push(tmp.defaultView
+											|| tmp.parentWindow || window);
+								}
+							}
+
+							// Fire handlers on the event path
+							i = 0;
+							while ((cur = eventPath[i++])
+									&& !event.isPropagationStopped()) {
+
+								event.type = i > 1 ? bubbleType
+										: special.bindType || type;
+
+								// jQuery handler
+								handle = (jQuery._data(cur, "events") || {})[event.type]
+										&& jQuery._data(cur, "handle");
+
+								if (handle) {
+									handle.apply(cur, data);
+								}
+
+								// Native handler
+								handle = ontype && cur[ontype];
+								if (handle && handle.apply && acceptData(cur)) {
+									event.result = handle.apply(cur, data);
+									if (event.result === false) {
+										event.preventDefault();
+									}
+								}
+							}
+							event.type = type;
+
+							// If nobody prevented the default action, do it now
+							if (!onlyHandlers && !event.isDefaultPrevented()) {
+
+								if ((!special._default || special._default
+										.apply(eventPath.pop(), data) === false)
+										&& acceptData(elem)) {
+
+									// Call a native DOM method on the target
+									// with the same name name as the event.
+									// Can't use an .isFunction() check here
+									// because IE6/7 fails that test.
+									// Don't do default actions on window,
+									// that's where global variables be (#6170)
+									if (ontype && elem[type]
+											&& !jQuery.isWindow(elem)) {
+
+										// Don't re-trigger an onFOO event when
+										// we call its FOO() method
+										tmp = elem[ontype];
+
+										if (tmp) {
+											elem[ontype] = null;
+										}
+
+										// Prevent re-triggering of the same
+										// event, since we already bubbled it
+										// above
+										jQuery.event.triggered = type;
+										try {
+											elem[type]();
+										} catch (e) {
+
+											// IE<9 dies on focus/blur to hidden
+											// element (#1486,#12518)
+											// only reproducible on winXP IE8
+											// native, not IE9 in IE8 mode
+										}
+										jQuery.event.triggered = undefined;
+
+										if (tmp) {
+											elem[ontype] = tmp;
+										}
+									}
+								}
+							}
+
+							return event.result;
+						},
+
+						dispatch : function(event) {
+
+							// Make a writable jQuery.Event from the native
+							// event object
+							event = jQuery.event.fix(event);
+
+							var i, j, ret, matched, handleObj, handlerQueue = [], args = slice
+									.call(arguments), handlers = (jQuery._data(
+									this, "events") || {})[event.type]
+									|| [], special = jQuery.event.special[event.type]
+									|| {};
+
+							// Use the fix-ed jQuery.Event rather than the
+							// (read-only) native event
+							args[0] = event;
+							event.delegateTarget = this;
+
+							// Call the preDispatch hook for the mapped type,
+							// and let it bail if desired
+							if (special.preDispatch
+									&& special.preDispatch.call(this, event) === false) {
+								return;
+							}
+
+							// Determine handlers
+							handlerQueue = jQuery.event.handlers.call(this,
+									event, handlers);
+
+							// Run delegates first; they may want to stop
+							// propagation beneath us
+							i = 0;
+							while ((matched = handlerQueue[i++])
+									&& !event.isPropagationStopped()) {
+								event.currentTarget = matched.elem;
+
+								j = 0;
+								while ((handleObj = matched.handlers[j++])
+										&& !event
+												.isImmediatePropagationStopped()) {
+
+									// Triggered event must either 1) have no
+									// namespace, or 2) have namespace(s)
+									// a subset or equal to those in the bound
+									// event (both can have no namespace).
+									if (!event.rnamespace
+											|| event.rnamespace
+													.test(handleObj.namespace)) {
+
+										event.handleObj = handleObj;
+										event.data = handleObj.data;
+
+										ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler)
+												.apply(matched.elem, args);
+
+										if (ret !== undefined) {
+											if ((event.result = ret) === false) {
+												event.preventDefault();
+												event.stopPropagation();
+											}
+										}
+									}
+								}
+							}
+
+							// Call the postDispatch hook for the mapped type
+							if (special.postDispatch) {
+								special.postDispatch.call(this, event);
+							}
+
+							return event.result;
+						},
+
+						handlers : function(event, handlers) {
+							var i, matches, sel, handleObj, handlerQueue = [], delegateCount = handlers.delegateCount, cur = event.target;
+
+							// Support (at least): Chrome, IE9
+							// Find delegate handlers
+							// Black-hole SVG <use> instance trees (#13180)
+							//
+							// Support: Firefox<=42+
+							// Avoid non-left-click in FF but don't block IE
+							// radio events (#3861, gh-2343)
+							if (delegateCount
+									&& cur.nodeType
+									&& (event.type !== "click"
+											|| isNaN(event.button) || event.button < 1)) {
+
+								/* jshint eqeqeq: false */
+								for (; cur != this; cur = cur.parentNode
+										|| this) {
+									/* jshint eqeqeq: true */
+
+									// Don't check non-elements (#13208)
+									// Don't process clicks on disabled elements
+									// (#6911, #8165, #11382, #11764)
+									if (cur.nodeType === 1
+											&& (cur.disabled !== true || event.type !== "click")) {
+										matches = [];
+										for (i = 0; i < delegateCount; i++) {
+											handleObj = handlers[i];
+
+											// Don't conflict with
+											// Object.prototype properties
+											// (#13203)
+											sel = handleObj.selector + " ";
+
+											if (matches[sel] === undefined) {
+												matches[sel] = handleObj.needsContext ? jQuery(
+														sel, this).index(cur) > -1
+														: jQuery.find(sel,
+																this, null,
+																[ cur ]).length;
+											}
+											if (matches[sel]) {
+												matches.push(handleObj);
+											}
+										}
+										if (matches.length) {
+											handlerQueue.push({
+												elem : cur,
+												handlers : matches
+											});
+										}
+									}
+								}
+							}
+
+							// Add the remaining (directly-bound) handlers
+							if (delegateCount < handlers.length) {
+								handlerQueue.push({
+									elem : this,
+									handlers : handlers.slice(delegateCount)
+								});
+							}
+
+							return handlerQueue;
+						},
+
+						fix : function(event) {
+							if (event[jQuery.expando]) {
+								return event;
+							}
+
+							// Create a writable copy of the event object and
+							// normalize some properties
+							var i, prop, copy, type = event.type, originalEvent = event, fixHook = this.fixHooks[type];
+
+							if (!fixHook) {
+								this.fixHooks[type] = fixHook = rmouseEvent
+										.test(type) ? this.mouseHooks
+										: rkeyEvent.test(type) ? this.keyHooks
+												: {};
+							}
+							copy = fixHook.props ? this.props
+									.concat(fixHook.props) : this.props;
+
+							event = new jQuery.Event(originalEvent);
+
+							i = copy.length;
+							while (i--) {
+								prop = copy[i];
+								event[prop] = originalEvent[prop];
+							}
+
+							// Support: IE<9
+							// Fix target property (#1925)
+							if (!event.target) {
+								event.target = originalEvent.srcElement
+										|| document;
+							}
+
+							// Support: Safari 6-8+
+							// Target should not be a text node (#504, #13143)
+							if (event.target.nodeType === 3) {
+								event.target = event.target.parentNode;
+							}
+
+							// Support: IE<9
+							// For mouse/key events, metaKey==false if it's
+							// undefined (#3368, #11328)
+							event.metaKey = !!event.metaKey;
+
+							return fixHook.filter ? fixHook.filter(event,
+									originalEvent) : event;
+						},
+
+						// Includes some event props shared by KeyEvent and
+						// MouseEvent
+						props : ("altKey bubbles cancelable ctrlKey currentTarget detail eventPhase "
+								+ "metaKey relatedTarget shiftKey target timeStamp view which")
+								.split(" "),
+
+						fixHooks : {},
+
+						keyHooks : {
+							props : "char charCode key keyCode".split(" "),
+							filter : function(event, original) {
+
+								// Add which for key events
+								if (event.which == null) {
+									event.which = original.charCode != null ? original.charCode
+											: original.keyCode;
+								}
+
+								return event;
+							}
+						},
+
+						mouseHooks : {
+							props : ("button buttons clientX clientY fromElement offsetX offsetY "
+									+ "pageX pageY screenX screenY toElement")
+									.split(" "),
+							filter : function(event, original) {
+								var body, eventDoc, doc, button = original.button, fromElement = original.fromElement;
+
+								// Calculate pageX/Y if missing and clientX/Y
+								// available
+								if (event.pageX == null
+										&& original.clientX != null) {
+									eventDoc = event.target.ownerDocument
+											|| document;
+									doc = eventDoc.documentElement;
+									body = eventDoc.body;
+
+									event.pageX = original.clientX
+											+ (doc && doc.scrollLeft || body
+													&& body.scrollLeft || 0)
+											- (doc && doc.clientLeft || body
+													&& body.clientLeft || 0);
+									event.pageY = original.clientY
+											+ (doc && doc.scrollTop || body
+													&& body.scrollTop || 0)
+											- (doc && doc.clientTop || body
+													&& body.clientTop || 0);
+								}
+
+								// Add relatedTarget, if necessary
+								if (!event.relatedTarget && fromElement) {
+									event.relatedTarget = fromElement === event.target ? original.toElement
+											: fromElement;
+								}
+
+								// Add which for click: 1 === left; 2 ===
+								// middle; 3 === right
+								// Note: button is not normalized, so don't use
+								// it
+								if (!event.which && button !== undefined) {
+									event.which = (button & 1 ? 1
+											: (button & 2 ? 3 : (button & 4 ? 2
+													: 0)));
+								}
+
+								return event;
+							}
+						},
+
+						special : {
+							load : {
+
+								// Prevent triggered image.load events from
+								// bubbling to window.load
+								noBubble : true
+							},
+							focus : {
+
+								// Fire native event if possible so blur/focus
+								// sequence is correct
+								trigger : function() {
+									if (this !== safeActiveElement()
+											&& this.focus) {
+										try {
+											this.focus();
+											return false;
+										} catch (e) {
+
+											// Support: IE<9
+											// If we error on focus to hidden
+											// element (#1486, #12518),
+											// let .trigger() run the handlers
+										}
+									}
+								},
+								delegateType : "focusin"
+							},
+							blur : {
+								trigger : function() {
+									if (this === safeActiveElement()
+											&& this.blur) {
+										this.blur();
+										return false;
+									}
+								},
+								delegateType : "focusout"
+							},
+							click : {
+
+								// For checkbox, fire native event so checked
+								// state will be right
+								trigger : function() {
+									if (jQuery.nodeName(this, "input")
+											&& this.type === "checkbox"
+											&& this.click) {
+										this.click();
+										return false;
+									}
+								},
+
+								// For cross-browser consistency, don't fire
+								// native .click() on links
+								_default : function(event) {
+									return jQuery.nodeName(event.target, "a");
+								}
+							},
+
+							beforeunload : {
+								postDispatch : function(event) {
+
+									// Support: Firefox 20+
+									// Firefox doesn't alert if the returnValue
+									// field is not set.
+									if (event.result !== undefined
+											&& event.originalEvent) {
+										event.originalEvent.returnValue = event.result;
+									}
+								}
+							}
+						},
+
+						// Piggyback on a donor event to simulate a different
+						// one
+						simulate : function(type, elem, event) {
+							var e = jQuery.extend(new jQuery.Event(), event, {
+								type : type,
+								isSimulated : true
+
+							// Previously, `originalEvent: {}` was set here, so
+							// stopPropagation call
+							// would not be triggered on donor event, since in
+							// our own
+							// jQuery.event.stopPropagation function we had a
+							// check for existence of
+							// originalEvent.stopPropagation method, so,
+							// consequently it would be a noop.
+							//
+							// Guard for simulated events was moved to
+							// jQuery.event.stopPropagation function
+							// since `originalEvent` should point to the
+							// original event for the
+							// constancy with other events and for more focused
+							// logic
+							});
+
+							jQuery.event.trigger(e, null, elem);
+
+							if (e.isDefaultPrevented()) {
+								event.preventDefault();
+							}
+						}
+					};
+
+					jQuery.removeEvent = document.removeEventListener ? function(
+							elem, type, handle) {
+
+						// This "if" is needed for plain objects
+						if (elem.removeEventListener) {
+							elem.removeEventListener(type, handle);
+						}
+					}
+							: function(elem, type, handle) {
+								var name = "on" + type;
+
+								if (elem.detachEvent) {
+
+									// #8545, #7054, preventing memory leaks for
+									// custom events in IE6-8
+									// detachEvent needed property on element,
+									// by name of that event,
+									// to properly expose it to GC
+									if (typeof elem[name] === "undefined") {
+										elem[name] = null;
+									}
+
+									elem.detachEvent(name, handle);
+								}
+							};
+
+					jQuery.Event = function(src, props) {
+
+						// Allow instantiation without the 'new' keyword
+						if (!(this instanceof jQuery.Event)) {
+							return new jQuery.Event(src, props);
+						}
+
+						// Event object
+						if (src && src.type) {
+							this.originalEvent = src;
+							this.type = src.type;
+
+							// Events bubbling up the document may have been
+							// marked as prevented
+							// by a handler lower down the tree; reflect the
+							// correct value.
+							this.isDefaultPrevented = src.defaultPrevented
+									|| src.defaultPrevented === undefined &&
+
+									// Support: IE < 9, Android < 4.0
+									src.returnValue === false ? returnTrue
+									: returnFalse;
+
+							// Event type
+						} else {
+							this.type = src;
+						}
+
+						// Put explicitly provided properties onto the event
+						// object
+						if (props) {
+							jQuery.extend(this, props);
+						}
+
+						// Create a timestamp if incoming event doesn't have one
+						this.timeStamp = src && src.timeStamp || jQuery.now();
+
+						// Mark it as fixed
+						this[jQuery.expando] = true;
+					};
+
+					// jQuery.Event is based on DOM3 Events as specified by the
+					// ECMAScript Language Binding
+					// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+					jQuery.Event.prototype = {
+						constructor : jQuery.Event,
+						isDefaultPrevented : returnFalse,
+						isPropagationStopped : returnFalse,
+						isImmediatePropagationStopped : returnFalse,
+
+						preventDefault : function() {
+							var e = this.originalEvent;
+
+							this.isDefaultPrevented = returnTrue;
+							if (!e) {
+								return;
+							}
+
+							// If preventDefault exists, run it on the original
+							// event
+							if (e.preventDefault) {
+								e.preventDefault();
+
+								// Support: IE
+								// Otherwise set the returnValue property of the
+								// original event to false
+							} else {
+								e.returnValue = false;
+							}
+						},
+						stopPropagation : function() {
+							var e = this.originalEvent;
+
+							this.isPropagationStopped = returnTrue;
+
+							if (!e || this.isSimulated) {
+								return;
+							}
+
+							// If stopPropagation exists, run it on the original
+							// event
+							if (e.stopPropagation) {
+								e.stopPropagation();
+							}
+
+							// Support: IE
+							// Set the cancelBubble property of the original
+							// event to true
+							e.cancelBubble = true;
+						},
+						stopImmediatePropagation : function() {
+							var e = this.originalEvent;
+
+							this.isImmediatePropagationStopped = returnTrue;
+
+							if (e && e.stopImmediatePropagation) {
+								e.stopImmediatePropagation();
+							}
+
+							this.stopPropagation();
+						}
+					};
+
+					// Create mouseenter/leave events using mouseover/out and
+					// event-time checks
+					// so that event delegation works in jQuery.
+					// Do the same for pointerenter/pointerleave and
+					// pointerover/pointerout
+					//
+					// Support: Safari 7 only
+					// Safari sends mouseenter too often; see:
+					// https://code.google.com/p/chromium/issues/detail?id=470258
+					// for the description of the bug (it existed in older
+					// Chrome versions as well).
+					jQuery
+							.each(
+									{
+										mouseenter : "mouseover",
+										mouseleave : "mouseout",
+										pointerenter : "pointerover",
+										pointerleave : "pointerout"
+									},
+									function(orig, fix) {
+										jQuery.event.special[orig] = {
+											delegateType : fix,
+											bindType : fix,
+
+											handle : function(event) {
+												var ret, target = this, related = event.relatedTarget, handleObj = event.handleObj;
+
+												// For mouseenter/leave call the
+												// handler if related is outside
+												// the target.
+												// NB: No relatedTarget if the
+												// mouse left/entered the
+												// browser window
+												if (!related
+														|| (related !== target && !jQuery
+																.contains(
+																		target,
+																		related))) {
+													event.type = handleObj.origType;
+													ret = handleObj.handler
+															.apply(this,
+																	arguments);
+													event.type = fix;
+												}
+												return ret;
+											}
+										};
+									});
+
+					// IE submit delegation
+					if (!support.submit) {
+
+						jQuery.event.special.submit = {
+							setup : function() {
+
+								// Only need this for delegated form submit
+								// events
+								if (jQuery.nodeName(this, "form")) {
+									return false;
+								}
+
+								// Lazy-add a submit handler when a descendant
+								// form may potentially be submitted
+								jQuery.event
+										.add(
+												this,
+												"click._submit keypress._submit",
+												function(e) {
+
+													// Node name check avoids a
+													// VML-related crash in IE
+													// (#9807)
+													var elem = e.target, form = jQuery
+															.nodeName(elem,
+																	"input")
+															|| jQuery.nodeName(
+																	elem,
+																	"button") ?
+
+													// Support: IE <=8
+													// We use jQuery.prop
+													// instead of elem.form
+													// to allow fixing the IE8
+													// delegated submit issue
+													// (gh-2332)
+													// by 3rd party
+													// polyfills/workarounds.
+													jQuery.prop(elem, "form")
+															: undefined;
+
+													if (form
+															&& !jQuery._data(
+																	form,
+																	"submit")) {
+														jQuery.event
+																.add(
+																		form,
+																		"submit._submit",
+																		function(
+																				event) {
+																			event._submitBubble = true;
+																		});
+														jQuery._data(form,
+																"submit", true);
+													}
+												});
+
+								// return undefined since we don't need an event
+								// listener
+							},
+
+							postDispatch : function(event) {
+
+								// If form was submitted by the user, bubble the
+								// event up the tree
+								if (event._submitBubble) {
+									delete event._submitBubble;
+									if (this.parentNode && !event.isTrigger) {
+										jQuery.event.simulate("submit",
+												this.parentNode, event);
+									}
+								}
+							},
+
+							teardown : function() {
+
+								// Only need this for delegated form submit
+								// events
+								if (jQuery.nodeName(this, "form")) {
+									return false;
+								}
+
+								// Remove delegated handlers; cleanData
+								// eventually reaps submit handlers attached
+								// above
+								jQuery.event.remove(this, "._submit");
+							}
+						};
+					}
+
+					// IE change delegation and checkbox/radio fix
+					if (!support.change) {
+
+						jQuery.event.special.change = {
+
+							setup : function() {
+
+								if (rformElems.test(this.nodeName)) {
+
+									// IE doesn't fire change on a check/radio
+									// until blur; trigger it on click
+									// after a propertychange. Eat the
+									// blur-change in special.change.handle.
+									// This still fires onchange a second time
+									// for check/radio after blur.
+									if (this.type === "checkbox"
+											|| this.type === "radio") {
+										jQuery.event
+												.add(
+														this,
+														"propertychange._change",
+														function(event) {
+															if (event.originalEvent.propertyName === "checked") {
+																this._justChanged = true;
+															}
+														});
+										jQuery.event
+												.add(
+														this,
+														"click._change",
+														function(event) {
+															if (this._justChanged
+																	&& !event.isTrigger) {
+																this._justChanged = false;
+															}
+
+															// Allow triggered,
+															// simulated change
+															// events (#11500)
+															jQuery.event
+																	.simulate(
+																			"change",
+																			this,
+																			event);
+														});
+									}
+									return false;
+								}
+
+								// Delegated event; lazy-add a change handler on
+								// descendant inputs
+								jQuery.event
+										.add(
+												this,
+												"beforeactivate._change",
+												function(e) {
+													var elem = e.target;
+
+													if (rformElems
+															.test(elem.nodeName)
+															&& !jQuery._data(
+																	elem,
+																	"change")) {
+														jQuery.event
+																.add(
+																		elem,
+																		"change._change",
+																		function(
+																				event) {
+																			if (this.parentNode
+																					&& !event.isSimulated
+																					&& !event.isTrigger) {
+																				jQuery.event
+																						.simulate(
+																								"change",
+																								this.parentNode,
+																								event);
+																			}
+																		});
+														jQuery._data(elem,
+																"change", true);
+													}
+												});
+							},
+
+							handle : function(event) {
+								var elem = event.target;
+
+								// Swallow native change events from
+								// checkbox/radio, we already triggered them
+								// above
+								if (this !== elem
+										|| event.isSimulated
+										|| event.isTrigger
+										|| (elem.type !== "radio" && elem.type !== "checkbox")) {
+
+									return event.handleObj.handler.apply(this,
+											arguments);
+								}
+							},
+
+							teardown : function() {
+								jQuery.event.remove(this, "._change");
+
+								return !rformElems.test(this.nodeName);
+							}
+						};
+					}
+
+					// Support: Firefox
+					// Firefox doesn't have focus(in | out) events
+					// Related ticket -
+					// https://bugzilla.mozilla.org/show_bug.cgi?id=687787
+					//
+					// Support: Chrome, Safari
+					// focus(in | out) events fire after focus & blur events,
+					// which is spec violation -
+					// http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
+					// Related ticket -
+					// https://code.google.com/p/chromium/issues/detail?id=449857
+					if (!support.focusin) {
+						jQuery.each({
+							focus : "focusin",
+							blur : "focusout"
+						},
+								function(orig, fix) {
+
+									// Attach a single capturing handler on the
+									// document while someone wants
+									// focusin/focusout
+									var handler = function(event) {
+										jQuery.event.simulate(fix,
+												event.target, jQuery.event
+														.fix(event));
+									};
+
+									jQuery.event.special[fix] = {
+										setup : function() {
+											var doc = this.ownerDocument
+													|| this, attaches = jQuery
+													._data(doc, fix);
+
+											if (!attaches) {
+												doc.addEventListener(orig,
+														handler, true);
+											}
+											jQuery._data(doc, fix,
+													(attaches || 0) + 1);
+										},
+										teardown : function() {
+											var doc = this.ownerDocument
+													|| this, attaches = jQuery
+													._data(doc, fix) - 1;
+
+											if (!attaches) {
+												doc.removeEventListener(orig,
+														handler, true);
+												jQuery._removeData(doc, fix);
+											} else {
+												jQuery
+														._data(doc, fix,
+																attaches);
+											}
+										}
+									};
+								});
+					}
+
+					jQuery.fn
+							.extend({
+
+								on : function(types, selector, data, fn) {
+									return on(this, types, selector, data, fn);
+								},
+								one : function(types, selector, data, fn) {
+									return on(this, types, selector, data, fn,
+											1);
+								},
+								off : function(types, selector, fn) {
+									var handleObj, type;
+									if (types && types.preventDefault
+											&& types.handleObj) {
+
+										// ( event ) dispatched jQuery.Event
+										handleObj = types.handleObj;
+										jQuery(types.delegateTarget)
+												.off(
+														handleObj.namespace ? handleObj.origType
+																+ "."
+																+ handleObj.namespace
+																: handleObj.origType,
+														handleObj.selector,
+														handleObj.handler);
+										return this;
+									}
+									if (typeof types === "object") {
+
+										// ( types-object [, selector] )
+										for (type in types) {
+											this.off(type, selector,
+													types[type]);
+										}
+										return this;
+									}
+									if (selector === false
+											|| typeof selector === "function") {
+
+										// ( types [, fn] )
+										fn = selector;
+										selector = undefined;
+									}
+									if (fn === false) {
+										fn = returnFalse;
+									}
+									return this.each(function() {
+										jQuery.event.remove(this, types, fn,
+												selector);
+									});
+								},
+
+								trigger : function(type, data) {
+									return this.each(function() {
+										jQuery.event.trigger(type, data, this);
+									});
+								},
+								triggerHandler : function(type, data) {
+									var elem = this[0];
+									if (elem) {
+										return jQuery.event.trigger(type, data,
+												elem, true);
+									}
+								}
+							});
+
+					var rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, rnoshimcache = new RegExp(
+							"<(?:" + nodeNames + ")[\\s/>]", "i"), rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
+
+					// Support: IE 10-11, Edge 10240+
+					// In IE/Edge using regex groups here causes severe
+					// slowdowns.
+					// See
+					// https://connect.microsoft.com/IE/feedback/details/1736512/
+					rnoInnerhtml = /<script|<style|<link/i,
+
+					// checked="checked" or checked
+					rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, rscriptTypeMasked = /^true\/(.*)/, rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g, safeFragment = createSafeFragment(document), fragmentDiv = safeFragment
+							.appendChild(document.createElement("div"));
+
+					// Support: IE<8
+					// Manipulating tables requires a tbody
+					function manipulationTarget(elem, content) {
+						return jQuery.nodeName(elem, "table")
+								&& jQuery.nodeName(
+										content.nodeType !== 11 ? content
+												: content.firstChild, "tr") ?
+
+						elem.getElementsByTagName("tbody")[0]
+								|| elem.appendChild(elem.ownerDocument
+										.createElement("tbody")) : elem;
+					}
+
+					// Replace/restore the type attribute of script elements for
+					// safe DOM manipulation
+					function disableScript(elem) {
+						elem.type = (jQuery.find.attr(elem, "type") !== null)
+								+ "/" + elem.type;
+						return elem;
+					}
+					function restoreScript(elem) {
+						var match = rscriptTypeMasked.exec(elem.type);
+						if (match) {
+							elem.type = match[1];
+						} else {
+							elem.removeAttribute("type");
+						}
+						return elem;
+					}
+
+					function cloneCopyEvent(src, dest) {
+						if (dest.nodeType !== 1 || !jQuery.hasData(src)) {
+							return;
+						}
+
+						var type, i, l, oldData = jQuery._data(src), curData = jQuery
+								._data(dest, oldData), events = oldData.events;
+
+						if (events) {
+							delete curData.handle;
+							curData.events = {};
+
+							for (type in events) {
+								for (i = 0, l = events[type].length; i < l; i++) {
+									jQuery.event.add(dest, type,
+											events[type][i]);
+								}
+							}
+						}
+
+						// make the cloned public data object a copy from the
+						// original
+						if (curData.data) {
+							curData.data = jQuery.extend({}, curData.data);
+						}
+					}
+
+					function fixCloneNodeIssues(src, dest) {
+						var nodeName, e, data;
+
+						// We do not need to do anything for non-Elements
+						if (dest.nodeType !== 1) {
+							return;
+						}
+
+						nodeName = dest.nodeName.toLowerCase();
+
+						// IE6-8 copies events bound via attachEvent when using
+						// cloneNode.
+						if (!support.noCloneEvent && dest[jQuery.expando]) {
+							data = jQuery._data(dest);
+
+							for (e in data.events) {
+								jQuery.removeEvent(dest, e, data.handle);
+							}
+
+							// Event data gets referenced instead of copied if
+							// the expando gets copied too
+							dest.removeAttribute(jQuery.expando);
+						}
+
+						// IE blanks contents when cloning scripts, and tries to
+						// evaluate newly-set text
+						if (nodeName === "script" && dest.text !== src.text) {
+							disableScript(dest).text = src.text;
+							restoreScript(dest);
+
+							// IE6-10 improperly clones children of object
+							// elements using classid.
+							// IE10 throws NoModificationAllowedError if parent
+							// is null, #12132.
+						} else if (nodeName === "object") {
+							if (dest.parentNode) {
+								dest.outerHTML = src.outerHTML;
+							}
+
+							// This path appears unavoidable for IE9. When
+							// cloning an object
+							// element in IE9, the outerHTML strategy above is
+							// not sufficient.
+							// If the src has innerHTML and the destination does
+							// not,
+							// copy the src.innerHTML into the dest.innerHTML.
+							// #10324
+							if (support.html5Clone
+									&& (src.innerHTML && !jQuery
+											.trim(dest.innerHTML))) {
+								dest.innerHTML = src.innerHTML;
+							}
+
+						} else if (nodeName === "input"
+								&& rcheckableType.test(src.type)) {
+
+							// IE6-8 fails to persist the checked state of a
+							// cloned checkbox
+							// or radio button. Worse, IE6-7 fail to give the
+							// cloned element
+							// a checked appearance if the defaultChecked value
+							// isn't also set
+
+							dest.defaultChecked = dest.checked = src.checked;
+
+							// IE6-7 get confused and end up setting the value
+							// of a cloned
+							// checkbox/radio button to an empty string instead
+							// of "on"
+							if (dest.value !== src.value) {
+								dest.value = src.value;
+							}
+
+							// IE6-8 fails to return the selected option to the
+							// default selected
+							// state when cloning options
+						} else if (nodeName === "option") {
+							dest.defaultSelected = dest.selected = src.defaultSelected;
+
+							// IE6-8 fails to set the defaultValue to the
+							// correct value when
+							// cloning other types of input fields
+						} else if (nodeName === "input"
+								|| nodeName === "textarea") {
+							dest.defaultValue = src.defaultValue;
+						}
+					}
+
+					function domManip(collection, args, callback, ignored) {
+
+						// Flatten any nested arrays
+						args = concat.apply([], args);
+
+						var first, node, hasScripts, scripts, doc, fragment, i = 0, l = collection.length, iNoClone = l - 1, value = args[0], isFunction = jQuery
+								.isFunction(value);
+
+						// We can't cloneNode fragments that contain checked, in
+						// WebKit
+						if (isFunction
+								|| (l > 1 && typeof value === "string"
+										&& !support.checkClone && rchecked
+										.test(value))) {
+							return collection.each(function(index) {
+								var self = collection.eq(index);
+								if (isFunction) {
+									args[0] = value.call(this, index, self
+											.html());
+								}
+								domManip(self, args, callback, ignored);
+							});
+						}
+
+						if (l) {
+							fragment = buildFragment(args,
+									collection[0].ownerDocument, false,
+									collection, ignored);
+							first = fragment.firstChild;
+
+							if (fragment.childNodes.length === 1) {
+								fragment = first;
+							}
+
+							// Require either new content or an interest in
+							// ignored elements to invoke the callback
+							if (first || ignored) {
+								scripts = jQuery.map(
+										getAll(fragment, "script"),
+										disableScript);
+								hasScripts = scripts.length;
+
+								// Use the original fragment for the last item
+								// instead of the first because it can end up
+								// being emptied incorrectly in certain
+								// situations (#8070).
+								for (; i < l; i++) {
+									node = fragment;
+
+									if (i !== iNoClone) {
+										node = jQuery.clone(node, true, true);
+
+										// Keep references to cloned scripts for
+										// later restoration
+										if (hasScripts) {
+
+											// Support: Android<4.1, PhantomJS<2
+											// push.apply(_, arraylike) throws
+											// on ancient WebKit
+											jQuery.merge(scripts, getAll(node,
+													"script"));
+										}
+									}
+
+									callback.call(collection[i], node, i);
+								}
+
+								if (hasScripts) {
+									doc = scripts[scripts.length - 1].ownerDocument;
+
+									// Reenable scripts
+									jQuery.map(scripts, restoreScript);
+
+									// Evaluate executable scripts on first
+									// document insertion
+									for (i = 0; i < hasScripts; i++) {
+										node = scripts[i];
+										if (rscriptType.test(node.type || "")
+												&& !jQuery._data(node,
+														"globalEval")
+												&& jQuery.contains(doc, node)) {
+
+											if (node.src) {
+
+												// Optional AJAX dependency, but
+												// won't run scripts if not
+												// present
+												if (jQuery._evalUrl) {
+													jQuery._evalUrl(node.src);
+												}
+											} else {
+												jQuery
+														.globalEval((node.text
+																|| node.textContent
+																|| node.innerHTML || "")
+																.replace(
+																		rcleanScript,
+																		""));
+											}
+										}
+									}
+								}
+
+								// Fix #11809: Avoid leaking memory
+								fragment = first = null;
+							}
+						}
+
+						return collection;
+					}
+
+					function remove(elem, selector, keepData) {
+						var node, elems = selector ? jQuery.filter(selector,
+								elem) : elem, i = 0;
+
+						for (; (node = elems[i]) != null; i++) {
+
+							if (!keepData && node.nodeType === 1) {
+								jQuery.cleanData(getAll(node));
+							}
+
+							if (node.parentNode) {
+								if (keepData
+										&& jQuery.contains(node.ownerDocument,
+												node)) {
+									setGlobalEval(getAll(node, "script"));
+								}
+								node.parentNode.removeChild(node);
+							}
+						}
+
+						return elem;
+					}
+
+					jQuery
+							.extend({
+								htmlPrefilter : function(html) {
+									return html.replace(rxhtmlTag, "<$1></$2>");
+								},
+
+								clone : function(elem, dataAndEvents,
+										deepDataAndEvents) {
+									var destElements, node, clone, i, srcElements, inPage = jQuery
+											.contains(elem.ownerDocument, elem);
+
+									if (support.html5Clone
+											|| jQuery.isXMLDoc(elem)
+											|| !rnoshimcache.test("<"
+													+ elem.nodeName + ">")) {
+
+										clone = elem.cloneNode(true);
+
+										// IE<=8 does not properly clone
+										// detached, unknown element nodes
+									} else {
+										fragmentDiv.innerHTML = elem.outerHTML;
+										fragmentDiv
+												.removeChild(clone = fragmentDiv.firstChild);
+									}
+
+									if ((!support.noCloneEvent || !support.noCloneChecked)
+											&& (elem.nodeType === 1 || elem.nodeType === 11)
+											&& !jQuery.isXMLDoc(elem)) {
+
+										// We eschew Sizzle here for performance
+										// reasons:
+										// http://jsperf.com/getall-vs-sizzle/2
+										destElements = getAll(clone);
+										srcElements = getAll(elem);
+
+										// Fix all IE cloning issues
+										for (i = 0; (node = srcElements[i]) != null; ++i) {
+
+											// Ensure that the destination node
+											// is not null; Fixes #9587
+											if (destElements[i]) {
+												fixCloneNodeIssues(node,
+														destElements[i]);
+											}
+										}
+									}
+
+									// Copy the events from the original to the
+									// clone
+									if (dataAndEvents) {
+										if (deepDataAndEvents) {
+											srcElements = srcElements
+													|| getAll(elem);
+											destElements = destElements
+													|| getAll(clone);
+
+											for (i = 0; (node = srcElements[i]) != null; i++) {
+												cloneCopyEvent(node,
+														destElements[i]);
+											}
+										} else {
+											cloneCopyEvent(elem, clone);
+										}
+									}
+
+									// Preserve script evaluation history
+									destElements = getAll(clone, "script");
+									if (destElements.length > 0) {
+										setGlobalEval(destElements, !inPage
+												&& getAll(elem, "script"));
+									}
+
+									destElements = srcElements = node = null;
+
+									// Return the cloned set
+									return clone;
+								},
+
+								cleanData : function(elems, /* internal */
+										forceAcceptData) {
+									var elem, type, id, data, i = 0, internalKey = jQuery.expando, cache = jQuery.cache, attributes = support.attributes, special = jQuery.event.special;
+
+									for (; (elem = elems[i]) != null; i++) {
+										if (forceAcceptData || acceptData(elem)) {
+
+											id = elem[internalKey];
+											data = id && cache[id];
+
+											if (data) {
+												if (data.events) {
+													for (type in data.events) {
+														if (special[type]) {
+															jQuery.event
+																	.remove(
+																			elem,
+																			type);
+
+															// This is a
+															// shortcut to avoid
+															// jQuery.event.remove's
+															// overhead
+														} else {
+															jQuery
+																	.removeEvent(
+																			elem,
+																			type,
+																			data.handle);
+														}
+													}
+												}
+
+												// Remove cache only if it was
+												// not already removed by
+												// jQuery.event.remove
+												if (cache[id]) {
+
+													delete cache[id];
+
+													// Support: IE<9
+													// IE does not allow us to
+													// delete expando properties
+													// from nodes
+													// IE creates expando
+													// attributes along with the
+													// property
+													// IE does not have a
+													// removeAttribute function
+													// on Document nodes
+													if (!attributes
+															&& typeof elem.removeAttribute !== "undefined") {
+														elem
+																.removeAttribute(internalKey);
+
+														// Webkit & Blink
+														// performance suffers
+														// when deleting
+														// properties
+														// from DOM nodes, so
+														// set to undefined
+														// instead
+														// https://code.google.com/p/chromium/issues/detail?id=378607
+													} else {
+														elem[internalKey] = undefined;
+													}
+
+													deletedIds.push(id);
+												}
+											}
+										}
+									}
+								}
+							});
+
+					jQuery.fn
+							.extend({
+
+								// Keep domManip exposed until 3.0 (gh-2225)
+								domManip : domManip,
+
+								detach : function(selector) {
+									return remove(this, selector, true);
+								},
+
+								remove : function(selector) {
+									return remove(this, selector);
+								},
+
+								text : function(value) {
+									return access(
+											this,
+											function(value) {
+												return value === undefined ? jQuery
+														.text(this)
+														: this
+																.empty()
+																.append(
+																		(this[0]
+																				&& this[0].ownerDocument || document)
+																				.createTextNode(value));
+											}, null, value, arguments.length);
+								},
+
+								append : function() {
+									return domManip(this, arguments, function(
+											elem) {
+										if (this.nodeType === 1
+												|| this.nodeType === 11
+												|| this.nodeType === 9) {
+											var target = manipulationTarget(
+													this, elem);
+											target.appendChild(elem);
+										}
+									});
+								},
+
+								prepend : function() {
+									return domManip(this, arguments, function(
+											elem) {
+										if (this.nodeType === 1
+												|| this.nodeType === 11
+												|| this.nodeType === 9) {
+											var target = manipulationTarget(
+													this, elem);
+											target.insertBefore(elem,
+													target.firstChild);
+										}
+									});
+								},
+
+								before : function() {
+									return domManip(this, arguments, function(
+											elem) {
+										if (this.parentNode) {
+											this.parentNode.insertBefore(elem,
+													this);
+										}
+									});
+								},
+
+								after : function() {
+									return domManip(this, arguments, function(
+											elem) {
+										if (this.parentNode) {
+											this.parentNode.insertBefore(elem,
+													this.nextSibling);
+										}
+									});
+								},
+
+								empty : function() {
+									var elem, i = 0;
+
+									for (; (elem = this[i]) != null; i++) {
+
+										// Remove element nodes and prevent
+										// memory leaks
+										if (elem.nodeType === 1) {
+											jQuery
+													.cleanData(getAll(elem,
+															false));
+										}
+
+										// Remove any remaining nodes
+										while (elem.firstChild) {
+											elem.removeChild(elem.firstChild);
+										}
+
+										// If this is a select, ensure that it
+										// displays empty (#12336)
+										// Support: IE<9
+										if (elem.options
+												&& jQuery.nodeName(elem,
+														"select")) {
+											elem.options.length = 0;
+										}
+									}
+
+									return this;
+								},
+
+								clone : function(dataAndEvents,
+										deepDataAndEvents) {
+									dataAndEvents = dataAndEvents == null ? false
+											: dataAndEvents;
+									deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents
+											: deepDataAndEvents;
+
+									return this.map(function() {
+										return jQuery.clone(this,
+												dataAndEvents,
+												deepDataAndEvents);
+									});
+								},
+
+								html : function(value) {
+									return access(
+											this,
+											function(value) {
+												var elem = this[0] || {}, i = 0, l = this.length;
+
+												if (value === undefined) {
+													return elem.nodeType === 1 ? elem.innerHTML
+															.replace(
+																	rinlinejQuery,
+																	"")
+															: undefined;
+												}
+
+												// See if we can take a shortcut
+												// and just use innerHTML
+												if (typeof value === "string"
+														&& !rnoInnerhtml
+																.test(value)
+														&& (support.htmlSerialize || !rnoshimcache
+																.test(value))
+														&& (support.leadingWhitespace || !rleadingWhitespace
+																.test(value))
+														&& !wrapMap[(rtagName
+																.exec(value) || [
+																"", "" ])[1]
+																.toLowerCase()]) {
+
+													value = jQuery
+															.htmlPrefilter(value);
+
+													try {
+														for (; i < l; i++) {
+
+															// Remove element
+															// nodes and prevent
+															// memory leaks
+															elem = this[i]
+																	|| {};
+															if (elem.nodeType === 1) {
+																jQuery
+																		.cleanData(getAll(
+																				elem,
+																				false));
+																elem.innerHTML = value;
+															}
+														}
+
+														elem = 0;
+
+														// If using innerHTML
+														// throws an exception,
+														// use the fallback
+														// method
+													} catch (e) {
+													}
+												}
+
+												if (elem) {
+													this.empty().append(value);
+												}
+											}, null, value, arguments.length);
+								},
+
+								replaceWith : function() {
+									var ignored = [];
+
+									// Make the changes, replacing each
+									// non-ignored context element with the new
+									// content
+									return domManip(
+											this,
+											arguments,
+											function(elem) {
+												var parent = this.parentNode;
+
+												if (jQuery.inArray(this,
+														ignored) < 0) {
+													jQuery
+															.cleanData(getAll(this));
+													if (parent) {
+														parent.replaceChild(
+																elem, this);
+													}
+												}
+
+												// Force callback invocation
+											}, ignored);
+								}
+							});
+
+					jQuery
+							.each(
+									{
+										appendTo : "append",
+										prependTo : "prepend",
+										insertBefore : "before",
+										insertAfter : "after",
+										replaceAll : "replaceWith"
+									},
+									function(name, original) {
+										jQuery.fn[name] = function(selector) {
+											var elems, i = 0, ret = [], insert = jQuery(selector), last = insert.length - 1;
+
+											for (; i <= last; i++) {
+												elems = i === last ? this
+														: this.clone(true);
+												jQuery(insert[i])[original]
+														(elems);
+
+												// Modern browsers can apply
+												// jQuery collections as arrays,
+												// but oldIE needs a .get()
+												push.apply(ret, elems.get());
+											}
+
+											return this.pushStack(ret);
+										};
+									});
+
+					var iframe, elemdisplay = {
+
+						// Support: Firefox
+						// We have to pre-define these values for FF (#10227)
+						HTML : "block",
+						BODY : "block"
+					};
+
+					/**
+					 * Retrieve the actual display of a element
+					 * 
+					 * @param {String}
+					 *            name nodeName of the element
+					 * @param {Object}
+					 *            doc Document object
+					 */
+
+					// Called only from within defaultDisplay
+					function actualDisplay(name, doc) {
+						var elem = jQuery(doc.createElement(name)).appendTo(
+								doc.body),
+
+						display = jQuery.css(elem[0], "display");
+
+						// We don't have any data stored on the element,
+						// so use "detach" method as fast way to get rid of the
+						// element
+						elem.detach();
+
+						return display;
+					}
+
+					/**
+					 * Try to determine the default display value of an element
+					 * 
+					 * @param {String}
+					 *            nodeName
+					 */
+					function defaultDisplay(nodeName) {
+						var doc = document, display = elemdisplay[nodeName];
+
+						if (!display) {
+							display = actualDisplay(nodeName, doc);
+
+							// If the simple way fails, read from inside an
+							// iframe
+							if (display === "none" || !display) {
+
+								// Use the already-created iframe if possible
+								iframe = (iframe || jQuery("<iframe frameborder='0' width='0' height='0'/>"))
+										.appendTo(doc.documentElement);
+
+								// Always write a new HTML skeleton so Webkit
+								// and Firefox don't choke on reuse
+								doc = (iframe[0].contentWindow || iframe[0].contentDocument).document;
+
+								// Support: IE
+								doc.write();
+								doc.close();
+
+								display = actualDisplay(nodeName, doc);
+								iframe.detach();
+							}
+
+							// Store the correct default display
+							elemdisplay[nodeName] = display;
+						}
+
+						return display;
+					}
+					var rmargin = (/^margin/);
+
+					var rnumnonpx = new RegExp("^(" + pnum + ")(?!px)[a-z%]+$",
+							"i");
+
+					var swap = function(elem, options, callback, args) {
+						var ret, name, old = {};
+
+						// Remember the old values, and insert the new ones
+						for (name in options) {
+							old[name] = elem.style[name];
+							elem.style[name] = options[name];
+						}
+
+						ret = callback.apply(elem, args || []);
+
+						// Revert the old values
+						for (name in options) {
+							elem.style[name] = old[name];
+						}
+
+						return ret;
+					};
+
+					var documentElement = document.documentElement;
+
+					(function() {
+						var pixelPositionVal, pixelMarginRightVal, boxSizingReliableVal, reliableHiddenOffsetsVal, reliableMarginRightVal, reliableMarginLeftVal, container = document
+								.createElement("div"), div = document
+								.createElement("div");
+
+						// Finish early in limited (non-browser) environments
+						if (!div.style) {
+							return;
+						}
+
+						div.style.cssText = "float:left;opacity:.5";
+
+						// Support: IE<9
+						// Make sure that element opacity exists (as opposed to
+						// filter)
+						support.opacity = div.style.opacity === "0.5";
+
+						// Verify style float existence
+						// (IE uses styleFloat instead of cssFloat)
+						support.cssFloat = !!div.style.cssFloat;
+
+						div.style.backgroundClip = "content-box";
+						div.cloneNode(true).style.backgroundClip = "";
+						support.clearCloneStyle = div.style.backgroundClip === "content-box";
+
+						container = document.createElement("div");
+						container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;"
+								+ "padding:0;margin-top:1px;position:absolute";
+						div.innerHTML = "";
+						container.appendChild(div);
+
+						// Support: Firefox<29, Android 2.3
+						// Vendor-prefix box-sizing
+						support.boxSizing = div.style.boxSizing === ""
+								|| div.style.MozBoxSizing === ""
+								|| div.style.WebkitBoxSizing === "";
+
+						jQuery.extend(support, {
+							reliableHiddenOffsets : function() {
+								if (pixelPositionVal == null) {
+									computeStyleTests();
+								}
+								return reliableHiddenOffsetsVal;
+							},
+
+							boxSizingReliable : function() {
+
+								// We're checking for pixelPositionVal here
+								// instead of boxSizingReliableVal
+								// since that compresses better and they're
+								// computed together anyway.
+								if (pixelPositionVal == null) {
+									computeStyleTests();
+								}
+								return boxSizingReliableVal;
+							},
+
+							pixelMarginRight : function() {
+
+								// Support: Android 4.0-4.3
+								if (pixelPositionVal == null) {
+									computeStyleTests();
+								}
+								return pixelMarginRightVal;
+							},
+
+							pixelPosition : function() {
+								if (pixelPositionVal == null) {
+									computeStyleTests();
+								}
+								return pixelPositionVal;
+							},
+
+							reliableMarginRight : function() {
+
+								// Support: Android 2.3
+								if (pixelPositionVal == null) {
+									computeStyleTests();
+								}
+								return reliableMarginRightVal;
+							},
+
+							reliableMarginLeft : function() {
+
+								// Support: IE <=8 only, Android 4.0 - 4.3 only,
+								// Firefox <=3 - 37
+								if (pixelPositionVal == null) {
+									computeStyleTests();
+								}
+								return reliableMarginLeftVal;
+							}
+						});
+
+						function computeStyleTests() {
+							var contents, divStyle, documentElement = document.documentElement;
+
+							// Setup
+							documentElement.appendChild(container);
+
+							div.style.cssText =
+
+							// Support: Android 2.3
+							// Vendor-prefix box-sizing
+							"-webkit-box-sizing:border-box;box-sizing:border-box;"
+									+ "position:relative;display:block;"
+									+ "margin:auto;border:1px;padding:1px;"
+									+ "top:1%;width:50%";
+
+							// Support: IE<9
+							// Assume reasonable values in the absence of
+							// getComputedStyle
+							pixelPositionVal = boxSizingReliableVal = reliableMarginLeftVal = false;
+							pixelMarginRightVal = reliableMarginRightVal = true;
+
+							// Check for getComputedStyle so that this code is
+							// not run in IE<9.
+							if (window.getComputedStyle) {
+								divStyle = window.getComputedStyle(div);
+								pixelPositionVal = (divStyle || {}).top !== "1%";
+								reliableMarginLeftVal = (divStyle || {}).marginLeft === "2px";
+								boxSizingReliableVal = (divStyle || {
+									width : "4px"
+								}).width === "4px";
+
+								// Support: Android 4.0 - 4.3 only
+								// Some styles come back with percentage values,
+								// even though they shouldn't
+								div.style.marginRight = "50%";
+								pixelMarginRightVal = (divStyle || {
+									marginRight : "4px"
+								}).marginRight === "4px";
+
+								// Support: Android 2.3 only
+								// Div with explicit width and no margin-right
+								// incorrectly
+								// gets computed margin-right based on width of
+								// container (#3333)
+								// WebKit Bug 13343 - getComputedStyle returns
+								// wrong value for margin-right
+								contents = div.appendChild(document
+										.createElement("div"));
+
+								// Reset CSS: box-sizing; display; margin;
+								// border; padding
+								contents.style.cssText = div.style.cssText =
+
+								// Support: Android 2.3
+								// Vendor-prefix box-sizing
+								"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;"
+										+ "box-sizing:content-box;display:block;margin:0;border:0;padding:0";
+								contents.style.marginRight = contents.style.width = "0";
+								div.style.width = "1px";
+
+								reliableMarginRightVal = !parseFloat((window
+										.getComputedStyle(contents) || {}).marginRight);
+
+								div.removeChild(contents);
+							}
+
+							// Support: IE6-8
+							// First check that getClientRects works as expected
+							// Check if table cells still have
+							// offsetWidth/Height when they are set
+							// to display:none and there are still other visible
+							// table cells in a
+							// table row; if so, offsetWidth/Height are not
+							// reliable for use when
+							// determining if an element has been hidden
+							// directly using
+							// display:none (it is still safe to use offsets if
+							// a parent element is
+							// hidden; don safety goggles and see bug #4512 for
+							// more information).
+							div.style.display = "none";
+							reliableHiddenOffsetsVal = div.getClientRects().length === 0;
+							if (reliableHiddenOffsetsVal) {
+								div.style.display = "";
+								div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
+								div.childNodes[0].style.borderCollapse = "separate";
+								contents = div.getElementsByTagName("td");
+								contents[0].style.cssText = "margin:0;border:0;padding:0;display:none";
+								reliableHiddenOffsetsVal = contents[0].offsetHeight === 0;
+								if (reliableHiddenOffsetsVal) {
+									contents[0].style.display = "";
+									contents[1].style.display = "none";
+									reliableHiddenOffsetsVal = contents[0].offsetHeight === 0;
+								}
+							}
+
+							// Teardown
+							documentElement.removeChild(container);
+						}
+
+					})();
+
+					var getStyles, curCSS, rposition = /^(top|right|bottom|left)$/;
+
+					if (window.getComputedStyle) {
+						getStyles = function(elem) {
+
+							// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
+							// IE throws on elements created in popups
+							// FF meanwhile throws on frame elements through
+							// "defaultView.getComputedStyle"
+							var view = elem.ownerDocument.defaultView;
+
+							if (!view || !view.opener) {
+								view = window;
+							}
+
+							return view.getComputedStyle(elem);
+						};
+
+						curCSS = function(elem, name, computed) {
+							var width, minWidth, maxWidth, ret, style = elem.style;
+
+							computed = computed || getStyles(elem);
+
+							// getPropertyValue is only needed for
+							// .css('filter') in IE9, see #12537
+							ret = computed ? computed.getPropertyValue(name)
+									|| computed[name] : undefined;
+
+							// Support: Opera 12.1x only
+							// Fall back to style even without computed
+							// computed is undefined for elems on document
+							// fragments
+							if ((ret === "" || ret === undefined)
+									&& !jQuery.contains(elem.ownerDocument,
+											elem)) {
+								ret = jQuery.style(elem, name);
+							}
+
+							if (computed) {
+
+								// A tribute to the "awesome hack by Dean
+								// Edwards"
+								// Chrome < 17 and Safari 5.0 uses "computed
+								// value"
+								// instead of "used value" for margin-right
+								// Safari 5.1.7 (at least) returns percentage
+								// for a larger set of values,
+								// but width seems to be reliably pixels
+								// this is against the CSSOM draft spec:
+								// http://dev.w3.org/csswg/cssom/#resolved-values
+								if (!support.pixelMarginRight()
+										&& rnumnonpx.test(ret)
+										&& rmargin.test(name)) {
+
+									// Remember the original values
+									width = style.width;
+									minWidth = style.minWidth;
+									maxWidth = style.maxWidth;
+
+									// Put in the new values to get a computed
+									// value out
+									style.minWidth = style.maxWidth = style.width = ret;
+									ret = computed.width;
+
+									// Revert the changed values
+									style.width = width;
+									style.minWidth = minWidth;
+									style.maxWidth = maxWidth;
+								}
+							}
+
+							// Support: IE
+							// IE returns zIndex value as an integer.
+							return ret === undefined ? ret : ret + "";
+						};
+					} else if (documentElement.currentStyle) {
+						getStyles = function(elem) {
+							return elem.currentStyle;
+						};
+
+						curCSS = function(elem, name, computed) {
+							var left, rs, rsLeft, ret, style = elem.style;
+
+							computed = computed || getStyles(elem);
+							ret = computed ? computed[name] : undefined;
+
+							// Avoid setting ret to empty string here
+							// so we don't default to auto
+							if (ret == null && style && style[name]) {
+								ret = style[name];
+							}
+
+							// From the awesome hack by Dean Edwards
+							// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+							// If we're not dealing with a regular pixel number
+							// but a number that has a weird ending, we need to
+							// convert it to pixels
+							// but not position css attributes, as those are
+							// proportional to the parent element instead
+							// and we can't measure the parent instead because
+							// it
+							// might trigger a "stacking dolls" problem
+							if (rnumnonpx.test(ret) && !rposition.test(name)) {
+
+								// Remember the original values
+								left = style.left;
+								rs = elem.runtimeStyle;
+								rsLeft = rs && rs.left;
+
+								// Put in the new values to get a computed value
+								// out
+								if (rsLeft) {
+									rs.left = elem.currentStyle.left;
+								}
+								style.left = name === "fontSize" ? "1em" : ret;
+								ret = style.pixelLeft + "px";
+
+								// Revert the changed values
+								style.left = left;
+								if (rsLeft) {
+									rs.left = rsLeft;
+								}
+							}
+
+							// Support: IE
+							// IE returns zIndex value as an integer.
+							return ret === undefined ? ret : ret + "" || "auto";
+						};
+					}
+
+					function addGetHookIf(conditionFn, hookFn) {
+
+						// Define the hook, we'll check on the first run if it's
+						// really needed.
+						return {
+							get : function() {
+								if (conditionFn()) {
+
+									// Hook not needed (or it's not possible to
+									// use it due
+									// to missing dependency), remove it.
+									delete this.get;
+									return;
+								}
+
+								// Hook needed; redefine it so that the support
+								// test is not executed again.
+								return (this.get = hookFn).apply(this,
+										arguments);
+							}
+						};
+					}
+
+					var
+
+					ralpha = /alpha\([^)]*\)/i, ropacity = /opacity\s*=\s*([^)]*)/i,
+
+					// swappable if display is none or starts with table except
+					// "table", "table-cell", or "table-caption"
+					// see here for display values:
+					// https://developer.mozilla.org/en-US/docs/CSS/display
+					rdisplayswap = /^(none|table(?!-c[ea]).+)/, rnumsplit = new RegExp(
+							"^(" + pnum + ")(.*)$", "i"),
+
+					cssShow = {
+						position : "absolute",
+						visibility : "hidden",
+						display : "block"
+					}, cssNormalTransform = {
+						letterSpacing : "0",
+						fontWeight : "400"
+					},
+
+					cssPrefixes = [ "Webkit", "O", "Moz", "ms" ], emptyStyle = document
+							.createElement("div").style;
+
+					// return a css property mapped to a potentially vendor
+					// prefixed property
+					function vendorPropName(name) {
+
+						// shortcut for names that are not vendor prefixed
+						if (name in emptyStyle) {
+							return name;
+						}
+
+						// check for vendor prefixed names
+						var capName = name.charAt(0).toUpperCase()
+								+ name.slice(1), i = cssPrefixes.length;
+
+						while (i--) {
+							name = cssPrefixes[i] + capName;
+							if (name in emptyStyle) {
+								return name;
+							}
+						}
+					}
+
+					function showHide(elements, show) {
+						var display, elem, hidden, values = [], index = 0, length = elements.length;
+
+						for (; index < length; index++) {
+							elem = elements[index];
+							if (!elem.style) {
+								continue;
+							}
+
+							values[index] = jQuery._data(elem, "olddisplay");
+							display = elem.style.display;
+							if (show) {
+
+								// Reset the inline display of this element to
+								// learn if it is
+								// being hidden by cascaded rules or not
+								if (!values[index] && display === "none") {
+									elem.style.display = "";
+								}
+
+								// Set elements which have been overridden with
+								// display: none
+								// in a stylesheet to whatever the default
+								// browser style is
+								// for such an element
+								if (elem.style.display === "" && isHidden(elem)) {
+									values[index] = jQuery._data(elem,
+											"olddisplay",
+											defaultDisplay(elem.nodeName));
+								}
+							} else {
+								hidden = isHidden(elem);
+
+								if (display && display !== "none" || !hidden) {
+									jQuery._data(elem, "olddisplay",
+											hidden ? display : jQuery.css(elem,
+													"display"));
+								}
+							}
+						}
+
+						// Set the display of most of the elements in a second
+						// loop
+						// to avoid the constant reflow
+						for (index = 0; index < length; index++) {
+							elem = elements[index];
+							if (!elem.style) {
+								continue;
+							}
+							if (!show || elem.style.display === "none"
+									|| elem.style.display === "") {
+								elem.style.display = show ? values[index] || ""
+										: "none";
+							}
+						}
+
+						return elements;
+					}
+
+					function setPositiveNumber(elem, value, subtract) {
+						var matches = rnumsplit.exec(value);
+						return matches ?
+
+						// Guard against undefined "subtract", e.g., when used
+						// as in cssHooks
+						Math.max(0, matches[1] - (subtract || 0))
+								+ (matches[2] || "px") : value;
+					}
+
+					function augmentWidthOrHeight(elem, name, extra,
+							isBorderBox, styles) {
+						var i = extra === (isBorderBox ? "border" : "content") ?
+
+						// If we already have the right measurement, avoid
+						// augmentation
+						4 :
+
+						// Otherwise initialize for horizontal or vertical
+						// properties
+						name === "width" ? 1 : 0,
+
+						val = 0;
+
+						for (; i < 4; i += 2) {
+
+							// both box models exclude margin, so add it if we
+							// want it
+							if (extra === "margin") {
+								val += jQuery.css(elem, extra + cssExpand[i],
+										true, styles);
+							}
+
+							if (isBorderBox) {
+
+								// border-box includes padding, so remove it if
+								// we want content
+								if (extra === "content") {
+									val -= jQuery.css(elem, "padding"
+											+ cssExpand[i], true, styles);
+								}
+
+								// at this point, extra isn't border nor margin,
+								// so remove border
+								if (extra !== "margin") {
+									val -= jQuery.css(elem, "border"
+											+ cssExpand[i] + "Width", true,
+											styles);
+								}
+							} else {
+
+								// at this point, extra isn't content, so add
+								// padding
+								val += jQuery.css(elem, "padding"
+										+ cssExpand[i], true, styles);
+
+								// at this point, extra isn't content nor
+								// padding, so add border
+								if (extra !== "padding") {
+									val += jQuery.css(elem, "border"
+											+ cssExpand[i] + "Width", true,
+											styles);
+								}
+							}
+						}
+
+						return val;
+					}
+
+					function getWidthOrHeight(elem, name, extra) {
+
+						// Start with offset property, which is equivalent to
+						// the border-box value
+						var valueIsBorderBox = true, val = name === "width" ? elem.offsetWidth
+								: elem.offsetHeight, styles = getStyles(elem), isBorderBox = support.boxSizing
+								&& jQuery.css(elem, "boxSizing", false, styles) === "border-box";
+
+						// some non-html elements return undefined for
+						// offsetWidth, so check for null/undefined
+						// svg -
+						// https://bugzilla.mozilla.org/show_bug.cgi?id=649285
+						// MathML -
+						// https://bugzilla.mozilla.org/show_bug.cgi?id=491668
+						if (val <= 0 || val == null) {
+
+							// Fall back to computed then uncomputed css if
+							// necessary
+							val = curCSS(elem, name, styles);
+							if (val < 0 || val == null) {
+								val = elem.style[name];
+							}
+
+							// Computed unit is not pixels. Stop here and
+							// return.
+							if (rnumnonpx.test(val)) {
+								return val;
+							}
+
+							// we need the check for style in case a browser
+							// which returns unreliable values
+							// for getComputedStyle silently falls back to the
+							// reliable elem.style
+							valueIsBorderBox = isBorderBox
+									&& (support.boxSizingReliable() || val === elem.style[name]);
+
+							// Normalize "", auto, and prepare for extra
+							val = parseFloat(val) || 0;
+						}
+
+						// use the active box-sizing model to add/subtract
+						// irrelevant styles
+						return (val + augmentWidthOrHeight(elem, name, extra
+								|| (isBorderBox ? "border" : "content"),
+								valueIsBorderBox, styles))
+								+ "px";
+					}
+
+					jQuery
+							.extend({
+
+								// Add in style property hooks for overriding
+								// the default
+								// behavior of getting and setting a style
+								// property
+								cssHooks : {
+									opacity : {
+										get : function(elem, computed) {
+											if (computed) {
+
+												// We should always get a number
+												// back from opacity
+												var ret = curCSS(elem,
+														"opacity");
+												return ret === "" ? "1" : ret;
+											}
+										}
+									}
+								},
+
+								// Don't automatically add "px" to these
+								// possibly-unitless properties
+								cssNumber : {
+									"animationIterationCount" : true,
+									"columnCount" : true,
+									"fillOpacity" : true,
+									"flexGrow" : true,
+									"flexShrink" : true,
+									"fontWeight" : true,
+									"lineHeight" : true,
+									"opacity" : true,
+									"order" : true,
+									"orphans" : true,
+									"widows" : true,
+									"zIndex" : true,
+									"zoom" : true
+								},
+
+								// Add in properties whose names you wish to fix
+								// before
+								// setting or getting the value
+								cssProps : {
+
+									// normalize float css property
+									"float" : support.cssFloat ? "cssFloat"
+											: "styleFloat"
+								},
+
+								// Get and set the style property on a DOM Node
+								style : function(elem, name, value, extra) {
+
+									// Don't set styles on text and comment
+									// nodes
+									if (!elem || elem.nodeType === 3
+											|| elem.nodeType === 8
+											|| !elem.style) {
+										return;
+									}
+
+									// Make sure that we're working with the
+									// right name
+									var ret, type, hooks, origName = jQuery
+											.camelCase(name), style = elem.style;
+
+									name = jQuery.cssProps[origName]
+											|| (jQuery.cssProps[origName] = vendorPropName(origName)
+													|| origName);
+
+									// gets hook for the prefixed version
+									// followed by the unprefixed version
+									hooks = jQuery.cssHooks[name]
+											|| jQuery.cssHooks[origName];
+
+									// Check if we're setting a value
+									if (value !== undefined) {
+										type = typeof value;
+
+										// Convert "+=" or "-=" to relative
+										// numbers (#7345)
+										if (type === "string"
+												&& (ret = rcssNum.exec(value))
+												&& ret[1]) {
+											value = adjustCSS(elem, name, ret);
+
+											// Fixes bug #9237
+											type = "number";
+										}
+
+										// Make sure that null and NaN values
+										// aren't set. See: #7116
+										if (value == null || value !== value) {
+											return;
+										}
+
+										// If a number was passed in, add the
+										// unit (except for certain CSS
+										// properties)
+										if (type === "number") {
+											value += ret
+													&& ret[3]
+													|| (jQuery.cssNumber[origName] ? ""
+															: "px");
+										}
+
+										// Fixes #8908, it can be done more
+										// correctly by specifing setters in
+										// cssHooks,
+										// but it would mean to define eight
+										// (for every problematic property)
+										// identical functions
+										if (!support.clearCloneStyle
+												&& value === ""
+												&& name.indexOf("background") === 0) {
+											style[name] = "inherit";
+										}
+
+										// If a hook was provided, use that
+										// value, otherwise just set the
+										// specified value
+										if (!hooks
+												|| !("set" in hooks)
+												|| (value = hooks.set(elem,
+														value, extra)) !== undefined) {
+
+											// Support: IE
+											// Swallow errors from 'invalid' CSS
+											// values (#5509)
+											try {
+												style[name] = value;
+											} catch (e) {
+											}
+										}
+
+									} else {
+
+										// If a hook was provided get the
+										// non-computed value from there
+										if (hooks
+												&& "get" in hooks
+												&& (ret = hooks.get(elem,
+														false, extra)) !== undefined) {
+
+											return ret;
+										}
+
+										// Otherwise just get the value from the
+										// style object
+										return style[name];
+									}
+								},
+
+								css : function(elem, name, extra, styles) {
+									var num, val, hooks, origName = jQuery
+											.camelCase(name);
+
+									// Make sure that we're working with the
+									// right name
+									name = jQuery.cssProps[origName]
+											|| (jQuery.cssProps[origName] = vendorPropName(origName)
+													|| origName);
+
+									// gets hook for the prefixed version
+									// followed by the unprefixed version
+									hooks = jQuery.cssHooks[name]
+											|| jQuery.cssHooks[origName];
+
+									// If a hook was provided get the computed
+									// value from there
+									if (hooks && "get" in hooks) {
+										val = hooks.get(elem, true, extra);
+									}
+
+									// Otherwise, if a way to get the computed
+									// value exists, use that
+									if (val === undefined) {
+										val = curCSS(elem, name, styles);
+									}
+
+									// convert "normal" to computed value
+									if (val === "normal"
+											&& name in cssNormalTransform) {
+										val = cssNormalTransform[name];
+									}
+
+									// Return, converting to number if forced or
+									// a qualifier was provided and val looks
+									// numeric
+									if (extra === "" || extra) {
+										num = parseFloat(val);
+										return extra === true || isFinite(num) ? num || 0
+												: val;
+									}
+									return val;
+								}
+							});
+
+					jQuery
+							.each(
+									[ "height", "width" ],
+									function(i, name) {
+										jQuery.cssHooks[name] = {
+											get : function(elem, computed,
+													extra) {
+												if (computed) {
+
+													// certain elements can have
+													// dimension info if we
+													// invisibly show them
+													// however, it must have a
+													// current display style
+													// that would benefit from
+													// this
+													return rdisplayswap
+															.test(jQuery.css(
+																	elem,
+																	"display"))
+															&& elem.offsetWidth === 0 ? swap(
+															elem,
+															cssShow,
+															function() {
+																return getWidthOrHeight(
+																		elem,
+																		name,
+																		extra);
+															})
+															: getWidthOrHeight(
+																	elem, name,
+																	extra);
+												}
+											},
+
+											set : function(elem, value, extra) {
+												var styles = extra
+														&& getStyles(elem);
+												return setPositiveNumber(
+														elem,
+														value,
+														extra ? augmentWidthOrHeight(
+																elem,
+																name,
+																extra,
+																support.boxSizing
+																		&& jQuery
+																				.css(
+																						elem,
+																						"boxSizing",
+																						false,
+																						styles) === "border-box",
+																styles)
+																: 0);
+											}
+										};
+									});
+
+					if (!support.opacity) {
+						jQuery.cssHooks.opacity = {
+							get : function(elem, computed) {
+
+								// IE uses filters for opacity
+								return ropacity
+										.test((computed && elem.currentStyle ? elem.currentStyle.filter
+												: elem.style.filter)
+												|| "") ? (0.01 * parseFloat(RegExp.$1))
+										+ ""
+										: computed ? "1" : "";
+							},
+
+							set : function(elem, value) {
+								var style = elem.style, currentStyle = elem.currentStyle, opacity = jQuery
+										.isNumeric(value) ? "alpha(opacity="
+										+ value * 100 + ")" : "", filter = currentStyle
+										&& currentStyle.filter
+										|| style.filter
+										|| "";
+
+								// IE has trouble with opacity if it does not
+								// have layout
+								// Force it by setting the zoom level
+								style.zoom = 1;
+
+								// if setting opacity to 1, and no other filters
+								// exist -
+								// attempt to remove filter attribute #6652
+								// if value === "", then remove inline opacity
+								// #12685
+								if ((value >= 1 || value === "")
+										&& jQuery.trim(filter.replace(ralpha,
+												"")) === ""
+										&& style.removeAttribute) {
+
+									// Setting style.filter to null, "" & " "
+									// still leave "filter:" in the cssText
+									// if "filter:" is present at all, clearType
+									// is disabled, we want to avoid this
+									// style.removeAttribute is IE Only, but so
+									// apparently is this code path...
+									style.removeAttribute("filter");
+
+									// if there is no filter style applied in a
+									// css rule
+									// or unset inline opacity, we are done
+									if (value === "" || currentStyle
+											&& !currentStyle.filter) {
+										return;
+									}
+								}
+
+								// otherwise, set new filter values
+								style.filter = ralpha.test(filter) ? filter
+										.replace(ralpha, opacity) : filter
+										+ " " + opacity;
+							}
+						};
+					}
+
+					jQuery.cssHooks.marginRight = addGetHookIf(
+							support.reliableMarginRight, function(elem,
+									computed) {
+								if (computed) {
+									return swap(elem, {
+										"display" : "inline-block"
+									}, curCSS, [ elem, "marginRight" ]);
+								}
+							});
+
+					jQuery.cssHooks.marginLeft = addGetHookIf(
+							support.reliableMarginLeft,
+							function(elem, computed) {
+								if (computed) {
+									return (parseFloat(curCSS(elem,
+											"marginLeft")) ||
+
+									// Support: IE<=11+
+									// Running getBoundingClientRect on a
+									// disconnected node in IE throws an error
+									// Support: IE8 only
+									// getClientRects() errors on disconnected
+									// elems
+									(jQuery.contains(elem.ownerDocument, elem) ? elem
+											.getBoundingClientRect().left
+											- swap(
+													elem,
+													{
+														marginLeft : 0
+													},
+													function() {
+														return elem
+																.getBoundingClientRect().left;
+													})
+											: 0))
+											+ "px";
+								}
+							});
+
+					// These hooks are used by animate to expand properties
+					jQuery
+							.each(
+									{
+										margin : "",
+										padding : "",
+										border : "Width"
+									},
+									function(prefix, suffix) {
+										jQuery.cssHooks[prefix + suffix] = {
+											expand : function(value) {
+												var i = 0, expanded = {},
+
+												// assumes a single number if
+												// not a string
+												parts = typeof value === "string" ? value
+														.split(" ")
+														: [ value ];
+
+												for (; i < 4; i++) {
+													expanded[prefix
+															+ cssExpand[i]
+															+ suffix] = parts[i]
+															|| parts[i - 2]
+															|| parts[0];
+												}
+
+												return expanded;
+											}
+										};
+
+										if (!rmargin.test(prefix)) {
+											jQuery.cssHooks[prefix + suffix].set = setPositiveNumber;
+										}
+									});
+
+					jQuery.fn.extend({
+						css : function(name, value) {
+							return access(this, function(elem, name, value) {
+								var styles, len, map = {}, i = 0;
+
+								if (jQuery.isArray(name)) {
+									styles = getStyles(elem);
+									len = name.length;
+
+									for (; i < len; i++) {
+										map[name[i]] = jQuery.css(elem,
+												name[i], false, styles);
+									}
+
+									return map;
+								}
+
+								return value !== undefined ? jQuery.style(elem,
+										name, value) : jQuery.css(elem, name);
+							}, name, value, arguments.length > 1);
+						},
+						show : function() {
+							return showHide(this, true);
+						},
+						hide : function() {
+							return showHide(this);
+						},
+						toggle : function(state) {
+							if (typeof state === "boolean") {
+								return state ? this.show() : this.hide();
+							}
+
+							return this.each(function() {
+								if (isHidden(this)) {
+									jQuery(this).show();
+								} else {
+									jQuery(this).hide();
+								}
+							});
+						}
+					});
+
+					function Tween(elem, options, prop, end, easing) {
+						return new Tween.prototype.init(elem, options, prop,
+								end, easing);
+					}
+					jQuery.Tween = Tween;
+
+					Tween.prototype = {
+						constructor : Tween,
+						init : function(elem, options, prop, end, easing, unit) {
+							this.elem = elem;
+							this.prop = prop;
+							this.easing = easing || jQuery.easing._default;
+							this.options = options;
+							this.start = this.now = this.cur();
+							this.end = end;
+							this.unit = unit
+									|| (jQuery.cssNumber[prop] ? "" : "px");
+						},
+						cur : function() {
+							var hooks = Tween.propHooks[this.prop];
+
+							return hooks && hooks.get ? hooks.get(this)
+									: Tween.propHooks._default.get(this);
+						},
+						run : function(percent) {
+							var eased, hooks = Tween.propHooks[this.prop];
+
+							if (this.options.duration) {
+								this.pos = eased = jQuery.easing[this.easing](
+										percent, this.options.duration
+												* percent, 0, 1,
+										this.options.duration);
+							} else {
+								this.pos = eased = percent;
+							}
+							this.now = (this.end - this.start) * eased
+									+ this.start;
+
+							if (this.options.step) {
+								this.options.step.call(this.elem, this.now,
+										this);
+							}
+
+							if (hooks && hooks.set) {
+								hooks.set(this);
+							} else {
+								Tween.propHooks._default.set(this);
+							}
+							return this;
+						}
+					};
+
+					Tween.prototype.init.prototype = Tween.prototype;
+
+					Tween.propHooks = {
+						_default : {
+							get : function(tween) {
+								var result;
+
+								// Use a property on the element directly when
+								// it is not a DOM element,
+								// or when there is no matching style property
+								// that exists.
+								if (tween.elem.nodeType !== 1
+										|| tween.elem[tween.prop] != null
+										&& tween.elem.style[tween.prop] == null) {
+									return tween.elem[tween.prop];
+								}
+
+								// passing an empty string as a 3rd parameter to
+								// .css will automatically
+								// attempt a parseFloat and fallback to a string
+								// if the parse fails
+								// so, simple values such as "10px" are parsed
+								// to Float.
+								// complex values such as "rotate(1rad)" are
+								// returned as is.
+								result = jQuery.css(tween.elem, tween.prop, "");
+
+								// Empty strings, null, undefined and "auto" are
+								// converted to 0.
+								return !result || result === "auto" ? 0
+										: result;
+							},
+							set : function(tween) {
+
+								// use step hook for back compat - use cssHook
+								// if its there - use .style if its
+								// available and use plain properties where
+								// available
+								if (jQuery.fx.step[tween.prop]) {
+									jQuery.fx.step[tween.prop](tween);
+								} else if (tween.elem.nodeType === 1
+										&& (tween.elem.style[jQuery.cssProps[tween.prop]] != null || jQuery.cssHooks[tween.prop])) {
+									jQuery.style(tween.elem, tween.prop,
+											tween.now + tween.unit);
+								} else {
+									tween.elem[tween.prop] = tween.now;
+								}
+							}
+						}
+					};
+
+					// Support: IE <=9
+					// Panic based approach to setting things on disconnected
+					// nodes
+
+					Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
+						set : function(tween) {
+							if (tween.elem.nodeType && tween.elem.parentNode) {
+								tween.elem[tween.prop] = tween.now;
+							}
+						}
+					};
+
+					jQuery.easing = {
+						linear : function(p) {
+							return p;
+						},
+						swing : function(p) {
+							return 0.5 - Math.cos(p * Math.PI) / 2;
+						},
+						_default : "swing"
+					};
+
+					jQuery.fx = Tween.prototype.init;
+
+					// Back Compat <1.8 extension point
+					jQuery.fx.step = {};
+
+					var fxNow, timerId, rfxtypes = /^(?:toggle|show|hide)$/, rrun = /queueHooks$/;
+
+					// Animations created synchronously will run synchronously
+					function createFxNow() {
+						window.setTimeout(function() {
+							fxNow = undefined;
+						});
+						return (fxNow = jQuery.now());
+					}
+
+					// Generate parameters to create a standard animation
+					function genFx(type, includeWidth) {
+						var which, attrs = {
+							height : type
+						}, i = 0;
+
+						// if we include width, step value is 1 to do all
+						// cssExpand values,
+						// if we don't include width, step value is 2 to skip
+						// over Left and Right
+						includeWidth = includeWidth ? 1 : 0;
+						for (; i < 4; i += 2 - includeWidth) {
+							which = cssExpand[i];
+							attrs["margin" + which] = attrs["padding" + which] = type;
+						}
+
+						if (includeWidth) {
+							attrs.opacity = attrs.width = type;
+						}
+
+						return attrs;
+					}
+
+					function createTween(value, prop, animation) {
+						var tween, collection = (Animation.tweeners[prop] || [])
+								.concat(Animation.tweeners["*"]), index = 0, length = collection.length;
+						for (; index < length; index++) {
+							if ((tween = collection[index].call(animation,
+									prop, value))) {
+
+								// we're done with this property
+								return tween;
+							}
+						}
+					}
+
+					function defaultPrefilter(elem, props, opts) {
+						/* jshint validthis: true */
+						var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay, anim = this, orig = {}, style = elem.style, hidden = elem.nodeType
+								&& isHidden(elem), dataShow = jQuery._data(
+								elem, "fxshow");
+
+						// handle queue: false promises
+						if (!opts.queue) {
+							hooks = jQuery._queueHooks(elem, "fx");
+							if (hooks.unqueued == null) {
+								hooks.unqueued = 0;
+								oldfire = hooks.empty.fire;
+								hooks.empty.fire = function() {
+									if (!hooks.unqueued) {
+										oldfire();
+									}
+								};
+							}
+							hooks.unqueued++;
+
+							anim.always(function() {
+
+								// doing this makes sure that the complete
+								// handler will be called
+								// before this completes
+								anim.always(function() {
+									hooks.unqueued--;
+									if (!jQuery.queue(elem, "fx").length) {
+										hooks.empty.fire();
+									}
+								});
+							});
+						}
+
+						// height/width overflow pass
+						if (elem.nodeType === 1
+								&& ("height" in props || "width" in props)) {
+
+							// Make sure that nothing sneaks out
+							// Record all 3 overflow attributes because IE does
+							// not
+							// change the overflow attribute when overflowX and
+							// overflowY are set to the same value
+							opts.overflow = [ style.overflow, style.overflowX,
+									style.overflowY ];
+
+							// Set display property to inline-block for
+							// height/width
+							// animations on inline elements that are having
+							// width/height animated
+							display = jQuery.css(elem, "display");
+
+							// Test default display if display is currently
+							// "none"
+							checkDisplay = display === "none" ? jQuery._data(
+									elem, "olddisplay")
+									|| defaultDisplay(elem.nodeName) : display;
+
+							if (checkDisplay === "inline"
+									&& jQuery.css(elem, "float") === "none") {
+
+								// inline-level elements accept inline-block;
+								// block-level elements need to be inline with
+								// layout
+								if (!support.inlineBlockNeedsLayout
+										|| defaultDisplay(elem.nodeName) === "inline") {
+									style.display = "inline-block";
+								} else {
+									style.zoom = 1;
+								}
+							}
+						}
+
+						if (opts.overflow) {
+							style.overflow = "hidden";
+							if (!support.shrinkWrapBlocks()) {
+								anim.always(function() {
+									style.overflow = opts.overflow[0];
+									style.overflowX = opts.overflow[1];
+									style.overflowY = opts.overflow[2];
+								});
+							}
+						}
+
+						// show/hide pass
+						for (prop in props) {
+							value = props[prop];
+							if (rfxtypes.exec(value)) {
+								delete props[prop];
+								toggle = toggle || value === "toggle";
+								if (value === (hidden ? "hide" : "show")) {
+
+									// If there is dataShow left over from a
+									// stopped hide or show
+									// and we are going to proceed with show, we
+									// should pretend to be hidden
+									if (value === "show" && dataShow
+											&& dataShow[prop] !== undefined) {
+										hidden = true;
+									} else {
+										continue;
+									}
+								}
+								orig[prop] = dataShow && dataShow[prop]
+										|| jQuery.style(elem, prop);
+
+								// Any non-fx value stops us from restoring the
+								// original display value
+							} else {
+								display = undefined;
+							}
+						}
+
+						if (!jQuery.isEmptyObject(orig)) {
+							if (dataShow) {
+								if ("hidden" in dataShow) {
+									hidden = dataShow.hidden;
+								}
+							} else {
+								dataShow = jQuery._data(elem, "fxshow", {});
+							}
+
+							// store state if its toggle - enables
+							// .stop().toggle() to "reverse"
+							if (toggle) {
+								dataShow.hidden = !hidden;
+							}
+							if (hidden) {
+								jQuery(elem).show();
+							} else {
+								anim.done(function() {
+									jQuery(elem).hide();
+								});
+							}
+							anim.done(function() {
+								var prop;
+								jQuery._removeData(elem, "fxshow");
+								for (prop in orig) {
+									jQuery.style(elem, prop, orig[prop]);
+								}
+							});
+							for (prop in orig) {
+								tween = createTween(
+										hidden ? dataShow[prop] : 0, prop, anim);
+
+								if (!(prop in dataShow)) {
+									dataShow[prop] = tween.start;
+									if (hidden) {
+										tween.end = tween.start;
+										tween.start = prop === "width"
+												|| prop === "height" ? 1 : 0;
+									}
+								}
+							}
+
+							// If this is a noop like .hide().hide(), restore an
+							// overwritten display value
+						} else if ((display === "none" ? defaultDisplay(elem.nodeName)
+								: display) === "inline") {
+							style.display = display;
+						}
+					}
+
+					function propFilter(props, specialEasing) {
+						var index, name, easing, value, hooks;
+
+						// camelCase, specialEasing and expand cssHook pass
+						for (index in props) {
+							name = jQuery.camelCase(index);
+							easing = specialEasing[name];
+							value = props[index];
+							if (jQuery.isArray(value)) {
+								easing = value[1];
+								value = props[index] = value[0];
+							}
+
+							if (index !== name) {
+								props[name] = value;
+								delete props[index];
+							}
+
+							hooks = jQuery.cssHooks[name];
+							if (hooks && "expand" in hooks) {
+								value = hooks.expand(value);
+								delete props[name];
+
+								// not quite $.extend, this wont overwrite keys
+								// already present.
+								// also - reusing 'index' from above because we
+								// have the correct "name"
+								for (index in value) {
+									if (!(index in props)) {
+										props[index] = value[index];
+										specialEasing[index] = easing;
+									}
+								}
+							} else {
+								specialEasing[name] = easing;
+							}
+						}
+					}
+
+					function Animation(elem, properties, options) {
+						var result, stopped, index = 0, length = Animation.prefilters.length, deferred = jQuery
+								.Deferred().always(function() {
+
+									// don't match elem in the :animated
+									// selector
+									delete tick.elem;
+								}), tick = function() {
+							if (stopped) {
+								return false;
+							}
+							var currentTime = fxNow || createFxNow(), remaining = Math
+									.max(0, animation.startTime
+											+ animation.duration - currentTime),
+
+							// Support: Android 2.3
+							// Archaic crash bug won't allow us to use `1 - (
+							// 0.5 || 0 )` (#12497)
+							temp = remaining / animation.duration || 0, percent = 1 - temp, index = 0, length = animation.tweens.length;
+
+							for (; index < length; index++) {
+								animation.tweens[index].run(percent);
+							}
+
+							deferred.notifyWith(elem, [ animation, percent,
+									remaining ]);
+
+							if (percent < 1 && length) {
+								return remaining;
+							} else {
+								deferred.resolveWith(elem, [ animation ]);
+								return false;
+							}
+						}, animation = deferred.promise({
+							elem : elem,
+							props : jQuery.extend({}, properties),
+							opts : jQuery.extend(true, {
+								specialEasing : {},
+								easing : jQuery.easing._default
+							}, options),
+							originalProperties : properties,
+							originalOptions : options,
+							startTime : fxNow || createFxNow(),
+							duration : options.duration,
+							tweens : [],
+							createTween : function(prop, end) {
+								var tween = jQuery.Tween(elem, animation.opts,
+										prop, end,
+										animation.opts.specialEasing[prop]
+												|| animation.opts.easing);
+								animation.tweens.push(tween);
+								return tween;
+							},
+							stop : function(gotoEnd) {
+								var index = 0,
+
+								// if we are going to the end, we want to run
+								// all the tweens
+								// otherwise we skip this part
+								length = gotoEnd ? animation.tweens.length : 0;
+								if (stopped) {
+									return this;
+								}
+								stopped = true;
+								for (; index < length; index++) {
+									animation.tweens[index].run(1);
+								}
+
+								// resolve when we played the last frame
+								// otherwise, reject
+								if (gotoEnd) {
+									deferred.notifyWith(elem,
+											[ animation, 1, 0 ]);
+									deferred.resolveWith(elem, [ animation,
+											gotoEnd ]);
+								} else {
+									deferred.rejectWith(elem, [ animation,
+											gotoEnd ]);
+								}
+								return this;
+							}
+						}), props = animation.props;
+
+						propFilter(props, animation.opts.specialEasing);
+
+						for (; index < length; index++) {
+							result = Animation.prefilters[index].call(
+									animation, elem, props, animation.opts);
+							if (result) {
+								if (jQuery.isFunction(result.stop)) {
+									jQuery._queueHooks(animation.elem,
+											animation.opts.queue).stop = jQuery
+											.proxy(result.stop, result);
+								}
+								return result;
+							}
+						}
+
+						jQuery.map(props, createTween, animation);
+
+						if (jQuery.isFunction(animation.opts.start)) {
+							animation.opts.start.call(elem, animation);
+						}
+
+						jQuery.fx.timer(jQuery.extend(tick, {
+							elem : elem,
+							anim : animation,
+							queue : animation.opts.queue
+						}));
+
+						// attach callbacks from options
+						return animation.progress(animation.opts.progress)
+								.done(animation.opts.done,
+										animation.opts.complete).fail(
+										animation.opts.fail).always(
+										animation.opts.always);
+					}
+
+					jQuery.Animation = jQuery
+							.extend(
+									Animation,
+									{
+
+										tweeners : {
+											"*" : [ function(prop, value) {
+												var tween = this.createTween(
+														prop, value);
+												adjustCSS(tween.elem, prop,
+														rcssNum.exec(value),
+														tween);
+												return tween;
+											} ]
+										},
+
+										tweener : function(props, callback) {
+											if (jQuery.isFunction(props)) {
+												callback = props;
+												props = [ "*" ];
+											} else {
+												props = props.match(rnotwhite);
+											}
+
+											var prop, index = 0, length = props.length;
+
+											for (; index < length; index++) {
+												prop = props[index];
+												Animation.tweeners[prop] = Animation.tweeners[prop]
+														|| [];
+												Animation.tweeners[prop]
+														.unshift(callback);
+											}
+										},
+
+										prefilters : [ defaultPrefilter ],
+
+										prefilter : function(callback, prepend) {
+											if (prepend) {
+												Animation.prefilters
+														.unshift(callback);
+											} else {
+												Animation.prefilters
+														.push(callback);
+											}
+										}
+									});
+
+					jQuery.speed = function(speed, easing, fn) {
+						var opt = speed && typeof speed === "object" ? jQuery
+								.extend({}, speed) : {
+							complete : fn || !fn && easing
+									|| jQuery.isFunction(speed) && speed,
+							duration : speed,
+							easing : fn && easing || easing
+									&& !jQuery.isFunction(easing) && easing
+						};
+
+						opt.duration = jQuery.fx.off ? 0
+								: typeof opt.duration === "number" ? opt.duration
+										: opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration]
+												: jQuery.fx.speeds._default;
+
+						// normalize opt.queue - true/undefined/null -> "fx"
+						if (opt.queue == null || opt.queue === true) {
+							opt.queue = "fx";
+						}
+
+						// Queueing
+						opt.old = opt.complete;
+
+						opt.complete = function() {
+							if (jQuery.isFunction(opt.old)) {
+								opt.old.call(this);
+							}
+
+							if (opt.queue) {
+								jQuery.dequeue(this, opt.queue);
+							}
+						};
+
+						return opt;
+					};
+
+					jQuery.fn
+							.extend({
+								fadeTo : function(speed, to, easing, callback) {
+
+									// show any hidden elements after setting
+									// opacity to 0
+									return this.filter(isHidden).css("opacity",
+											0).show()
+
+									// animate to the value specified
+									.end().animate({
+										opacity : to
+									}, speed, easing, callback);
+								},
+								animate : function(prop, speed, easing,
+										callback) {
+									var empty = jQuery.isEmptyObject(prop), optall = jQuery
+											.speed(speed, easing, callback), doAnimation = function() {
+
+										// Operate on a copy of prop so
+										// per-property easing won't be lost
+										var anim = Animation(this, jQuery
+												.extend({}, prop), optall);
+
+										// Empty animations, or finishing
+										// resolves immediately
+										if (empty
+												|| jQuery._data(this, "finish")) {
+											anim.stop(true);
+										}
+									};
+									doAnimation.finish = doAnimation;
+
+									return empty || optall.queue === false ? this
+											.each(doAnimation)
+											: this.queue(optall.queue,
+													doAnimation);
+								},
+								stop : function(type, clearQueue, gotoEnd) {
+									var stopQueue = function(hooks) {
+										var stop = hooks.stop;
+										delete hooks.stop;
+										stop(gotoEnd);
+									};
+
+									if (typeof type !== "string") {
+										gotoEnd = clearQueue;
+										clearQueue = type;
+										type = undefined;
+									}
+									if (clearQueue && type !== false) {
+										this.queue(type || "fx", []);
+									}
+
+									return this
+											.each(function() {
+												var dequeue = true, index = type != null
+														&& type + "queueHooks", timers = jQuery.timers, data = jQuery
+														._data(this);
+
+												if (index) {
+													if (data[index]
+															&& data[index].stop) {
+														stopQueue(data[index]);
+													}
+												} else {
+													for (index in data) {
+														if (data[index]
+																&& data[index].stop
+																&& rrun
+																		.test(index)) {
+															stopQueue(data[index]);
+														}
+													}
+												}
+
+												for (index = timers.length; index--;) {
+													if (timers[index].elem === this
+															&& (type == null || timers[index].queue === type)) {
+
+														timers[index].anim
+																.stop(gotoEnd);
+														dequeue = false;
+														timers.splice(index, 1);
+													}
+												}
+
+												// start the next in the queue
+												// if the last step wasn't
+												// forced
+												// timers currently will call
+												// their complete callbacks,
+												// which will dequeue
+												// but only if they were gotoEnd
+												if (dequeue || !gotoEnd) {
+													jQuery.dequeue(this, type);
+												}
+											});
+								},
+								finish : function(type) {
+									if (type !== false) {
+										type = type || "fx";
+									}
+									return this
+											.each(function() {
+												var index, data = jQuery
+														._data(this), queue = data[type
+														+ "queue"], hooks = data[type
+														+ "queueHooks"], timers = jQuery.timers, length = queue ? queue.length
+														: 0;
+
+												// enable finishing flag on
+												// private data
+												data.finish = true;
+
+												// empty the queue first
+												jQuery.queue(this, type, []);
+
+												if (hooks && hooks.stop) {
+													hooks.stop.call(this, true);
+												}
+
+												// look for any active
+												// animations, and finish them
+												for (index = timers.length; index--;) {
+													if (timers[index].elem === this
+															&& timers[index].queue === type) {
+														timers[index].anim
+																.stop(true);
+														timers.splice(index, 1);
+													}
+												}
+
+												// look for any animations in
+												// the old queue and finish them
+												for (index = 0; index < length; index++) {
+													if (queue[index]
+															&& queue[index].finish) {
+														queue[index].finish
+																.call(this);
+													}
+												}
+
+												// turn off finishing flag
+												delete data.finish;
+											});
+								}
+							});
+
+					jQuery
+							.each(
+									[ "toggle", "show", "hide" ],
+									function(i, name) {
+										var cssFn = jQuery.fn[name];
+										jQuery.fn[name] = function(speed,
+												easing, callback) {
+											return speed == null
+													|| typeof speed === "boolean" ? cssFn
+													.apply(this, arguments)
+													: this.animate(genFx(name,
+															true), speed,
+															easing, callback);
+										};
+									});
+
+					// Generate shortcuts for custom animations
+					jQuery.each({
+						slideDown : genFx("show"),
+						slideUp : genFx("hide"),
+						slideToggle : genFx("toggle"),
+						fadeIn : {
+							opacity : "show"
+						},
+						fadeOut : {
+							opacity : "hide"
+						},
+						fadeToggle : {
+							opacity : "toggle"
+						}
+					},
+							function(name, props) {
+								jQuery.fn[name] = function(speed, easing,
+										callback) {
+									return this.animate(props, speed, easing,
+											callback);
+								};
+							});
+
+					jQuery.timers = [];
+					jQuery.fx.tick = function() {
+						var timer, timers = jQuery.timers, i = 0;
+
+						fxNow = jQuery.now();
+
+						for (; i < timers.length; i++) {
+							timer = timers[i];
+
+							// Checks the timer has not already been removed
+							if (!timer() && timers[i] === timer) {
+								timers.splice(i--, 1);
+							}
+						}
+
+						if (!timers.length) {
+							jQuery.fx.stop();
+						}
+						fxNow = undefined;
+					};
+
+					jQuery.fx.timer = function(timer) {
+						jQuery.timers.push(timer);
+						if (timer()) {
+							jQuery.fx.start();
+						} else {
+							jQuery.timers.pop();
+						}
+					};
+
+					jQuery.fx.interval = 13;
+
+					jQuery.fx.start = function() {
+						if (!timerId) {
+							timerId = window.setInterval(jQuery.fx.tick,
+									jQuery.fx.interval);
+						}
+					};
+
+					jQuery.fx.stop = function() {
+						window.clearInterval(timerId);
+						timerId = null;
+					};
+
+					jQuery.fx.speeds = {
+						slow : 600,
+						fast : 200,
+
+						// Default speed
+						_default : 400
+					};
+
+					// Based off of the plugin by Clint Helfers, with
+					// permission.
+					// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
+					jQuery.fn.delay = function(time, type) {
+						time = jQuery.fx ? jQuery.fx.speeds[time] || time
+								: time;
+						type = type || "fx";
+
+						return this.queue(type, function(next, hooks) {
+							var timeout = window.setTimeout(next, time);
+							hooks.stop = function() {
+								window.clearTimeout(timeout);
+							};
+						});
+					};
+
+					(function() {
+						var a, input = document.createElement("input"), div = document
+								.createElement("div"), select = document
+								.createElement("select"), opt = select
+								.appendChild(document.createElement("option"));
+
+						// Setup
+						div = document.createElement("div");
+						div.setAttribute("className", "t");
+						div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
+						a = div.getElementsByTagName("a")[0];
+
+						// Support: Windows Web Apps (WWA)
+						// `type` must use .setAttribute for WWA (#14901)
+						input.setAttribute("type", "checkbox");
+						div.appendChild(input);
+
+						a = div.getElementsByTagName("a")[0];
+
+						// First batch of tests.
+						a.style.cssText = "top:1px";
+
+						// Test setAttribute on camelCase class.
+						// If it works, we need attrFixes when doing
+						// get/setAttribute (ie6/7)
+						support.getSetAttribute = div.className !== "t";
+
+						// Get the style information from getAttribute
+						// (IE uses .cssText instead)
+						support.style = /top/.test(a.getAttribute("style"));
+
+						// Make sure that URLs aren't manipulated
+						// (IE normalizes it by default)
+						support.hrefNormalized = a.getAttribute("href") === "/a";
+
+						// Check the default checkbox/radio value ("" on WebKit;
+						// "on" elsewhere)
+						support.checkOn = !!input.value;
+
+						// Make sure that a selected-by-default option has a
+						// working selected property.
+						// (WebKit defaults to false instead of true, IE too, if
+						// it's in an optgroup)
+						support.optSelected = opt.selected;
+
+						// Tests for enctype support on a form (#6743)
+						support.enctype = !!document.createElement("form").enctype;
+
+						// Make sure that the options inside disabled selects
+						// aren't marked as disabled
+						// (WebKit marks them as disabled)
+						select.disabled = true;
+						support.optDisabled = !opt.disabled;
+
+						// Support: IE8 only
+						// Check if we can trust getAttribute("value")
+						input = document.createElement("input");
+						input.setAttribute("value", "");
+						support.input = input.getAttribute("value") === "";
+
+						// Check if an input maintains its value after becoming
+						// a radio
+						input.value = "t";
+						input.setAttribute("type", "radio");
+						support.radioValue = input.value === "t";
+					})();
+
+					var rreturn = /\r/g, rspaces = /[\x20\t\r\n\f]+/g;
+
+					jQuery.fn
+							.extend({
+								val : function(value) {
+									var hooks, ret, isFunction, elem = this[0];
+
+									if (!arguments.length) {
+										if (elem) {
+											hooks = jQuery.valHooks[elem.type]
+													|| jQuery.valHooks[elem.nodeName
+															.toLowerCase()];
+
+											if (hooks
+													&& "get" in hooks
+													&& (ret = hooks.get(elem,
+															"value")) !== undefined) {
+												return ret;
+											}
+
+											ret = elem.value;
+
+											return typeof ret === "string" ?
+
+											// handle most common string cases
+											ret.replace(rreturn, "") :
+
+											// handle cases where value is
+											// null/undef or number
+											ret == null ? "" : ret;
+										}
+
+										return;
+									}
+
+									isFunction = jQuery.isFunction(value);
+
+									return this
+											.each(function(i) {
+												var val;
+
+												if (this.nodeType !== 1) {
+													return;
+												}
+
+												if (isFunction) {
+													val = value.call(this, i,
+															jQuery(this).val());
+												} else {
+													val = value;
+												}
+
+												// Treat null/undefined as "";
+												// convert numbers to string
+												if (val == null) {
+													val = "";
+												} else if (typeof val === "number") {
+													val += "";
+												} else if (jQuery.isArray(val)) {
+													val = jQuery
+															.map(
+																	val,
+																	function(
+																			value) {
+																		return value == null ? ""
+																				: value
+																						+ "";
+																	});
+												}
+
+												hooks = jQuery.valHooks[this.type]
+														|| jQuery.valHooks[this.nodeName
+																.toLowerCase()];
+
+												// If set returns undefined,
+												// fall back to normal setting
+												if (!hooks
+														|| !("set" in hooks)
+														|| hooks.set(this, val,
+																"value") === undefined) {
+													this.value = val;
+												}
+											});
+								}
+							});
+
+					jQuery
+							.extend({
+								valHooks : {
+									option : {
+										get : function(elem) {
+											var val = jQuery.find.attr(elem,
+													"value");
+											return val != null ? val :
+
+											// Support: IE10-11+
+											// option.text throws exceptions
+											// (#14686, #14858)
+											// Strip and collapse whitespace
+											// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
+											jQuery.trim(jQuery.text(elem))
+													.replace(rspaces, " ");
+										}
+									},
+									select : {
+										get : function(elem) {
+											var value, option, options = elem.options, index = elem.selectedIndex, one = elem.type === "select-one"
+													|| index < 0, values = one ? null
+													: [], max = one ? index + 1
+													: options.length, i = index < 0 ? max
+													: one ? index : 0;
+
+											// Loop through all the selected
+											// options
+											for (; i < max; i++) {
+												option = options[i];
+
+												// oldIE doesn't update selected
+												// after form reset (#2551)
+												if ((option.selected || i === index)
+														&&
+
+														// Don't return options
+														// that are disabled or
+														// in a disabled
+														// optgroup
+														(support.optDisabled ? !option.disabled
+																: option
+																		.getAttribute("disabled") === null)
+														&& (!option.parentNode.disabled || !jQuery
+																.nodeName(
+																		option.parentNode,
+																		"optgroup"))) {
+
+													// Get the specific value
+													// for the option
+													value = jQuery(option)
+															.val();
+
+													// We don't need an array
+													// for one selects
+													if (one) {
+														return value;
+													}
+
+													// Multi-Selects return an
+													// array
+													values.push(value);
+												}
+											}
+
+											return values;
+										},
+
+										set : function(elem, value) {
+											var optionSet, option, options = elem.options, values = jQuery
+													.makeArray(value), i = options.length;
+
+											while (i--) {
+												option = options[i];
+
+												if (jQuery.inArray(
+														jQuery.valHooks.option
+																.get(option),
+														values) > -1) {
+
+													// Support: IE6
+													// When new option element
+													// is added to select box we
+													// need to
+													// force reflow of newly
+													// added node in order to
+													// workaround delay
+													// of initialization
+													// properties
+													try {
+														option.selected = optionSet = true;
+
+													} catch (_) {
+
+														// Will be executed only
+														// in IE6
+														option.scrollHeight;
+													}
+
+												} else {
+													option.selected = false;
+												}
+											}
+
+											// Force browsers to behave
+											// consistently when non-matching
+											// value is set
+											if (!optionSet) {
+												elem.selectedIndex = -1;
+											}
+
+											return options;
+										}
+									}
+								}
+							});
+
+					// Radios and checkboxes getter/setter
+					jQuery
+							.each(
+									[ "radio", "checkbox" ],
+									function() {
+										jQuery.valHooks[this] = {
+											set : function(elem, value) {
+												if (jQuery.isArray(value)) {
+													return (elem.checked = jQuery
+															.inArray(
+																	jQuery(elem)
+																			.val(),
+																	value) > -1);
+												}
+											}
+										};
+										if (!support.checkOn) {
+											jQuery.valHooks[this].get = function(
+													elem) {
+												return elem
+														.getAttribute("value") === null ? "on"
+														: elem.value;
+											};
+										}
+									});
+
+					var nodeHook, boolHook, attrHandle = jQuery.expr.attrHandle, ruseDefault = /^(?:checked|selected)$/i, getSetAttribute = support.getSetAttribute, getSetInput = support.input;
+
+					jQuery.fn.extend({
+						attr : function(name, value) {
+							return access(this, jQuery.attr, name, value,
+									arguments.length > 1);
+						},
+
+						removeAttr : function(name) {
+							return this.each(function() {
+								jQuery.removeAttr(this, name);
+							});
+						}
+					});
+
+					jQuery
+							.extend({
+								attr : function(elem, name, value) {
+									var ret, hooks, nType = elem.nodeType;
+
+									// Don't get/set attributes on text, comment
+									// and attribute nodes
+									if (nType === 3 || nType === 8
+											|| nType === 2) {
+										return;
+									}
+
+									// Fallback to prop when attributes are not
+									// supported
+									if (typeof elem.getAttribute === "undefined") {
+										return jQuery.prop(elem, name, value);
+									}
+
+									// All attributes are lowercase
+									// Grab necessary hook if one is defined
+									if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
+										name = name.toLowerCase();
+										hooks = jQuery.attrHooks[name]
+												|| (jQuery.expr.match.bool
+														.test(name) ? boolHook
+														: nodeHook);
+									}
+
+									if (value !== undefined) {
+										if (value === null) {
+											jQuery.removeAttr(elem, name);
+											return;
+										}
+
+										if (hooks
+												&& "set" in hooks
+												&& (ret = hooks.set(elem,
+														value, name)) !== undefined) {
+											return ret;
+										}
+
+										elem.setAttribute(name, value + "");
+										return value;
+									}
+
+									if (hooks
+											&& "get" in hooks
+											&& (ret = hooks.get(elem, name)) !== null) {
+										return ret;
+									}
+
+									ret = jQuery.find.attr(elem, name);
+
+									// Non-existent attributes return null, we
+									// normalize to undefined
+									return ret == null ? undefined : ret;
+								},
+
+								attrHooks : {
+									type : {
+										set : function(elem, value) {
+											if (!support.radioValue
+													&& value === "radio"
+													&& jQuery.nodeName(elem,
+															"input")) {
+
+												// Setting the type on a radio
+												// button after the value resets
+												// the value in IE8-9
+												// Reset value to default in
+												// case type is set after value
+												// during creation
+												var val = elem.value;
+												elem
+														.setAttribute("type",
+																value);
+												if (val) {
+													elem.value = val;
+												}
+												return value;
+											}
+										}
+									}
+								},
+
+								removeAttr : function(elem, value) {
+									var name, propName, i = 0, attrNames = value
+											&& value.match(rnotwhite);
+
+									if (attrNames && elem.nodeType === 1) {
+										while ((name = attrNames[i++])) {
+											propName = jQuery.propFix[name]
+													|| name;
+
+											// Boolean attributes get special
+											// treatment (#10870)
+											if (jQuery.expr.match.bool
+													.test(name)) {
+
+												// Set corresponding property to
+												// false
+												if (getSetInput
+														&& getSetAttribute
+														|| !ruseDefault
+																.test(name)) {
+													elem[propName] = false;
+
+													// Support: IE<9
+													// Also clear
+													// defaultChecked/defaultSelected
+													// (if appropriate)
+												} else {
+													elem[jQuery
+															.camelCase("default-"
+																	+ name)] = elem[propName] = false;
+												}
+
+												// See #9699 for explanation of
+												// this approach (setting first,
+												// then removal)
+											} else {
+												jQuery.attr(elem, name, "");
+											}
+
+											elem
+													.removeAttribute(getSetAttribute ? name
+															: propName);
+										}
+									}
+								}
+							});
+
+					// Hooks for boolean attributes
+					boolHook = {
+						set : function(elem, value, name) {
+							if (value === false) {
+
+								// Remove boolean attributes when set to false
+								jQuery.removeAttr(elem, name);
+							} else if (getSetInput && getSetAttribute
+									|| !ruseDefault.test(name)) {
+
+								// IE<8 needs the *property* name
+								elem.setAttribute(!getSetAttribute
+										&& jQuery.propFix[name] || name, name);
+
+							} else {
+
+								// Support: IE<9
+								// Use defaultChecked and defaultSelected for
+								// oldIE
+								elem[jQuery.camelCase("default-" + name)] = elem[name] = true;
+							}
+							return name;
+						}
+					};
+
+					jQuery
+							.each(
+									jQuery.expr.match.bool.source.match(/\w+/g),
+									function(i, name) {
+										var getter = attrHandle[name]
+												|| jQuery.find.attr;
+
+										if (getSetInput && getSetAttribute
+												|| !ruseDefault.test(name)) {
+											attrHandle[name] = function(elem,
+													name, isXML) {
+												var ret, handle;
+												if (!isXML) {
+
+													// Avoid an infinite loop by
+													// temporarily removing this
+													// function from the getter
+													handle = attrHandle[name];
+													attrHandle[name] = ret;
+													ret = getter(elem, name,
+															isXML) != null ? name
+															.toLowerCase()
+															: null;
+													attrHandle[name] = handle;
+												}
+												return ret;
+											};
+										} else {
+											attrHandle[name] = function(elem,
+													name, isXML) {
+												if (!isXML) {
+													return elem[jQuery
+															.camelCase("default-"
+																	+ name)] ? name
+															.toLowerCase()
+															: null;
+												}
+											};
+										}
+									});
+
+					// fix oldIE attroperties
+					if (!getSetInput || !getSetAttribute) {
+						jQuery.attrHooks.value = {
+							set : function(elem, value, name) {
+								if (jQuery.nodeName(elem, "input")) {
+
+									// Does not return so that setAttribute is
+									// also used
+									elem.defaultValue = value;
+								} else {
+
+									// Use nodeHook if defined (#1954);
+									// otherwise setAttribute is fine
+									return nodeHook
+											&& nodeHook.set(elem, value, name);
+								}
+							}
+						};
+					}
+
+					// IE6/7 do not support getting/setting some attributes with
+					// get/setAttribute
+					if (!getSetAttribute) {
+
+						// Use this for any attribute in IE6/7
+						// This fixes almost every IE6/7 issue
+						nodeHook = {
+							set : function(elem, value, name) {
+
+								// Set the existing or create a new attribute
+								// node
+								var ret = elem.getAttributeNode(name);
+								if (!ret) {
+									elem
+											.setAttributeNode((ret = elem.ownerDocument
+													.createAttribute(name)));
+								}
+
+								ret.value = value += "";
+
+								// Break association with cloned elements by
+								// also using setAttribute (#9646)
+								if (name === "value"
+										|| value === elem.getAttribute(name)) {
+									return value;
+								}
+							}
+						};
+
+						// Some attributes are constructed with empty-string
+						// values when not defined
+						attrHandle.id = attrHandle.name = attrHandle.coords = function(
+								elem, name, isXML) {
+							var ret;
+							if (!isXML) {
+								return (ret = elem.getAttributeNode(name))
+										&& ret.value !== "" ? ret.value : null;
+							}
+						};
+
+						// Fixing value retrieval on a button requires this
+						// module
+						jQuery.valHooks.button = {
+							get : function(elem, name) {
+								var ret = elem.getAttributeNode(name);
+								if (ret && ret.specified) {
+									return ret.value;
+								}
+							},
+							set : nodeHook.set
+						};
+
+						// Set contenteditable to false on removals(#10429)
+						// Setting to empty string throws an error as an invalid
+						// value
+						jQuery.attrHooks.contenteditable = {
+							set : function(elem, value, name) {
+								nodeHook.set(elem,
+										value === "" ? false : value, name);
+							}
+						};
+
+						// Set width and height to auto instead of 0 on empty
+						// string( Bug #8150 )
+						// This is for removals
+						jQuery.each([ "width", "height" ], function(i, name) {
+							jQuery.attrHooks[name] = {
+								set : function(elem, value) {
+									if (value === "") {
+										elem.setAttribute(name, "auto");
+										return value;
+									}
+								}
+							};
+						});
+					}
+
+					if (!support.style) {
+						jQuery.attrHooks.style = {
+							get : function(elem) {
+
+								// Return undefined in the case of empty string
+								// Note: IE uppercases css property names, but
+								// if we were to .toLowerCase()
+								// .cssText, that would destroy case sensitivity
+								// in URL's, like in "background"
+								return elem.style.cssText || undefined;
+							},
+							set : function(elem, value) {
+								return (elem.style.cssText = value + "");
+							}
+						};
+					}
+
+					var rfocusable = /^(?:input|select|textarea|button|object)$/i, rclickable = /^(?:a|area)$/i;
+
+					jQuery.fn.extend({
+						prop : function(name, value) {
+							return access(this, jQuery.prop, name, value,
+									arguments.length > 1);
+						},
+
+						removeProp : function(name) {
+							name = jQuery.propFix[name] || name;
+							return this.each(function() {
+
+								// try/catch handles cases where IE balks (such
+								// as removing a property on window)
+								try {
+									this[name] = undefined;
+									delete this[name];
+								} catch (e) {
+								}
+							});
+						}
+					});
+
+					jQuery
+							.extend({
+								prop : function(elem, name, value) {
+									var ret, hooks, nType = elem.nodeType;
+
+									// Don't get/set properties on text, comment
+									// and attribute nodes
+									if (nType === 3 || nType === 8
+											|| nType === 2) {
+										return;
+									}
+
+									if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
+
+										// Fix name and attach hooks
+										name = jQuery.propFix[name] || name;
+										hooks = jQuery.propHooks[name];
+									}
+
+									if (value !== undefined) {
+										if (hooks
+												&& "set" in hooks
+												&& (ret = hooks.set(elem,
+														value, name)) !== undefined) {
+											return ret;
+										}
+
+										return (elem[name] = value);
+									}
+
+									if (hooks
+											&& "get" in hooks
+											&& (ret = hooks.get(elem, name)) !== null) {
+										return ret;
+									}
+
+									return elem[name];
+								},
+
+								propHooks : {
+									tabIndex : {
+										get : function(elem) {
+
+											// elem.tabIndex doesn't always
+											// return the
+											// correct value when it hasn't been
+											// explicitly set
+											// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+											// Use proper attribute
+											// retrieval(#12072)
+											var tabindex = jQuery.find.attr(
+													elem, "tabindex");
+
+											return tabindex ? parseInt(
+													tabindex, 10)
+													: rfocusable
+															.test(elem.nodeName)
+															|| rclickable
+																	.test(elem.nodeName)
+															&& elem.href ? 0
+															: -1;
+										}
+									}
+								},
+
+								propFix : {
+									"for" : "htmlFor",
+									"class" : "className"
+								}
+							});
+
+					// Some attributes require a special call on IE
+					// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+					if (!support.hrefNormalized) {
+
+						// href/src property should get the full normalized URL
+						// (#10299/#12915)
+						jQuery.each([ "href", "src" ], function(i, name) {
+							jQuery.propHooks[name] = {
+								get : function(elem) {
+									return elem.getAttribute(name, 4);
+								}
+							};
+						});
+					}
+
+					// Support: Safari, IE9+
+					// Accessing the selectedIndex property
+					// forces the browser to respect setting selected
+					// on the option
+					// The getter ensures a default option is selected
+					// when in an optgroup
+					if (!support.optSelected) {
+						jQuery.propHooks.selected = {
+							get : function(elem) {
+								var parent = elem.parentNode;
+
+								if (parent) {
+									parent.selectedIndex;
+
+									// Make sure that it also works with
+									// optgroups, see #5701
+									if (parent.parentNode) {
+										parent.parentNode.selectedIndex;
+									}
+								}
+								return null;
+							},
+							set : function(elem) {
+								var parent = elem.parentNode;
+								if (parent) {
+									parent.selectedIndex;
+
+									if (parent.parentNode) {
+										parent.parentNode.selectedIndex;
+									}
+								}
+							}
+						};
+					}
+
+					jQuery.each([ "tabIndex", "readOnly", "maxLength",
+							"cellSpacing", "cellPadding", "rowSpan", "colSpan",
+							"useMap", "frameBorder", "contentEditable" ],
+							function() {
+								jQuery.propFix[this.toLowerCase()] = this;
+							});
+
+					// IE6/7 call enctype encoding
+					if (!support.enctype) {
+						jQuery.propFix.enctype = "encoding";
+					}
+
+					var rclass = /[\t\r\n\f]/g;
+
+					function getClass(elem) {
+						return jQuery.attr(elem, "class") || "";
+					}
+
+					jQuery.fn
+							.extend({
+								addClass : function(value) {
+									var classes, elem, cur, curValue, clazz, j, finalValue, i = 0;
+
+									if (jQuery.isFunction(value)) {
+										return this.each(function(j) {
+											jQuery(this).addClass(
+													value.call(this, j,
+															getClass(this)));
+										});
+									}
+
+									if (typeof value === "string" && value) {
+										classes = value.match(rnotwhite) || [];
+
+										while ((elem = this[i++])) {
+											curValue = getClass(elem);
+											cur = elem.nodeType === 1
+													&& (" " + curValue + " ")
+															.replace(rclass,
+																	" ");
+
+											if (cur) {
+												j = 0;
+												while ((clazz = classes[j++])) {
+													if (cur.indexOf(" " + clazz
+															+ " ") < 0) {
+														cur += clazz + " ";
+													}
+												}
+
+												// only assign if different to
+												// avoid unneeded rendering.
+												finalValue = jQuery.trim(cur);
+												if (curValue !== finalValue) {
+													jQuery.attr(elem, "class",
+															finalValue);
+												}
+											}
+										}
+									}
+
+									return this;
+								},
+
+								removeClass : function(value) {
+									var classes, elem, cur, curValue, clazz, j, finalValue, i = 0;
+
+									if (jQuery.isFunction(value)) {
+										return this.each(function(j) {
+											jQuery(this).removeClass(
+													value.call(this, j,
+															getClass(this)));
+										});
+									}
+
+									if (!arguments.length) {
+										return this.attr("class", "");
+									}
+
+									if (typeof value === "string" && value) {
+										classes = value.match(rnotwhite) || [];
+
+										while ((elem = this[i++])) {
+											curValue = getClass(elem);
+
+											// This expression is here for
+											// better compressibility (see
+											// addClass)
+											cur = elem.nodeType === 1
+													&& (" " + curValue + " ")
+															.replace(rclass,
+																	" ");
+
+											if (cur) {
+												j = 0;
+												while ((clazz = classes[j++])) {
+
+													// Remove *all* instances
+													while (cur.indexOf(" "
+															+ clazz + " ") > -1) {
+														cur = cur.replace(" "
+																+ clazz + " ",
+																" ");
+													}
+												}
+
+												// Only assign if different to
+												// avoid unneeded rendering.
+												finalValue = jQuery.trim(cur);
+												if (curValue !== finalValue) {
+													jQuery.attr(elem, "class",
+															finalValue);
+												}
+											}
+										}
+									}
+
+									return this;
+								},
+
+								toggleClass : function(value, stateVal) {
+									var type = typeof value;
+
+									if (typeof stateVal === "boolean"
+											&& type === "string") {
+										return stateVal ? this.addClass(value)
+												: this.removeClass(value);
+									}
+
+									if (jQuery.isFunction(value)) {
+										return this
+												.each(function(i) {
+													jQuery(this)
+															.toggleClass(
+																	value
+																			.call(
+																					this,
+																					i,
+																					getClass(this),
+																					stateVal),
+																	stateVal);
+												});
+									}
+
+									return this
+											.each(function() {
+												var className, i, self, classNames;
+
+												if (type === "string") {
+
+													// Toggle individual class
+													// names
+													i = 0;
+													self = jQuery(this);
+													classNames = value
+															.match(rnotwhite)
+															|| [];
+
+													while ((className = classNames[i++])) {
+
+														// Check each className
+														// given, space
+														// separated list
+														if (self
+																.hasClass(className)) {
+															self
+																	.removeClass(className);
+														} else {
+															self
+																	.addClass(className);
+														}
+													}
+
+													// Toggle whole class name
+												} else if (value === undefined
+														|| type === "boolean") {
+													className = getClass(this);
+													if (className) {
+
+														// store className if
+														// set
+														jQuery
+																._data(
+																		this,
+																		"__className__",
+																		className);
+													}
+
+													// If the element has a
+													// class name or if we're
+													// passed "false",
+													// then remove the whole
+													// classname (if there was
+													// one, the above saved it).
+													// Otherwise bring back
+													// whatever was previously
+													// saved (if anything),
+													// falling back to the empty
+													// string if nothing was
+													// stored.
+													jQuery
+															.attr(
+																	this,
+																	"class",
+																	className
+																			|| value === false ? ""
+																			: jQuery
+																					._data(
+																							this,
+																							"__className__")
+																					|| "");
+												}
+											});
+								},
+
+								hasClass : function(selector) {
+									var className, elem, i = 0;
+
+									className = " " + selector + " ";
+									while ((elem = this[i++])) {
+										if (elem.nodeType === 1
+												&& (" " + getClass(elem) + " ")
+														.replace(rclass, " ")
+														.indexOf(className) > -1) {
+											return true;
+										}
+									}
+
+									return false;
+								}
+							});
+
+					// Return jQuery for attributes-only inclusion
+
+					jQuery
+							.each(
+									("blur focus focusin focusout load resize scroll unload click dblclick "
+											+ "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave "
+											+ "change select submit keydown keypress keyup error contextmenu")
+											.split(" "), function(i, name) {
+
+										// Handle event binding
+										jQuery.fn[name] = function(data, fn) {
+											return arguments.length > 0 ? this
+													.on(name, null, data, fn)
+													: this.trigger(name);
+										};
+									});
+
+					jQuery.fn.extend({
+						hover : function(fnOver, fnOut) {
+							return this.mouseenter(fnOver).mouseleave(
+									fnOut || fnOver);
+						}
+					});
+
+					var location = window.location;
+
+					var nonce = jQuery.now();
+
+					var rquery = (/\?/);
+
+					var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
+
+					jQuery.parseJSON = function(data) {
+
+						// Attempt to parse using the native JSON parser first
+						if (window.JSON && window.JSON.parse) {
+
+							// Support: Android 2.3
+							// Workaround failure to string-cast null input
+							return window.JSON.parse(data + "");
+						}
+
+						var requireNonComma, depth = null, str = jQuery
+								.trim(data + "");
+
+						// Guard against invalid (and possibly dangerous) input
+						// by ensuring that nothing remains
+						// after removing valid tokens
+						return str
+								&& !jQuery.trim(str.replace(rvalidtokens,
+										function(token, comma, open, close) {
+
+											// Force termination if we see a
+											// misplaced comma
+											if (requireNonComma && comma) {
+												depth = 0;
+											}
+
+											// Perform no more replacements
+											// after returning to outermost
+											// depth
+											if (depth === 0) {
+												return token;
+											}
+
+											// Commas must not follow "[", "{",
+											// or ","
+											requireNonComma = open || comma;
+
+											// Determine new depth
+											// array/object open ("[" or "{"):
+											// depth += true - false (increment)
+											// array/object close ("]" or "}"):
+											// depth += false - true (decrement)
+											// other cases ("," or primitive):
+											// depth += true - true (numeric
+											// cast)
+											depth += !close - !open;
+
+											// Remove this token
+											return "";
+										})) ? (Function("return " + str))()
+								: jQuery.error("Invalid JSON: " + data);
+					};
+
+					// Cross-browser xml parsing
+					jQuery.parseXML = function(data) {
+						var xml, tmp;
+						if (!data || typeof data !== "string") {
+							return null;
+						}
+						try {
+							if (window.DOMParser) { // Standard
+								tmp = new window.DOMParser();
+								xml = tmp.parseFromString(data, "text/xml");
+							} else { // IE
+								xml = new window.ActiveXObject(
+										"Microsoft.XMLDOM");
+								xml.async = "false";
+								xml.loadXML(data);
+							}
+						} catch (e) {
+							xml = undefined;
+						}
+						if (!xml
+								|| !xml.documentElement
+								|| xml.getElementsByTagName("parsererror").length) {
+							jQuery.error("Invalid XML: " + data);
+						}
+						return xml;
+					};
+
+					var rhash = /#.*$/, rts = /([?&])_=[^&]*/,
+
+					// IE leaves an \r character at EOL
+					rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg,
+
+					// #7653, #8125, #8152: local protocol detection
+					rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
+
+					/*
+					 * Prefilters 1) They are useful to introduce custom
+					 * dataTypes (see ajax/jsonp.js for an example) 2) These are
+					 * called: - BEFORE asking for a transport - AFTER param
+					 * serialization (s.data is a string if s.processData is
+					 * true) 3) key is the dataType 4) the catchall symbol "*"
+					 * can be used 5) execution will start with transport
+					 * dataType and THEN continue down to "*" if needed
+					 */
+					prefilters = {},
+
+					/*
+					 * Transports bindings 1) key is the dataType 2) the
+					 * catchall symbol "*" can be used 3) selection will start
+					 * with transport dataType and THEN go to "*" if needed
+					 */
+					transports = {},
+
+					// Avoid comment-prolog char sequence (#10098); must appease
+					// lint and evade compression
+					allTypes = "*/".concat("*"),
+
+					// Document location
+					ajaxLocation = location.href,
+
+					// Segment location into parts
+					ajaxLocParts = rurl.exec(ajaxLocation.toLowerCase()) || [];
+
+					// Base "constructor" for jQuery.ajaxPrefilter and
+					// jQuery.ajaxTransport
+					function addToPrefiltersOrTransports(structure) {
+
+						// dataTypeExpression is optional and defaults to "*"
+						return function(dataTypeExpression, func) {
+
+							if (typeof dataTypeExpression !== "string") {
+								func = dataTypeExpression;
+								dataTypeExpression = "*";
+							}
+
+							var dataType, i = 0, dataTypes = dataTypeExpression
+									.toLowerCase().match(rnotwhite)
+									|| [];
+
+							if (jQuery.isFunction(func)) {
+
+								// For each dataType in the dataTypeExpression
+								while ((dataType = dataTypes[i++])) {
+
+									// Prepend if requested
+									if (dataType.charAt(0) === "+") {
+										dataType = dataType.slice(1) || "*";
+										(structure[dataType] = structure[dataType]
+												|| []).unshift(func);
+
+										// Otherwise append
+									} else {
+										(structure[dataType] = structure[dataType]
+												|| []).push(func);
+									}
+								}
+							}
+						};
+					}
+
+					// Base inspection function for prefilters and transports
+					function inspectPrefiltersOrTransports(structure, options,
+							originalOptions, jqXHR) {
+
+						var inspected = {}, seekingTransport = (structure === transports);
+
+						function inspect(dataType) {
+							var selected;
+							inspected[dataType] = true;
+							jQuery.each(structure[dataType] || [], function(_,
+									prefilterOrFactory) {
+								var dataTypeOrTransport = prefilterOrFactory(
+										options, originalOptions, jqXHR);
+								if (typeof dataTypeOrTransport === "string"
+										&& !seekingTransport
+										&& !inspected[dataTypeOrTransport]) {
+
+									options.dataTypes
+											.unshift(dataTypeOrTransport);
+									inspect(dataTypeOrTransport);
+									return false;
+								} else if (seekingTransport) {
+									return !(selected = dataTypeOrTransport);
+								}
+							});
+							return selected;
+						}
+
+						return inspect(options.dataTypes[0]) || !inspected["*"]
+								&& inspect("*");
+					}
+
+					// A special extend for ajax options
+					// that takes "flat" options (not to be deep extended)
+					// Fixes #9887
+					function ajaxExtend(target, src) {
+						var deep, key, flatOptions = jQuery.ajaxSettings.flatOptions
+								|| {};
+
+						for (key in src) {
+							if (src[key] !== undefined) {
+								(flatOptions[key] ? target
+										: (deep || (deep = {})))[key] = src[key];
+							}
+						}
+						if (deep) {
+							jQuery.extend(true, target, deep);
+						}
+
+						return target;
+					}
+
+					/*
+					 * Handles responses to an ajax request: - finds the right
+					 * dataType (mediates between content-type and expected
+					 * dataType) - returns the corresponding response
+					 */
+					function ajaxHandleResponses(s, jqXHR, responses) {
+						var firstDataType, ct, finalDataType, type, contents = s.contents, dataTypes = s.dataTypes;
+
+						// Remove auto dataType and get content-type in the
+						// process
+						while (dataTypes[0] === "*") {
+							dataTypes.shift();
+							if (ct === undefined) {
+								ct = s.mimeType
+										|| jqXHR
+												.getResponseHeader("Content-Type");
+							}
+						}
+
+						// Check if we're dealing with a known content-type
+						if (ct) {
+							for (type in contents) {
+								if (contents[type] && contents[type].test(ct)) {
+									dataTypes.unshift(type);
+									break;
+								}
+							}
+						}
+
+						// Check to see if we have a response for the expected
+						// dataType
+						if (dataTypes[0] in responses) {
+							finalDataType = dataTypes[0];
+						} else {
+
+							// Try convertible dataTypes
+							for (type in responses) {
+								if (!dataTypes[0]
+										|| s.converters[type + " "
+												+ dataTypes[0]]) {
+									finalDataType = type;
+									break;
+								}
+								if (!firstDataType) {
+									firstDataType = type;
+								}
+							}
+
+							// Or just use first one
+							finalDataType = finalDataType || firstDataType;
+						}
+
+						// If we found a dataType
+						// We add the dataType to the list if needed
+						// and return the corresponding response
+						if (finalDataType) {
+							if (finalDataType !== dataTypes[0]) {
+								dataTypes.unshift(finalDataType);
+							}
+							return responses[finalDataType];
+						}
+					}
+
+					/*
+					 * Chain conversions given the request and the original
+					 * response Also sets the responseXXX fields on the jqXHR
+					 * instance
+					 */
+					function ajaxConvert(s, response, jqXHR, isSuccess) {
+						var conv2, current, conv, tmp, prev, converters = {},
+
+						// Work with a copy of dataTypes in case we need to
+						// modify it for conversion
+						dataTypes = s.dataTypes.slice();
+
+						// Create converters map with lowercased keys
+						if (dataTypes[1]) {
+							for (conv in s.converters) {
+								converters[conv.toLowerCase()] = s.converters[conv];
+							}
+						}
+
+						current = dataTypes.shift();
+
+						// Convert to each sequential dataType
+						while (current) {
+
+							if (s.responseFields[current]) {
+								jqXHR[s.responseFields[current]] = response;
+							}
+
+							// Apply the dataFilter if provided
+							if (!prev && isSuccess && s.dataFilter) {
+								response = s.dataFilter(response, s.dataType);
+							}
+
+							prev = current;
+							current = dataTypes.shift();
+
+							if (current) {
+
+								// There's only work to do if current dataType
+								// is non-auto
+								if (current === "*") {
+
+									current = prev;
+
+									// Convert response if prev dataType is
+									// non-auto and differs from current
+								} else if (prev !== "*" && prev !== current) {
+
+									// Seek a direct converter
+									conv = converters[prev + " " + current]
+											|| converters["* " + current];
+
+									// If none found, seek a pair
+									if (!conv) {
+										for (conv2 in converters) {
+
+											// If conv2 outputs current
+											tmp = conv2.split(" ");
+											if (tmp[1] === current) {
+
+												// If prev can be converted to
+												// accepted input
+												conv = converters[prev + " "
+														+ tmp[0]]
+														|| converters["* "
+																+ tmp[0]];
+												if (conv) {
+
+													// Condense equivalence
+													// converters
+													if (conv === true) {
+														conv = converters[conv2];
+
+														// Otherwise, insert the
+														// intermediate dataType
+													} else if (converters[conv2] !== true) {
+														current = tmp[0];
+														dataTypes
+																.unshift(tmp[1]);
+													}
+													break;
+												}
+											}
+										}
+									}
+
+									// Apply converter (if not an equivalence)
+									if (conv !== true) {
+
+										// Unless errors are allowed to bubble,
+										// catch and return them
+										if (conv && s["throws"]) { // jscs:ignore
+																	// requireDotNotation
+											response = conv(response);
+										} else {
+											try {
+												response = conv(response);
+											} catch (e) {
+												return {
+													state : "parsererror",
+													error : conv ? e
+															: "No conversion from "
+																	+ prev
+																	+ " to "
+																	+ current
+												};
+											}
+										}
+									}
+								}
+							}
+						}
+
+						return {
+							state : "success",
+							data : response
+						};
+					}
+
+					jQuery
+							.extend({
+
+								// Counter for holding the number of active
+								// queries
+								active : 0,
+
+								// Last-Modified header cache for next request
+								lastModified : {},
+								etag : {},
+
+								ajaxSettings : {
+									url : ajaxLocation,
+									type : "GET",
+									isLocal : rlocalProtocol
+											.test(ajaxLocParts[1]),
+									global : true,
+									processData : true,
+									async : true,
+									contentType : "application/x-www-form-urlencoded; charset=UTF-8",
+									/*
+									 * timeout: 0, data: null, dataType: null,
+									 * username: null, password: null, cache:
+									 * null, throws: false, traditional: false,
+									 * headers: {},
+									 */
+
+									accepts : {
+										"*" : allTypes,
+										text : "text/plain",
+										html : "text/html",
+										xml : "application/xml, text/xml",
+										json : "application/json, text/javascript"
+									},
+
+									contents : {
+										xml : /\bxml\b/,
+										html : /\bhtml/,
+										json : /\bjson\b/
+									},
+
+									responseFields : {
+										xml : "responseXML",
+										text : "responseText",
+										json : "responseJSON"
+									},
+
+									// Data converters
+									// Keys separate source (or catchall "*")
+									// and destination types with a single space
+									converters : {
+
+										// Convert anything to text
+										"* text" : String,
+
+										// Text to html (true = no
+										// transformation)
+										"text html" : true,
+
+										// Evaluate text as a json expression
+										"text json" : jQuery.parseJSON,
+
+										// Parse text as xml
+										"text xml" : jQuery.parseXML
+									},
+
+									// For options that shouldn't be deep
+									// extended:
+									// you can add your own custom options here
+									// if
+									// and when you create one that shouldn't be
+									// deep extended (see ajaxExtend)
+									flatOptions : {
+										url : true,
+										context : true
+									}
+								},
+
+								// Creates a full fledged settings object into
+								// target
+								// with both ajaxSettings and settings fields.
+								// If target is omitted, writes into
+								// ajaxSettings.
+								ajaxSetup : function(target, settings) {
+									return settings ?
+
+									// Building a settings object
+									ajaxExtend(ajaxExtend(target,
+											jQuery.ajaxSettings), settings) :
+
+									// Extending ajaxSettings
+									ajaxExtend(jQuery.ajaxSettings, target);
+								},
+
+								ajaxPrefilter : addToPrefiltersOrTransports(prefilters),
+								ajaxTransport : addToPrefiltersOrTransports(transports),
+
+								// Main method
+								ajax : function(url, options) {
+
+									// If url is an object, simulate pre-1.5
+									// signature
+									if (typeof url === "object") {
+										options = url;
+										url = undefined;
+									}
+
+									// Force options to be an object
+									options = options || {};
+
+									var
+
+									// Cross-domain detection vars
+									parts,
+
+									// Loop variable
+									i,
+
+									// URL without anti-cache param
+									cacheURL,
+
+									// Response headers as string
+									responseHeadersString,
+
+									// timeout handle
+									timeoutTimer,
+
+									// To know if global events are to be
+									// dispatched
+									fireGlobals,
+
+									transport,
+
+									// Response headers
+									responseHeaders,
+
+									// Create the final options object
+									s = jQuery.ajaxSetup({}, options),
+
+									// Callbacks context
+									callbackContext = s.context || s,
+
+									// Context for global events is
+									// callbackContext if it is a DOM node or
+									// jQuery collection
+									globalEventContext = s.context
+											&& (callbackContext.nodeType || callbackContext.jquery) ? jQuery(callbackContext)
+											: jQuery.event,
+
+									// Deferreds
+									deferred = jQuery.Deferred(), completeDeferred = jQuery
+											.Callbacks("once memory"),
+
+									// Status-dependent callbacks
+									statusCode = s.statusCode || {},
+
+									// Headers (they are sent all at once)
+									requestHeaders = {}, requestHeadersNames = {},
+
+									// The jqXHR state
+									state = 0,
+
+									// Default abort message
+									strAbort = "canceled",
+
+									// Fake xhr
+									jqXHR = {
+										readyState : 0,
+
+										// Builds headers hashtable if needed
+										getResponseHeader : function(key) {
+											var match;
+											if (state === 2) {
+												if (!responseHeaders) {
+													responseHeaders = {};
+													while ((match = rheaders
+															.exec(responseHeadersString))) {
+														responseHeaders[match[1]
+																.toLowerCase()] = match[2];
+													}
+												}
+												match = responseHeaders[key
+														.toLowerCase()];
+											}
+											return match == null ? null : match;
+										},
+
+										// Raw string
+										getAllResponseHeaders : function() {
+											return state === 2 ? responseHeadersString
+													: null;
+										},
+
+										// Caches the header
+										setRequestHeader : function(name, value) {
+											var lname = name.toLowerCase();
+											if (!state) {
+												name = requestHeadersNames[lname] = requestHeadersNames[lname]
+														|| name;
+												requestHeaders[name] = value;
+											}
+											return this;
+										},
+
+										// Overrides response content-type
+										// header
+										overrideMimeType : function(type) {
+											if (!state) {
+												s.mimeType = type;
+											}
+											return this;
+										},
+
+										// Status-dependent callbacks
+										statusCode : function(map) {
+											var code;
+											if (map) {
+												if (state < 2) {
+													for (code in map) {
+
+														// Lazy-add the new
+														// callback in a way
+														// that preserves old
+														// ones
+														statusCode[code] = [
+																statusCode[code],
+																map[code] ];
+													}
+												} else {
+
+													// Execute the appropriate
+													// callbacks
+													jqXHR
+															.always(map[jqXHR.status]);
+												}
+											}
+											return this;
+										},
+
+										// Cancel the request
+										abort : function(statusText) {
+											var finalText = statusText
+													|| strAbort;
+											if (transport) {
+												transport.abort(finalText);
+											}
+											done(0, finalText);
+											return this;
+										}
+									};
+
+									// Attach deferreds
+									deferred.promise(jqXHR).complete = completeDeferred.add;
+									jqXHR.success = jqXHR.done;
+									jqXHR.error = jqXHR.fail;
+
+									// Remove hash character (#7531: and string
+									// promotion)
+									// Add protocol if not provided (#5866: IE7
+									// issue with protocol-less urls)
+									// Handle falsy url in the settings object
+									// (#10093: consistency with old signature)
+									// We also use the url parameter if
+									// available
+									s.url = ((url || s.url || ajaxLocation) + "")
+											.replace(rhash, "").replace(
+													rprotocol,
+													ajaxLocParts[1] + "//");
+
+									// Alias method option to type as per ticket
+									// #12004
+									s.type = options.method || options.type
+											|| s.method || s.type;
+
+									// Extract dataTypes list
+									s.dataTypes = jQuery
+											.trim(s.dataType || "*")
+											.toLowerCase().match(rnotwhite)
+											|| [ "" ];
+
+									// A cross-domain request is in order when
+									// we have a protocol:host:port mismatch
+									if (s.crossDomain == null) {
+										parts = rurl.exec(s.url.toLowerCase());
+										s.crossDomain = !!(parts && (parts[1] !== ajaxLocParts[1]
+												|| parts[2] !== ajaxLocParts[2] || (parts[3] || (parts[1] === "http:" ? "80"
+												: "443")) !== (ajaxLocParts[3] || (ajaxLocParts[1] === "http:" ? "80"
+												: "443"))));
+									}
+
+									// Convert data if not already a string
+									if (s.data && s.processData
+											&& typeof s.data !== "string") {
+										s.data = jQuery.param(s.data,
+												s.traditional);
+									}
+
+									// Apply prefilters
+									inspectPrefiltersOrTransports(prefilters,
+											s, options, jqXHR);
+
+									// If request was aborted inside a
+									// prefilter, stop there
+									if (state === 2) {
+										return jqXHR;
+									}
+
+									// We can fire global events as of now if
+									// asked to
+									// Don't fire events if jQuery.event is
+									// undefined in an AMD-usage scenario
+									// (#15118)
+									fireGlobals = jQuery.event && s.global;
+
+									// Watch for a new set of requests
+									if (fireGlobals && jQuery.active++ === 0) {
+										jQuery.event.trigger("ajaxStart");
+									}
+
+									// Uppercase the type
+									s.type = s.type.toUpperCase();
+
+									// Determine if request has content
+									s.hasContent = !rnoContent.test(s.type);
+
+									// Save the URL in case we're toying with
+									// the If-Modified-Since
+									// and/or If-None-Match header later on
+									cacheURL = s.url;
+
+									// More options handling for requests with
+									// no content
+									if (!s.hasContent) {
+
+										// If data is available, append data to
+										// url
+										if (s.data) {
+											cacheURL = (s.url += (rquery
+													.test(cacheURL) ? "&" : "?")
+													+ s.data);
+
+											// #9682: remove data so that it's
+											// not used in an eventual retry
+											delete s.data;
+										}
+
+										// Add anti-cache in url if needed
+										if (s.cache === false) {
+											s.url = rts.test(cacheURL) ?
+
+											// If there is already a '_'
+											// parameter, set its value
+											cacheURL.replace(rts, "$1_="
+													+ nonce++)
+													:
+
+													// Otherwise add one to the
+													// end
+													cacheURL
+															+ (rquery
+																	.test(cacheURL) ? "&"
+																	: "?")
+															+ "_=" + nonce++;
+										}
+									}
+
+									// Set the If-Modified-Since and/or
+									// If-None-Match header, if in ifModified
+									// mode.
+									if (s.ifModified) {
+										if (jQuery.lastModified[cacheURL]) {
+											jqXHR
+													.setRequestHeader(
+															"If-Modified-Since",
+															jQuery.lastModified[cacheURL]);
+										}
+										if (jQuery.etag[cacheURL]) {
+											jqXHR.setRequestHeader(
+													"If-None-Match",
+													jQuery.etag[cacheURL]);
+										}
+									}
+
+									// Set the correct header, if data is being
+									// sent
+									if (s.data && s.hasContent
+											&& s.contentType !== false
+											|| options.contentType) {
+										jqXHR.setRequestHeader("Content-Type",
+												s.contentType);
+									}
+
+									// Set the Accepts header for the server,
+									// depending on the dataType
+									jqXHR
+											.setRequestHeader(
+													"Accept",
+													s.dataTypes[0]
+															&& s.accepts[s.dataTypes[0]] ? s.accepts[s.dataTypes[0]]
+															+ (s.dataTypes[0] !== "*" ? ", "
+																	+ allTypes
+																	+ "; q=0.01"
+																	: "")
+															: s.accepts["*"]);
+
+									// Check for headers option
+									for (i in s.headers) {
+										jqXHR.setRequestHeader(i, s.headers[i]);
+									}
+
+									// Allow custom headers/mimetypes and early
+									// abort
+									if (s.beforeSend
+											&& (s.beforeSend.call(
+													callbackContext, jqXHR, s) === false || state === 2)) {
+
+										// Abort if not done already and return
+										return jqXHR.abort();
+									}
+
+									// aborting is no longer a cancellation
+									strAbort = "abort";
+
+									// Install callbacks on deferreds
+									for (i in {
+										success : 1,
+										error : 1,
+										complete : 1
+									}) {
+										jqXHR[i](s[i]);
+									}
+
+									// Get transport
+									transport = inspectPrefiltersOrTransports(
+											transports, s, options, jqXHR);
+
+									// If no transport, we auto-abort
+									if (!transport) {
+										done(-1, "No Transport");
+									} else {
+										jqXHR.readyState = 1;
+
+										// Send global event
+										if (fireGlobals) {
+											globalEventContext.trigger(
+													"ajaxSend", [ jqXHR, s ]);
+										}
+
+										// If request was aborted inside
+										// ajaxSend, stop there
+										if (state === 2) {
+											return jqXHR;
+										}
+
+										// Timeout
+										if (s.async && s.timeout > 0) {
+											timeoutTimer = window.setTimeout(
+													function() {
+														jqXHR.abort("timeout");
+													}, s.timeout);
+										}
+
+										try {
+											state = 1;
+											transport
+													.send(requestHeaders, done);
+										} catch (e) {
+
+											// Propagate exception as error if
+											// not done
+											if (state < 2) {
+												done(-1, e);
+
+												// Simply rethrow otherwise
+											} else {
+												throw e;
+											}
+										}
+									}
+
+									// Callback for when everything is done
+									function done(status, nativeStatusText,
+											responses, headers) {
+										var isSuccess, success, error, response, modified, statusText = nativeStatusText;
+
+										// Called once
+										if (state === 2) {
+											return;
+										}
+
+										// State is "done" now
+										state = 2;
+
+										// Clear timeout if it exists
+										if (timeoutTimer) {
+											window.clearTimeout(timeoutTimer);
+										}
+
+										// Dereference transport for early
+										// garbage collection
+										// (no matter how long the jqXHR object
+										// will be used)
+										transport = undefined;
+
+										// Cache response headers
+										responseHeadersString = headers || "";
+
+										// Set readyState
+										jqXHR.readyState = status > 0 ? 4 : 0;
+
+										// Determine if successful
+										isSuccess = status >= 200
+												&& status < 300
+												|| status === 304;
+
+										// Get response data
+										if (responses) {
+											response = ajaxHandleResponses(s,
+													jqXHR, responses);
+										}
+
+										// Convert no matter what (that way
+										// responseXXX fields are always set)
+										response = ajaxConvert(s, response,
+												jqXHR, isSuccess);
+
+										// If successful, handle type chaining
+										if (isSuccess) {
+
+											// Set the If-Modified-Since and/or
+											// If-None-Match header, if in
+											// ifModified mode.
+											if (s.ifModified) {
+												modified = jqXHR
+														.getResponseHeader("Last-Modified");
+												if (modified) {
+													jQuery.lastModified[cacheURL] = modified;
+												}
+												modified = jqXHR
+														.getResponseHeader("etag");
+												if (modified) {
+													jQuery.etag[cacheURL] = modified;
+												}
+											}
+
+											// if no content
+											if (status === 204
+													|| s.type === "HEAD") {
+												statusText = "nocontent";
+
+												// if not modified
+											} else if (status === 304) {
+												statusText = "notmodified";
+
+												// If we have data, let's
+												// convert it
+											} else {
+												statusText = response.state;
+												success = response.data;
+												error = response.error;
+												isSuccess = !error;
+											}
+										} else {
+
+											// We extract error from statusText
+											// then normalize statusText and
+											// status for non-aborts
+											error = statusText;
+											if (status || !statusText) {
+												statusText = "error";
+												if (status < 0) {
+													status = 0;
+												}
+											}
+										}
+
+										// Set data for the fake xhr object
+										jqXHR.status = status;
+										jqXHR.statusText = (nativeStatusText || statusText)
+												+ "";
+
+										// Success/Error
+										if (isSuccess) {
+											deferred
+													.resolveWith(
+															callbackContext, [
+																	success,
+																	statusText,
+																	jqXHR ]);
+										} else {
+											deferred
+													.rejectWith(
+															callbackContext, [
+																	jqXHR,
+																	statusText,
+																	error ]);
+										}
+
+										// Status-dependent callbacks
+										jqXHR.statusCode(statusCode);
+										statusCode = undefined;
+
+										if (fireGlobals) {
+											globalEventContext.trigger(
+													isSuccess ? "ajaxSuccess"
+															: "ajaxError", [
+															jqXHR,
+															s,
+															isSuccess ? success
+																	: error ]);
+										}
+
+										// Complete
+										completeDeferred.fireWith(
+												callbackContext, [ jqXHR,
+														statusText ]);
+
+										if (fireGlobals) {
+											globalEventContext.trigger(
+													"ajaxComplete",
+													[ jqXHR, s ]);
+
+											// Handle the global AJAX counter
+											if (!(--jQuery.active)) {
+												jQuery.event
+														.trigger("ajaxStop");
+											}
+										}
+									}
+
+									return jqXHR;
+								},
+
+								getJSON : function(url, data, callback) {
+									return jQuery.get(url, data, callback,
+											"json");
+								},
+
+								getScript : function(url, callback) {
+									return jQuery.get(url, undefined, callback,
+											"script");
+								}
+							});
+
+					jQuery.each([ "get", "post" ], function(i, method) {
+						jQuery[method] = function(url, data, callback, type) {
+
+							// shift arguments if data argument was omitted
+							if (jQuery.isFunction(data)) {
+								type = type || callback;
+								callback = data;
+								data = undefined;
+							}
+
+							// The url can be an options object (which then must
+							// have .url)
+							return jQuery.ajax(jQuery.extend({
+								url : url,
+								type : method,
+								dataType : type,
+								data : data,
+								success : callback
+							}, jQuery.isPlainObject(url) && url));
+						};
+					});
+
+					jQuery._evalUrl = function(url) {
+						return jQuery.ajax({
+							url : url,
+
+							// Make this explicit, since user can override this
+							// through ajaxSetup (#11264)
+							type : "GET",
+							dataType : "script",
+							cache : true,
+							async : false,
+							global : false,
+							"throws" : true
+						});
+					};
+
+					jQuery.fn
+							.extend({
+								wrapAll : function(html) {
+									if (jQuery.isFunction(html)) {
+										return this.each(function(i) {
+											jQuery(this).wrapAll(
+													html.call(this, i));
+										});
+									}
+
+									if (this[0]) {
+
+										// The elements to wrap the target
+										// around
+										var wrap = jQuery(html,
+												this[0].ownerDocument).eq(0)
+												.clone(true);
+
+										if (this[0].parentNode) {
+											wrap.insertBefore(this[0]);
+										}
+
+										wrap
+												.map(
+														function() {
+															var elem = this;
+
+															while (elem.firstChild
+																	&& elem.firstChild.nodeType === 1) {
+																elem = elem.firstChild;
+															}
+
+															return elem;
+														}).append(this);
+									}
+
+									return this;
+								},
+
+								wrapInner : function(html) {
+									if (jQuery.isFunction(html)) {
+										return this.each(function(i) {
+											jQuery(this).wrapInner(
+													html.call(this, i));
+										});
+									}
+
+									return this
+											.each(function() {
+												var self = jQuery(this), contents = self
+														.contents();
+
+												if (contents.length) {
+													contents.wrapAll(html);
+
+												} else {
+													self.append(html);
+												}
+											});
+								},
+
+								wrap : function(html) {
+									var isFunction = jQuery.isFunction(html);
+
+									return this.each(function(i) {
+										jQuery(this).wrapAll(
+												isFunction ? html.call(this, i)
+														: html);
+									});
+								},
+
+								unwrap : function() {
+									return this.parent().each(
+											function() {
+												if (!jQuery.nodeName(this,
+														"body")) {
+													jQuery(this).replaceWith(
+															this.childNodes);
+												}
+											}).end();
+								}
+							});
+
+					function getDisplay(elem) {
+						return elem.style && elem.style.display
+								|| jQuery.css(elem, "display");
+					}
+
+					function filterHidden(elem) {
+
+						// Disconnected elements are considered hidden
+						if (!jQuery.contains(elem.ownerDocument || document,
+								elem)) {
+							return true;
+						}
+						while (elem && elem.nodeType === 1) {
+							if (getDisplay(elem) === "none"
+									|| elem.type === "hidden") {
+								return true;
+							}
+							elem = elem.parentNode;
+						}
+						return false;
+					}
+
+					jQuery.expr.filters.hidden = function(elem) {
+
+						// Support: Opera <= 12.12
+						// Opera reports offsetWidths and offsetHeights less
+						// than zero on some elements
+						return support.reliableHiddenOffsets() ? (elem.offsetWidth <= 0
+								&& elem.offsetHeight <= 0 && !elem
+								.getClientRects().length)
+								: filterHidden(elem);
+					};
+
+					jQuery.expr.filters.visible = function(elem) {
+						return !jQuery.expr.filters.hidden(elem);
+					};
+
+					var r20 = /%20/g, rbracket = /\[\]$/, rCRLF = /\r?\n/g, rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, rsubmittable = /^(?:input|select|textarea|keygen)/i;
+
+					function buildParams(prefix, obj, traditional, add) {
+						var name;
+
+						if (jQuery.isArray(obj)) {
+
+							// Serialize array item.
+							jQuery.each(obj, function(i, v) {
+								if (traditional || rbracket.test(prefix)) {
+
+									// Treat each array item as a scalar.
+									add(prefix, v);
+
+								} else {
+
+									// Item is non-scalar (array or object),
+									// encode its numeric index.
+									buildParams(prefix
+											+ "["
+											+ (typeof v === "object"
+													&& v != null ? i : "")
+											+ "]", v, traditional, add);
+								}
+							});
+
+						} else if (!traditional
+								&& jQuery.type(obj) === "object") {
+
+							// Serialize object item.
+							for (name in obj) {
+								buildParams(prefix + "[" + name + "]",
+										obj[name], traditional, add);
+							}
+
+						} else {
+
+							// Serialize scalar item.
+							add(prefix, obj);
+						}
+					}
+
+					// Serialize an array of form elements or a set of
+					// key/values into a query string
+					jQuery.param = function(a, traditional) {
+						var prefix, s = [], add = function(key, value) {
+
+							// If value is a function, invoke it and return its
+							// value
+							value = jQuery.isFunction(value) ? value()
+									: (value == null ? "" : value);
+							s[s.length] = encodeURIComponent(key) + "="
+									+ encodeURIComponent(value);
+						};
+
+						// Set traditional to true for jQuery <= 1.3.2 behavior.
+						if (traditional === undefined) {
+							traditional = jQuery.ajaxSettings
+									&& jQuery.ajaxSettings.traditional;
+						}
+
+						// If an array was passed in, assume that it is an array
+						// of form elements.
+						if (jQuery.isArray(a)
+								|| (a.jquery && !jQuery.isPlainObject(a))) {
+
+							// Serialize the form elements
+							jQuery.each(a, function() {
+								add(this.name, this.value);
+							});
+
+						} else {
+
+							// If traditional, encode the "old" way (the way
+							// 1.3.2 or older
+							// did it), otherwise encode params recursively.
+							for (prefix in a) {
+								buildParams(prefix, a[prefix], traditional, add);
+							}
+						}
+
+						// Return the resulting serialization
+						return s.join("&").replace(r20, "+");
+					};
+
+					jQuery.fn
+							.extend({
+								serialize : function() {
+									return jQuery.param(this.serializeArray());
+								},
+								serializeArray : function() {
+									return this
+											.map(
+													function() {
+
+														// Can add propHook for
+														// "elements" to filter
+														// or add form elements
+														var elements = jQuery
+																.prop(this,
+																		"elements");
+														return elements ? jQuery
+																.makeArray(elements)
+																: this;
+													})
+											.filter(
+													function() {
+														var type = this.type;
+
+														// Use .is(":disabled")
+														// so that
+														// fieldset[disabled]
+														// works
+														return this.name
+																&& !jQuery(this)
+																		.is(
+																				":disabled")
+																&& rsubmittable
+																		.test(this.nodeName)
+																&& !rsubmitterTypes
+																		.test(type)
+																&& (this.checked || !rcheckableType
+																		.test(type));
+													})
+											.map(
+													function(i, elem) {
+														var val = jQuery(this)
+																.val();
+
+														return val == null ? null
+																: jQuery
+																		.isArray(val) ? jQuery
+																		.map(
+																				val,
+																				function(
+																						val) {
+																					return {
+																						name : elem.name,
+																						value : val
+																								.replace(
+																										rCRLF,
+																										"\r\n")
+																					};
+																				})
+																		: {
+																			name : elem.name,
+																			value : val
+																					.replace(
+																							rCRLF,
+																							"\r\n")
+																		};
+													}).get();
+								}
+							});
+
+					// Create the request object
+					// (This is still attached to ajaxSettings for backward
+					// compatibility)
+					jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
+
+					// Support: IE6-IE8
+					function() {
+
+						// XHR cannot access local files, always use ActiveX for
+						// that case
+						if (this.isLocal) {
+							return createActiveXHR();
+						}
+
+						// Support: IE 9-11
+						// IE seems to error on cross-domain PATCH requests when
+						// ActiveX XHR
+						// is used. In IE 9+ always use the native XHR.
+						// Note: this condition won't catch Edge as it doesn't
+						// define
+						// document.documentMode but it also doesn't support
+						// ActiveX so it won't
+						// reach this code.
+						if (document.documentMode > 8) {
+							return createStandardXHR();
+						}
+
+						// Support: IE<9
+						// oldIE XHR does not support non-RFC2616 methods
+						// (#13240)
+						// See
+						// http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
+						// and
+						// http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
+						// Although this check for six methods instead of eight
+						// since IE also does not support "trace" and "connect"
+						return /^(get|post|head|put|delete|options)$/i
+								.test(this.type)
+								&& createStandardXHR() || createActiveXHR();
+					}
+							:
+
+							// For all other browsers, use the standard
+							// XMLHttpRequest object
+							createStandardXHR;
+
+					var xhrId = 0, xhrCallbacks = {}, xhrSupported = jQuery.ajaxSettings
+							.xhr();
+
+					// Support: IE<10
+					// Open requests must be manually aborted on unload (#5280)
+					// See https://support.microsoft.com/kb/2856746 for more
+					// info
+					if (window.attachEvent) {
+						window.attachEvent("onunload", function() {
+							for ( var key in xhrCallbacks) {
+								xhrCallbacks[key](undefined, true);
+							}
+						});
+					}
+
+					// Determine support properties
+					support.cors = !!xhrSupported
+							&& ("withCredentials" in xhrSupported);
+					xhrSupported = support.ajax = !!xhrSupported;
+
+					// Create transport if the browser can provide an xhr
+					if (xhrSupported) {
+
+						jQuery
+								.ajaxTransport(function(options) {
+
+									// Cross domain only allowed if supported
+									// through XMLHttpRequest
+									if (!options.crossDomain || support.cors) {
+
+										var callback;
+
+										return {
+											send : function(headers, complete) {
+												var i, xhr = options.xhr(), id = ++xhrId;
+
+												// Open the socket
+												xhr.open(options.type,
+														options.url,
+														options.async,
+														options.username,
+														options.password);
+
+												// Apply custom fields if
+												// provided
+												if (options.xhrFields) {
+													for (i in options.xhrFields) {
+														xhr[i] = options.xhrFields[i];
+													}
+												}
+
+												// Override mime type if needed
+												if (options.mimeType
+														&& xhr.overrideMimeType) {
+													xhr
+															.overrideMimeType(options.mimeType);
+												}
+
+												// X-Requested-With header
+												// For cross-domain requests,
+												// seeing as conditions for a
+												// preflight are
+												// akin to a jigsaw puzzle, we
+												// simply never set it to be
+												// sure.
+												// (it can always be set on a
+												// per-request basis or even
+												// using ajaxSetup)
+												// For same-domain requests,
+												// won't change header if
+												// already provided.
+												if (!options.crossDomain
+														&& !headers["X-Requested-With"]) {
+													headers["X-Requested-With"] = "XMLHttpRequest";
+												}
+
+												// Set headers
+												for (i in headers) {
+
+													// Support: IE<9
+													// IE's ActiveXObject throws
+													// a 'Type Mismatch'
+													// exception when setting
+													// request header to a
+													// null-value.
+													//
+													// To keep consistent with
+													// other XHR
+													// implementations, cast the
+													// value
+													// to string and ignore
+													// `undefined`.
+													if (headers[i] !== undefined) {
+														xhr
+																.setRequestHeader(
+																		i,
+																		headers[i]
+																				+ "");
+													}
+												}
+
+												// Do send the request
+												// This may raise an exception
+												// which is actually
+												// handled in jQuery.ajax (so no
+												// try/catch here)
+												xhr
+														.send((options.hasContent && options.data)
+																|| null);
+
+												// Listener
+												callback = function(_, isAbort) {
+													var status, statusText, responses;
+
+													// Was never called and is
+													// aborted or complete
+													if (callback
+															&& (isAbort || xhr.readyState === 4)) {
+
+														// Clean up
+														delete xhrCallbacks[id];
+														callback = undefined;
+														xhr.onreadystatechange = jQuery.noop;
+
+														// Abort manually if
+														// needed
+														if (isAbort) {
+															if (xhr.readyState !== 4) {
+																xhr.abort();
+															}
+														} else {
+															responses = {};
+															status = xhr.status;
+
+															// Support: IE<10
+															// Accessing
+															// binary-data
+															// responseText
+															// throws an
+															// exception
+															// (#11426)
+															if (typeof xhr.responseText === "string") {
+																responses.text = xhr.responseText;
+															}
+
+															// Firefox throws an
+															// exception when
+															// accessing
+															// statusText for
+															// faulty
+															// cross-domain
+															// requests
+															try {
+																statusText = xhr.statusText;
+															} catch (e) {
+
+																// We normalize
+																// with Webkit
+																// giving an
+																// empty
+																// statusText
+																statusText = "";
+															}
+
+															// Filter status for
+															// non standard
+															// behaviors
+
+															// If the request is
+															// local and we have
+															// data: assume a
+															// success
+															// (success with no
+															// data won't get
+															// notified, that's
+															// the best we
+															// can do given
+															// current
+															// implementations)
+															if (!status
+																	&& options.isLocal
+																	&& !options.crossDomain) {
+																status = responses.text ? 200
+																		: 404;
+
+																// IE - #1450:
+																// sometimes
+																// returns 1223
+																// when it
+																// should be 204
+															} else if (status === 1223) {
+																status = 204;
+															}
+														}
+													}
+
+													// Call complete if needed
+													if (responses) {
+														complete(
+																status,
+																statusText,
+																responses,
+																xhr
+																		.getAllResponseHeaders());
+													}
+												};
+
+												// Do send the request
+												// `xhr.send` may raise an
+												// exception, but it will be
+												// handled in jQuery.ajax (so no
+												// try/catch here)
+												if (!options.async) {
+
+													// If we're in sync mode we
+													// fire the callback
+													callback();
+												} else if (xhr.readyState === 4) {
+
+													// (IE6 & IE7) if it's in
+													// cache and has been
+													// retrieved directly we
+													// need to fire the callback
+													window.setTimeout(callback);
+												} else {
+
+													// Register the callback,
+													// but delay it in case
+													// `xhr.send` throws
+													// Add to the list of active
+													// xhr callbacks
+													xhr.onreadystatechange = xhrCallbacks[id] = callback;
+												}
+											},
+
+											abort : function() {
+												if (callback) {
+													callback(undefined, true);
+												}
+											}
+										};
+									}
+								});
+					}
+
+					// Functions to create xhrs
+					function createStandardXHR() {
+						try {
+							return new window.XMLHttpRequest();
+						} catch (e) {
+						}
+					}
+
+					function createActiveXHR() {
+						try {
+							return new window.ActiveXObject("Microsoft.XMLHTTP");
+						} catch (e) {
+						}
+					}
+
+					// Install script dataType
+					jQuery
+							.ajaxSetup({
+								accepts : {
+									script : "text/javascript, application/javascript, "
+											+ "application/ecmascript, application/x-ecmascript"
+								},
+								contents : {
+									script : /\b(?:java|ecma)script\b/
+								},
+								converters : {
+									"text script" : function(text) {
+										jQuery.globalEval(text);
+										return text;
+									}
+								}
+							});
+
+					// Handle cache's special case and global
+					jQuery.ajaxPrefilter("script", function(s) {
+						if (s.cache === undefined) {
+							s.cache = false;
+						}
+						if (s.crossDomain) {
+							s.type = "GET";
+							s.global = false;
+						}
+					});
+
+					// Bind script tag hack transport
+					jQuery
+							.ajaxTransport(
+									"script",
+									function(s) {
+
+										// This transport only deals with cross
+										// domain requests
+										if (s.crossDomain) {
+
+											var script, head = document.head
+													|| jQuery("head")[0]
+													|| document.documentElement;
+
+											return {
+
+												send : function(_, callback) {
+
+													script = document
+															.createElement("script");
+
+													script.async = true;
+
+													if (s.scriptCharset) {
+														script.charset = s.scriptCharset;
+													}
+
+													script.src = s.url;
+
+													// Attach handlers for all
+													// browsers
+													script.onload = script.onreadystatechange = function(
+															_, isAbort) {
+
+														if (isAbort
+																|| !script.readyState
+																|| /loaded|complete/
+																		.test(script.readyState)) {
+
+															// Handle memory
+															// leak in IE
+															script.onload = script.onreadystatechange = null;
+
+															// Remove the script
+															if (script.parentNode) {
+																script.parentNode
+																		.removeChild(script);
+															}
+
+															// Dereference the
+															// script
+															script = null;
+
+															// Callback if not
+															// abort
+															if (!isAbort) {
+																callback(200,
+																		"success");
+															}
+														}
+													};
+
+													// Circumvent IE6 bugs with
+													// base elements (#2709 and
+													// #4378) by prepending
+													// Use native DOM
+													// manipulation to avoid our
+													// domManip AJAX trickery
+													head.insertBefore(script,
+															head.firstChild);
+												},
+
+												abort : function() {
+													if (script) {
+														script
+																.onload(
+																		undefined,
+																		true);
+													}
+												}
+											};
+										}
+									});
+
+					var oldCallbacks = [], rjsonp = /(=)\?(?=&|$)|\?\?/;
+
+					// Default jsonp settings
+					jQuery.ajaxSetup({
+						jsonp : "callback",
+						jsonpCallback : function() {
+							var callback = oldCallbacks.pop()
+									|| (jQuery.expando + "_" + (nonce++));
+							this[callback] = true;
+							return callback;
+						}
+					});
+
+					// Detect, normalize options and install callbacks for jsonp
+					// requests
+					jQuery
+							.ajaxPrefilter(
+									"json jsonp",
+									function(s, originalSettings, jqXHR) {
+
+										var callbackName, overwritten, responseContainer, jsonProp = s.jsonp !== false
+												&& (rjsonp.test(s.url) ? "url"
+														: typeof s.data === "string"
+																&& (s.contentType || "")
+																		.indexOf("application/x-www-form-urlencoded") === 0
+																&& rjsonp
+																		.test(s.data)
+																&& "data");
+
+										// Handle iff the expected data type is
+										// "jsonp" or we have a parameter to set
+										if (jsonProp
+												|| s.dataTypes[0] === "jsonp") {
+
+											// Get callback name, remembering
+											// preexisting value associated with
+											// it
+											callbackName = s.jsonpCallback = jQuery
+													.isFunction(s.jsonpCallback) ? s
+													.jsonpCallback()
+													: s.jsonpCallback;
+
+											// Insert callback into url or form
+											// data
+											if (jsonProp) {
+												s[jsonProp] = s[jsonProp]
+														.replace(rjsonp, "$1"
+																+ callbackName);
+											} else if (s.jsonp !== false) {
+												s.url += (rquery.test(s.url) ? "&"
+														: "?")
+														+ s.jsonp
+														+ "="
+														+ callbackName;
+											}
+
+											// Use data converter to retrieve
+											// json after script execution
+											s.converters["script json"] = function() {
+												if (!responseContainer) {
+													jQuery
+															.error(callbackName
+																	+ " was not called");
+												}
+												return responseContainer[0];
+											};
+
+											// force json dataType
+											s.dataTypes[0] = "json";
+
+											// Install callback
+											overwritten = window[callbackName];
+											window[callbackName] = function() {
+												responseContainer = arguments;
+											};
+
+											// Clean-up function (fires after
+											// converters)
+											jqXHR
+													.always(function() {
+
+														// If previous value
+														// didn't exist - remove
+														// it
+														if (overwritten === undefined) {
+															jQuery(window)
+																	.removeProp(
+																			callbackName);
+
+															// Otherwise restore
+															// preexisting value
+														} else {
+															window[callbackName] = overwritten;
+														}
+
+														// Save back as free
+														if (s[callbackName]) {
+
+															// make sure that
+															// re-using the
+															// options doesn't
+															// screw things
+															// around
+															s.jsonpCallback = originalSettings.jsonpCallback;
+
+															// save the callback
+															// name for future
+															// use
+															oldCallbacks
+																	.push(callbackName);
+														}
+
+														// Call if it was a
+														// function and we have
+														// a response
+														if (responseContainer
+																&& jQuery
+																		.isFunction(overwritten)) {
+															overwritten(responseContainer[0]);
+														}
+
+														responseContainer = overwritten = undefined;
+													});
+
+											// Delegate to script
+											return "script";
+										}
+									});
+
+					// data: string of html
+					// context (optional): If specified, the fragment will be
+					// created in this context,
+					// defaults to document
+					// keepScripts (optional): If true, will include scripts
+					// passed in the html string
+					jQuery.parseHTML = function(data, context, keepScripts) {
+						if (!data || typeof data !== "string") {
+							return null;
+						}
+						if (typeof context === "boolean") {
+							keepScripts = context;
+							context = false;
+						}
+						context = context || document;
+
+						var parsed = rsingleTag.exec(data), scripts = !keepScripts
+								&& [];
+
+						// Single tag
+						if (parsed) {
+							return [ context.createElement(parsed[1]) ];
+						}
+
+						parsed = buildFragment([ data ], context, scripts);
+
+						if (scripts && scripts.length) {
+							jQuery(scripts).remove();
+						}
+
+						return jQuery.merge([], parsed.childNodes);
+					};
+
+					// Keep a copy of the old load method
+					var _load = jQuery.fn.load;
+
+					/**
+					 * Load a url into a page
+					 */
+					jQuery.fn.load = function(url, params, callback) {
+						if (typeof url !== "string" && _load) {
+							return _load.apply(this, arguments);
+						}
+
+						var selector, type, response, self = this, off = url
+								.indexOf(" ");
+
+						if (off > -1) {
+							selector = jQuery.trim(url.slice(off, url.length));
+							url = url.slice(0, off);
+						}
+
+						// If it's a function
+						if (jQuery.isFunction(params)) {
+
+							// We assume that it's the callback
+							callback = params;
+							params = undefined;
+
+							// Otherwise, build a param string
+						} else if (params && typeof params === "object") {
+							type = "POST";
+						}
+
+						// If we have elements to modify, make the request
+						if (self.length > 0) {
+							jQuery
+									.ajax({
+										url : url,
+
+										// If "type" variable is undefined, then
+										// "GET" method will be used.
+										// Make value of this field explicit
+										// since
+										// user can override it through
+										// ajaxSetup method
+										type : type || "GET",
+										dataType : "html",
+										data : params
+									})
+									.done(
+											function(responseText) {
+
+												// Save response for use in
+												// complete callback
+												response = arguments;
+
+												self
+														.html(selector ?
+
+														// If a selector was
+														// specified, locate the
+														// right elements in a
+														// dummy div
+														// Exclude scripts to
+														// avoid IE 'Permission
+														// Denied' errors
+														jQuery("<div>")
+																.append(
+																		jQuery
+																				.parseHTML(responseText))
+																.find(selector)
+																:
+
+																// Otherwise use
+																// the full
+																// result
+																responseText);
+
+												// If the request succeeds, this
+												// function gets "data",
+												// "status", "jqXHR"
+												// but they are ignored because
+												// response was set above.
+												// If it fails, this function
+												// gets "jqXHR", "status",
+												// "error"
+											})
+									.always(
+											callback
+													&& function(jqXHR, status) {
+														self
+																.each(function() {
+																	callback
+																			.apply(
+																					this,
+																					response
+																							|| [
+																									jqXHR.responseText,
+																									status,
+																									jqXHR ]);
+																});
+													});
+						}
+
+						return this;
+					};
+
+					// Attach a bunch of functions for handling common AJAX
+					// events
+					jQuery.each([ "ajaxStart", "ajaxStop", "ajaxComplete",
+							"ajaxError", "ajaxSuccess", "ajaxSend" ], function(
+							i, type) {
+						jQuery.fn[type] = function(fn) {
+							return this.on(type, fn);
+						};
+					});
+
+					jQuery.expr.filters.animated = function(elem) {
+						return jQuery.grep(jQuery.timers, function(fn) {
+							return elem === fn.elem;
+						}).length;
+					};
+
+					/**
+					 * Gets a window from an element
+					 */
+					function getWindow(elem) {
+						return jQuery.isWindow(elem) ? elem
+								: elem.nodeType === 9 ? elem.defaultView
+										|| elem.parentWindow : false;
+					}
+
+					jQuery.offset = {
+						setOffset : function(elem, options, i) {
+							var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, position = jQuery
+									.css(elem, "position"), curElem = jQuery(elem), props = {};
+
+							// set position first, in-case top/left are set even
+							// on static elem
+							if (position === "static") {
+								elem.style.position = "relative";
+							}
+
+							curOffset = curElem.offset();
+							curCSSTop = jQuery.css(elem, "top");
+							curCSSLeft = jQuery.css(elem, "left");
+							calculatePosition = (position === "absolute" || position === "fixed")
+									&& jQuery.inArray("auto", [ curCSSTop,
+											curCSSLeft ]) > -1;
+
+							// need to be able to calculate position if either
+							// top or left
+							// is auto and position is either absolute or fixed
+							if (calculatePosition) {
+								curPosition = curElem.position();
+								curTop = curPosition.top;
+								curLeft = curPosition.left;
+							} else {
+								curTop = parseFloat(curCSSTop) || 0;
+								curLeft = parseFloat(curCSSLeft) || 0;
+							}
+
+							if (jQuery.isFunction(options)) {
+
+								// Use jQuery.extend here to allow modification
+								// of coordinates argument (gh-1848)
+								options = options.call(elem, i, jQuery.extend(
+										{}, curOffset));
+							}
+
+							if (options.top != null) {
+								props.top = (options.top - curOffset.top)
+										+ curTop;
+							}
+							if (options.left != null) {
+								props.left = (options.left - curOffset.left)
+										+ curLeft;
+							}
+
+							if ("using" in options) {
+								options.using.call(elem, props);
+							} else {
+								curElem.css(props);
+							}
+						}
+					};
+
+					jQuery.fn
+							.extend({
+								offset : function(options) {
+									if (arguments.length) {
+										return options === undefined ? this
+												: this.each(function(i) {
+													jQuery.offset.setOffset(
+															this, options, i);
+												});
+									}
+
+									var docElem, win, box = {
+										top : 0,
+										left : 0
+									}, elem = this[0], doc = elem
+											&& elem.ownerDocument;
+
+									if (!doc) {
+										return;
+									}
+
+									docElem = doc.documentElement;
+
+									// Make sure it's not a disconnected DOM
+									// node
+									if (!jQuery.contains(docElem, elem)) {
+										return box;
+									}
+
+									// If we don't have gBCR, just use 0,0
+									// rather than error
+									// BlackBerry 5, iOS 3 (original iPhone)
+									if (typeof elem.getBoundingClientRect !== "undefined") {
+										box = elem.getBoundingClientRect();
+									}
+									win = getWindow(doc);
+									return {
+										top : box.top
+												+ (win.pageYOffset || docElem.scrollTop)
+												- (docElem.clientTop || 0),
+										left : box.left
+												+ (win.pageXOffset || docElem.scrollLeft)
+												- (docElem.clientLeft || 0)
+									};
+								},
+
+								position : function() {
+									if (!this[0]) {
+										return;
+									}
+
+									var offsetParent, offset, parentOffset = {
+										top : 0,
+										left : 0
+									}, elem = this[0];
+
+									// Fixed elements are offset from window
+									// (parentOffset = {top:0, left: 0},
+									// because it is its only offset parent
+									if (jQuery.css(elem, "position") === "fixed") {
+
+										// we assume that getBoundingClientRect
+										// is available when computed position
+										// is fixed
+										offset = elem.getBoundingClientRect();
+									} else {
+
+										// Get *real* offsetParent
+										offsetParent = this.offsetParent();
+
+										// Get correct offsets
+										offset = this.offset();
+										if (!jQuery.nodeName(offsetParent[0],
+												"html")) {
+											parentOffset = offsetParent
+													.offset();
+										}
+
+										// Add offsetParent borders
+										parentOffset.top += jQuery.css(
+												offsetParent[0],
+												"borderTopWidth", true);
+										parentOffset.left += jQuery.css(
+												offsetParent[0],
+												"borderLeftWidth", true);
+									}
+
+									// Subtract parent offsets and element
+									// margins
+									// note: when an element has margin: auto
+									// the offsetLeft and marginLeft
+									// are the same in Safari causing
+									// offset.left to incorrectly be 0
+									return {
+										top : offset.top
+												- parentOffset.top
+												- jQuery.css(elem, "marginTop",
+														true),
+										left : offset.left
+												- parentOffset.left
+												- jQuery.css(elem,
+														"marginLeft", true)
+									};
+								},
+
+								offsetParent : function() {
+									return this
+											.map(function() {
+												var offsetParent = this.offsetParent;
+
+												while (offsetParent
+														&& (!jQuery.nodeName(
+																offsetParent,
+																"html") && jQuery
+																.css(
+																		offsetParent,
+																		"position") === "static")) {
+													offsetParent = offsetParent.offsetParent;
+												}
+												return offsetParent
+														|| documentElement;
+											});
+								}
+							});
+
+					// Create scrollLeft and scrollTop methods
+					jQuery
+							.each(
+									{
+										scrollLeft : "pageXOffset",
+										scrollTop : "pageYOffset"
+									},
+									function(method, prop) {
+										var top = /Y/.test(prop);
+
+										jQuery.fn[method] = function(val) {
+											return access(
+													this,
+													function(elem, method, val) {
+														var win = getWindow(elem);
+
+														if (val === undefined) {
+															return win ? (prop in win) ? win[prop]
+																	: win.document.documentElement[method]
+																	: elem[method];
+														}
+
+														if (win) {
+															win
+																	.scrollTo(
+																			!top ? val
+																					: jQuery(
+																							win)
+																							.scrollLeft(),
+																			top ? val
+																					: jQuery(
+																							win)
+																							.scrollTop());
+
+														} else {
+															elem[method] = val;
+														}
+													}, method, val,
+													arguments.length, null);
+										};
+									});
+
+					// Support: Safari<7-8+, Chrome<37-44+
+					// Add the top/left cssHooks using jQuery.fn.position
+					// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
+					// getComputedStyle returns percent when specified for
+					// top/left/bottom/right
+					// rather than make the css module depend on the offset
+					// module, we just check for it here
+					jQuery
+							.each(
+									[ "top", "left" ],
+									function(i, prop) {
+										jQuery.cssHooks[prop] = addGetHookIf(
+												support.pixelPosition,
+												function(elem, computed) {
+													if (computed) {
+														computed = curCSS(elem,
+																prop);
+
+														// if curCSS returns
+														// percentage, fallback
+														// to offset
+														return rnumnonpx
+																.test(computed) ? jQuery(
+																elem)
+																.position()[prop]
+																+ "px"
+																: computed;
+													}
+												});
+									});
+
+					// Create innerHeight, innerWidth, height, width,
+					// outerHeight and outerWidth methods
+					jQuery
+							.each(
+									{
+										Height : "height",
+										Width : "width"
+									},
+									function(name, type) {
+										jQuery
+												.each(
+														{
+															padding : "inner"
+																	+ name,
+															content : type,
+															"" : "outer" + name
+														},
+														function(defaultExtra,
+																funcName) {
+
+															// margin is only
+															// for outerHeight,
+															// outerWidth
+															jQuery.fn[funcName] = function(
+																	margin,
+																	value) {
+																var chainable = arguments.length
+																		&& (defaultExtra || typeof margin !== "boolean"), extra = defaultExtra
+																		|| (margin === true
+																				|| value === true ? "margin"
+																				: "border");
+
+																return access(
+																		this,
+																		function(
+																				elem,
+																				type,
+																				value) {
+																			var doc;
+
+																			if (jQuery
+																					.isWindow(elem)) {
+
+																				// As
+																				// of
+																				// 5/8/2012
+																				// this
+																				// will
+																				// yield
+																				// incorrect
+																				// results
+																				// for
+																				// Mobile
+																				// Safari,
+																				// but
+																				// there
+																				// isn't
+																				// a
+																				// whole
+																				// lot
+																				// we
+																				// can
+																				// do.
+																				// See
+																				// pull
+																				// request
+																				// at
+																				// this
+																				// URL
+																				// for
+																				// discussion:
+																				// https://github.com/jquery/jquery/pull/764
+																				return elem.document.documentElement["client"
+																						+ name];
+																			}
+
+																			// Get
+																			// document
+																			// width
+																			// or
+																			// height
+																			if (elem.nodeType === 9) {
+																				doc = elem.documentElement;
+
+																				// Either
+																				// scroll[Width/Height]
+																				// or
+																				// offset[Width/Height]
+																				// or
+																				// client[Width/Height],
+																				// whichever
+																				// is
+																				// greatest
+																				// unfortunately,
+																				// this
+																				// causes
+																				// bug
+																				// #3838
+																				// in
+																				// IE6/8
+																				// only,
+																				// but
+																				// there
+																				// is
+																				// currently
+																				// no
+																				// good,
+																				// small
+																				// way
+																				// to
+																				// fix
+																				// it.
+																				return Math
+																						.max(
+																								elem.body["scroll"
+																										+ name],
+																								doc["scroll"
+																										+ name],
+																								elem.body["offset"
+																										+ name],
+																								doc["offset"
+																										+ name],
+																								doc["client"
+																										+ name]);
+																			}
+
+																			return value === undefined ?
+
+																			// Get
+																			// width
+																			// or
+																			// height
+																			// on
+																			// the
+																			// element,
+																			// requesting
+																			// but
+																			// not
+																			// forcing
+																			// parseFloat
+																			jQuery
+																					.css(
+																							elem,
+																							type,
+																							extra)
+																					:
+
+																					// Set
+																					// width
+																					// or
+																					// height
+																					// on
+																					// the
+																					// element
+																					jQuery
+																							.style(
+																									elem,
+																									type,
+																									value,
+																									extra);
+																		},
+																		type,
+																		chainable ? margin
+																				: undefined,
+																		chainable,
+																		null);
+															};
+														});
+									});
+
+					jQuery.fn.extend({
+
+						bind : function(types, data, fn) {
+							return this.on(types, null, data, fn);
+						},
+						unbind : function(types, fn) {
+							return this.off(types, null, fn);
+						},
+
+						delegate : function(selector, types, data, fn) {
+							return this.on(types, selector, data, fn);
+						},
+						undelegate : function(selector, types, fn) {
+
+							// ( namespace ) or ( selector, types [, fn] )
+							return arguments.length === 1 ? this.off(selector,
+									"**") : this.off(types, selector || "**",
+									fn);
+						}
+					});
+
+					// The number of elements contained in the matched element
+					// set
+					jQuery.fn.size = function() {
+						return this.length;
+					};
+
+					jQuery.fn.andSelf = jQuery.fn.addBack;
+
+					// Register as a named AMD module, since jQuery can be
+					// concatenated with other
+					// files that may use define, but not via a proper
+					// concatenation script that
+					// understands anonymous AMD modules. A named AMD is safest
+					// and most robust
+					// way to register. Lowercase jquery is used because AMD
+					// module names are
+					// derived from file names, and jQuery is normally delivered
+					// in a lowercase
+					// file name. Do this after creating the global so that if
+					// an AMD module wants
+					// to call noConflict to hide this version of jQuery, it
+					// will work.
+
+					// Note that for maximum portability, libraries that are not
+					// jQuery should
+					// declare themselves as anonymous modules, and avoid
+					// setting a global if an
+					// AMD loader is present. jQuery is a special case. For more
+					// information, see
+					// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
+
+					if (typeof define === "function" && define.amd) {
+						define("jquery", [], function() {
+							return jQuery;
+						});
+					}
+
+					var
+
+					// Map over jQuery in case of overwrite
+					_jQuery = window.jQuery,
+
+					// Map over the $ in case of overwrite
+					_$ = window.$;
+
+					jQuery.noConflict = function(deep) {
+						if (window.$ === jQuery) {
+							window.$ = _$;
+						}
+
+						if (deep && window.jQuery === jQuery) {
+							window.jQuery = _jQuery;
+						}
+
+						return jQuery;
+					};
+
+					// Expose jQuery and $ identifiers, even in
+					// AMD (#7102#comment:10,
+					// https://github.com/jquery/jquery/pull/557)
+					// and CommonJS for browser emulators (#13566)
+					if (!noGlobal) {
+						window.jQuery = window.$ = jQuery;
+					}
+
+					return jQuery;
+				}));
diff --git a/client/client-monitoring/src/main/resources/webapp/resources/16px/rowCollapsed_black_16px.svg b/client/client-monitoring/src/main/resources/webapp/resources/16px/rowCollapsed_black_16px.svg
new file mode 100644
index 0000000..6878c86
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/resources/16px/rowCollapsed_black_16px.svg
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+	<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
+]>
+<svg version="1.1"
+	 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+	 x="0px" y="0px" width="16px" height="16px" viewBox="13 2437.971 16 16" enable-background="new 13 2437.971 16 16"
+	 xml:space="preserve">
+<defs>
+</defs>
+<rect display="none" fill="#66A19F" width="87" height="3280.97"/>
+<rect x="17" y="2441.97" fill="#FFFFFF" width="7" height="7"/>
+<path d="M24.5,2440.97c-0.275,0-7.725,0-8,0s-0.5,0.225-0.5,0.5s0,7.725,0,8s0.225,0.499,0.5,0.499c0.22,0,7.78,0,8,0
+	c0.275,0,0.5-0.223,0.5-0.499s0-7.725,0-8S24.775,2440.97,24.5,2440.97z M24,2448.97h-7v-7.001h7V2448.97z"/>
+<line fill="none" stroke="#000000" stroke-miterlimit="10" x1="18" y1="2445.47" x2="23" y2="2445.47"/>
+<line fill="none" stroke="#000000" stroke-miterlimit="10" x1="20.5" y1="2447.97" x2="20.5" y2="2442.971"/>
+<rect x="13" y="2437.97" display="none" opacity="0.2" fill="#E94E47" width="16" height="16"/>
+</svg>
diff --git a/client/client-monitoring/src/main/resources/webapp/resources/16px/rowExpanded_black_16px.svg b/client/client-monitoring/src/main/resources/webapp/resources/16px/rowExpanded_black_16px.svg
new file mode 100644
index 0000000..5e3e46a
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/resources/16px/rowExpanded_black_16px.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+	<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
+]>
+<svg version="1.1"
+	 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+	 x="0px" y="0px" width="16px" height="16px" viewBox="13 2405.971 16 16" enable-background="new 13 2405.971 16 16"
+	 xml:space="preserve">
+<defs>
+</defs>
+<rect display="none" fill="#66A19F" width="87" height="3280.97"/>
+<rect x="17" y="2409.97" fill="#FFFFFF" width="7" height="7"/>
+<path d="M24.5,2408.971c-0.275,0-7.725,0-8,0s-0.5,0.225-0.5,0.5s0,7.725,0,8s0.225,0.499,0.5,0.499c0.22,0,7.78,0,8,0
+	c0.275,0,0.5-0.223,0.5-0.499s0-7.725,0-8S24.775,2408.971,24.5,2408.971z M24,2416.971h-7v-7.001h7V2416.971z"/>
+<line fill="none" stroke="#000000" stroke-miterlimit="10" x1="18" y1="2413.471" x2="23" y2="2413.471"/>
+<rect x="13" y="2405.97" display="none" opacity="0.2" fill="#E94E47" width="16" height="16"/>
+</svg>
diff --git a/client/client-monitoring/src/main/resources/webapp/resources/16px/settings_black_16px.svg b/client/client-monitoring/src/main/resources/webapp/resources/16px/settings_black_16px.svg
new file mode 100644
index 0000000..c347888
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/resources/16px/settings_black_16px.svg
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+	<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
+]>
+<svg version="1.1"
+	 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:a="http://ns.adobe.com/AdobeSVGViewerExtensions/3.0/"
+	 x="0px" y="0px" width="16px" height="16px" viewBox="13 101.971 16 16" enable-background="new 13 101.971 16 16"
+	 xml:space="preserve">
+<defs>
+</defs>
+<rect display="none" fill="#66A19F" width="87" height="3280.97"/>
+<path d="M28,110.97v-2h-2.101c-0.13-0.638-0.383-1.229-0.73-1.754l1.488-1.488l-1.414-1.414l-1.488,1.488
+	c-0.524-0.347-1.117-0.601-1.755-0.731v-2.101h-2v2.101c-0.638,0.129-1.23,0.383-1.754,0.731l-1.488-1.488l-1.414,1.414l1.488,1.488
+	c-0.347,0.524-0.601,1.116-0.731,1.754H14v2h2.101c0.13,0.638,0.384,1.23,0.731,1.755l-1.488,1.488l1.414,1.414l1.488-1.488
+	c0.524,0.347,1.116,0.601,1.754,0.73v2.101h2v-2.101c0.638-0.129,1.23-0.383,1.754-0.731l1.489,1.489l1.414-1.414l-1.489-1.489
+	c0.347-0.524,0.601-1.116,0.731-1.754H28z M21,112.47c-1.381,0-2.5-1.119-2.5-2.5s1.119-2.5,2.5-2.5s2.5,1.119,2.5,2.5
+	S22.381,112.47,21,112.47z"/>
+<rect x="13" y="101.97" display="none" opacity="0.2" fill="#E94E47" width="16" height="16"/>
+</svg>
diff --git a/client/client-monitoring/src/main/resources/webapp/resources/systemBar/help_black.svg b/client/client-monitoring/src/main/resources/webapp/resources/systemBar/help_black.svg
new file mode 100644
index 0000000..14fdf5d
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/resources/systemBar/help_black.svg
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 width="16px" height="16px" viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
+<path fill="#1D1D1B" d="M8,0C3.582,0,0,3.582,0,8s3.582,8,8,8s8-3.582,8-8S12.418,0,8,0z M8.608,12.149
+	c-0.205,0.183-0.442,0.273-0.711,0.273c-0.277,0-0.521-0.09-0.728-0.27c-0.207-0.181-0.311-0.433-0.311-0.756
+	c0-0.287,0.101-0.528,0.3-0.724c0.201-0.196,0.447-0.295,0.738-0.295c0.287,0,0.529,0.099,0.725,0.295
+	c0.196,0.195,0.295,0.437,0.295,0.724C8.917,11.717,8.813,11.967,8.608,12.149z M10.46,6.227c-0.123,0.229-0.27,0.427-0.439,0.594
+	C9.85,6.986,9.545,7.267,9.104,7.661c-0.122,0.111-0.22,0.208-0.293,0.292C8.738,8.038,8.684,8.114,8.647,8.185
+	c-0.036,0.069-0.063,0.14-0.083,0.209c-0.02,0.07-0.049,0.193-0.089,0.368C8.408,9.135,8.194,9.32,7.837,9.32
+	c-0.187,0-0.343-0.061-0.47-0.183C7.239,9.016,7.176,8.835,7.176,8.595c0-0.301,0.047-0.561,0.14-0.782
+	c0.093-0.22,0.217-0.413,0.371-0.58C7.84,7.067,8.048,6.869,8.31,6.64c0.229-0.201,0.395-0.352,0.497-0.454
+	c0.102-0.103,0.188-0.216,0.257-0.341c0.07-0.125,0.105-0.261,0.105-0.408c0-0.287-0.107-0.528-0.32-0.725S8.361,4.417,8.024,4.417
+	c-0.394,0-0.684,0.099-0.87,0.298C6.968,4.913,6.811,5.206,6.682,5.593C6.56,5.998,6.329,6.2,5.989,6.2
+	c-0.201,0-0.37-0.071-0.508-0.212C5.344,5.846,5.274,5.693,5.274,5.528c0-0.34,0.109-0.685,0.328-1.034
+	C5.82,4.146,6.14,3.856,6.559,3.627s0.907-0.344,1.466-0.344c0.52,0,0.978,0.096,1.375,0.287c0.397,0.192,0.705,0.452,0.922,0.782
+	c0.216,0.33,0.324,0.688,0.324,1.074C10.646,5.73,10.584,5.998,10.46,6.227z"/>
+</svg>
diff --git a/client/client-monitoring/src/main/resources/webapp/resources/systemBar/logout_black.svg b/client/client-monitoring/src/main/resources/webapp/resources/systemBar/logout_black.svg
new file mode 100644
index 0000000..af297ac
--- /dev/null
+++ b/client/client-monitoring/src/main/resources/webapp/resources/systemBar/logout_black.svg
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 width="16px" height="16px" viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
+<g>
+	<g>
+		<path fill="#1D1D1B" d="M10.77,12.455c0,0-0.684,0.192-0.684-0.684c0-0.199,0-0.861,0-1.711H5.98
+			c-0.377,0-0.684-0.308-0.684-0.684V6.639c0-0.377,0.307-0.684,0.684-0.684h4.106c0-0.818,0-1.475,0-1.732
+			c0-0.919,0.684-0.662,0.684-0.662l5.133,4.447L10.77,12.455z"/>
+	</g>
+	<path fill="#1D1D1B" d="M9.85,14H3.099c-0.551,0-1-0.447-1-1V3c0-0.552,0.449-1,1-1H9.85V0H3.099c-1.656,0-3,1.344-3,3v10
+		c0,1.656,1.344,3,3,3H9.85V14z"/>
+</g>
+</svg>
