summaryrefslogtreecommitdiffstats
path: root/client/client-monitoring/src
diff options
context:
space:
mode:
authorramverma <ram.krishna.verma@ericsson.com>2018-07-06 16:29:16 +0100
committerramverma <ram.krishna.verma@ericsson.com>2018-07-09 15:14:03 +0100
commit0ba667816e703344eec33bda147546b30b6bbd5b (patch)
treeda7f8e53a8ae1266717957eea7e95324cf3fe1d7 /client/client-monitoring/src
parentdcf8f703fdd07161c86231ecc4af0f25872a45f4 (diff)
Adding client monitoring module to apex-pdp
Change-Id: I6b4d00a5e49326f62f3585526ede8e89df99d7e5 Issue-ID: POLICY-864 Signed-off-by: ramverma <ram.krishna.verma@ericsson.com>
Diffstat (limited to 'client/client-monitoring/src')
-rw-r--r--client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRest.java80
-rw-r--r--client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestMain.java192
-rw-r--r--client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestParameterException.java49
-rw-r--r--client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestParameterParser.java116
-rw-r--r--client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestParameters.java115
-rw-r--r--client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ApexMonitoringRestResource.java346
-rw-r--r--client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/ParameterCheck.java211
-rw-r--r--client/client-monitoring/src/main/java/org/onap/policy/apex/client/monitoring/rest/package-info.java27
-rw-r--r--client/client-monitoring/src/main/resources/webapp/WEB-INF/web.xml42
-rw-r--r--client/client-monitoring/src/main/resources/webapp/css/apexChartLib.css74
-rw-r--r--client/client-monitoring/src/main/resources/webapp/css/interfaceAssets.css3454
-rw-r--r--client/client-monitoring/src/main/resources/webapp/css/styles.css441
-rw-r--r--client/client-monitoring/src/main/resources/webapp/index.html103
-rw-r--r--client/client-monitoring/src/main/resources/webapp/js/ApexAjax.js89
-rw-r--r--client/client-monitoring/src/main/resources/webapp/js/ApexChart.js256
-rw-r--r--client/client-monitoring/src/main/resources/webapp/js/ApexContext.js94
-rw-r--r--client/client-monitoring/src/main/resources/webapp/js/ApexEngineService.js104
-rw-r--r--client/client-monitoring/src/main/resources/webapp/js/ApexEngineStatus.js184
-rw-r--r--client/client-monitoring/src/main/resources/webapp/js/ApexEngineSummary.js152
-rw-r--r--client/client-monitoring/src/main/resources/webapp/js/ApexServicesMain.js253
-rw-r--r--client/client-monitoring/src/main/resources/webapp/js/ApexTable.js60
-rw-r--r--client/client-monitoring/src/main/resources/webapp/js/ApexUtils.js332
-rw-r--r--client/client-monitoring/src/main/resources/webapp/js/avsc/avsc.js21605
-rw-r--r--client/client-monitoring/src/main/resources/webapp/js/d3/LICENSE27
-rw-r--r--client/client-monitoring/src/main/resources/webapp/js/d3/d3.min.js5
-rw-r--r--client/client-monitoring/src/main/resources/webapp/js/jquery/jquery-1.12.4.js13201
-rw-r--r--client/client-monitoring/src/main/resources/webapp/resources/16px/rowCollapsed_black_16px.svg19
-rw-r--r--client/client-monitoring/src/main/resources/webapp/resources/16px/rowExpanded_black_16px.svg18
-rw-r--r--client/client-monitoring/src/main/resources/webapp/resources/16px/settings_black_16px.svg20
-rw-r--r--client/client-monitoring/src/main/resources/webapp/resources/systemBar/help_black.svg19
-rw-r--r--client/client-monitoring/src/main/resources/webapp/resources/systemBar/logout_black.svg15
31 files changed, 41703 insertions, 0 deletions
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 000000000..d6f7e64ad
--- /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 000000000..fcc29ed29
--- /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 000000000..cbbc2940a
--- /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 000000000..35ee6b4fa
--- /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 000000000..a1a8efc57
--- /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 000000000..84f29dfe2
--- /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 000000000..8edeb54f1
--- /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 000000000..d6c8d3c5e
--- /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 000000000..5906c2c74
--- /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 000000000..628fc0eb9
--- /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 000000000..acb8fe23b
--- /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 000000000..fcb78fb43
--- /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 000000000..bd5ce0f70
--- /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 000000000..e62489fa2
--- /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 000000000..438a3e5d9
--- /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 000000000..437d8177d
--- /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 000000000..0573dd886
--- /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 000000000..832a704f7
--- /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 000000000..8b4051467
--- /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 000000000..f22b3077c
--- /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 000000000..95e9ec1f8
--- /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 000000000..732fbfd25
--- /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 000000000..717794363
--- /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 000000000..a626880a9
--- /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 000000000..166487309
--- /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 000000000..13ca4772b
--- /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 000000000..6878c863c
--- /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 000000000..5e3e46a66
--- /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 000000000..c347888e9
--- /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 000000000..14fdf5d35
--- /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 000000000..af297acde
--- /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>