diff --git a/http/bundle/DEPENDENCIES b/http/bundle/DEPENDENCIES
index 4c1aef6..8efdfd4 100644
--- a/http/bundle/DEPENDENCIES
+++ b/http/bundle/DEPENDENCIES
@@ -7,8 +7,12 @@
 
 I. Included Third-Party Software
 
+This product includes software developed at
+Eclipse (http://eclipse.org)
+Licensed under the Apache License 2.0.
+
 This product includes software developed by
-Mortbay (http://mortbay.org)
+the cometd project (http://cometd.org)
 Licensed under the Apache License 2.0.
 
 This product includes software developed at
diff --git a/http/bundle/NOTICE b/http/bundle/NOTICE
index 7140e41..b94c364 100644
--- a/http/bundle/NOTICE
+++ b/http/bundle/NOTICE
@@ -5,8 +5,12 @@
 The Apache Software Foundation (http://www.apache.org/).
 Licensed under the Apache License 2.0.
 
+This product includes software developed at
+Eclipse (http://eclipse.org)
+Licensed under the Apache License 2.0.
+
 This product includes software developed by
-Mortbay (http://mortbay.org)
+the cometd project (http://cometd.org)
 Licensed under the Apache License 2.0.
 
 This product includes software developed at
diff --git a/http/bundle/pom.xml b/http/bundle/pom.xml
index e02fbca..896fe18 100644
--- a/http/bundle/pom.xml
+++ b/http/bundle/pom.xml
@@ -42,9 +42,12 @@
                             org.apache.felix.http.bundle.internal.CombinedActivator
                         </Bundle-Activator>
                         <Export-Package>
-                            org.apache.felix.http.api;version=2.0.4;-split-package:=merge-first,
+                            org.apache.felix.http.api;version=${project.version};-split-package:=merge-first,
+                            org.apache.felix.http.cometd;version=${project.version};-split-package:=merge-first,
                             org.osgi.service.http;version=1.2.0;-split-package:=merge-first,
-                            org.cometd;version=1.0.beta7,
+                            org.cometd.bayeux;version=2.4.2;-split-package:=merge-first,
+                            org.cometd.bayeux.client;version=2.4.2;-split-package:=merge-first,
+                            org.cometd.bayeux.server;version=2.4.2;-split-package:=merge-first,
                             javax.servlet.*;version=2.5;-split-package:=merge-first
                         </Export-Package>
                         <Private-Package>
@@ -54,11 +57,15 @@
                             org.apache.felix.http.cometd.*,
                             org.apache.felix.http.jetty.*,
                             org.apache.felix.http.whiteboard.*,
-                            org.mortbay.*;-split-package:=merge-first
+                            org.eclipse.jetty.*;-split-package:=merge-first,
+                            org.cometd.server.*;-split-package:=merge-first,
+                            org.cometd.common.*;-split-package:=merge-first
                         </Private-Package>
                         <Import-Package>
                             javax.servlet.*,
-                            org.cometd,
+                            org.cometd.bayeux,
+                            org.cometd.bayeux.client,
+                            org.cometd.bayeux.server,
                             *;resolution:=optional
                         </Import-Package>
                     </instructions>
diff --git a/http/cometd/DEPENDENCIES b/http/cometd/DEPENDENCIES
index dc4222f..b5d4162 100644
--- a/http/cometd/DEPENDENCIES
+++ b/http/cometd/DEPENDENCIES
@@ -7,8 +7,12 @@
 
 I. Included Third-Party Software
 
+This product includes software developed at
+Eclipse (http://eclipse.org)
+Licensed under the Apache License 2.0.
+
 This product includes software developed by
-Mortbay (http://mortbay.org)
+the cometd project (http://cometd.org)
 Licensed under the Apache License 2.0.
 
 This product includes software developed at
diff --git a/http/cometd/NOTICE b/http/cometd/NOTICE
index 60a7467..239ff76 100644
--- a/http/cometd/NOTICE
+++ b/http/cometd/NOTICE
@@ -5,8 +5,12 @@
 The Apache Software Foundation (http://www.apache.org/).
 Licensed under the Apache License 2.0.
 
+This product includes software developed at
+Eclipse (http://eclipse.org)
+Licensed under the Apache License 2.0.
+
 This product includes software developed by
-Mortbay (http://mortbay.org)
+the cometd project (http://cometd.org)
 Licensed under the Apache License 2.0.
 
 This product includes software developed at
diff --git a/http/cometd/pom.xml b/http/cometd/pom.xml
index 90e037f..659c5a5 100644
--- a/http/cometd/pom.xml
+++ b/http/cometd/pom.xml
@@ -43,16 +43,18 @@
                         </Bundle-Activator>
                         <Export-Package>
                             org.apache.felix.http.cometd;version=${project.version},
-                            org.cometd;version=1.1.4
+                            org.cometd.bayeux;version=2.4.2,
+                            org.cometd.bayeux.client;version=2.4.2,
+                            org.cometd.client;version=2.4.2
                         </Export-Package>
                         <Private-Package>
                             org.apache.felix.http.base.*,
                             org.apache.felix.http.cometd.internal
                         </Private-Package>
                         <Embed-Dependency>
-                            cometd-jetty;inline=true,
+                            cometd-java-server;inline=true,
+                            cometd-java-common;inline=true,
                             jetty-util;inline=true,
-                            jetty-util5;inline=true
                         </Embed-Dependency>
                     </instructions>
                 </configuration>
@@ -77,24 +79,29 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.mortbay.jetty</groupId>
+            <groupId>org.eclipse.jetty</groupId>
             <artifactId>jetty-util</artifactId>
-            <version>6.1.26</version>
+            <version>7.6.3.v20120416</version>
         </dependency>
         <dependency>
-            <groupId>org.mortbay.jetty</groupId>
-            <artifactId>jetty-util5</artifactId>
-            <version>6.1.26</version>
+        	<groupId>org.cometd.java</groupId>
+        	<artifactId>cometd-java-server</artifactId>
+        	<version>2.4.2</version>
         </dependency>
         <dependency>
-            <groupId>org.mortbay.jetty</groupId>
-            <artifactId>cometd-jetty</artifactId>
-            <version>6.1.15</version>
-        </dependency>
+        	<groupId>org.cometd.java</groupId>
+        	<artifactId>cometd-java-client</artifactId>
+        	<version>2.4.2</version>
+        </dependency>        
+        <dependency>
+        	<groupId>org.cometd.java</groupId>
+        	<artifactId>cometd-java-common</artifactId>
+        	<version>2.4.2</version>
+        </dependency>            
         <dependency>
             <groupId>org.cometd.java</groupId>
-            <artifactId>cometd-api</artifactId>
-            <version>1.1.4</version>
+            <artifactId>bayeux-api</artifactId>
+            <version>2.4.2</version>
         </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
diff --git a/http/cometd/src/main/java/org/apache/felix/http/cometd/CometdService.java b/http/cometd/src/main/java/org/apache/felix/http/cometd/CometdService.java
index b55df45..fc5c90b 100644
--- a/http/cometd/src/main/java/org/apache/felix/http/cometd/CometdService.java
+++ b/http/cometd/src/main/java/org/apache/felix/http/cometd/CometdService.java
@@ -17,10 +17,11 @@
 package org.apache.felix.http.cometd;
 
 import javax.servlet.ServletException;
-import org.cometd.Bayeux;
+
+import org.cometd.bayeux.server.BayeuxServer;
 
 public interface CometdService
 {
-    public Bayeux getBayeux()
+    public BayeuxServer getBayeuxServer()
         throws ServletException;
 }
diff --git a/http/cometd/src/main/java/org/apache/felix/http/cometd/internal/CometdServiceImpl.java b/http/cometd/src/main/java/org/apache/felix/http/cometd/internal/CometdServiceImpl.java
index 3dd832e..acdaa45 100644
--- a/http/cometd/src/main/java/org/apache/felix/http/cometd/internal/CometdServiceImpl.java
+++ b/http/cometd/src/main/java/org/apache/felix/http/cometd/internal/CometdServiceImpl.java
@@ -16,24 +16,25 @@
  */
 package org.apache.felix.http.cometd.internal;
 
-import org.apache.felix.http.cometd.CometdService;
-import org.apache.felix.http.base.internal.logger.SystemLogger;
-import org.cometd.Bayeux;
-import org.mortbay.cometd.continuation.ContinuationCometdServlet;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Properties;
 
-import org.osgi.service.cm.ManagedService;
-import org.osgi.service.http.HttpService;
+import javax.servlet.http.HttpServlet;
+
+import org.apache.felix.http.base.internal.logger.SystemLogger;
+import org.apache.felix.http.cometd.CometdService;
+import org.cometd.bayeux.server.BayeuxServer;
+import org.cometd.server.CometdServlet;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ManagedService;
+import org.osgi.service.http.HttpService;
 import org.osgi.util.tracker.ServiceTracker;
 import org.osgi.util.tracker.ServiceTrackerCustomizer;
 
-import java.util.Properties;
-import java.util.Dictionary;
-import javax.servlet.http.HttpServlet;
-
 public final class CometdServiceImpl
     extends HttpServlet
     implements ManagedService, ServiceTrackerCustomizer, CometdService
@@ -46,7 +47,7 @@
     private ServiceRegistration configServiceReg;
     private ServiceTracker httpServiceTracker;
     private ServiceRegistration cometdServiceReg;
-    private ContinuationCometdServlet continuationCometdServlet;
+    private CometdServlet continuationCometdServlet;
 
     public CometdServiceImpl(BundleContext context)
     {
@@ -109,10 +110,12 @@
 
     private void register(HttpService httpService) {
         if (this.continuationCometdServlet == null) {
-            this.continuationCometdServlet = new ContinuationCometdServlet();
+            this.continuationCometdServlet = new CometdServlet();
         }
         try {
-          httpService.registerServlet(this.config.getPath(), this.continuationCometdServlet, null, null);
+          Dictionary dictionary = new Hashtable();
+          dictionary.put("requestAvailable","true");
+          httpService.registerServlet(this.config.getPath(), this.continuationCometdServlet, dictionary, null);
         }
         catch (Exception e) {
           SystemLogger.error("Failed to register ContinuationCometdServlet to " + this.config.getPath(), e);
@@ -129,7 +132,7 @@
         }
     }
 
-    public Bayeux getBayeux() {
+    public BayeuxServer getBayeuxServer() {
         return this.continuationCometdServlet.getBayeux();
     }
 }
diff --git a/http/jetty/pom.xml b/http/jetty/pom.xml
index e66face..45d9df3 100644
--- a/http/jetty/pom.xml
+++ b/http/jetty/pom.xml
@@ -49,7 +49,7 @@
                         <Private-Package>
                             org.apache.felix.http.base.*,
                             org.apache.felix.http.jetty.*,
-                            org.mortbay.*;-split-package:=merge-first                            
+                            org.eclipse.*;-split-package:=merge-first        
                         </Private-Package>
                         <Import-Package>
                             javax.net.ssl; javax.security.cert;
@@ -83,24 +83,29 @@
             <artifactId>servlet-api</artifactId>
         </dependency>
         <dependency>
-            <groupId>org.mortbay.jetty</groupId>
-            <artifactId>jetty</artifactId>
-            <version>6.1.24</version>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-servlet</artifactId>
+            <version>7.6.3.v20120416</version>
         </dependency>
         <dependency>
-            <groupId>org.mortbay.jetty</groupId>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-server</artifactId>
+            <version>7.6.3.v20120416</version>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse.jetty</groupId>
             <artifactId>jetty-util</artifactId>
-            <version>6.1.24</version>
+            <version>7.6.3.v20120416</version>
         </dependency>
         <dependency>
-            <groupId>org.mortbay.jetty</groupId>
-            <artifactId>jetty-management</artifactId>
-            <version>6.1.24</version>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-jmx</artifactId>
+            <version>7.6.3.v20120416</version>
         </dependency>
         <dependency>
-            <groupId>org.mortbay.jetty</groupId>
-            <artifactId>jetty-sslengine</artifactId>
-            <version>6.1.24</version>
+            <groupId>org.eclipse.jetty</groupId>
+            <artifactId>jetty-security</artifactId>
+            <version>7.6.3.v20120416</version>
         </dependency>
         <dependency>
             <groupId>org.apache.felix</groupId>
diff --git a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
index 6a642f0..8091832 100644
--- a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
+++ b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyConfig.java
@@ -16,13 +16,14 @@
  */
 package org.apache.felix.http.jetty.internal;
 
-import org.osgi.framework.BundleContext;
 import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.Hashtable;
 import java.util.Map;
 import java.util.Properties;
-import java.util.Hashtable;
+
+import org.osgi.framework.BundleContext;
 
 public final class JettyConfig
 {
@@ -112,7 +113,6 @@
     private boolean useHttpsNio;
     private boolean registerMBeans;
     private int sessionTimeout;
-    private int headerBufferSize;
     private int requestBufferSize;
     private int responseBufferSize;
     private String contextPath;
@@ -232,11 +232,6 @@
         return this.sessionTimeout;
     }
 
-    public int getHeaderBufferSize()
-    {
-        return this.headerBufferSize;
-    }
-
     public int getRequestBufferSize()
     {
         return this.requestBufferSize;
@@ -280,7 +275,6 @@
         this.useHttpsNio = getBooleanProperty(props, FELIX_HTTPS_NIO, this.useHttpNio);
         this.registerMBeans = getBooleanProperty(props, FELIX_HTTP_MBEANS, false);
         this.sessionTimeout = getIntProperty(props, FELIX_SESSION_TIMEOUT, 0);
-        this.headerBufferSize = getIntProperty(FELIX_JETTY_HEADER_BUFFER_SIZE, 16 * 1024);
         this.requestBufferSize = getIntProperty(FELIX_JETTY_REQUEST_BUFFER_SIZE, 8 * 014);
         this.responseBufferSize = getIntProperty(FELIX_JETTY_RESPONSE_BUFFER_SIZE, 24 * 1024);
         this.contextPath = validateContextPath(getProperty(props, FELIX_HTTP_CONTEXT_PATH, null));
diff --git a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyLogger.java b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyLogger.java
index 02d73f6..4f89666 100644
--- a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyLogger.java
+++ b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyLogger.java
@@ -16,11 +16,10 @@
  */
 package org.apache.felix.http.jetty.internal;
 
-import org.mortbay.log.Logger;
-import org.mortbay.log.Log;
+import java.text.MessageFormat;
+
 import org.apache.felix.http.base.internal.logger.SystemLogger;
-import java.io.PrintStream;
-import java.io.ByteArrayOutputStream;
+import org.eclipse.jetty.util.log.Logger;
 
 public final class JettyLogger
     implements Logger
@@ -30,7 +29,7 @@
 
     public JettyLogger()
     {
-        this("org.mortbay.log");
+        this("org.eclipse.jetty.log");
     }
 
     public JettyLogger(String name)
@@ -55,69 +54,57 @@
         this.debugEnabled = enabled;
     }
 
-    public void debug(String msg, Throwable cause)
-    {
-        if (this.debugEnabled) {
-            SystemLogger.debug(msg);
-        }
-    }
+	public void debug(Throwable throwable) {
+		if (this.debugEnabled) {
+			SystemLogger.debug(throwable.getMessage());
+		}
+		
+	}
 
-    public void debug(String msg, Object arg0, Object arg1)
-    {
-        if (this.debugEnabled) {
-            SystemLogger.debug(format(msg, arg0, arg1));
-        }
-    }
+	public void debug(String msg, Object... args) {
+		if (this.debugEnabled) {
+			SystemLogger.debug(MessageFormat.format(msg, args));
+		}
+	}
 
-    public void info(String msg, Object arg0, Object arg1)
-    {
-        // Classify all info messages as debug messages.
-        // Jetty uses way to much verbose info messages.
-        if (this.debugEnabled) {
-            SystemLogger.info(format(msg, arg0, arg1));
-        }
-    }
+	public void debug(String msg, Throwable throwable) {
+		if (this.debugEnabled) {
+			SystemLogger.debug(msg + ": " + throwable.getMessage());
+		}
+	}
 
-    public void warn(String msg, Throwable cause)
-    {
-        SystemLogger.warning(msg, cause);
-    }
+	public String getName() {
+		return name;
+	}
 
-    public void warn( String msg, Object arg0, Object arg1 )
-    {
-        SystemLogger.warning(format(msg, arg0, arg1), null);
-    }
+	public void ignore(Throwable throwable) {
+		
+	}
 
-    public String toString()
-    {
-        return this.name;
-    }
+	public void info(Throwable throwable) {
+		SystemLogger.info(throwable.getMessage());
+	}
 
-    private String format(String msg, Object arg0, Object arg1)
-    {
-        int i0 = msg.indexOf("{}");
-        int i1 = i0 < 0 ? -1 : msg.indexOf("{}", i0 + 2);
+	public void info(String msg, Object... args) {
+		SystemLogger.info(MessageFormat.format(msg, args));
+		
+	}
 
-        if (arg1 != null && i1 >= 0) {
-            msg = msg.substring(0, i1) + arg1 + msg.substring(i1 + 2);
-        }
+	public void info(String msg, Throwable throwable) {
+		SystemLogger.info(msg + ": " + throwable.getMessage());
+	}
 
-        if (arg0 != null && i0 >= 0) {
-            msg = msg.substring(0, i0) + arg0 + msg.substring(i0 + 2);
-        }
+	public void warn(Throwable throwable) {
+		SystemLogger.warning(null, throwable);
+	}
 
-        return msg;
-    }
+	public void warn(String msg, Object... args) {
+		SystemLogger.warning(MessageFormat.format(msg, args), null);
+		
+	}
 
-    public static void init()
-    {
-        PrintStream out = System.err;
+	public void warn(String msg, Throwable throwable) {
+		SystemLogger.warning(msg, throwable);
+	}
 
-        try {
-            System.setErr(new PrintStream(new ByteArrayOutputStream()));
-            Log.setLog(new JettyLogger());
-        } finally {
-            System.setErr(out);
-        }
-    }
 }
diff --git a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
index ce36439..c8c1e44 100644
--- a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
+++ b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
@@ -24,17 +24,17 @@
 import org.apache.felix.http.base.internal.EventDispatcher;
 import org.apache.felix.http.base.internal.HttpServiceController;
 import org.apache.felix.http.base.internal.logger.SystemLogger;
-import org.mortbay.jetty.Connector;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.SessionManager;
-import org.mortbay.jetty.bio.SocketConnector;
-import org.mortbay.jetty.handler.StatisticsHandler;
-import org.mortbay.jetty.nio.SelectChannelConnector;
-import org.mortbay.jetty.security.HashUserRealm;
-import org.mortbay.jetty.security.SslSelectChannelConnector;
-import org.mortbay.jetty.security.SslSocketConnector;
-import org.mortbay.jetty.servlet.Context;
-import org.mortbay.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.security.HashLoginService;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.SessionManager;
+import org.eclipse.jetty.server.bio.SocketConnector;
+import org.eclipse.jetty.server.handler.StatisticsHandler;
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
+import org.eclipse.jetty.server.ssl.SslSocketConnector;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
@@ -69,8 +69,6 @@
     public void start()
         throws Exception
     {
-        JettyLogger.init();
-
         Properties props = new Properties();
         props.put(Constants.SERVICE_PID, PID);
         this.configServiceReg = this.context.registerService("org.osgi.service.cm.ManagedService",
@@ -150,13 +148,13 @@
         if (this.config.isUseHttp() || this.config.isUseHttps())
         {
             StringBuffer message = new StringBuffer("Started jetty ").append(Server.getVersion()).append(" at port(s)");
-            HashUserRealm realm = new HashUserRealm("OSGi HTTP Service Realm");
+            HashLoginService realm = new HashLoginService("OSGi HTTP Service Realm");
             this.server = new Server();
 
             // HTTP/1.1 requires Date header if possible (it is)
             this.server.setSendDateHeader(true);
 
-            this.server.addUserRealm(realm);
+            this.server.addBean(realm);
 
             if (this.config.isUseHttp())
             {
@@ -170,7 +168,8 @@
                 message.append(" HTTPS:").append(this.config.getHttpsPort());
             }
 
-            Context context = new Context(this.server, this.config.getContextPath(), Context.SESSIONS);
+            ServletContextHandler context = new ServletContextHandler(this.server, "/", ServletContextHandler.SESSIONS);
+            
             message.append(" on context path ").append(this.config.getContextPath());
             configureSessionManager(context);
             context.addEventListener(eventDispatcher);
@@ -181,7 +180,7 @@
             {
                 this.mbeanServerTracker = new MBeanServerTracker(this.context, this.server);
                 this.mbeanServerTracker.open();
-                context.addHandler(new StatisticsHandler());
+                context.addBean(new StatisticsHandler());
             }
 
             this.server.start();
@@ -307,7 +306,6 @@
     private void configureConnector(final Connector connector)
     {
         connector.setMaxIdleTime(this.config.getHttpTimeout());
-        connector.setHeaderBufferSize(this.config.getHeaderBufferSize());
         connector.setRequestBufferSize(this.config.getRequestBufferSize());
         connector.setResponseBufferSize(this.config.getResponseBufferSize());
         connector.setHost(this.config.getHost());
@@ -318,14 +316,14 @@
         // connector.setResponseBufferSize(responseBufferSize);
     }
 
-    private void configureSessionManager(final Context context)
+    private void configureSessionManager(final ServletContextHandler context)
     {
         final SessionManager manager = context.getSessionHandler().getSessionManager();
 
         manager.setMaxInactiveInterval(this.config.getSessionTimeout() * 60);
 
         manager.setSessionCookie(this.config.getProperty(SessionManager.__SessionCookieProperty, SessionManager.__DefaultSessionCookie));
-        manager.setSessionURL(this.config.getProperty(SessionManager.__SessionURLProperty, SessionManager.__DefaultSessionURL));
+        manager.setSessionIdPathParameterName(this.config.getProperty(SessionManager.__SessionIdPathParameterNameProperty, SessionManager.__DefaultSessionIdPathParameterName));
         manager.setSessionDomain(this.config.getProperty(SessionManager.__SessionDomainProperty, SessionManager.__DefaultSessionDomain));
         manager.setSessionPath(this.config.getProperty(SessionManager.__SessionPathProperty, context.getContextPath()));
         manager.setMaxCookieAge(this.config.getIntProperty(SessionManager.__MaxAgeProperty, -1));
diff --git a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/MBeanServerTracker.java b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/MBeanServerTracker.java
index 203155d..be0b16e 100644
--- a/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/MBeanServerTracker.java
+++ b/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/MBeanServerTracker.java
@@ -20,8 +20,8 @@
 
 import javax.management.MBeanServer;
 
-import org.mortbay.jetty.Server;
-import org.mortbay.management.MBeanContainer;
+import org.eclipse.jetty.jmx.MBeanContainer;
+import org.eclipse.jetty.server.Server;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.osgi.util.tracker.ServiceTracker;
diff --git a/http/samples/cometd/DEPENDENCIES b/http/samples/cometd/DEPENDENCIES
index ccacee9..292422e 100644
--- a/http/samples/cometd/DEPENDENCIES
+++ b/http/samples/cometd/DEPENDENCIES
@@ -7,7 +7,9 @@
 
 I. Included Third-Party Software
 
-N/A
+This product includes software developed by
+the cometd project (http://cometd.org)
+Licensed under the Apache License 2.0.
 
 II. Used Third-Party Software
 
diff --git a/http/samples/cometd/NOTICE b/http/samples/cometd/NOTICE
index 32f0c55..9c09aa8 100644
--- a/http/samples/cometd/NOTICE
+++ b/http/samples/cometd/NOTICE
@@ -4,3 +4,11 @@
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
 Licensed under the Apache License 2.0.
+
+This product includes software developed by
+the cometd project (http://cometd.org)
+Licensed under the Apache License 2.0.
+
+This product includes software developed by
+the cometd project (http://cometd.org)
+Licensed under the  academic free license 1.2 or new BSD license.
\ No newline at end of file
diff --git a/http/samples/cometd/academic-2.1.txt b/http/samples/cometd/academic-2.1.txt
new file mode 100644
index 0000000..7c5ee34
--- /dev/null
+++ b/http/samples/cometd/academic-2.1.txt
@@ -0,0 +1,153 @@
+The Academic Free License, v. 2.1 (for cometd.dojox):
+**********************************
+
+This Academic Free License (the "License") applies to any original work of
+authorship (the "Original Work") whose owner (the "Licensor") has placed the
+following notice immediately following the copyright notice for the Original
+Work:
+
+Licensed under the Academic Free License version 2.1
+
+1) Grant of Copyright License. Licensor hereby grants You a world-wide,
+royalty-free, non-exclusive, perpetual, sublicenseable license to do the
+following:
+
+a) to reproduce the Original Work in copies;
+
+b) to prepare derivative works ("Derivative Works") based upon the Original
+Work;
+
+c) to distribute copies of the Original Work and Derivative Works to the
+public;
+
+d) to perform the Original Work publicly; and
+
+e) to display the Original Work publicly.
+
+2) Grant of Patent License. Licensor hereby grants You a world-wide,
+royalty-free, non-exclusive, perpetual, sublicenseable license, under patent
+claims owned or controlled by the Licensor that are embodied in the Original
+Work as furnished by the Licensor, to make, use, sell and offer for sale the
+Original Work and Derivative Works.
+
+3) Grant of Source Code License. The term "Source Code" means the preferred
+form of the Original Work for making modifications to it and all available
+documentation describing how to modify the Original Work. Licensor hereby
+agrees to provide a machine-readable copy of the Source Code of the Original
+Work along with each copy of the Original Work that Licensor distributes.
+Licensor reserves the right to satisfy this obligation by placing a
+machine-readable copy of the Source Code in an information repository
+reasonably calculated to permit inexpensive and convenient access by You for as
+long as Licensor continues to distribute the Original Work, and by publishing
+the address of that information repository in a notice immediately following
+the copyright notice that applies to the Original Work.
+
+4) Exclusions From License Grant. Neither the names of Licensor, nor the names
+of any contributors to the Original Work, nor any of their trademarks or
+service marks, may be used to endorse or promote products derived from this
+Original Work without express prior written permission of the Licensor. Nothing
+in this License shall be deemed to grant any rights to trademarks, copyrights,
+patents, trade secrets or any other intellectual property of Licensor except as
+expressly stated herein. No patent license is granted to make, use, sell or
+offer to sell embodiments of any patent claims other than the licensed claims
+defined in Section 2. No right is granted to the trademarks of Licensor even if
+such marks are included in the Original Work. Nothing in this License shall be
+interpreted to prohibit Licensor from licensing under different terms from this
+License any Original Work that Licensor otherwise would have a right to
+license.
+
+5) This section intentionally omitted.
+
+6) Attribution Rights. You must retain, in the Source Code of any Derivative
+Works that You create, all copyright, patent or trademark notices from the
+Source Code of the Original Work, as well as any notices of licensing and any
+descriptive text identified therein as an "Attribution Notice." You must cause
+the Source Code for any Derivative Works that You create to carry a prominent
+Attribution Notice reasonably calculated to inform recipients that You have
+modified the Original Work.
+
+7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that
+the copyright in and to the Original Work and the patent rights granted herein
+by Licensor are owned by the Licensor or are sublicensed to You under the terms
+of this License with the permission of the contributor(s) of those copyrights
+and patent rights. Except as expressly stated in the immediately proceeding
+sentence, the Original Work is provided under this License on an "AS IS" BASIS
+and WITHOUT WARRANTY, either express or implied, including, without limitation,
+the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU.
+This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No
+license to Original Work is granted hereunder except under this disclaimer.
+
+8) Limitation of Liability. Under no circumstances and under no legal theory,
+whether in tort (including negligence), contract, or otherwise, shall the
+Licensor be liable to any person for any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License
+or the use of the Original Work including, without limitation, damages for loss
+of goodwill, work stoppage, computer failure or malfunction, or any and all
+other commercial damages or losses. This limitation of liability shall not
+apply to liability for death or personal injury resulting from Licensor's
+negligence to the extent applicable law prohibits such limitation. Some
+jurisdictions do not allow the exclusion or limitation of incidental or
+consequential damages, so this exclusion and limitation may not apply to You.
+
+9) Acceptance and Termination. If You distribute copies of the Original Work or
+a Derivative Work, You must make a reasonable effort under the circumstances to
+obtain the express assent of recipients to the terms of this License. Nothing
+else but this License (or another written agreement between Licensor and You)
+grants You permission to create Derivative Works based upon the Original Work
+or to exercise any of the rights granted in Section 1 herein, and any attempt
+to do so except under the terms of this License (or another written agreement
+between Licensor and You) is expressly prohibited by U.S. copyright law, the
+equivalent laws of other countries, and by international treaty. Therefore, by
+exercising any of the rights granted to You in Section 1 herein, You indicate
+Your acceptance of this License and all of its terms and conditions.
+
+10) Termination for Patent Action. This License shall terminate automatically
+and You may no longer exercise any of the rights granted to You by this License
+as of the date You commence an action, including a cross-claim or counterclaim,
+against Licensor or any licensee alleging that the Original Work infringes a
+patent. This termination provision shall not apply for an action alleging
+patent infringement by combinations of the Original Work with other software or
+hardware.
+
+11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this
+License may be brought only in the courts of a jurisdiction wherein the
+Licensor resides or in which Licensor conducts its primary business, and under
+the laws of that jurisdiction excluding its conflict-of-law provisions. The
+application of the United Nations Convention on Contracts for the International
+Sale of Goods is expressly excluded. Any use of the Original Work outside the
+scope of this License or after its termination shall be subject to the
+requirements and penalties of the U.S. Copyright Act, 17 U.S.C. Â§ 101 et
+seq., the equivalent laws of other countries, and international treaty. This
+section shall survive the termination of this License.
+
+12) Attorneys Fees. In any action to enforce the terms of this License or
+seeking damages relating thereto, the prevailing party shall be entitled to
+recover its costs and expenses, including, without limitation, reasonable
+attorneys' fees and costs incurred in connection with such action, including
+any appeal of such action. This section shall survive the termination of this
+License.
+
+13) Miscellaneous. This License represents the complete agreement concerning
+the subject matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent necessary to
+make it enforceable.
+
+14) Definition of "You" in This License. "You" throughout this License, whether
+in upper or lower case, means an individual or a legal entity exercising rights
+under, and complying with all of the terms of, this License. For legal
+entities, "You" includes any entity that controls, is controlled by, or is
+under common control with you. For purposes of this definition, "control" means
+(i) the power, direct or indirect, to cause the direction or management of such
+entity, whether by contract or otherwise, or (ii) ownership of fifty percent
+(50%) or more of the outstanding shares, or (iii) beneficial ownership of such
+entity.
+
+15) Right to Use. You may use the Original Work in all ways not otherwise
+restricted or conditioned by this License or by law, and Licensor promises not
+to interfere with or be responsible for such uses by You.
+
+This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved.
+Permission is hereby granted to copy and distribute this license without
+modification. This license may not be modified without the express written
+permission of its copyright owner.
diff --git a/http/samples/cometd/new_bsd.txt b/http/samples/cometd/new_bsd.txt
new file mode 100644
index 0000000..2957312
--- /dev/null
+++ b/http/samples/cometd/new_bsd.txt
@@ -0,0 +1,29 @@
+The "New" BSD License (for cometd.dojox):
+**********************
+
+Copyright (c) 2005-2009, The Dojo Foundation
+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 Dojo Foundation nor the names of its 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.
+
diff --git a/http/samples/cometd/pom.xml b/http/samples/cometd/pom.xml
index f650fbd..fe24221 100644
--- a/http/samples/cometd/pom.xml
+++ b/http/samples/cometd/pom.xml
@@ -47,6 +47,10 @@
                         <Import-Package>
                             *;resolution:=optional
                         </Import-Package>
+                        <Include-Resource>
+                        	{maven-resources}, {maven-dependencies},
+                        	src-web=src-web
+                        </Include-Resource>
                     </instructions>
                 </configuration>
             </plugin>
diff --git a/http/samples/cometd/src-web/dojo/dojo.js b/http/samples/cometd/src-web/dojo/dojo.js
new file mode 100644
index 0000000..9f5f7d5
--- /dev/null
+++ b/http/samples/cometd/src-web/dojo/dojo.js
@@ -0,0 +1,15 @@
+/*
+	Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+	Available via Academic Free License >= 2.1 OR the modified BSD license.
+	see: http://dojotoolkit.org/license for details
+*/
+
+/*
+	This is an optimized version of Dojo, built for deployment and not for
+	development. To get sources and documentation, please visit:
+
+		http://dojotoolkit.org
+*/
+
+//>>built
+(function(_1,_2){var _3=function(){},_4=function(it){for(var p in it){return 0;}return 1;},_5={}.toString,_6=function(it){return _5.call(it)=="[object Function]";},_7=function(it){return _5.call(it)=="[object String]";},_8=function(it){return _5.call(it)=="[object Array]";},_9=function(_a,_b){if(_a){for(var i=0;i<_a.length;){_b(_a[i++]);}}},_c=function(_d,_e){for(var p in _e){_d[p]=_e[p];}return _d;},_f=function(_10,_11){return _c(new Error(_10),{src:"dojoLoader",info:_11});},_12=1,uid=function(){return "_"+_12++;},req=function(_13,_14,_15){return _16(_13,_14,_15,0,req);},_17=this,doc=_17.document,_18=doc&&doc.createElement("DiV"),has=req.has=function(_19){return _6(_1a[_19])?(_1a[_19]=_1a[_19](_17,doc,_18)):_1a[_19];},_1a=has.cache=_2.hasCache;has.add=function(_1b,_1c,now,_1d){(_1a[_1b]===undefined||_1d)&&(_1a[_1b]=_1c);return now&&has(_1b);};false&&has.add("host-node",typeof process=="object"&&/node(\.exe)?$/.test(process.execPath));if(0){require("./_base/configNode.js").config(_2);_2.loaderPatch.nodeRequire=require;}false&&has.add("host-rhino",typeof load=="function"&&(typeof Packages=="function"||typeof Packages=="object"));if(0){for(var _1e=_1.baseUrl||".",arg,_1f=this.arguments,i=0;i<_1f.length;){arg=(_1f[i++]+"").split("=");if(arg[0]=="baseUrl"){_1e=arg[1];break;}}load(_1e+"/_base/configRhino.js");rhinoDojoConfig(_2,_1e,_1f);}for(var p in _1.has){has.add(p,_1.has[p],0,1);}var _20=1,_21=2,_22=3,_23=4,_24=5;if(0){_20="requested";_21="arrived";_22="not-a-module";_23="executing";_24="executed";}var _25=0,_26="sync",xd="xd",_27=[],_28=0,_29=_3,_2a=_3,_2b;if(1){req.isXdUrl=_3;req.initSyncLoader=function(_2c,_2d,_2e){if(!_28){_28=_2c;_29=_2d;_2a=_2e;}return {sync:_26,xd:xd,arrived:_21,nonmodule:_22,executing:_23,executed:_24,syncExecStack:_27,modules:_2f,execQ:_30,getModule:_31,injectModule:_32,setArrived:_33,signal:_34,finishExec:_35,execModule:_36,dojoRequirePlugin:_28,getLegacyMode:function(){return _25;},holdIdle:function(){_74++;},releaseIdle:function(){_37();}};};if(1){var _38=location.protocol,_39=location.host,_3a=!_39;req.isXdUrl=function(url){if(_3a||/^\./.test(url)){return false;}if(/^\/\//.test(url)){return true;}var _3b=url.match(/^([^\/\:]+\:)\/\/([^\/]+)/);return _3b&&(_3b[1]!=_38||_3b[2]!=_39);};true||has.add("dojo-xhr-factory",1);has.add("dojo-force-activex-xhr",1&&!doc.addEventListener&&window.location.protocol=="file:");has.add("native-xhr",typeof XMLHttpRequest!="undefined");if(has("native-xhr")&&!has("dojo-force-activex-xhr")){_2b=function(){return new XMLHttpRequest();};}else{for(var _3c=["Msxml2.XMLHTTP","Microsoft.XMLHTTP","Msxml2.XMLHTTP.4.0"],_3d,i=0;i<3;){try{_3d=_3c[i++];if(new ActiveXObject(_3d)){break;}}catch(e){}}_2b=function(){return new ActiveXObject(_3d);};}req.getXhr=_2b;has.add("dojo-gettext-api",1);req.getText=function(url,_3e,_3f){var xhr=_2b();xhr.open("GET",_40(url),false);xhr.send(null);if(xhr.status==200||(!location.host&&!xhr.status)){if(_3f){_3f(xhr.responseText,_3e);}}else{throw _f("xhrFailed",xhr.status);}return xhr.responseText;};}}else{req.async=1;}var _41=new Function("__text","return eval(__text);");req.eval=function(_42,_43){return _41(_42+"\r\n////@ sourceURL="+_43);};var _44={},_45="error",_34=req.signal=function(_46,_47){var _48=_44[_46];_9(_48&&_48.slice(0),function(_49){_49.apply(null,_8(_47)?_47:[_47]);});},on=req.on=function(_4a,_4b){var _4c=_44[_4a]||(_44[_4a]=[]);_4c.push(_4b);return {remove:function(){for(var i=0;i<_4c.length;i++){if(_4c[i]===_4b){_4c.splice(i,1);return;}}}};};var _4d=[],_4e={},_4f=[],_50={},_51={},_52=[],_2f={},_53="",_54={},_55={},_56={};if(1){var _57=function(_58){for(var p in _55){var _59=p.match(/^url\:(.+)/);if(_59){_54[_5a(_59[1],_58)]=_55[p];}else{if(p!="*noref"){_54[_5b(p,_58).mid]=_55[p];}}}_55={};},_5c=function(map,_5d,_5e){_5d.splice(0,_5d.length);var p,i,_5f,_60=0;for(p in map){_5d.push([p,map[p]]);if(map[p]==_5e){_60=p;}}_5d.sort(function(lhs,rhs){return rhs[0].length-lhs[0].length;});for(i=0;i<_5d.length;){_5f=_5d[i++];_5f[2]=new RegExp("^"+_5f[0].replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g,function(c){return "\\"+c;})+"(/|$)");_5f[3]=_5f[0].length+1;}return _60;},_61=function(_62,_63){var _64=_62.name;if(!_64){_64=_62;_62={name:_64};}_62=_c({main:"main",mapProg:[]},_62);_62.location=(_63||"")+(_62.location?_62.location:_64);_62.reverseName=_5c(_62.packageMap,_62.mapProg,_64);if(!_62.main.indexOf("./")){_62.main=_62.main.substring(2);}_c(_4e,_62.paths);_50[_64]=_62;_51[_64]=_64;},_65=function(_66,_67){for(var p in _66){if(p=="waitSeconds"){req.waitms=(_66[p]||0)*1000;}if(p=="cacheBust"){_53=_66[p]?(_7(_66[p])?_66[p]:(new Date()).getTime()+""):"";}if(p=="baseUrl"||p=="combo"){req[p]=_66[p];}if(1&&p=="async"){var _68=_66[p];req.legacyMode=_25=(_7(_68)&&/sync|legacyAsync/.test(_68)?_68:(!_68?"sync":false));req.async=!_25;}if(_66[p]!==_1a){req.rawConfig[p]=_66[p];p!="has"&&has.add("config-"+p,_66[p],0,_67);}}if(!req.baseUrl){req.baseUrl="./";}if(!/\/$/.test(req.baseUrl)){req.baseUrl+="/";}for(p in _66.has){has.add(p,_66.has[p],0,_67);}_9(_66.packages,_61);for(_1e in _66.packagePaths){_9(_66.packagePaths[_1e],function(_69){_61(_69,_1e+"/");});}_5c(_c(_4e,_66.paths),_4f);_9(_66.aliases,function(_6a){if(_7(_6a[0])){_6a[0]=new RegExp("^"+_6a[0].replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g,function(c){return "\\"+c;})+"$");}_4d.push(_6a);});_5c(_c(_51,_66.packageMap),_52);if(_66.cache){_57();_55=_66.cache;if(_66.cache["*noref"]){_57();}}_34("config",[_66,req.rawConfig]);};if(has("dojo-cdn")||1){for(var _6b,src,_6c,_6d=doc.getElementsByTagName("script"),i=0;i<_6d.length&&!_6c;i++){if((src=_6d[i].getAttribute("src"))&&(_6c=src.match(/(.*)\/?dojo\.js(\W|$)/i))){_1.baseUrl=_6b=_1.baseUrl||_2.baseUrl||_6c[1];src=(_6d[i].getAttribute("data-dojo-config")||_6d[i].getAttribute("djConfig"));if(src){_56=req.eval("({ "+src+" })","data-dojo-config");}if(0){var _6e=_6d[i].getAttribute("data-main");if(_6e){_56.deps=_56.deps||[_6e];}}}}}if(0){try{if(window.parent!=window&&window.parent.require){var doh=window.parent.require("doh");doh&&_c(_56,doh.testConfig);}}catch(e){}}req.rawConfig={};_65(_2,1);_65(_1,1);_65(_56,1);if(has("dojo-cdn")){_50.dojo.location=_6b;_50.dijit.location=_6b+"../dijit/";_50.dojox.location=_6b+"../dojox/";}}else{_4e=_2.paths;_4f=_2.pathsMapProg;_50=_2.packs;_4d=_2.aliases;_51=_2.packageMap;_52=_2.packageMapProg;_2f=_2.modules;_54=_2.cache;_53=_2.cacheBust;req.rawConfig=_2;}if(0){req.combo=req.combo||{add:_3};var _6f=0,_70=[],_71=null;}var _72=function(_73){_74++;_9(_73.deps,_32);if(0&&_6f&&!_71){_71=setTimeout(function(){_6f=0;_71=null;req.combo.done(function(_75,url){var _76=function(){_77(0,_75);_78();};_70.push(_75);_79=_75;req.injectUrl(url,_76,_75);_79=0;},req);},0);}_37();},_16=function(a1,a2,a3,_7a,_7b){var _7c,_7d;if(_7(a1)){_7c=_31(a1,_7a,true);if(_7c&&_7c.executed){return _7c.result;}throw _f("undefinedModule",a1);}if(!_8(a1)){_65(a1);a1=a2;a2=a3;}if(_8(a1)){if(!a1.length){a2&&a2();}else{_7d="require*"+uid();for(var mid,_7e=[],i=0;i<a1.length;){mid=a1[i++];if(mid in {exports:1,module:1}){throw _f("illegalModuleId",mid);}_7e.push(_31(mid,_7a));}_7c=_c(_7f("",_7d,0,""),{injected:_21,deps:_7e,def:a2||_3,require:_7a?_7a.require:req});_2f[_7c.mid]=_7c;_72(_7c);var _80=_74&&req.async;_74++;_36(_7c,_80);_37();if(!_7c.executed){_30.push(_7c);}_78();}}return _7b;},_81=function(_82){if(!_82){return req;}var _83=_82.require;if(!_83){_83=function(a1,a2,a3){return _16(a1,a2,a3,_82,_83);};_82.require=_c(_83,req);_83.module=_82;_83.toUrl=function(_84){return _5a(_84,_82);};_83.toAbsMid=function(mid){return _af(mid,_82);};if(0){_83.undef=function(mid){req.undef(mid,_82);};}}return _83;},_30=[],_85=[],_86={},_87=function(_88){_88.injected=_20;_86[_88.mid]=1;if(_88.url){_86[_88.url]=_88.pack||1;}},_33=function(_89){_89.injected=_21;delete _86[_89.mid];if(_89.url){delete _86[_89.url];}if(_4(_86)){_8a();1&&_25==xd&&(_25=_26);}},_8b=req.idle=function(){return !_85.length&&_4(_86)&&!_30.length&&!_74;},_8c=function(_8d,map){for(var i=0;i<map.length;i++){if(map[i][2].test(_8d)){return map[i];}}return 0;},_8e=function(_8f){var _90=[],_91,_92;_8f=_8f.replace(/\\/g,"/").split("/");while(_8f.length){_91=_8f.shift();if(_91==".."&&_90.length&&_92!=".."){_90.pop();_92=_90[_90.length-1];}else{if(_91!="."){_90.push(_92=_91);}}}return _90.join("/");},_7f=function(pid,mid,_93,url,_94){if(1){var xd=req.isXdUrl(url);return {pid:pid,mid:mid,pack:_93,url:url,executed:0,def:0,isXd:xd,isAmd:!!(xd||(_50[pid]&&_50[pid].isAmd)),cacheId:_94};}else{return {pid:pid,mid:mid,pack:_93,url:url,executed:0,def:0,cacheId:_94};}},_95=function(mid,_96,_97,_98,_99,_9a,_9b,_9c){var pid,_9d,_9e,_9f,_a0,_a1,url,_a2,_a3,_a4,_a5=0;_a4=mid;_a3=/^\./.test(mid);if(/(^\/)|(\:)|(\.js$)/.test(mid)||(_a3&&!_96)){return _7f(0,mid,0,mid);}else{mid=_8e(_a3?(_96.mid+"/../"+mid):mid);if(/^\./.test(mid)){throw _f("irrationalPath",mid);}_9f=_96&&_96.pack&&_96.pack.mapProg;_a0=(_9f&&_8c(mid,_9f))||_8c(mid,_9a);if(_a0){pid=_a0[1];mid=mid.substring(_a0[3]);_9d=_97[pid];if(!mid){mid=_9d.main;}_9e=mid;_a5=_9d.reverseName+"/"+mid;mid=pid+"/"+mid;}else{pid="";}var _a6=0,_a7=0;_9(_4d,function(_a8){var _a9=mid.match(_a8[0]);if(_a9&&_a9.length>_a6){_a7=_6(_a8[1])?mid.replace(_a8[0],_a8[1]):_a8[1];}});if(_a7){return _95(_a7,0,_97,_98,_99,_9a,_9b,_9c);}_a2=_98[mid];if(_a2){return _9c?_7f(_a2.pid,_a2.mid,_a2.pack,_a2.url,_a5):_98[mid];}}_a0=_8c(mid,_9b);if(_a0){url=_a0[1]+mid.substring(_a0[3]-1);}else{if(pid){url=_9d.location+"/"+_9e;}else{if(has("config-tlmSiblingOfDojo")){url="../"+mid;}else{url=mid;}}}if(!(/(^\/)|(\:)/.test(url))){url=_99+url;}url+=".js";return _7f(pid,mid,_9d,_8e(url),_a5);},_5b=function(mid,_aa){return _95(mid,_aa,_50,_2f,req.baseUrl,_52,_4f);},_ab=function(_ac,_ad,_ae){return _ac.normalize?_ac.normalize(_ad,function(mid){return _af(mid,_ae);}):_af(_ad,_ae);},_b0=0,_31=function(mid,_b1,_b2){var _b3,_b4,_b5,_b6;_b3=mid.match(/^(.+?)\!(.*)$/);if(_b3){_b4=_31(_b3[1],_b1,_b2);if(1&&_25==_26&&!_b4.executed){_32(_b4);if(_b4.injected===_21&&!_b4.executed){_74++;_36(_b4);_37();}if(_b4.executed){_b7(_b4);}else{_30.unshift(_b4);}}if(_b4.executed===_24&&!_b4.load){_b7(_b4);}if(_b4.load){_b5=_ab(_b4,_b3[2],_b1);mid=(_b4.mid+"!"+(_b4.dynamic?++_b0+"!":"")+_b5);}else{_b5=_b3[2];mid=_b4.mid+"!"+(++_b0)+"!waitingForPlugin";}_b6={plugin:_b4,mid:mid,req:_81(_b1),prid:_b5};}else{_b6=_5b(mid,_b1);}return _2f[_b6.mid]||(!_b2&&(_2f[_b6.mid]=_b6));},_af=req.toAbsMid=function(mid,_b8){return _5b(mid,_b8).mid;},_5a=req.toUrl=function(_b9,_ba){var _bb=_b9.match(/(.+)(\.[^\/\.]+?)$/),_bc=(_bb&&_bb[1])||_b9,ext=(_bb&&_bb[2])||"",_bd=_5b(_bc,_ba),url=_bd.url;url=typeof _bd.pid=="string"?url.substring(0,url.length-3):url;return _40(url+ext);},_be={injected:_21,executed:_24,def:_22,result:_22},_bf=function(mid){return _2f[mid]=_c({mid:mid},_be);},_c0=_bf("require"),_c1=_bf("exports"),_c2=_bf("module"),_c3=function(_c4,_c5){req.trace("loader-run-factory",[_c4.mid]);var _c6=_c4.def,_c7;1&&_27.unshift(_c4);if(has("config-dojo-loader-catches")){try{_c7=_6(_c6)?_c6.apply(null,_c5):_c6;}catch(e){_34(_45,_c4.result=_f("factoryThrew",[_c4,e]));}}else{_c7=_6(_c6)?_c6.apply(null,_c5):_c6;}_c4.result=_c7===undefined&&_c4.cjs?_c4.cjs.exports:_c7;1&&_27.shift(_c4);},_c8={},_c9=0,_b7=function(_ca){var _cb=_ca.result;_ca.dynamic=_cb.dynamic;_ca.normalize=_cb.normalize;_ca.load=_cb.load;return _ca;},_cc=function(_cd){var map={};_9(_cd.loadQ,function(_ce){var _cf=_ce.mid,_d0=_ab(_cd,_ce.prid,_ce.req.module),mid=_cd.dynamic?_ce.mid.replace(/waitingForPlugin$/,_d0):(_cd.mid+"!"+_d0),_d1=_c(_c({},_ce),{mid:mid,prid:_d0,injected:0});if(!_2f[mid]){_e2(_2f[mid]=_d1);}map[_ce.mid]=_2f[mid];_33(_ce);delete _2f[_ce.mid];});_cd.loadQ=0;var _d2=function(_d3){for(var _d4,_d5=_d3.deps||[],i=0;i<_d5.length;i++){_d4=map[_d5[i].mid];if(_d4){_d5[i]=_d4;}}};for(var p in _2f){_d2(_2f[p]);}_9(_30,_d2);},_35=function(_d6){req.trace("loader-finish-exec",[_d6.mid]);_d6.executed=_24;_d6.defOrder=_c9++;1&&_9(_d6.provides,function(cb){cb();});if(_d6.loadQ){_b7(_d6);_cc(_d6);}for(i=0;i<_30.length;){if(_30[i]===_d6){_30.splice(i,1);}else{i++;}}},_d7=[],_36=function(_d8,_d9){if(_d8.executed===_23){req.trace("loader-circular-dependency",[_d7.concat(mid).join("->")]);return (!_d8.def||_d9)?_c8:(_d8.cjs&&_d8.cjs.exports);}if(!_d8.executed){if(!_d8.def){return _c8;}var mid=_d8.mid,_da=_d8.deps||[],arg,_db,_dc=[],i=0;if(0){_d7.push(mid);req.trace("loader-exec-module",["exec",_d7.length,mid]);}_d8.executed=_23;while(i<_da.length){arg=_da[i++];_db=((arg===_c0)?_81(_d8):((arg===_c1)?_d8.cjs.exports:((arg===_c2)?_d8.cjs:_36(arg,_d9))));if(_db===_c8){_d8.executed=0;req.trace("loader-exec-module",["abort",mid]);0&&_d7.pop();return _c8;}_dc.push(_db);}_c3(_d8,_dc);_35(_d8);}0&&_d7.pop();return _d8.result;},_74=0,_78=function(){if(_74){return;}_74++;_29();for(var _dd,_de,i=0;i<_30.length;){_dd=_c9;_de=_30[i];_36(_de);if(_dd!=_c9){_29();i=0;}else{i++;}}_37();},_37=function(){_74--;if(_8b()){_34("idle",[]);}};if(0){req.undef=function(_df,_e0){var _e1=_31(_df,_e0);_33(_e1);delete _2f[_e1.mid];};}if(1){if(has("dojo-loader-eval-hint-url")===undefined){has.add("dojo-loader-eval-hint-url",1);}var _40=function(url){url+="";return url+(_53?((/\?/.test(url)?"&":"?")+_53):"");},_e2=function(_e3){var _e4=_e3.plugin;if(_e4.executed===_24&&!_e4.load){_b7(_e4);}var _e5=function(def){_e3.result=def;_33(_e3);_35(_e3);_78();};_87(_e3);if(_e4.load){_e4.load(_e3.prid,_e3.req,_e5);}else{if(_e4.loadQ){_e4.loadQ.push(_e3);}else{_30.unshift(_e4);_32(_e4);if(_e4.load){_e4.load(_e3.prid,_e3.req,_e5);}else{_e4.loadQ=[_e3];}}}},_e6=0,_79=0,_e7=0,_e8=function(_e9,_ea){_e7=1;if(has("config-dojo-loader-catches")){try{if(_e9===_e6){_e6.call(null);}else{req.eval(_e9,has("dojo-loader-eval-hint-url")?_ea.url:_ea.mid);}}catch(e){_34(_45,_f("evalModuleThrew",_ea));}}else{if(_e9===_e6){_e6.call(null);}else{req.eval(_e9,has("dojo-loader-eval-hint-url")?_ea.url:_ea.mid);}}_e7=0;},_32=function(_eb){var mid=_eb.mid,url=_eb.url;if(_eb.executed||_eb.injected||_86[mid]||(_eb.url&&((_eb.pack&&_86[_eb.url]===_eb.pack)||_86[_eb.url]==1))){return;}if(0){var _ec=0;if(_eb.plugin&&_eb.plugin.isCombo){req.combo.add(_eb.plugin.mid,_eb.prid,0,req);_ec=1;}else{if(!_eb.plugin){_ec=req.combo.add(0,_eb.mid,_eb.url,req);}}if(_ec){_87(_eb);_6f=1;return;}}if(_eb.plugin){_e2(_eb);return;}_87(_eb);var _ed=function(){_77(_eb);if(_eb.injected!==_21){_33(_eb);_c(_eb,_be);}if(1&&_25){!_27.length&&_78();}else{_78();}};_e6=_54[mid]||_54[_eb.cacheId];if(_e6){req.trace("loader-inject",["cache",_eb.mid,url]);_e8(_e6,_eb);_ed();return;}if(1&&_25){if(_eb.isXd){_25==_26&&(_25=xd);}else{if(_eb.isAmd&&_25!=_26){}else{var _ee=function(_ef){if(_25==_26){_27.unshift(_eb);_e8(_ef,_eb);_27.shift();_77(_eb);if(!_eb.cjs){_33(_eb);_35(_eb);}if(_eb.finish){var _f0=mid+"*finish",_f1=_eb.finish;delete _eb.finish;def(_f0,["dojo",("dojo/require!"+_f1.join(",")).replace(/\./g,"/")],function(_f2){_9(_f1,function(mid){_f2.require(mid);});});_30.unshift(_31(_f0));}_ed();}else{_ef=_2a(_eb,_ef);if(_ef){_e8(_ef,_eb);_ed();}else{_79=_eb;req.injectUrl(_40(url),_ed,_eb);_79=0;}}};req.trace("loader-inject",["xhr",_eb.mid,url,_25!=_26]);if(has("config-dojo-loader-catches")){try{req.getText(url,_25!=_26,_ee);}catch(e){_34(_45,_f("xhrInjectFailed",[_eb,e]));}}else{req.getText(url,_25!=_26,_ee);}return;}}}req.trace("loader-inject",["script",_eb.mid,url]);_79=_eb;req.injectUrl(_40(url),_ed,_eb);_79=0;},_f3=function(_f4,_f5,def){req.trace("loader-define-module",[_f4.mid,_f5]);if(0&&_f4.plugin&&_f4.plugin.isCombo){_f4.result=_6(def)?def():def;_33(_f4);_35(_f4);return _f4;}var mid=_f4.mid;if(_f4.injected===_21){_34(_45,_f("multipleDefine",_f4));return _f4;}_c(_f4,{deps:_f5,def:def,cjs:{id:_f4.mid,uri:_f4.url,exports:(_f4.result={}),setExports:function(_f6){_f4.cjs.exports=_f6;}}});for(var i=0;i<_f5.length;i++){_f5[i]=_31(_f5[i],_f4);}if(1&&_25&&!_86[mid]){_72(_f4);_30.push(_f4);_78();}_33(_f4);if(!_6(def)&&!_f5.length){_f4.result=def;_35(_f4);}return _f4;},_77=function(_f7,_f8){_57(_f7);var _f9=[],_fa,_fb;while(_85.length){_fb=_85.shift();_f8&&(_fb[0]=_f8.shift());_fa=_fb[0]&&_31(_fb[0])||_f7;_f9.push(_f3(_fa,_fb[1],_fb[2]));}_9(_f9,_72);};}var _fc=0,_8a=_3,_fd=_3;if(1){_8a=function(){_fc&&clearTimeout(_fc);_fc=0;},_fd=function(){_8a();req.waitms&&(_fc=setTimeout(function(){_8a();_34(_45,_f("timeout",_86));},req.waitms));};}if(1){has.add("ie-event-behavior",doc.attachEvent&&(typeof opera==="undefined"||opera.toString()!="[object Opera]"));}if(1&&(1||1)){var _fe=function(_ff,_100,_101,_102){if(!has("ie-event-behavior")){_ff.addEventListener(_100,_102,false);return function(){_ff.removeEventListener(_100,_102,false);};}else{_ff.attachEvent(_101,_102);return function(){_ff.detachEvent(_101,_102);};}},_103=_fe(window,"load","onload",function(){req.pageLoaded=1;doc.readyState!="complete"&&(doc.readyState="complete");_103();});if(1){var _104=doc.getElementsByTagName("script")[0],_105=_104.parentNode;req.injectUrl=function(url,_106,_107){_fd();var node=_107.node=doc.createElement("script"),_108=function(e){e=e||window.event;var node=e.target||e.srcElement;if(e.type==="load"||/complete|loaded/.test(node.readyState)){_109();_106&&_106();}},_109=_fe(node,"load","onreadystatechange",_108);node.type="text/javascript";node.charset="utf-8";node.src=url;_105.insertBefore(node,_104);return node;};}}if(1){req.log=function(){try{for(var i=0;i<arguments.length;i++){}}catch(e){}};}else{req.log=_3;}if(0){var _10a=req.trace=function(_10b,args){if(_10a.on&&_10a.group[_10b]){_34("trace",[_10b,args]);for(var arg,dump=[],text="trace:"+_10b+(args.length?(":"+args[0]):""),i=1;i<args.length;){arg=args[i++];if(_7(arg)){text+=", "+arg;}else{dump.push(arg);}}req.log(text);dump.length&&dump.push(".");req.log.apply(req,dump);}};_c(_10a,{on:1,group:{},set:function(_10c,_10d){if(_7(_10c)){_10a.group[_10c]=_10d;}else{_c(_10a.group,_10c);}}});_10a.set(_c(_c(_c({},_2.trace),_1.trace),_56.trace));on("config",function(_10e){_10e.trace&&_10a.set(_10e.trace);});}else{req.trace=_3;}var def=function(mid,_10f,_110){var _111=arguments.length,args=0,_112=["require","exports","module"];if(0){if(_111==1&&_6(mid)){_10f=[];mid.toString().replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg,"").replace(/require\(["']([\w\!\-_\.\/]+)["']\)/g,function(_113,dep){_10f.push(dep);});args=[0,_112.concat(_10f),mid];}}if(!args){args=_111==1?[0,_112,mid]:(_111==2?(_8(mid)?[0,mid,_10f]:(_6(_10f)?[mid,_112,_10f]:[mid,[],_10f])):[mid,_10f,_110]);}req.trace("loader-define",args.slice(0,2));var _114=args[0]&&_31(args[0]),_115;if(_114&&!_86[_114.mid]){_72(_f3(_114,args[1],args[2]));}else{if(!has("ie-event-behavior")||!1||_e7){_85.push(args);}else{_114=_114||_79;if(!_114){for(mid in _86){_115=_2f[mid];if(_115&&_115.node&&_115.node.readyState==="interactive"){_114=_115;break;}}if(0&&!_114){for(var i=0;i<_70.length;i++){_114=_70[i];if(_114.node&&_114.node.readyState==="interactive"){break;}_114=0;}}}if(0&&_8(_114)){_72(_f3(_31(_114.shift()),args[1],args[2]));if(!_114.length){_70.splice(i,1);}}else{if(_114){_57(_114);_72(_f3(_114,args[1],args[2]));}else{_34(_45,_f("ieDefineFailed",args[0]));}}_78();}}};def.amd={vendor:"dojotoolkit.org"};if(0){req.def=def;}_c(_c(req,_2.loaderPatch),_1.loaderPatch);on(_45,function(arg){try{console.error(arg);if(arg instanceof Error){for(var p in arg){}}}catch(e){}});_c(req,{uid:uid,cache:_54,packs:_50});if(0){_c(req,{paths:_4e,aliases:_4d,packageMap:_51,modules:_2f,legacyMode:_25,execQ:_30,defQ:_85,waiting:_86,pathsMapProg:_4f,packageMapProg:_52,listenerQueues:_44,computeMapProg:_5c,runMapProg:_8c,compactPath:_8e,getModuleInfo:_95});}if(_17.define){if(1){_34(_45,_f("defineAlreadyDefined",0));}}else{_17.define=def;_17.require=req;}if(0&&req.combo&&req.combo.plugins){var _116=req.combo.plugins,_117;for(_117 in _116){_c(_c(_31(_117),_116[_117]),{isCombo:1,executed:"executed",load:1});}}if(1){var _118=_2.deps||_1.deps||_56.deps,_119=_2.callback||_1.callback||_56.callback;req.boot=(_118||_119)?[_118||[],_119]:0;}if(!1){!req.async&&req(["dojo"]);req.boot&&req.apply(null,req.boot);}})(this.dojoConfig||this.djConfig||this.require||{},{async:0,hasCache:{"config-selectorEngine":"acme","config-tlmSiblingOfDojo":1,"dojo-built":1,"dojo-loader":1,dom:1,"host-browser":1},packages:[{location:"../dijit",name:"dijit"},{location:"../dojox",name:"dojox"},{location:".",name:"dojo"}]});require({cache:{"dojo/_base/fx":function(){define(["./kernel","./lang","../Evented","./Color","./connect","./sniff","../dom","../dom-style"],function(dojo,lang,_11a,_11b,_11c,has,dom,_11d){var _11e=lang.mixin;dojo._Line=function(_11f,end){this.start=_11f;this.end=end;};dojo._Line.prototype.getValue=function(n){return ((this.end-this.start)*n)+this.start;};dojo.Animation=function(args){_11e(this,args);if(lang.isArray(this.curve)){this.curve=new dojo._Line(this.curve[0],this.curve[1]);}};dojo.Animation.prototype=new _11a();dojo._Animation=dojo.Animation;lang.extend(dojo.Animation,{duration:350,repeat:0,rate:20,_percent:0,_startRepeatCount:0,_getStep:function(){var _120=this._percent,_121=this.easing;return _121?_121(_120):_120;},_fire:function(evt,args){var a=args||[];if(this[evt]){if(dojo.config.debugAtAllCosts){this[evt].apply(this,a);}else{try{this[evt].apply(this,a);}catch(e){console.error("exception in animation handler for:",evt);console.error(e);}}}return this;},play:function(_122,_123){var _124=this;if(_124._delayTimer){_124._clearTimer();}if(_123){_124._stopTimer();_124._active=_124._paused=false;_124._percent=0;}else{if(_124._active&&!_124._paused){return _124;}}_124._fire("beforeBegin",[_124.node]);var de=_122||_124.delay,_125=lang.hitch(_124,"_play",_123);if(de>0){_124._delayTimer=setTimeout(_125,de);return _124;}_125();return _124;},_play:function(_126){var _127=this;if(_127._delayTimer){_127._clearTimer();}_127._startTime=new Date().valueOf();if(_127._paused){_127._startTime-=_127.duration*_127._percent;}_127._active=true;_127._paused=false;var _128=_127.curve.getValue(_127._getStep());if(!_127._percent){if(!_127._startRepeatCount){_127._startRepeatCount=_127.repeat;}_127._fire("onBegin",[_128]);}_127._fire("onPlay",[_128]);_127._cycle();return _127;},pause:function(){var _129=this;if(_129._delayTimer){_129._clearTimer();}_129._stopTimer();if(!_129._active){return _129;}_129._paused=true;_129._fire("onPause",[_129.curve.getValue(_129._getStep())]);return _129;},gotoPercent:function(_12a,_12b){var _12c=this;_12c._stopTimer();_12c._active=_12c._paused=true;_12c._percent=_12a;if(_12b){_12c.play();}return _12c;},stop:function(_12d){var _12e=this;if(_12e._delayTimer){_12e._clearTimer();}if(!_12e._timer){return _12e;}_12e._stopTimer();if(_12d){_12e._percent=1;}_12e._fire("onStop",[_12e.curve.getValue(_12e._getStep())]);_12e._active=_12e._paused=false;return _12e;},status:function(){if(this._active){return this._paused?"paused":"playing";}return "stopped";},_cycle:function(){var _12f=this;if(_12f._active){var curr=new Date().valueOf();var step=(curr-_12f._startTime)/(_12f.duration);if(step>=1){step=1;}_12f._percent=step;if(_12f.easing){step=_12f.easing(step);}_12f._fire("onAnimate",[_12f.curve.getValue(step)]);if(_12f._percent<1){_12f._startTimer();}else{_12f._active=false;if(_12f.repeat>0){_12f.repeat--;_12f.play(null,true);}else{if(_12f.repeat==-1){_12f.play(null,true);}else{if(_12f._startRepeatCount){_12f.repeat=_12f._startRepeatCount;_12f._startRepeatCount=0;}}}_12f._percent=0;_12f._fire("onEnd",[_12f.node]);!_12f.repeat&&_12f._stopTimer();}}return _12f;},_clearTimer:function(){clearTimeout(this._delayTimer);delete this._delayTimer;}});var ctr=0,_130=null,_131={run:function(){}};lang.extend(dojo.Animation,{_startTimer:function(){if(!this._timer){this._timer=_11c.connect(_131,"run",this,"_cycle");ctr++;}if(!_130){_130=setInterval(lang.hitch(_131,"run"),this.rate);}},_stopTimer:function(){if(this._timer){_11c.disconnect(this._timer);this._timer=null;ctr--;}if(ctr<=0){clearInterval(_130);_130=null;ctr=0;}}});var _132=has("ie")?function(node){var ns=node.style;if(!ns.width.length&&_11d.get(node,"width")=="auto"){ns.width="auto";}}:function(){};dojo._fade=function(args){args.node=dom.byId(args.node);var _133=_11e({properties:{}},args),_134=(_133.properties.opacity={});_134.start=!("start" in _133)?function(){return +_11d.get(_133.node,"opacity")||0;}:_133.start;_134.end=_133.end;var anim=dojo.animateProperty(_133);_11c.connect(anim,"beforeBegin",lang.partial(_132,_133.node));return anim;};dojo.fadeIn=function(args){return dojo._fade(_11e({end:1},args));};dojo.fadeOut=function(args){return dojo._fade(_11e({end:0},args));};dojo._defaultEasing=function(n){return 0.5+((Math.sin((n+1.5)*Math.PI))/2);};var _135=function(_136){this._properties=_136;for(var p in _136){var prop=_136[p];if(prop.start instanceof _11b){prop.tempColor=new _11b();}}};_135.prototype.getValue=function(r){var ret={};for(var p in this._properties){var prop=this._properties[p],_137=prop.start;if(_137 instanceof _11b){ret[p]=_11b.blendColors(_137,prop.end,r,prop.tempColor).toCss();}else{if(!lang.isArray(_137)){ret[p]=((prop.end-_137)*r)+_137+(p!="opacity"?prop.units||"px":0);}}}return ret;};dojo.animateProperty=function(args){var n=args.node=dom.byId(args.node);if(!args.easing){args.easing=dojo._defaultEasing;}var anim=new dojo.Animation(args);_11c.connect(anim,"beforeBegin",anim,function(){var pm={};for(var p in this.properties){if(p=="width"||p=="height"){this.node.display="block";}var prop=this.properties[p];if(lang.isFunction(prop)){prop=prop(n);}prop=pm[p]=_11e({},(lang.isObject(prop)?prop:{end:prop}));if(lang.isFunction(prop.start)){prop.start=prop.start(n);}if(lang.isFunction(prop.end)){prop.end=prop.end(n);}var _138=(p.toLowerCase().indexOf("color")>=0);function _139(node,p){var v={height:node.offsetHeight,width:node.offsetWidth}[p];if(v!==undefined){return v;}v=_11d.get(node,p);return (p=="opacity")?+v:(_138?v:parseFloat(v));};if(!("end" in prop)){prop.end=_139(n,p);}else{if(!("start" in prop)){prop.start=_139(n,p);}}if(_138){prop.start=new _11b(prop.start);prop.end=new _11b(prop.end);}else{prop.start=(p=="opacity")?+prop.start:parseFloat(prop.start);}}this.curve=new _135(pm);});_11c.connect(anim,"onAnimate",lang.hitch(_11d,"set",anim.node));return anim;};dojo.anim=function(node,_13a,_13b,_13c,_13d,_13e){return dojo.animateProperty({node:node,duration:_13b||dojo.Animation.prototype.duration,properties:_13a,easing:_13c,onEnd:_13d}).play(_13e||0);};return {_Line:dojo._Line,Animation:dojo.Animation,_fade:dojo._fade,fadeIn:dojo.fadeIn,fadeOut:dojo.fadeOut,_defaultEasing:dojo._defaultEasing,animateProperty:dojo.animateProperty,anim:dojo.anim};});},"dojo/dom-form":function(){define("dojo/dom-form",["./_base/lang","./dom","./io-query","./json"],function(lang,dom,ioq,json){function _13f(obj,name,_140){if(_140===null){return;}var val=obj[name];if(typeof val=="string"){obj[name]=[val,_140];}else{if(lang.isArray(val)){val.push(_140);}else{obj[name]=_140;}}};var _141="file|submit|image|reset|button";var form={fieldToObject:function fieldToObject(_142){var ret=null;_142=dom.byId(_142);if(_142){var _143=_142.name,type=(_142.type||"").toLowerCase();if(_143&&type&&!_142.disabled){if(type=="radio"||type=="checkbox"){if(_142.checked){ret=_142.value;}}else{if(_142.multiple){ret=[];var _144=[_142.firstChild];while(_144.length){for(var node=_144.pop();node;node=node.nextSibling){if(node.nodeType==1&&node.tagName.toLowerCase()=="option"){if(node.selected){ret.push(node.value);}}else{if(node.nextSibling){_144.push(node.nextSibling);}if(node.firstChild){_144.push(node.firstChild);}break;}}}}else{ret=_142.value;}}}}return ret;},toObject:function formToObject(_145){var ret={},_146=dom.byId(_145).elements;for(var i=0,l=_146.length;i<l;++i){var item=_146[i],_147=item.name,type=(item.type||"").toLowerCase();if(_147&&type&&_141.indexOf(type)<0&&!item.disabled){_13f(ret,_147,form.fieldToObject(item));if(type=="image"){ret[_147+".x"]=ret[_147+".y"]=ret[_147].x=ret[_147].y=0;}}}return ret;},toQuery:function formToQuery(_148){return ioq.objectToQuery(form.toObject(_148));},toJson:function formToJson(_149,_14a){return json.stringify(form.toObject(_149),null,_14a?4:0);}};return form;});},"dojo/i18n":function(){define(["./_base/kernel","require","./has","./_base/array","./_base/config","./_base/lang","./_base/xhr"],function(dojo,_14b,has,_14c,_14d,lang,xhr){var _14e=dojo.i18n={},_14f=/(^.*(^|\/)nls)(\/|$)([^\/]*)\/?([^\/]*)/,_150=function(root,_151,_152,_153){for(var _154=[_152+_153],_155=_151.split("-"),_156="",i=0;i<_155.length;i++){_156+=(_156?"-":"")+_155[i];if(!root||root[_156]){_154.push(_152+_156+"/"+_153);}}return _154;},_157={},_158=dojo.getL10nName=function(_159,_15a,_15b){_15b=_15b?_15b.toLowerCase():dojo.locale;_159="dojo/i18n!"+_159.replace(/\./g,"/");_15a=_15a.replace(/\./g,"/");return (/root/i.test(_15b))?(_159+"/nls/"+_15a):(_159+"/nls/"+_15b+"/"+_15a);},_15c=function(_15d,_15e,_15f,_160,_161,load){_15d([_15e],function(root){var _162=_157[_15e+"/"]=lang.clone(root.root),_163=_150(!root._v1x&&root,_161,_15f,_160);_15d(_163,function(){for(var i=1;i<_163.length;i++){_157[_163[i]]=_162=lang.mixin(lang.clone(_162),arguments[i]);}var _164=_15e+"/"+_161;_157[_164]=_162;load&&load(lang.delegate(_162));});});},_165=function(id,_166){var _167=_14f.exec(id),_168=_167[1];return /^\./.test(_168)?_166(_168)+"/"+id.substring(_168.length):id;},_169=function(){},load=function(id,_16a,load){var _16b=_14f.exec(id),_16c=_16b[1]+"/",_16d=_16b[5]||_16b[4],_16e=_16c+_16d,_16f=(_16b[5]&&_16b[4]),_170=_16f||dojo.locale,_171=_16e+"/"+_170;if(_16f){_169(_171);if(_157[_171]){load(_157[_171]);}else{_15c(_16a,_16e,_16c,_16d,_170,load);}return;}var _172=_14d.extraLocale||[];_172=lang.isArray(_172)?_172:[_172];_172.push(_170);var _173=_172.length,_174;_14c.forEach(_172,function(_175){_15c(_16a,_16e,_16c,_16d,_175,function(_176){if(_175==_170){_174=_176;}if(!--_173){load(_174);}});});};if(has("dojo-unit-tests")){var _177=_14e.unitTests=[];}true||has.add("dojo-v1x-i18n-Api",1);if(1){var _178={},_179=new Function("bundle, __evalError","var __amdResult, define = function(x){__amdResult= x;};"+"return [(function(){"+"try{eval(arguments[0]);}catch(e){}"+"if(__amdResult)return 0;"+"try{return eval('('+arguments[0]+')');}"+"catch(e){__evalError.e = e; return __evalError;}"+"})(arguments[0]) , __amdResult];"),_17a=function(url,_17b,_17c){if(_17b===_178){console.error("failed to evaluate i18n bundle; url="+url,_178.e);return {};}return _17b?(/nls\/[^\/]+\/[^\/]+$/.test(url)?_17b:{root:_17b,_v1x:1}):_17c;},_17d=function(deps,_17e){var _17f=[];_14c.forEach(deps,function(mid){var url=_14b.toUrl(mid+".js");if(_157[url]){_17f.push(_157[url]);}else{try{var _180=_14b(mid);if(_180){_17f.push(_180);return;}}catch(e){}xhr.get({url:url,sync:true,load:function(text){var _181=_179(text,_178);_17f.push(_157[url]=_17a(url,_181[0],_181[1]));},error:function(){_17f.push(_157[url]={});}});}});_17e&&_17e.apply(null,_17f);},_182=_14e.normalizeLocale=function(_183){var _184=_183?_183.toLowerCase():dojo.locale;if(_184=="root"){_184="ROOT";}return _184;},_185=function(_186,func){var _187=_186.split("-");while(_187.length){if(func(_187.join("-"))){return true;}_187.pop();}return func("ROOT");};_169=function(_188){for(var _189=_188.split("/"),_18a=dojo.global[_189[0]],i=1;_18a&&i<_189.length;_18a=_18a[_189[i++]]){}if(_18a){_157[_188]=_18a;}};_14e.getLocalization=function(_18b,_18c,_18d){var _18e,_18f=_158(_18b,_18c,_18d).substring(10);load(_18f,(1&&!_14b.isXdUrl(_14b.toUrl(_18f+".js"))?_17d:_14b),function(_190){_18e=_190;});return _18e;};_14e._preloadLocalizations=function(_191,_192){function _193(_194){_194=_182(_194);_185(_194,function(loc){for(var i=0;i<_192.length;i++){if(_192[i]==loc){_17d([_191.replace(/\./g,"/")+"_"+loc]);return true;}}return false;});};_193();var _195=dojo.config.extraLocale||[];for(var i=0;i<_195.length;i++){_193(_195[i]);}};if(has("dojo-unit-tests")){_177.push(function(doh){doh.register("tests.i18n.unit",function(t){var _196;_196=_179("{prop:1}",_178);t.is({prop:1},_196[0]);t.is(undefined,_196[1]);_196=_179("({prop:1})",_178);t.is({prop:1},_196[0]);t.is(undefined,_196[1]);_196=_179("{'prop-x':1}",_178);t.is({"prop-x":1},_196[0]);t.is(undefined,_196[1]);_196=_179("({'prop-x':1})",_178);t.is({"prop-x":1},_196[0]);t.is(undefined,_196[1]);_196=_179("define({'prop-x':1})",_178);t.is(0,_196[0]);t.is({"prop-x":1},_196[1]);_196=_179("define({'prop-x':1});",_178);t.is(0,_196[0]);t.is({"prop-x":1},_196[1]);_196=_179("this is total nonsense and should throw an error",_178);t.is(_178,_196[0]);t.is(undefined,_196[1]);t.is({},_17a("some/url",_196[0],_196[1]));});});}}return lang.mixin(_14e,{dynamic:true,normalize:_165,load:load,cache:function(mid,_197){_157[mid]=_197;}});});},"dojo/_base/html":function(){define(["./kernel","../dom","../dom-style","../dom-attr","../dom-prop","../dom-class","../dom-construct","../dom-geometry"],function(dojo,dom,_198,attr,prop,cls,ctr,geom){dojo.byId=dom.byId;dojo.isDescendant=dom.isDescendant;dojo.setSelectable=dom.setSelectable;dojo.getAttr=attr.get;dojo.setAttr=attr.set;dojo.hasAttr=attr.has;dojo.removeAttr=attr.remove;dojo.getNodeProp=attr.getNodeProp;dojo.attr=function(node,name,_199){if(arguments.length==2){return attr[typeof name=="string"?"get":"set"](node,name);}return attr.set(node,name,_199);};dojo.hasClass=cls.contains;dojo.addClass=cls.add;dojo.removeClass=cls.remove;dojo.toggleClass=cls.toggle;dojo.replaceClass=cls.replace;dojo._toDom=dojo.toDom=ctr.toDom;dojo.place=ctr.place;dojo.create=ctr.create;dojo.empty=function(node){ctr.empty(node);};dojo._destroyElement=dojo.destroy=function(node){ctr.destroy(node);};dojo._getPadExtents=dojo.getPadExtents=geom.getPadExtents;dojo._getBorderExtents=dojo.getBorderExtents=geom.getBorderExtents;dojo._getPadBorderExtents=dojo.getPadBorderExtents=geom.getPadBorderExtents;dojo._getMarginExtents=dojo.getMarginExtents=geom.getMarginExtents;dojo._getMarginSize=dojo.getMarginSize=geom.getMarginSize;dojo._getMarginBox=dojo.getMarginBox=geom.getMarginBox;dojo.setMarginBox=geom.setMarginBox;dojo._getContentBox=dojo.getContentBox=geom.getContentBox;dojo.setContentSize=geom.setContentSize;dojo._isBodyLtr=dojo.isBodyLtr=geom.isBodyLtr;dojo._docScroll=dojo.docScroll=geom.docScroll;dojo._getIeDocumentElementOffset=dojo.getIeDocumentElementOffset=geom.getIeDocumentElementOffset;dojo._fixIeBiDiScrollLeft=dojo.fixIeBiDiScrollLeft=geom.fixIeBiDiScrollLeft;dojo.position=geom.position;dojo.marginBox=function marginBox(node,box){return box?geom.setMarginBox(node,box):geom.getMarginBox(node);};dojo.contentBox=function contentBox(node,box){return box?geom.setContentSize(node,box):geom.getContentBox(node);};dojo.coords=function(node,_19a){dojo.deprecated("dojo.coords()","Use dojo.position() or dojo.marginBox().");node=dom.byId(node);var s=_198.getComputedStyle(node),mb=geom.getMarginBox(node,s);var abs=geom.position(node,_19a);mb.x=abs.x;mb.y=abs.y;return mb;};dojo.getProp=prop.get;dojo.setProp=prop.set;dojo.prop=function(node,name,_19b){if(arguments.length==2){return prop[typeof name=="string"?"get":"set"](node,name);}return prop.set(node,name,_19b);};dojo.getStyle=_198.get;dojo.setStyle=_198.set;dojo.getComputedStyle=_198.getComputedStyle;dojo.__toPixelValue=dojo.toPixelValue=_198.toPixelValue;dojo.style=function(node,name,_19c){switch(arguments.length){case 1:return _198.get(node);case 2:return _198[typeof name=="string"?"get":"set"](node,name);}return _198.set(node,name,_19c);};return dojo;});},"dojo/_base/kernel":function(){define(["../has","./config","require","module"],function(has,_19d,_19e,_19f){var i,p,_1a0={},_1a1={},dojo={config:_19d,global:this,dijit:_1a0,dojox:_1a1};var _1a2={dojo:["dojo",dojo],dijit:["dijit",_1a0],dojox:["dojox",_1a1]},_1a3=(_19e.packs&&_19e.packs[_19f.id.match(/[^\/]+/)[0]].packageMap)||{},item;for(p in _1a3){if(_1a2[p]){_1a2[p][0]=_1a3[p];}else{_1a2[p]=[_1a3[p],{}];}}for(p in _1a2){item=_1a2[p];item[1]._scopeName=item[0];if(!_19d.noGlobals){this[item[0]]=item[1];}}dojo.scopeMap=_1a2;dojo.baseUrl=dojo.config.baseUrl=_19e.baseUrl;dojo.isAsync=!1||_19e.async;dojo.locale=_19d.locale;var rev="$Rev: 27913 $".match(/\d+/);dojo.version={major:1,minor:7,patch:2,flag:"",revision:rev?+rev[0]:NaN,toString:function(){var v=dojo.version;return v.major+"."+v.minor+"."+v.patch+v.flag+" ("+v.revision+")";}};true||has.add("extend-dojo",1);dojo.eval=function(_1a4){};(Function("d","d.eval = function(){return d.global.eval ? d.global.eval(arguments[0]) : eval(arguments[0]);}"))(dojo);if(0){dojo.exit=function(_1a5){quit(_1a5);};}else{dojo.exit=function(){};}true||has.add("dojo-guarantee-console",1);if(1){typeof console!="undefined"||(console={});var cn=["assert","count","debug","dir","dirxml","error","group","groupEnd","info","profile","profileEnd","time","timeEnd","trace","warn","log"];var tn;i=0;while((tn=cn[i++])){if(!console[tn]){(function(){var tcn=tn+"";console[tcn]=("log" in console)?function(){var a=Array.apply({},arguments);a.unshift(tcn+":");console["log"](a.join(" "));}:function(){};console[tcn]._fake=true;})();}}}has.add("dojo-debug-messages",!!_19d.isDebug);if(has("dojo-debug-messages")){dojo.deprecated=function(_1a6,_1a7,_1a8){var _1a9="DEPRECATED: "+_1a6;if(_1a7){_1a9+=" "+_1a7;}if(_1a8){_1a9+=" -- will be removed in version: "+_1a8;}console.warn(_1a9);};dojo.experimental=function(_1aa,_1ab){var _1ac="EXPERIMENTAL: "+_1aa+" -- APIs subject to change without notice.";if(_1ab){_1ac+=" "+_1ab;}console.warn(_1ac);};}else{dojo.deprecated=dojo.experimental=function(){};}true||has.add("dojo-modulePaths",1);if(1){if(_19d.modulePaths){dojo.deprecated("dojo.modulePaths","use paths configuration");var _1ad={};for(p in _19d.modulePaths){_1ad[p.replace(/\./g,"/")]=_19d.modulePaths[p];}_19e({paths:_1ad});}}true||has.add("dojo-moduleUrl",1);if(1){dojo.moduleUrl=function(_1ae,url){dojo.deprecated("dojo.moduleUrl()","use require.toUrl","2.0");var _1af=null;if(_1ae){_1af=_19e.toUrl(_1ae.replace(/\./g,"/")+(url?("/"+url):"")+"/*.*").replace(/\/\*\.\*/,"")+(url?"":"/");}return _1af;};}dojo._hasResource={};return dojo;});},"dojo/io-query":function(){define(["./_base/lang"],function(lang){var _1b0={};function _1b1(map){var enc=encodeURIComponent,_1b2=[];for(var name in map){var _1b3=map[name];if(_1b3!=_1b0[name]){var _1b4=enc(name)+"=";if(lang.isArray(_1b3)){for(var i=0,l=_1b3.length;i<l;++i){_1b2.push(_1b4+enc(_1b3[i]));}}else{_1b2.push(_1b4+enc(_1b3));}}}return _1b2.join("&");};function _1b5(str){var dec=decodeURIComponent,qp=str.split("&"),ret={},name,val;for(var i=0,l=qp.length,item;i<l;++i){item=qp[i];if(item.length){var s=item.indexOf("=");if(s<0){name=dec(item);val="";}else{name=dec(item.slice(0,s));val=dec(item.slice(s+1));}if(typeof ret[name]=="string"){ret[name]=[ret[name]];}if(lang.isArray(ret[name])){ret[name].push(val);}else{ret[name]=val;}}}return ret;};return {objectToQuery:_1b1,queryToObject:_1b5};});},"dojo/_base/Deferred":function(){define("dojo/_base/Deferred",["./kernel","./lang"],function(dojo,lang){var _1b6=function(){};var _1b7=Object.freeze||function(){};dojo.Deferred=function(_1b8){var _1b9,_1ba,_1bb,head,_1bc;var _1bd=(this.promise={});function _1be(_1bf){if(_1ba){throw new Error("This deferred has already been resolved");}_1b9=_1bf;_1ba=true;_1c0();};function _1c0(){var _1c1;while(!_1c1&&_1bc){var _1c2=_1bc;_1bc=_1bc.next;if((_1c1=(_1c2.progress==_1b6))){_1ba=false;}var func=(_1bb?_1c2.error:_1c2.resolved);if(func){try{var _1c3=func(_1b9);if(_1c3&&typeof _1c3.then==="function"){_1c3.then(lang.hitch(_1c2.deferred,"resolve"),lang.hitch(_1c2.deferred,"reject"),lang.hitch(_1c2.deferred,"progress"));continue;}var _1c4=_1c1&&_1c3===undefined;if(_1c1&&!_1c4){_1bb=_1c3 instanceof Error;}_1c2.deferred[_1c4&&_1bb?"reject":"resolve"](_1c4?_1b9:_1c3);}catch(e){_1c2.deferred.reject(e);}}else{if(_1bb){_1c2.deferred.reject(_1b9);}else{_1c2.deferred.resolve(_1b9);}}}};this.resolve=this.callback=function(_1c5){this.fired=0;this.results=[_1c5,null];_1be(_1c5);};this.reject=this.errback=function(_1c6){_1bb=true;this.fired=1;_1be(_1c6);this.results=[null,_1c6];if(!_1c6||_1c6.log!==false){(dojo.config.deferredOnError||function(x){console.error(x);})(_1c6);}};this.progress=function(_1c7){var _1c8=_1bc;while(_1c8){var _1c9=_1c8.progress;_1c9&&_1c9(_1c7);_1c8=_1c8.next;}};this.addCallbacks=function(_1ca,_1cb){this.then(_1ca,_1cb,_1b6);return this;};_1bd.then=this.then=function(_1cc,_1cd,_1ce){var _1cf=_1ce==_1b6?this:new dojo.Deferred(_1bd.cancel);var _1d0={resolved:_1cc,error:_1cd,progress:_1ce,deferred:_1cf};if(_1bc){head=head.next=_1d0;}else{_1bc=head=_1d0;}if(_1ba){_1c0();}return _1cf.promise;};var _1d1=this;_1bd.cancel=this.cancel=function(){if(!_1ba){var _1d2=_1b8&&_1b8(_1d1);if(!_1ba){if(!(_1d2 instanceof Error)){_1d2=new Error(_1d2);}_1d2.log=false;_1d1.reject(_1d2);}}};_1b7(_1bd);};lang.extend(dojo.Deferred,{addCallback:function(_1d3){return this.addCallbacks(lang.hitch.apply(dojo,arguments));},addErrback:function(_1d4){return this.addCallbacks(null,lang.hitch.apply(dojo,arguments));},addBoth:function(_1d5){var _1d6=lang.hitch.apply(dojo,arguments);return this.addCallbacks(_1d6,_1d6);},fired:-1});dojo.Deferred.when=dojo.when=function(_1d7,_1d8,_1d9,_1da){if(_1d7&&typeof _1d7.then==="function"){return _1d7.then(_1d8,_1d9,_1da);}return _1d8?_1d8(_1d7):_1d7;};return dojo.Deferred;});},"dojo/NodeList-dom":function(){define(["./_base/kernel","./query","./_base/array","./_base/lang","./dom-class","./dom-construct","./dom-geometry","./dom-attr","./dom-style"],function(dojo,_1db,_1dc,lang,_1dd,_1de,_1df,_1e0,_1e1){var _1e2=function(a){return a.length==1&&(typeof a[0]=="string");};var _1e3=function(node){var p=node.parentNode;if(p){p.removeChild(node);}};var _1e4=_1db.NodeList,awc=_1e4._adaptWithCondition,aafe=_1e4._adaptAsForEach,aam=_1e4._adaptAsMap;function _1e5(_1e6){return function(node,name,_1e7){if(arguments.length==2){return _1e6[typeof name=="string"?"get":"set"](node,name);}return _1e6.set(node,name,_1e7);};};lang.extend(_1e4,{_normalize:function(_1e8,_1e9){var _1ea=_1e8.parse===true;if(typeof _1e8.template=="string"){var _1eb=_1e8.templateFunc||(dojo.string&&dojo.string.substitute);_1e8=_1eb?_1eb(_1e8.template,_1e8):_1e8;}var type=(typeof _1e8);if(type=="string"||type=="number"){_1e8=_1de.toDom(_1e8,(_1e9&&_1e9.ownerDocument));if(_1e8.nodeType==11){_1e8=lang._toArray(_1e8.childNodes);}else{_1e8=[_1e8];}}else{if(!lang.isArrayLike(_1e8)){_1e8=[_1e8];}else{if(!lang.isArray(_1e8)){_1e8=lang._toArray(_1e8);}}}if(_1ea){_1e8._runParse=true;}return _1e8;},_cloneNode:function(node){return node.cloneNode(true);},_place:function(ary,_1ec,_1ed,_1ee){if(_1ec.nodeType!=1&&_1ed=="only"){return;}var _1ef=_1ec,_1f0;var _1f1=ary.length;for(var i=_1f1-1;i>=0;i--){var node=(_1ee?this._cloneNode(ary[i]):ary[i]);if(ary._runParse&&dojo.parser&&dojo.parser.parse){if(!_1f0){_1f0=_1ef.ownerDocument.createElement("div");}_1f0.appendChild(node);dojo.parser.parse(_1f0);node=_1f0.firstChild;while(_1f0.firstChild){_1f0.removeChild(_1f0.firstChild);}}if(i==_1f1-1){_1de.place(node,_1ef,_1ed);}else{_1ef.parentNode.insertBefore(node,_1ef);}_1ef=node;}},attr:awc(_1e5(_1e0),_1e2),style:awc(_1e5(_1e1),_1e2),addClass:aafe(_1dd.add),removeClass:aafe(_1dd.remove),replaceClass:aafe(_1dd.replace),toggleClass:aafe(_1dd.toggle),empty:aafe(_1de.empty),removeAttr:aafe(_1e0.remove),position:aam(_1df.position),marginBox:aam(_1df.getMarginBox),place:function(_1f2,_1f3){var item=_1db(_1f2)[0];return this.forEach(function(node){_1de.place(node,item,_1f3);});},orphan:function(_1f4){return (_1f4?_1db._filterResult(this,_1f4):this).forEach(_1e3);},adopt:function(_1f5,_1f6){return _1db(_1f5).place(this[0],_1f6)._stash(this);},query:function(_1f7){if(!_1f7){return this;}var ret=new _1e4;this.map(function(node){_1db(_1f7,node).forEach(function(_1f8){if(_1f8!==undefined){ret.push(_1f8);}});});return ret._stash(this);},filter:function(_1f9){var a=arguments,_1fa=this,_1fb=0;if(typeof _1f9=="string"){_1fa=_1db._filterResult(this,a[0]);if(a.length==1){return _1fa._stash(this);}_1fb=1;}return this._wrap(_1dc.filter(_1fa,a[_1fb],a[_1fb+1]),this);},addContent:function(_1fc,_1fd){_1fc=this._normalize(_1fc,this[0]);for(var i=0,node;(node=this[i]);i++){this._place(_1fc,node,_1fd,i>0);}return this;}});return _1e4;});},"dojo/query":function(){define(["./_base/kernel","./has","./dom","./on","./_base/array","./_base/lang","./selector/_loader","./selector/_loader!default"],function(dojo,has,dom,on,_1fe,lang,_1ff,_200){"use strict";has.add("array-extensible",function(){return lang.delegate([],{length:1}).length==1&&!has("bug-for-in-skips-shadowed");});var ap=Array.prototype,aps=ap.slice,apc=ap.concat,_201=_1fe.forEach;var tnl=function(a,_202,_203){var _204=new (_203||this._NodeListCtor||nl)(a);return _202?_204._stash(_202):_204;};var _205=function(f,a,o){a=[0].concat(aps.call(a,0));o=o||dojo.global;return function(node){a[0]=node;return f.apply(o,a);};};var _206=function(f,o){return function(){this.forEach(_205(f,arguments,o));return this;};};var _207=function(f,o){return function(){return this.map(_205(f,arguments,o));};};var _208=function(f,o){return function(){return this.filter(_205(f,arguments,o));};};var _209=function(f,g,o){return function(){var a=arguments,body=_205(f,a,o);if(g.call(o||dojo.global,a)){return this.map(body);}this.forEach(body);return this;};};var _20a=function(_20b){var _20c=this instanceof nl&&has("array-extensible");if(typeof _20b=="number"){_20b=Array(_20b);}var _20d=(_20b&&"length" in _20b)?_20b:arguments;if(_20c||!_20d.sort){var _20e=_20c?this:[],l=_20e.length=_20d.length;for(var i=0;i<l;i++){_20e[i]=_20d[i];}if(_20c){return _20e;}_20d=_20e;}lang._mixin(_20d,nlp);_20d._NodeListCtor=function(_20f){return nl(_20f);};return _20d;};var nl=_20a,nlp=nl.prototype=has("array-extensible")?[]:{};nl._wrap=nlp._wrap=tnl;nl._adaptAsMap=_207;nl._adaptAsForEach=_206;nl._adaptAsFilter=_208;nl._adaptWithCondition=_209;_201(["slice","splice"],function(name){var f=ap[name];nlp[name]=function(){return this._wrap(f.apply(this,arguments),name=="slice"?this:null);};});_201(["indexOf","lastIndexOf","every","some"],function(name){var f=_1fe[name];nlp[name]=function(){return f.apply(dojo,[this].concat(aps.call(arguments,0)));};});lang.extend(_20a,{constructor:nl,_NodeListCtor:nl,toString:function(){return this.join(",");},_stash:function(_210){this._parent=_210;return this;},on:function(_211,_212){var _213=this.map(function(node){return on(node,_211,_212);});_213.remove=function(){for(var i=0;i<_213.length;i++){_213[i].remove();}};return _213;},end:function(){if(this._parent){return this._parent;}else{return new this._NodeListCtor(0);}},concat:function(item){var t=lang.isArray(this)?this:aps.call(this,0),m=_1fe.map(arguments,function(a){return a&&!lang.isArray(a)&&(typeof _20a!="undefined"&&a.constructor===_20a||a.constructor===this._NodeListCtor)?aps.call(a,0):a;});return this._wrap(apc.apply(t,m),this);},map:function(func,obj){return this._wrap(_1fe.map(this,func,obj),this);},forEach:function(_214,_215){_201(this,_214,_215);return this;},filter:function(_216){var a=arguments,_217=this,_218=0;if(typeof _216=="string"){_217=_219._filterResult(this,a[0]);if(a.length==1){return _217._stash(this);}_218=1;}return this._wrap(_1fe.filter(_217,a[_218],a[_218+1]),this);},instantiate:function(_21a,_21b){var c=lang.isFunction(_21a)?_21a:lang.getObject(_21a);_21b=_21b||{};return this.forEach(function(node){new c(_21b,node);});},at:function(){var t=new this._NodeListCtor(0);_201(arguments,function(i){if(i<0){i=this.length+i;}if(this[i]){t.push(this[i]);}},this);return t._stash(this);}});function _21c(_21d,_21e){var _21f=function(_220,root){if(typeof root=="string"){root=dom.byId(root);if(!root){return new _21e([]);}}var _221=typeof _220=="string"?_21d(_220,root):_220.orphan?_220:[_220];if(_221.orphan){return _221;}return new _21e(_221);};_21f.matches=_21d.match||function(node,_222,root){return _21f.filter([node],_222,root).length>0;};_21f.filter=_21d.filter||function(_223,_224,root){return _21f(_224,root).filter(function(node){return _1fe.indexOf(_223,node)>-1;});};if(typeof _21d!="function"){var _225=_21d.search;_21d=function(_226,root){return _225(root||document,_226);};}return _21f;};var _219=_21c(_200,_20a);dojo.query=_21c(_200,function(_227){return _20a(_227);});_219.load=function(id,_228,_229,_22a){_1ff.load(id,_228,function(_22b){_229(_21c(_22b,_20a));});};dojo._filterQueryResult=_219._filterResult=function(_22c,_22d,root){return new _20a(_219.filter(_22c,_22d,root));};dojo.NodeList=_219.NodeList=_20a;return _219;});},"dojo/has":function(){define(["require"],function(_22e){var has=_22e.has||function(){};if(!1){var _22f=typeof window!="undefined"&&typeof location!="undefined"&&typeof document!="undefined"&&window.location==location&&window.document==document,_230=this,doc=_22f&&document,_231=doc&&doc.createElement("DiV"),_232={};has=function(name){return typeof _232[name]=="function"?(_232[name]=_232[name](_230,doc,_231)):_232[name];};has.cache=_232;has.add=function(name,test,now,_233){(typeof _232[name]=="undefined"||_233)&&(_232[name]=test);return now&&has(name);};true||has.add("host-browser",_22f);true||has.add("dom",_22f);true||has.add("dojo-dom-ready-api",1);true||has.add("dojo-sniff",1);}if(1){var _234=navigator.userAgent;has.add("dom-addeventlistener",!!document.addEventListener);has.add("touch","ontouchstart" in document);has.add("device-width",screen.availWidth||innerWidth);has.add("agent-ios",!!_234.match(/iPhone|iP[ao]d/));has.add("agent-android",_234.indexOf("android")>1);}has.clearElement=function(_235){_235.innerHTML="";return _235;};has.normalize=function(id,_236){var _237=id.match(/[\?:]|[^:\?]*/g),i=0,get=function(skip){var term=_237[i++];if(term==":"){return 0;}else{if(_237[i++]=="?"){if(!skip&&has(term)){return get();}else{get(true);return get(skip);}}return term||0;}};id=get();return id&&_236(id);};has.load=function(id,_238,_239){if(id){_238([id],_239);}else{_239();}};return has;});},"dojo/_base/loader":function(){define(["./kernel","../has","require","module","./json","./lang","./array"],function(dojo,has,_23a,_23b,json,lang,_23c){if(!1){console.error("cannot load the Dojo v1.x loader with a foreign loader");return 0;}var _23d=function(id){return {src:_23b.id,id:id};},_23e=function(name){return name.replace(/\./g,"/");},_23f=/\/\/>>built/,_240=[],_241=[],_242=function(mid,_243,_244){_240.push(_244);_23c.forEach(mid.split(","),function(mid){var _245=_246(mid,_243.module);_241.push(_245);_247(_245);});_248();},_249,_24a=function(m){if(_249[m.mid]||/loadInit\!/.test(m.mid)){return true;}_249[m.mid]=1;if(m.injected!==_24b&&!m.executed){return false;}for(var deps=m.deps||[],i=0;i<deps.length;i++){if(!_24a(deps[i])){return false;}}return true;},_248=function(){_249={};_241=_23c.filter(_241,function(_24c){return !_24a(_24c);});if(!_241.length){_24e.holdIdle();var _24d=_240;_240=[];_23c.forEach(_24d,function(cb){cb(1);});_24e.releaseIdle();}},_24f=function(mid,_250,_251){_250([mid],function(_252){_250(_252.names,function(){for(var _253="",args=[],i=0;i<arguments.length;i++){_253+="var "+_252.names[i]+"= arguments["+i+"]; ";args.push(arguments[i]);}eval(_253);var _254=_250.module,deps=[],hold={},_255=[],p,_256={provide:function(_257){_257=_23e(_257);var _258=_246(_257,_254);if(_258!==_254){_27d(_258);}},require:function(_259,_25a){_259=_23e(_259);_25a&&(_246(_259,_254).result=_277);_255.push(_259);},requireLocalization:function(_25b,_25c,_25d){deps.length||(deps=["dojo/i18n"]);_25d=(_25d||dojo.locale).toLowerCase();_25b=_23e(_25b)+"/nls/"+(/root/i.test(_25d)?"":_25d+"/")+_23e(_25c);if(_246(_25b,_254).isXd){deps.push("dojo/i18n!"+_25b);}},loadInit:function(f){f();}};try{for(p in _256){hold[p]=dojo[p];dojo[p]=_256[p];}_252.def.apply(null,args);}catch(e){_27e("error",[_23d("failedDojoLoadInit"),e]);}finally{for(p in _256){dojo[p]=hold[p];}}_255.length&&deps.push("dojo/require!"+_255.join(","));_240.push(_251);_23c.forEach(_255,function(mid){var _25e=_246(mid,_250.module);_241.push(_25e);_247(_25e);});_248();});});},_25f=function(text,_260,_261){var _262=/\(|\)/g,_263=1,_264;_262.lastIndex=_260;while((_264=_262.exec(text))){if(_264[0]==")"){_263-=1;}else{_263+=1;}if(_263==0){break;}}if(_263!=0){throw "unmatched paren around character "+_262.lastIndex+" in: "+text;}return [dojo.trim(text.substring(_261,_262.lastIndex))+";\n",_262.lastIndex];},_265=/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg,_266=/(^|\s)dojo\.(loadInit|require|provide|requireLocalization|requireIf|requireAfterIf|platformRequire)\s*\(/mg,_267=/(^|\s)(require|define)\s*\(/m,_268=function(text,_269){var _26a,_26b,_26c,_26d,_26e=[],_26f=[],_270=[];_269=_269||text.replace(_265,function(_271){_266.lastIndex=_267.lastIndex=0;return (_266.test(_271)||_267.test(_271))?"":_271;});while((_26a=_266.exec(_269))){_26b=_266.lastIndex;_26c=_26b-_26a[0].length;_26d=_25f(_269,_26b,_26c);if(_26a[2]=="loadInit"){_26e.push(_26d[0]);}else{_26f.push(_26d[0]);}_266.lastIndex=_26d[1];}_270=_26e.concat(_26f);if(_270.length||!_267.test(_269)){return [text.replace(/(^|\s)dojo\.loadInit\s*\(/g,"\n0 && dojo.loadInit("),_270.join(""),_270];}else{return 0;}},_272=function(_273,text){var _274,id,_275=[],_276=[];if(_23f.test(text)||!(_274=_268(text))){return 0;}id=_273.mid+"-*loadInit";for(var p in _246("dojo",_273).result.scopeMap){_275.push(p);_276.push("\""+p+"\"");}return "// xdomain rewrite of "+_273.path+"\n"+"define('"+id+"',{\n"+"\tnames:"+dojo.toJson(_275)+",\n"+"\tdef:function("+_275.join(",")+"){"+_274[1]+"}"+"});\n\n"+"define("+dojo.toJson(_275.concat(["dojo/loadInit!"+id]))+", function("+_275.join(",")+"){\n"+_274[0]+"});";},_24e=_23a.initSyncLoader(_242,_248,_272),sync=_24e.sync,xd=_24e.xd,_24b=_24e.arrived,_277=_24e.nonmodule,_278=_24e.executing,_279=_24e.executed,_27a=_24e.syncExecStack,_27b=_24e.modules,_27c=_24e.execQ,_246=_24e.getModule,_247=_24e.injectModule,_27d=_24e.setArrived,_27e=_24e.signal,_27f=_24e.finishExec,_280=_24e.execModule,_281=_24e.getLegacyMode;dojo.provide=function(mid){var _282=_27a[0],_283=lang.mixin(_246(_23e(mid),_23a.module),{executed:_278,result:lang.getObject(mid,true)});_27d(_283);if(_282){(_282.provides||(_282.provides=[])).push(function(){_283.result=lang.getObject(mid);delete _283.provides;_283.executed!==_279&&_27f(_283);});}return _283.result;};has.add("config-publishRequireResult",1,0,0);dojo.require=function(_284,_285){function _286(mid,_287){var _288=_246(_23e(mid),_23a.module);if(_27a.length&&_27a[0].finish){_27a[0].finish.push(mid);return undefined;}if(_288.executed){return _288.result;}_287&&(_288.result=_277);var _289=_281();_247(_288);_289=_281();if(_288.executed!==_279&&_288.injected===_24b){_24e.holdIdle();_280(_288);_24e.releaseIdle();}if(_288.executed){return _288.result;}if(_289==sync){if(_288.cjs){_27c.unshift(_288);}else{_27a.length&&(_27a[0].finish=[mid]);}}else{_27c.push(_288);}return undefined;};var _28a=_286(_284,_285);if(has("config-publishRequireResult")&&!lang.exists(_284)&&_28a!==undefined){lang.setObject(_284,_28a);}return _28a;};dojo.loadInit=function(f){f();};dojo.registerModulePath=function(_28b,_28c){var _28d={};_28d[_28b.replace(/\./g,"/")]=_28c;_23a({paths:_28d});};dojo.platformRequire=function(_28e){var _28f=(_28e.common||[]).concat(_28e[dojo._name]||_28e["default"]||[]),temp;while(_28f.length){if(lang.isArray(temp=_28f.shift())){dojo.require.apply(dojo,temp);}else{dojo.require(temp);}}};dojo.requireIf=dojo.requireAfterIf=function(_290,_291,_292){if(_290){dojo.require(_291,_292);}};dojo.requireLocalization=function(_293,_294,_295){_23a(["../i18n"],function(i18n){i18n.getLocalization(_293,_294,_295);});};return {extractLegacyApiApplications:_268,require:_24e.dojoRequirePlugin,loadInit:_24f};});},"dojo/json":function(){define(["./has"],function(has){"use strict";var _296=typeof JSON!="undefined";has.add("json-parse",_296);has.add("json-stringify",_296&&JSON.stringify({a:0},function(k,v){return v||1;})=="{\"a\":1}");if(has("json-stringify")){return JSON;}else{var _297=function(str){return ("\""+str.replace(/(["\\])/g,"\\$1")+"\"").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r");};return {parse:has("json-parse")?JSON.parse:function(str,_298){if(_298&&!/^([\s\[\{]*(?:"(?:\\.|[^"])+"|-?\d[\d\.]*(?:[Ee][+-]?\d+)?|null|true|false|)[\s\]\}]*(?:,|:|$))+$/.test(str)){throw new SyntaxError("Invalid characters in JSON");}return eval("("+str+")");},stringify:function(_299,_29a,_29b){var _29c;if(typeof _29a=="string"){_29b=_29a;_29a=null;}function _29d(it,_29e,key){if(_29a){it=_29a(key,it);}var val,_29f=typeof it;if(_29f=="number"){return isFinite(it)?it+"":"null";}if(_29f=="boolean"){return it+"";}if(it===null){return "null";}if(typeof it=="string"){return _297(it);}if(_29f=="function"||_29f=="undefined"){return _29c;}if(typeof it.toJSON=="function"){return _29d(it.toJSON(key),_29e,key);}if(it instanceof Date){return "\"{FullYear}-{Month+}-{Date}T{Hours}:{Minutes}:{Seconds}Z\"".replace(/\{(\w+)(\+)?\}/g,function(t,prop,plus){var num=it["getUTC"+prop]()+(plus?1:0);return num<10?"0"+num:num;});}if(it.valueOf()!==it){return _29d(it.valueOf(),_29e,key);}var _2a0=_29b?(_29e+_29b):"";var sep=_29b?" ":"";var _2a1=_29b?"\n":"";if(it instanceof Array){var itl=it.length,res=[];for(key=0;key<itl;key++){var obj=it[key];val=_29d(obj,_2a0,key);if(typeof val!="string"){val="null";}res.push(_2a1+_2a0+val);}return "["+res.join(",")+_2a1+_29e+"]";}var _2a2=[];for(key in it){var _2a3;if(typeof key=="number"){_2a3="\""+key+"\"";}else{if(typeof key=="string"){_2a3=_297(key);}else{continue;}}val=_29d(it[key],_2a0,key);if(typeof val!="string"){continue;}_2a2.push(_2a1+_2a0+_2a3+":"+sep+val);}return "{"+_2a2.join(",")+_2a1+_29e+"}";};return _29d(_299,"","");}};}});},"dojo/_base/declare":function(){define(["./kernel","../has","./lang"],function(dojo,has,lang){var mix=lang.mixin,op=Object.prototype,opts=op.toString,xtor=new Function,_2a4=0,_2a5="constructor";function err(msg,cls){throw new Error("declare"+(cls?" "+cls:"")+": "+msg);};function _2a6(_2a7,_2a8){var _2a9=[],_2aa=[{cls:0,refs:[]}],_2ab={},_2ac=1,l=_2a7.length,i=0,j,lin,base,top,_2ad,rec,name,refs;for(;i<l;++i){base=_2a7[i];if(!base){err("mixin #"+i+" is unknown. Did you use dojo.require to pull it in?",_2a8);}else{if(opts.call(base)!="[object Function]"){err("mixin #"+i+" is not a callable constructor.",_2a8);}}lin=base._meta?base._meta.bases:[base];top=0;for(j=lin.length-1;j>=0;--j){_2ad=lin[j].prototype;if(!_2ad.hasOwnProperty("declaredClass")){_2ad.declaredClass="uniqName_"+(_2a4++);}name=_2ad.declaredClass;if(!_2ab.hasOwnProperty(name)){_2ab[name]={count:0,refs:[],cls:lin[j]};++_2ac;}rec=_2ab[name];if(top&&top!==rec){rec.refs.push(top);++top.count;}top=rec;}++top.count;_2aa[0].refs.push(top);}while(_2aa.length){top=_2aa.pop();_2a9.push(top.cls);--_2ac;while(refs=top.refs,refs.length==1){top=refs[0];if(!top||--top.count){top=0;break;}_2a9.push(top.cls);--_2ac;}if(top){for(i=0,l=refs.length;i<l;++i){top=refs[i];if(!--top.count){_2aa.push(top);}}}}if(_2ac){err("can't build consistent linearization",_2a8);}base=_2a7[0];_2a9[0]=base?base._meta&&base===_2a9[_2a9.length-base._meta.bases.length]?base._meta.bases.length:1:0;return _2a9;};function _2ae(args,a,f){var name,_2af,_2b0,_2b1,meta,base,_2b2,opf,pos,_2b3=this._inherited=this._inherited||{};if(typeof args=="string"){name=args;args=a;a=f;}f=0;_2b1=args.callee;name=name||_2b1.nom;if(!name){err("can't deduce a name to call inherited()",this.declaredClass);}meta=this.constructor._meta;_2b0=meta.bases;pos=_2b3.p;if(name!=_2a5){if(_2b3.c!==_2b1){pos=0;base=_2b0[0];meta=base._meta;if(meta.hidden[name]!==_2b1){_2af=meta.chains;if(_2af&&typeof _2af[name]=="string"){err("calling chained method with inherited: "+name,this.declaredClass);}do{meta=base._meta;_2b2=base.prototype;if(meta&&(_2b2[name]===_2b1&&_2b2.hasOwnProperty(name)||meta.hidden[name]===_2b1)){break;}}while(base=_2b0[++pos]);pos=base?pos:-1;}}base=_2b0[++pos];if(base){_2b2=base.prototype;if(base._meta&&_2b2.hasOwnProperty(name)){f=_2b2[name];}else{opf=op[name];do{_2b2=base.prototype;f=_2b2[name];if(f&&(base._meta?_2b2.hasOwnProperty(name):f!==opf)){break;}}while(base=_2b0[++pos]);}}f=base&&f||op[name];}else{if(_2b3.c!==_2b1){pos=0;meta=_2b0[0]._meta;if(meta&&meta.ctor!==_2b1){_2af=meta.chains;if(!_2af||_2af.constructor!=="manual"){err("calling chained constructor with inherited",this.declaredClass);}while(base=_2b0[++pos]){meta=base._meta;if(meta&&meta.ctor===_2b1){break;}}pos=base?pos:-1;}}while(base=_2b0[++pos]){meta=base._meta;f=meta?meta.ctor:base;if(f){break;}}f=base&&f;}_2b3.c=f;_2b3.p=pos;if(f){return a===true?f:f.apply(this,a||args);}};function _2b4(name,args){if(typeof name=="string"){return this.__inherited(name,args,true);}return this.__inherited(name,true);};function _2b5(args,a1,a2){var f=this.getInherited(args,a1);if(f){return f.apply(this,a2||a1||args);}};var _2b6=dojo.config.isDebug?_2b5:_2ae;function _2b7(cls){var _2b8=this.constructor._meta.bases;for(var i=0,l=_2b8.length;i<l;++i){if(_2b8[i]===cls){return true;}}return this instanceof cls;};function _2b9(_2ba,_2bb){for(var name in _2bb){if(name!=_2a5&&_2bb.hasOwnProperty(name)){_2ba[name]=_2bb[name];}}if(has("bug-for-in-skips-shadowed")){for(var _2bc=lang._extraNames,i=_2bc.length;i;){name=_2bc[--i];if(name!=_2a5&&_2bb.hasOwnProperty(name)){_2ba[name]=_2bb[name];}}}};function _2bd(_2be,_2bf){var name,t;for(name in _2bf){t=_2bf[name];if((t!==op[name]||!(name in op))&&name!=_2a5){if(opts.call(t)=="[object Function]"){t.nom=name;}_2be[name]=t;}}if(has("bug-for-in-skips-shadowed")){for(var _2c0=lang._extraNames,i=_2c0.length;i;){name=_2c0[--i];t=_2bf[name];if((t!==op[name]||!(name in op))&&name!=_2a5){if(opts.call(t)=="[object Function]"){t.nom=name;}_2be[name]=t;}}}return _2be;};function _2c1(_2c2){_2c3.safeMixin(this.prototype,_2c2);return this;};function _2c4(_2c5,_2c6){return function(){var a=arguments,args=a,a0=a[0],f,i,m,l=_2c5.length,_2c7;if(!(this instanceof a.callee)){return _2c8(a);}if(_2c6&&(a0&&a0.preamble||this.preamble)){_2c7=new Array(_2c5.length);_2c7[0]=a;for(i=0;;){a0=a[0];if(a0){f=a0.preamble;if(f){a=f.apply(this,a)||a;}}f=_2c5[i].prototype;f=f.hasOwnProperty("preamble")&&f.preamble;if(f){a=f.apply(this,a)||a;}if(++i==l){break;}_2c7[i]=a;}}for(i=l-1;i>=0;--i){f=_2c5[i];m=f._meta;f=m?m.ctor:f;if(f){f.apply(this,_2c7?_2c7[i]:a);}}f=this.postscript;if(f){f.apply(this,args);}};};function _2c9(ctor,_2ca){return function(){var a=arguments,t=a,a0=a[0],f;if(!(this instanceof a.callee)){return _2c8(a);}if(_2ca){if(a0){f=a0.preamble;if(f){t=f.apply(this,t)||t;}}f=this.preamble;if(f){f.apply(this,t);}}if(ctor){ctor.apply(this,a);}f=this.postscript;if(f){f.apply(this,a);}};};function _2cb(_2cc){return function(){var a=arguments,i=0,f,m;if(!(this instanceof a.callee)){return _2c8(a);}for(;f=_2cc[i];++i){m=f._meta;f=m?m.ctor:f;if(f){f.apply(this,a);break;}}f=this.postscript;if(f){f.apply(this,a);}};};function _2cd(name,_2ce,_2cf){return function(){var b,m,f,i=0,step=1;if(_2cf){i=_2ce.length-1;step=-1;}for(;b=_2ce[i];i+=step){m=b._meta;f=(m?m.hidden:b.prototype)[name];if(f){f.apply(this,arguments);}}};};function _2d0(ctor){xtor.prototype=ctor.prototype;var t=new xtor;xtor.prototype=null;return t;};function _2c8(args){var ctor=args.callee,t=_2d0(ctor);ctor.apply(t,args);return t;};function _2c3(_2d1,_2d2,_2d3){if(typeof _2d1!="string"){_2d3=_2d2;_2d2=_2d1;_2d1="";}_2d3=_2d3||{};var _2d4,i,t,ctor,name,_2d5,_2d6,_2d7=1,_2d8=_2d2;if(opts.call(_2d2)=="[object Array]"){_2d5=_2a6(_2d2,_2d1);t=_2d5[0];_2d7=_2d5.length-t;_2d2=_2d5[_2d7];}else{_2d5=[0];if(_2d2){if(opts.call(_2d2)=="[object Function]"){t=_2d2._meta;_2d5=_2d5.concat(t?t.bases:_2d2);}else{err("base class is not a callable constructor.",_2d1);}}else{if(_2d2!==null){err("unknown base class. Did you use dojo.require to pull it in?",_2d1);}}}if(_2d2){for(i=_2d7-1;;--i){_2d4=_2d0(_2d2);if(!i){break;}t=_2d5[i];(t._meta?_2b9:mix)(_2d4,t.prototype);ctor=new Function;ctor.superclass=_2d2;ctor.prototype=_2d4;_2d2=_2d4.constructor=ctor;}}else{_2d4={};}_2c3.safeMixin(_2d4,_2d3);t=_2d3.constructor;if(t!==op.constructor){t.nom=_2a5;_2d4.constructor=t;}for(i=_2d7-1;i;--i){t=_2d5[i]._meta;if(t&&t.chains){_2d6=mix(_2d6||{},t.chains);}}if(_2d4["-chains-"]){_2d6=mix(_2d6||{},_2d4["-chains-"]);}t=!_2d6||!_2d6.hasOwnProperty(_2a5);_2d5[0]=ctor=(_2d6&&_2d6.constructor==="manual")?_2cb(_2d5):(_2d5.length==1?_2c9(_2d3.constructor,t):_2c4(_2d5,t));ctor._meta={bases:_2d5,hidden:_2d3,chains:_2d6,parents:_2d8,ctor:_2d3.constructor};ctor.superclass=_2d2&&_2d2.prototype;ctor.extend=_2c1;ctor.prototype=_2d4;_2d4.constructor=ctor;_2d4.getInherited=_2b4;_2d4.isInstanceOf=_2b7;_2d4.inherited=_2b6;_2d4.__inherited=_2ae;if(_2d1){_2d4.declaredClass=_2d1;lang.setObject(_2d1,ctor);}if(_2d6){for(name in _2d6){if(_2d4[name]&&typeof _2d6[name]=="string"&&name!=_2a5){t=_2d4[name]=_2cd(name,_2d5,_2d6[name]==="after");t.nom=name;}}}return ctor;};dojo.safeMixin=_2c3.safeMixin=_2bd;dojo.declare=_2c3;return _2c3;});},"dojo/dom":function(){define(["./_base/sniff","./_base/lang","./_base/window"],function(has,lang,win){try{document.execCommand("BackgroundImageCache",false,true);}catch(e){}var dom={};if(has("ie")){dom.byId=function(id,doc){if(typeof id!="string"){return id;}var _2d9=doc||win.doc,te=id&&_2d9.getElementById(id);if(te&&(te.attributes.id.value==id||te.id==id)){return te;}else{var eles=_2d9.all[id];if(!eles||eles.nodeName){eles=[eles];}var i=0;while((te=eles[i++])){if((te.attributes&&te.attributes.id&&te.attributes.id.value==id)||te.id==id){return te;}}}};}else{dom.byId=function(id,doc){return ((typeof id=="string")?(doc||win.doc).getElementById(id):id)||null;};}dom.isDescendant=function(node,_2da){try{node=dom.byId(node);_2da=dom.byId(_2da);while(node){if(node==_2da){return true;}node=node.parentNode;}}catch(e){}return false;};dom.setSelectable=function(node,_2db){node=dom.byId(node);if(has("mozilla")){node.style.MozUserSelect=_2db?"":"none";}else{if(has("khtml")||has("webkit")){node.style.KhtmlUserSelect=_2db?"auto":"none";}else{if(has("ie")){var v=(node.unselectable=_2db?"":"on"),cs=node.getElementsByTagName("*"),i=0,l=cs.length;for(;i<l;++i){cs.item(i).unselectable=v;}}}}};return dom;});},"dojo/_base/browser":function(){if(require.has){require.has.add("config-selectorEngine","acme");}define("dojo/_base/browser",["../ready","./kernel","./connect","./unload","./window","./event","./html","./NodeList","../query","./xhr","./fx"],function(dojo){return dojo;});},"dojo/selector/acme":function(){define(["../_base/kernel","../has","../dom","../_base/sniff","../_base/array","../_base/lang","../_base/window"],function(dojo,has,dom){var trim=dojo.trim;var each=dojo.forEach;var _2dc=function(){return dojo.doc;};var _2dd=((dojo.isWebKit||dojo.isMozilla)&&((_2dc().compatMode)=="BackCompat"));var _2de=">~+";var _2df=false;var _2e0=function(){return true;};var _2e1=function(_2e2){if(_2de.indexOf(_2e2.slice(-1))>=0){_2e2+=" * ";}else{_2e2+=" ";}var ts=function(s,e){return trim(_2e2.slice(s,e));};var _2e3=[];var _2e4=-1,_2e5=-1,_2e6=-1,_2e7=-1,_2e8=-1,inId=-1,_2e9=-1,lc="",cc="",_2ea;var x=0,ql=_2e2.length,_2eb=null,_2ec=null;var _2ed=function(){if(_2e9>=0){var tv=(_2e9==x)?null:ts(_2e9,x);_2eb[(_2de.indexOf(tv)<0)?"tag":"oper"]=tv;_2e9=-1;}};var _2ee=function(){if(inId>=0){_2eb.id=ts(inId,x).replace(/\\/g,"");inId=-1;}};var _2ef=function(){if(_2e8>=0){_2eb.classes.push(ts(_2e8+1,x).replace(/\\/g,""));_2e8=-1;}};var _2f0=function(){_2ee();_2ed();_2ef();};var _2f1=function(){_2f0();if(_2e7>=0){_2eb.pseudos.push({name:ts(_2e7+1,x)});}_2eb.loops=(_2eb.pseudos.length||_2eb.attrs.length||_2eb.classes.length);_2eb.oquery=_2eb.query=ts(_2ea,x);_2eb.otag=_2eb.tag=(_2eb["oper"])?null:(_2eb.tag||"*");if(_2eb.tag){_2eb.tag=_2eb.tag.toUpperCase();}if(_2e3.length&&(_2e3[_2e3.length-1].oper)){_2eb.infixOper=_2e3.pop();_2eb.query=_2eb.infixOper.query+" "+_2eb.query;}_2e3.push(_2eb);_2eb=null;};for(;lc=cc,cc=_2e2.charAt(x),x<ql;x++){if(lc=="\\"){continue;}if(!_2eb){_2ea=x;_2eb={query:null,pseudos:[],attrs:[],classes:[],tag:null,oper:null,id:null,getTag:function(){return (_2df)?this.otag:this.tag;}};_2e9=x;}if(_2e4>=0){if(cc=="]"){if(!_2ec.attr){_2ec.attr=ts(_2e4+1,x);}else{_2ec.matchFor=ts((_2e6||_2e4+1),x);}var cmf=_2ec.matchFor;if(cmf){if((cmf.charAt(0)=="\"")||(cmf.charAt(0)=="'")){_2ec.matchFor=cmf.slice(1,-1);}}_2eb.attrs.push(_2ec);_2ec=null;_2e4=_2e6=-1;}else{if(cc=="="){var _2f2=("|~^$*".indexOf(lc)>=0)?lc:"";_2ec.type=_2f2+cc;_2ec.attr=ts(_2e4+1,x-_2f2.length);_2e6=x+1;}}}else{if(_2e5>=0){if(cc==")"){if(_2e7>=0){_2ec.value=ts(_2e5+1,x);}_2e7=_2e5=-1;}}else{if(cc=="#"){_2f0();inId=x+1;}else{if(cc=="."){_2f0();_2e8=x;}else{if(cc==":"){_2f0();_2e7=x;}else{if(cc=="["){_2f0();_2e4=x;_2ec={};}else{if(cc=="("){if(_2e7>=0){_2ec={name:ts(_2e7+1,x),value:null};_2eb.pseudos.push(_2ec);}_2e5=x;}else{if((cc==" ")&&(lc!=cc)){_2f1();}}}}}}}}}return _2e3;};var _2f3=function(_2f4,_2f5){if(!_2f4){return _2f5;}if(!_2f5){return _2f4;}return function(){return _2f4.apply(window,arguments)&&_2f5.apply(window,arguments);};};var _2f6=function(i,arr){var r=arr||[];if(i){r.push(i);}return r;};var _2f7=function(n){return (1==n.nodeType);};var _2f8="";var _2f9=function(elem,attr){if(!elem){return _2f8;}if(attr=="class"){return elem.className||_2f8;}if(attr=="for"){return elem.htmlFor||_2f8;}if(attr=="style"){return elem.style.cssText||_2f8;}return (_2df?elem.getAttribute(attr):elem.getAttribute(attr,2))||_2f8;};var _2fa={"*=":function(attr,_2fb){return function(elem){return (_2f9(elem,attr).indexOf(_2fb)>=0);};},"^=":function(attr,_2fc){return function(elem){return (_2f9(elem,attr).indexOf(_2fc)==0);};},"$=":function(attr,_2fd){return function(elem){var ea=" "+_2f9(elem,attr);return (ea.lastIndexOf(_2fd)==(ea.length-_2fd.length));};},"~=":function(attr,_2fe){var tval=" "+_2fe+" ";return function(elem){var ea=" "+_2f9(elem,attr)+" ";return (ea.indexOf(tval)>=0);};},"|=":function(attr,_2ff){var _300=_2ff+"-";return function(elem){var ea=_2f9(elem,attr);return ((ea==_2ff)||(ea.indexOf(_300)==0));};},"=":function(attr,_301){return function(elem){return (_2f9(elem,attr)==_301);};}};var _302=(typeof _2dc().firstChild.nextElementSibling=="undefined");var _303=!_302?"nextElementSibling":"nextSibling";var _304=!_302?"previousElementSibling":"previousSibling";var _305=(_302?_2f7:_2e0);var _306=function(node){while(node=node[_304]){if(_305(node)){return false;}}return true;};var _307=function(node){while(node=node[_303]){if(_305(node)){return false;}}return true;};var _308=function(node){var root=node.parentNode;var i=0,tret=root.children||root.childNodes,ci=(node["_i"]||-1),cl=(root["_l"]||-1);if(!tret){return -1;}var l=tret.length;if(cl==l&&ci>=0&&cl>=0){return ci;}root["_l"]=l;ci=-1;for(var te=root["firstElementChild"]||root["firstChild"];te;te=te[_303]){if(_305(te)){te["_i"]=++i;if(node===te){ci=i;}}}return ci;};var _309=function(elem){return !((_308(elem))%2);};var _30a=function(elem){return ((_308(elem))%2);};var _30b={"checked":function(name,_30c){return function(elem){return !!("checked" in elem?elem.checked:elem.selected);};},"first-child":function(){return _306;},"last-child":function(){return _307;},"only-child":function(name,_30d){return function(node){return _306(node)&&_307(node);};},"empty":function(name,_30e){return function(elem){var cn=elem.childNodes;var cnl=elem.childNodes.length;for(var x=cnl-1;x>=0;x--){var nt=cn[x].nodeType;if((nt===1)||(nt==3)){return false;}}return true;};},"contains":function(name,_30f){var cz=_30f.charAt(0);if(cz=="\""||cz=="'"){_30f=_30f.slice(1,-1);}return function(elem){return (elem.innerHTML.indexOf(_30f)>=0);};},"not":function(name,_310){var p=_2e1(_310)[0];var _311={el:1};if(p.tag!="*"){_311.tag=1;}if(!p.classes.length){_311.classes=1;}var ntf=_312(p,_311);return function(elem){return (!ntf(elem));};},"nth-child":function(name,_313){var pi=parseInt;if(_313=="odd"){return _30a;}else{if(_313=="even"){return _309;}}if(_313.indexOf("n")!=-1){var _314=_313.split("n",2);var pred=_314[0]?((_314[0]=="-")?-1:pi(_314[0])):1;var idx=_314[1]?pi(_314[1]):0;var lb=0,ub=-1;if(pred>0){if(idx<0){idx=(idx%pred)&&(pred+(idx%pred));}else{if(idx>0){if(idx>=pred){lb=idx-idx%pred;}idx=idx%pred;}}}else{if(pred<0){pred*=-1;if(idx>0){ub=idx;idx=idx%pred;}}}if(pred>0){return function(elem){var i=_308(elem);return (i>=lb)&&(ub<0||i<=ub)&&((i%pred)==idx);};}else{_313=idx;}}var _315=pi(_313);return function(elem){return (_308(elem)==_315);};}};var _316=(dojo.isIE&&(dojo.isIE<9||dojo.isQuirks))?function(cond){var clc=cond.toLowerCase();if(clc=="class"){cond="className";}return function(elem){return (_2df?elem.getAttribute(cond):elem[cond]||elem[clc]);};}:function(cond){return function(elem){return (elem&&elem.getAttribute&&elem.hasAttribute(cond));};};var _312=function(_317,_318){if(!_317){return _2e0;}_318=_318||{};var ff=null;if(!("el" in _318)){ff=_2f3(ff,_2f7);}if(!("tag" in _318)){if(_317.tag!="*"){ff=_2f3(ff,function(elem){return (elem&&(elem.tagName==_317.getTag()));});}}if(!("classes" in _318)){each(_317.classes,function(_319,idx,arr){var re=new RegExp("(?:^|\\s)"+_319+"(?:\\s|$)");ff=_2f3(ff,function(elem){return re.test(elem.className);});ff.count=idx;});}if(!("pseudos" in _318)){each(_317.pseudos,function(_31a){var pn=_31a.name;if(_30b[pn]){ff=_2f3(ff,_30b[pn](pn,_31a.value));}});}if(!("attrs" in _318)){each(_317.attrs,function(attr){var _31b;var a=attr.attr;if(attr.type&&_2fa[attr.type]){_31b=_2fa[attr.type](a,attr.matchFor);}else{if(a.length){_31b=_316(a);}}if(_31b){ff=_2f3(ff,_31b);}});}if(!("id" in _318)){if(_317.id){ff=_2f3(ff,function(elem){return (!!elem&&(elem.id==_317.id));});}}if(!ff){if(!("default" in _318)){ff=_2e0;}}return ff;};var _31c=function(_31d){return function(node,ret,bag){while(node=node[_303]){if(_302&&(!_2f7(node))){continue;}if((!bag||_31e(node,bag))&&_31d(node)){ret.push(node);}break;}return ret;};};var _31f=function(_320){return function(root,ret,bag){var te=root[_303];while(te){if(_305(te)){if(bag&&!_31e(te,bag)){break;}if(_320(te)){ret.push(te);}}te=te[_303];}return ret;};};var _321=function(_322){_322=_322||_2e0;return function(root,ret,bag){var te,x=0,tret=root.children||root.childNodes;while(te=tret[x++]){if(_305(te)&&(!bag||_31e(te,bag))&&(_322(te,x))){ret.push(te);}}return ret;};};var _323=function(node,root){var pn=node.parentNode;while(pn){if(pn==root){break;}pn=pn.parentNode;}return !!pn;};var _324={};var _325=function(_326){var _327=_324[_326.query];if(_327){return _327;}var io=_326.infixOper;var oper=(io?io.oper:"");var _328=_312(_326,{el:1});var qt=_326.tag;var _329=("*"==qt);var ecs=_2dc()["getElementsByClassName"];if(!oper){if(_326.id){_328=(!_326.loops&&_329)?_2e0:_312(_326,{el:1,id:1});_327=function(root,arr){var te=dom.byId(_326.id,(root.ownerDocument||root));if(!te||!_328(te)){return;}if(9==root.nodeType){return _2f6(te,arr);}else{if(_323(te,root)){return _2f6(te,arr);}}};}else{if(ecs&&/\{\s*\[native code\]\s*\}/.test(String(ecs))&&_326.classes.length&&!_2dd){_328=_312(_326,{el:1,classes:1,id:1});var _32a=_326.classes.join(" ");_327=function(root,arr,bag){var ret=_2f6(0,arr),te,x=0;var tret=root.getElementsByClassName(_32a);while((te=tret[x++])){if(_328(te,root)&&_31e(te,bag)){ret.push(te);}}return ret;};}else{if(!_329&&!_326.loops){_327=function(root,arr,bag){var ret=_2f6(0,arr),te,x=0;var tret=root.getElementsByTagName(_326.getTag());while((te=tret[x++])){if(_31e(te,bag)){ret.push(te);}}return ret;};}else{_328=_312(_326,{el:1,tag:1,id:1});_327=function(root,arr,bag){var ret=_2f6(0,arr),te,x=0;var tret=root.getElementsByTagName(_326.getTag());while((te=tret[x++])){if(_328(te,root)&&_31e(te,bag)){ret.push(te);}}return ret;};}}}}else{var _32b={el:1};if(_329){_32b.tag=1;}_328=_312(_326,_32b);if("+"==oper){_327=_31c(_328);}else{if("~"==oper){_327=_31f(_328);}else{if(">"==oper){_327=_321(_328);}}}}return _324[_326.query]=_327;};var _32c=function(root,_32d){var _32e=_2f6(root),qp,x,te,qpl=_32d.length,bag,ret;for(var i=0;i<qpl;i++){ret=[];qp=_32d[i];x=_32e.length-1;if(x>0){bag={};ret.nozip=true;}var gef=_325(qp);for(var j=0;(te=_32e[j]);j++){gef(te,ret,bag);}if(!ret.length){break;}_32e=ret;}return ret;};var _32f={},_330={};var _331=function(_332){var _333=_2e1(trim(_332));if(_333.length==1){var tef=_325(_333[0]);return function(root){var r=tef(root,[]);if(r){r.nozip=true;}return r;};}return function(root){return _32c(root,_333);};};var nua=navigator.userAgent;var wk="WebKit/";var _334=(dojo.isWebKit&&(nua.indexOf(wk)>0)&&(parseFloat(nua.split(wk)[1])>528));var _335=dojo.isIE?"commentStrip":"nozip";var qsa="querySelectorAll";var _336=(!!_2dc()[qsa]&&(!dojo.isSafari||(dojo.isSafari>3.1)||_334));var _337=/n\+\d|([^ ])?([>~+])([^ =])?/g;var _338=function(_339,pre,ch,post){return ch?(pre?pre+" ":"")+ch+(post?" "+post:""):_339;};var _33a=function(_33b,_33c){_33b=_33b.replace(_337,_338);if(_336){var _33d=_330[_33b];if(_33d&&!_33c){return _33d;}}var _33e=_32f[_33b];if(_33e){return _33e;}var qcz=_33b.charAt(0);var _33f=(-1==_33b.indexOf(" "));if((_33b.indexOf("#")>=0)&&(_33f)){_33c=true;}var _340=(_336&&(!_33c)&&(_2de.indexOf(qcz)==-1)&&(!dojo.isIE||(_33b.indexOf(":")==-1))&&(!(_2dd&&(_33b.indexOf(".")>=0)))&&(_33b.indexOf(":contains")==-1)&&(_33b.indexOf(":checked")==-1)&&(_33b.indexOf("|=")==-1));if(_340){var tq=(_2de.indexOf(_33b.charAt(_33b.length-1))>=0)?(_33b+" *"):_33b;return _330[_33b]=function(root){try{if(!((9==root.nodeType)||_33f)){throw "";}var r=root[qsa](tq);r[_335]=true;return r;}catch(e){return _33a(_33b,true)(root);}};}else{var _341=_33b.split(/\s*,\s*/);return _32f[_33b]=((_341.length<2)?_331(_33b):function(root){var _342=0,ret=[],tp;while((tp=_341[_342++])){ret=ret.concat(_331(tp)(root));}return ret;});}};var _343=0;var _344=dojo.isIE?function(node){if(_2df){return (node.getAttribute("_uid")||node.setAttribute("_uid",++_343)||_343);}else{return node.uniqueID;}}:function(node){return (node._uid||(node._uid=++_343));};var _31e=function(node,bag){if(!bag){return 1;}var id=_344(node);if(!bag[id]){return bag[id]=1;}return 0;};var _345="_zipIdx";var _346=function(arr){if(arr&&arr.nozip){return arr;}var ret=[];if(!arr||!arr.length){return ret;}if(arr[0]){ret.push(arr[0]);}if(arr.length<2){return ret;}_343++;if(dojo.isIE&&_2df){var _347=_343+"";arr[0].setAttribute(_345,_347);for(var x=1,te;te=arr[x];x++){if(arr[x].getAttribute(_345)!=_347){ret.push(te);}te.setAttribute(_345,_347);}}else{if(dojo.isIE&&arr.commentStrip){try{for(var x=1,te;te=arr[x];x++){if(_2f7(te)){ret.push(te);}}}catch(e){}}else{if(arr[0]){arr[0][_345]=_343;}for(var x=1,te;te=arr[x];x++){if(arr[x][_345]!=_343){ret.push(te);}te[_345]=_343;}}}return ret;};var _348=function(_349,root){root=root||_2dc();var od=root.ownerDocument||root.documentElement;_2df=(root.contentType&&root.contentType=="application/xml")||(dojo.isOpera&&(root.doctype||od.toString()=="[object XMLDocument]"))||(!!od)&&(dojo.isIE?od.xml:(root.xmlVersion||od.xmlVersion));var r=_33a(_349)(root);if(r&&r.nozip){return r;}return _346(r);};_348.filter=function(_34a,_34b,root){var _34c=[],_34d=_2e1(_34b),_34e=(_34d.length==1&&!/[^\w#\.]/.test(_34b))?_312(_34d[0]):function(node){return dojo.query(_34b,root).indexOf(node)!=-1;};for(var x=0,te;te=_34a[x];x++){if(_34e(te)){_34c.push(te);}}return _34c;};return _348;});},"dojo/dom-style":function(){define(["./_base/sniff","./dom"],function(has,dom){var _34f,_350={};if(has("webkit")){_34f=function(node){var s;if(node.nodeType==1){var dv=node.ownerDocument.defaultView;s=dv.getComputedStyle(node,null);if(!s&&node.style){node.style.display="";s=dv.getComputedStyle(node,null);}}return s||{};};}else{if(has("ie")&&(has("ie")<9||has("quirks"))){_34f=function(node){return node.nodeType==1?node.currentStyle:{};};}else{_34f=function(node){return node.nodeType==1?node.ownerDocument.defaultView.getComputedStyle(node,null):{};};}}_350.getComputedStyle=_34f;var _351;if(!has("ie")){_351=function(_352,_353){return parseFloat(_353)||0;};}else{_351=function(_354,_355){if(!_355){return 0;}if(_355=="medium"){return 4;}if(_355.slice&&_355.slice(-2)=="px"){return parseFloat(_355);}var s=_354.style,rs=_354.runtimeStyle,cs=_354.currentStyle,_356=s.left,_357=rs.left;rs.left=cs.left;try{s.left=_355;_355=s.pixelLeft;}catch(e){_355=0;}s.left=_356;rs.left=_357;return _355;};}_350.toPixelValue=_351;var astr="DXImageTransform.Microsoft.Alpha";var af=function(n,f){try{return n.filters.item(astr);}catch(e){return f?{}:null;}};var _358=has("ie")<9||(has("ie")&&has("quirks"))?function(node){try{return af(node).Opacity/100;}catch(e){return 1;}}:function(node){return _34f(node).opacity;};var _359=has("ie")<9||(has("ie")&&has("quirks"))?function(node,_35a){var ov=_35a*100,_35b=_35a==1;node.style.zoom=_35b?"":1;if(!af(node)){if(_35b){return _35a;}node.style.filter+=" progid:"+astr+"(Opacity="+ov+")";}else{af(node,1).Opacity=ov;}af(node,1).Enabled=!_35b;if(node.tagName.toLowerCase()=="tr"){for(var td=node.firstChild;td;td=td.nextSibling){if(td.tagName.toLowerCase()=="td"){_359(td,_35a);}}}return _35a;}:function(node,_35c){return node.style.opacity=_35c;};var _35d={left:true,top:true};var _35e=/margin|padding|width|height|max|min|offset/;function _35f(node,type,_360){type=type.toLowerCase();if(has("ie")){if(_360=="auto"){if(type=="height"){return node.offsetHeight;}if(type=="width"){return node.offsetWidth;}}if(type=="fontweight"){switch(_360){case 700:return "bold";case 400:default:return "normal";}}}if(!(type in _35d)){_35d[type]=_35e.test(type);}return _35d[type]?_351(node,_360):_360;};var _361=has("ie")?"styleFloat":"cssFloat",_362={"cssFloat":_361,"styleFloat":_361,"float":_361};_350.get=function getStyle(node,name){var n=dom.byId(node),l=arguments.length,op=(name=="opacity");if(l==2&&op){return _358(n);}name=_362[name]||name;var s=_350.getComputedStyle(n);return (l==1)?s:_35f(n,name,s[name]||n.style[name]);};_350.set=function setStyle(node,name,_363){var n=dom.byId(node),l=arguments.length,op=(name=="opacity");name=_362[name]||name;if(l==3){return op?_359(n,_363):n.style[name]=_363;}for(var x in name){_350.set(node,x,name[x]);}return _350.getComputedStyle(n);};return _350;});},"dojo/dom-geometry":function(){define(["./_base/sniff","./_base/window","./dom","./dom-style"],function(has,win,dom,_364){var geom={};geom.boxModel="content-box";if(has("ie")){geom.boxModel=document.compatMode=="BackCompat"?"border-box":"content-box";}geom.getPadExtents=function getPadExtents(node,_365){node=dom.byId(node);var s=_365||_364.getComputedStyle(node),px=_364.toPixelValue,l=px(node,s.paddingLeft),t=px(node,s.paddingTop),r=px(node,s.paddingRight),b=px(node,s.paddingBottom);return {l:l,t:t,r:r,b:b,w:l+r,h:t+b};};var none="none";geom.getBorderExtents=function getBorderExtents(node,_366){node=dom.byId(node);var px=_364.toPixelValue,s=_366||_364.getComputedStyle(node),l=s.borderLeftStyle!=none?px(node,s.borderLeftWidth):0,t=s.borderTopStyle!=none?px(node,s.borderTopWidth):0,r=s.borderRightStyle!=none?px(node,s.borderRightWidth):0,b=s.borderBottomStyle!=none?px(node,s.borderBottomWidth):0;return {l:l,t:t,r:r,b:b,w:l+r,h:t+b};};geom.getPadBorderExtents=function getPadBorderExtents(node,_367){node=dom.byId(node);var s=_367||_364.getComputedStyle(node),p=geom.getPadExtents(node,s),b=geom.getBorderExtents(node,s);return {l:p.l+b.l,t:p.t+b.t,r:p.r+b.r,b:p.b+b.b,w:p.w+b.w,h:p.h+b.h};};geom.getMarginExtents=function getMarginExtents(node,_368){node=dom.byId(node);var s=_368||_364.getComputedStyle(node),px=_364.toPixelValue,l=px(node,s.marginLeft),t=px(node,s.marginTop),r=px(node,s.marginRight),b=px(node,s.marginBottom);if(has("webkit")&&(s.position!="absolute")){r=l;}return {l:l,t:t,r:r,b:b,w:l+r,h:t+b};};geom.getMarginBox=function getMarginBox(node,_369){node=dom.byId(node);var s=_369||_364.getComputedStyle(node),me=geom.getMarginExtents(node,s),l=node.offsetLeft-me.l,t=node.offsetTop-me.t,p=node.parentNode,px=_364.toPixelValue,pcs;if(has("mozilla")){var sl=parseFloat(s.left),st=parseFloat(s.top);if(!isNaN(sl)&&!isNaN(st)){l=sl,t=st;}else{if(p&&p.style){pcs=_364.getComputedStyle(p);if(pcs.overflow!="visible"){l+=pcs.borderLeftStyle!=none?px(node,pcs.borderLeftWidth):0;t+=pcs.borderTopStyle!=none?px(node,pcs.borderTopWidth):0;}}}}else{if(has("opera")||(has("ie")==8&&!has("quirks"))){if(p){pcs=_364.getComputedStyle(p);l-=pcs.borderLeftStyle!=none?px(node,pcs.borderLeftWidth):0;t-=pcs.borderTopStyle!=none?px(node,pcs.borderTopWidth):0;}}}return {l:l,t:t,w:node.offsetWidth+me.w,h:node.offsetHeight+me.h};};geom.getContentBox=function getContentBox(node,_36a){node=dom.byId(node);var s=_36a||_364.getComputedStyle(node),w=node.clientWidth,h,pe=geom.getPadExtents(node,s),be=geom.getBorderExtents(node,s);if(!w){w=node.offsetWidth;h=node.offsetHeight;}else{h=node.clientHeight;be.w=be.h=0;}if(has("opera")){pe.l+=be.l;pe.t+=be.t;}return {l:pe.l,t:pe.t,w:w-pe.w-be.w,h:h-pe.h-be.h};};function _36b(node,l,t,w,h,u){u=u||"px";var s=node.style;if(!isNaN(l)){s.left=l+u;}if(!isNaN(t)){s.top=t+u;}if(w>=0){s.width=w+u;}if(h>=0){s.height=h+u;}};function _36c(node){return node.tagName.toLowerCase()=="button"||node.tagName.toLowerCase()=="input"&&(node.getAttribute("type")||"").toLowerCase()=="button";};function _36d(node){return geom.boxModel=="border-box"||node.tagName.toLowerCase()=="table"||_36c(node);};geom.setContentSize=function setContentSize(node,box,_36e){node=dom.byId(node);var w=box.w,h=box.h;if(_36d(node)){var pb=geom.getPadBorderExtents(node,_36e);if(w>=0){w+=pb.w;}if(h>=0){h+=pb.h;}}_36b(node,NaN,NaN,w,h);};var _36f={l:0,t:0,w:0,h:0};geom.setMarginBox=function setMarginBox(node,box,_370){node=dom.byId(node);var s=_370||_364.getComputedStyle(node),w=box.w,h=box.h,pb=_36d(node)?_36f:geom.getPadBorderExtents(node,s),mb=geom.getMarginExtents(node,s);if(has("webkit")){if(_36c(node)){var ns=node.style;if(w>=0&&!ns.width){ns.width="4px";}if(h>=0&&!ns.height){ns.height="4px";}}}if(w>=0){w=Math.max(w-pb.w-mb.w,0);}if(h>=0){h=Math.max(h-pb.h-mb.h,0);}_36b(node,box.l,box.t,w,h);};geom.isBodyLtr=function isBodyLtr(){return (win.body().dir||win.doc.documentElement.dir||"ltr").toLowerCase()=="ltr";};geom.docScroll=function docScroll(){var node=win.doc.parentWindow||win.doc.defaultView;return "pageXOffset" in node?{x:node.pageXOffset,y:node.pageYOffset}:(node=has("quirks")?win.body():win.doc.documentElement,{x:geom.fixIeBiDiScrollLeft(node.scrollLeft||0),y:node.scrollTop||0});};geom.getIeDocumentElementOffset=function getIeDocumentElementOffset(){var de=win.doc.documentElement;if(has("ie")<8){var r=de.getBoundingClientRect(),l=r.left,t=r.top;if(has("ie")<7){l+=de.clientLeft;t+=de.clientTop;}return {x:l<0?0:l,y:t<0?0:t};}else{return {x:0,y:0};}};geom.fixIeBiDiScrollLeft=function fixIeBiDiScrollLeft(_371){var ie=has("ie");if(ie&&!geom.isBodyLtr()){var qk=has("quirks"),de=qk?win.body():win.doc.documentElement;if(ie==6&&!qk&&win.global.frameElement&&de.scrollHeight>de.clientHeight){_371+=de.clientLeft;}return (ie<8||qk)?(_371+de.clientWidth-de.scrollWidth):-_371;}return _371;};geom.position=function(node,_372){node=dom.byId(node);var db=win.body(),dh=db.parentNode,ret=node.getBoundingClientRect();ret={x:ret.left,y:ret.top,w:ret.right-ret.left,h:ret.bottom-ret.top};if(has("ie")){var _373=geom.getIeDocumentElementOffset();ret.x-=_373.x+(has("quirks")?db.clientLeft+db.offsetLeft:0);ret.y-=_373.y+(has("quirks")?db.clientTop+db.offsetTop:0);}else{if(has("ff")==3){var cs=_364.getComputedStyle(dh),px=_364.toPixelValue;ret.x-=px(dh,cs.marginLeft)+px(dh,cs.borderLeftWidth);ret.y-=px(dh,cs.marginTop)+px(dh,cs.borderTopWidth);}}if(_372){var _374=geom.docScroll();ret.x+=_374.x;ret.y+=_374.y;}return ret;};geom.getMarginSize=function getMarginSize(node,_375){node=dom.byId(node);var me=geom.getMarginExtents(node,_375||_364.getComputedStyle(node));var size=node.getBoundingClientRect();return {w:(size.right-size.left)+me.w,h:(size.bottom-size.top)+me.h};};geom.normalizeEvent=function(_376){if(!("layerX" in _376)){_376.layerX=_376.offsetX;_376.layerY=_376.offsetY;}if(!has("dom-addeventlistener")){var se=_376.target;var doc=(se&&se.ownerDocument)||document;var _377=has("quirks")?doc.body:doc.documentElement;var _378=geom.getIeDocumentElementOffset();_376.pageX=_376.clientX+geom.fixIeBiDiScrollLeft(_377.scrollLeft||0)-_378.x;_376.pageY=_376.clientY+(_377.scrollTop||0)-_378.y;}};return geom;});},"dojo/dom-prop":function(){define("dojo/dom-prop",["exports","./_base/kernel","./_base/sniff","./_base/lang","./dom","./dom-style","./dom-construct","./_base/connect"],function(_379,dojo,has,lang,dom,_37a,ctr,conn){var _37b={},_37c=0,_37d=dojo._scopeName+"attrid";var _37e={col:1,colgroup:1,table:1,tbody:1,tfoot:1,thead:1,tr:1,title:1};_379.names={"class":"className","for":"htmlFor",tabindex:"tabIndex",readonly:"readOnly",colspan:"colSpan",frameborder:"frameBorder",rowspan:"rowSpan",valuetype:"valueType"};_379.get=function getProp(node,name){node=dom.byId(node);var lc=name.toLowerCase(),_37f=_379.names[lc]||name;return node[_37f];};_379.set=function setProp(node,name,_380){node=dom.byId(node);var l=arguments.length;if(l==2&&typeof name!="string"){for(var x in name){_379.set(node,x,name[x]);}return node;}var lc=name.toLowerCase(),_381=_379.names[lc]||name;if(_381=="style"&&typeof _380!="string"){_37a.style(node,_380);return node;}if(_381=="innerHTML"){if(has("ie")&&node.tagName.toLowerCase() in _37e){ctr.empty(node);node.appendChild(ctr.toDom(_380,node.ownerDocument));}else{node[_381]=_380;}return node;}if(lang.isFunction(_380)){var _382=node[_37d];if(!_382){_382=_37c++;node[_37d]=_382;}if(!_37b[_382]){_37b[_382]={};}var h=_37b[_382][_381];if(h){conn.disconnect(h);}else{try{delete node[_381];}catch(e){}}if(_380){_37b[_382][_381]=conn.connect(node,_381,_380);}else{node[_381]=null;}return node;}node[_381]=_380;return node;};});},"dojo/dom-attr":function(){define(["exports","./_base/sniff","./_base/lang","./dom","./dom-style","./dom-prop"],function(_383,has,lang,dom,_384,prop){var _385={innerHTML:1,className:1,htmlFor:has("ie"),value:1},_386={classname:"class",htmlfor:"for",tabindex:"tabIndex",readonly:"readOnly"};function _387(node,name){var attr=node.getAttributeNode&&node.getAttributeNode(name);return attr&&attr.specified;};_383.has=function hasAttr(node,name){var lc=name.toLowerCase();return _385[prop.names[lc]||name]||_387(dom.byId(node),_386[lc]||name);};_383.get=function getAttr(node,name){node=dom.byId(node);var lc=name.toLowerCase(),_388=prop.names[lc]||name,_389=_385[_388];value=node[_388];if(_389&&typeof value!="undefined"){return value;}if(_388!="href"&&(typeof value=="boolean"||lang.isFunction(value))){return value;}var _38a=_386[lc]||name;return _387(node,_38a)?node.getAttribute(_38a):null;};_383.set=function setAttr(node,name,_38b){node=dom.byId(node);if(arguments.length==2){for(var x in name){_383.set(node,x,name[x]);}return node;}var lc=name.toLowerCase(),_38c=prop.names[lc]||name,_38d=_385[_38c];if(_38c=="style"&&typeof _38b!="string"){_384.set(node,_38b);return node;}if(_38d||typeof _38b=="boolean"||lang.isFunction(_38b)){return prop.set(node,name,_38b);}node.setAttribute(_386[lc]||name,_38b);return node;};_383.remove=function removeAttr(node,name){dom.byId(node).removeAttribute(_386[name.toLowerCase()]||name);};_383.getNodeProp=function getNodeProp(node,name){node=dom.byId(node);var lc=name.toLowerCase(),_38e=prop.names[lc]||name;if((_38e in node)&&_38e!="href"){return node[_38e];}var _38f=_386[lc]||name;return _387(node,_38f)?node.getAttribute(_38f):null;};});},"dojo/dom-construct":function(){define("dojo/dom-construct",["exports","./_base/kernel","./_base/sniff","./_base/window","./dom","./dom-attr","./on"],function(_390,dojo,has,win,dom,attr,on){var _391={option:["select"],tbody:["table"],thead:["table"],tfoot:["table"],tr:["table","tbody"],td:["table","tbody","tr"],th:["table","thead","tr"],legend:["fieldset"],caption:["table"],colgroup:["table"],col:["table","colgroup"],li:["ul"]},_392=/<\s*([\w\:]+)/,_393={},_394=0,_395="__"+dojo._scopeName+"ToDomId";for(var _396 in _391){if(_391.hasOwnProperty(_396)){var tw=_391[_396];tw.pre=_396=="option"?"<select multiple=\"multiple\">":"<"+tw.join("><")+">";tw.post="</"+tw.reverse().join("></")+">";}}function _397(node,ref){var _398=ref.parentNode;if(_398){_398.insertBefore(node,ref);}};function _399(node,ref){var _39a=ref.parentNode;if(_39a){if(_39a.lastChild==ref){_39a.appendChild(node);}else{_39a.insertBefore(node,ref.nextSibling);}}};var _39b=null,_39c;on(window,"unload",function(){_39b=null;});_390.toDom=function toDom(frag,doc){doc=doc||win.doc;var _39d=doc[_395];if(!_39d){doc[_395]=_39d=++_394+"";_393[_39d]=doc.createElement("div");}frag+="";var _39e=frag.match(_392),tag=_39e?_39e[1].toLowerCase():"",_39f=_393[_39d],wrap,i,fc,df;if(_39e&&_391[tag]){wrap=_391[tag];_39f.innerHTML=wrap.pre+frag+wrap.post;for(i=wrap.length;i;--i){_39f=_39f.firstChild;}}else{_39f.innerHTML=frag;}if(_39f.childNodes.length==1){return _39f.removeChild(_39f.firstChild);}df=doc.createDocumentFragment();while(fc=_39f.firstChild){df.appendChild(fc);}return df;};_390.place=function place(node,_3a0,_3a1){_3a0=dom.byId(_3a0);if(typeof node=="string"){node=/^\s*</.test(node)?_390.toDom(node,_3a0.ownerDocument):dom.byId(node);}if(typeof _3a1=="number"){var cn=_3a0.childNodes;if(!cn.length||cn.length<=_3a1){_3a0.appendChild(node);}else{_397(node,cn[_3a1<0?0:_3a1]);}}else{switch(_3a1){case "before":_397(node,_3a0);break;case "after":_399(node,_3a0);break;case "replace":_3a0.parentNode.replaceChild(node,_3a0);break;case "only":_390.empty(_3a0);_3a0.appendChild(node);break;case "first":if(_3a0.firstChild){_397(node,_3a0.firstChild);break;}default:_3a0.appendChild(node);}}return node;};_390.create=function create(tag,_3a2,_3a3,pos){var doc=win.doc;if(_3a3){_3a3=dom.byId(_3a3);doc=_3a3.ownerDocument;}if(typeof tag=="string"){tag=doc.createElement(tag);}if(_3a2){attr.set(tag,_3a2);}if(_3a3){_390.place(tag,_3a3,pos);}return tag;};_390.empty=has("ie")?function(node){node=dom.byId(node);for(var c;c=node.lastChild;){_390.destroy(c);}}:function(node){dom.byId(node).innerHTML="";};_390.destroy=function destroy(node){node=dom.byId(node);try{var doc=node.ownerDocument;if(!_39b||_39c!=doc){_39b=doc.createElement("div");_39c=doc;}_39b.appendChild(node.parentNode?node.parentNode.removeChild(node):node);_39b.innerHTML="";}catch(e){}};});},"dojo/text":function(){define(["./_base/kernel","require","./has","./_base/xhr"],function(dojo,_3a4,has,xhr){var _3a5;if(1){_3a5=function(url,sync,load){xhr("GET",{url:url,sync:!!sync,load:load});};}else{if(_3a4.getText){_3a5=_3a4.getText;}else{console.error("dojo/text plugin failed to load because loader does not support getText");}}var _3a6={},_3a7=function(text){if(text){text=text.replace(/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,"");var _3a8=text.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im);if(_3a8){text=_3a8[1];}}else{text="";}return text;},_3a9={},_3aa={},_3ab={dynamic:true,normalize:function(id,_3ac){var _3ad=id.split("!"),url=_3ad[0];return (/^\./.test(url)?_3ac(url):url)+(_3ad[1]?"!"+_3ad[1]:"");},load:function(id,_3ae,load){var _3af=id.split("!"),_3b0=_3af.length>1,_3b1=_3af[0],url=_3ae.toUrl(_3af[0]),text=_3a9,_3b2=function(text){load(_3b0?_3a7(text):text);};if(_3b1 in _3a6){text=_3a6[_3b1];}else{if(url in _3ae.cache){text=_3ae.cache[url];}else{if(url in _3a6){text=_3a6[url];}}}if(text===_3a9){if(_3aa[url]){_3aa[url].push(_3b2);}else{var _3b3=_3aa[url]=[_3b2];_3a5(url,!_3ae.async,function(text){_3a6[_3b1]=_3a6[url]=text;for(var i=0;i<_3b3.length;){_3b3[i++](text);}delete _3aa[url];});}}else{_3b2(text);}}};dojo.cache=function(_3b4,url,_3b5){var key;if(typeof _3b4=="string"){if(/\//.test(_3b4)){key=_3b4;_3b5=url;}else{key=_3a4.toUrl(_3b4.replace(/\./g,"/")+(url?("/"+url):""));}}else{key=_3b4+"";_3b5=url;}var val=(_3b5!=undefined&&typeof _3b5!="string")?_3b5.value:_3b5,_3b6=_3b5&&_3b5.sanitize;if(typeof val=="string"){_3a6[key]=val;return _3b6?_3a7(val):val;}else{if(val===null){delete _3a6[key];return null;}else{if(!(key in _3a6)){_3a5(key,true,function(text){_3a6[key]=text;});}return _3b6?_3a7(_3a6[key]):_3a6[key];}}};return _3ab;});},"dojo/keys":function(){define("dojo/keys",["./_base/kernel","./_base/sniff"],function(dojo,has){return dojo.keys={BACKSPACE:8,TAB:9,CLEAR:12,ENTER:13,SHIFT:16,CTRL:17,ALT:18,META:has("safari")?91:224,PAUSE:19,CAPS_LOCK:20,ESCAPE:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT_ARROW:37,UP_ARROW:38,RIGHT_ARROW:39,DOWN_ARROW:40,INSERT:45,DELETE:46,HELP:47,LEFT_WINDOW:91,RIGHT_WINDOW:92,SELECT:93,NUMPAD_0:96,NUMPAD_1:97,NUMPAD_2:98,NUMPAD_3:99,NUMPAD_4:100,NUMPAD_5:101,NUMPAD_6:102,NUMPAD_7:103,NUMPAD_8:104,NUMPAD_9:105,NUMPAD_MULTIPLY:106,NUMPAD_PLUS:107,NUMPAD_ENTER:108,NUMPAD_MINUS:109,NUMPAD_PERIOD:110,NUMPAD_DIVIDE:111,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123,F13:124,F14:125,F15:126,NUM_LOCK:144,SCROLL_LOCK:145,UP_DPAD:175,DOWN_DPAD:176,LEFT_DPAD:177,RIGHT_DPAD:178,copyKey:has("mac")&&!has("air")?(has("safari")?91:224):17};});},"dojo/domReady":function(){define(["./has"],function(has){var _3b7=this,doc=document,_3b8={"loaded":1,"complete":1},_3b9=typeof doc.readyState!="string",_3ba=!!_3b8[doc.readyState];if(_3b9){doc.readyState="loading";}if(!_3ba){var _3bb=[],_3bc=[],_3bd=function(evt){evt=evt||_3b7.event;if(_3ba||(evt.type=="readystatechange"&&!_3b8[doc.readyState])){return;}_3ba=1;if(_3b9){doc.readyState="complete";}while(_3bb.length){(_3bb.shift())();}},on=function(node,_3be){node.addEventListener(_3be,_3bd,false);_3bb.push(function(){node.removeEventListener(_3be,_3bd,false);});};if(!has("dom-addeventlistener")){on=function(node,_3bf){_3bf="on"+_3bf;node.attachEvent(_3bf,_3bd);_3bb.push(function(){node.detachEvent(_3bf,_3bd);});};var div=doc.createElement("div");try{if(div.doScroll&&_3b7.frameElement===null){_3bc.push(function(){try{div.doScroll("left");return 1;}catch(e){}});}}catch(e){}}on(doc,"DOMContentLoaded");on(_3b7,"load");if("onreadystatechange" in doc){on(doc,"readystatechange");}else{if(!_3b9){_3bc.push(function(){return _3b8[doc.readyState];});}}if(_3bc.length){var _3c0=function(){if(_3ba){return;}var i=_3bc.length;while(i--){if(_3bc[i]()){_3bd("poller");return;}}setTimeout(_3c0,30);};_3c0();}}function _3c1(_3c2){if(_3ba){_3c2(1);}else{_3bb.push(_3c2);}};_3c1.load=function(id,req,load){_3c1(load);};return _3c1;});},"dojo/_base/lang":function(){define(["./kernel","../has","./sniff"],function(dojo,has){has.add("bug-for-in-skips-shadowed",function(){for(var i in {toString:1}){return 0;}return 1;});var _3c3=has("bug-for-in-skips-shadowed")?"hasOwnProperty.valueOf.isPrototypeOf.propertyIsEnumerable.toLocaleString.toString.constructor".split("."):[],_3c4=_3c3.length,_3c5=function(dest,_3c6,_3c7){var name,s,i,_3c8={};for(name in _3c6){s=_3c6[name];if(!(name in dest)||(dest[name]!==s&&(!(name in _3c8)||_3c8[name]!==s))){dest[name]=_3c7?_3c7(s):s;}}if(has("bug-for-in-skips-shadowed")){if(_3c6){for(i=0;i<_3c4;++i){name=_3c3[i];s=_3c6[name];if(!(name in dest)||(dest[name]!==s&&(!(name in _3c8)||_3c8[name]!==s))){dest[name]=_3c7?_3c7(s):s;}}}}return dest;},_3c9=function(dest,_3ca){if(!dest){dest={};}for(var i=1,l=arguments.length;i<l;i++){lang._mixin(dest,arguments[i]);}return dest;},_3cb=function(_3cc,_3cd,_3ce){var p,i=0,_3cf=dojo.global;if(!_3ce){if(!_3cc.length){return _3cf;}else{p=_3cc[i++];try{_3ce=dojo.scopeMap[p]&&dojo.scopeMap[p][1];}catch(e){}_3ce=_3ce||(p in _3cf?_3cf[p]:(_3cd?_3cf[p]={}:undefined));}}while(_3ce&&(p=_3cc[i++])){_3ce=(p in _3ce?_3ce[p]:(_3cd?_3ce[p]={}:undefined));}return _3ce;},_3d0=function(name,_3d1,_3d2){var _3d3=name.split("."),p=_3d3.pop(),obj=_3cb(_3d3,true,_3d2);return obj&&p?(obj[p]=_3d1):undefined;},_3d4=function(name,_3d5,_3d6){return _3cb(name.split("."),_3d5,_3d6);},_3d7=function(name,obj){return lang.getObject(name,false,obj)!==undefined;},opts=Object.prototype.toString,_3d8=function(it){return (typeof it=="string"||it instanceof String);},_3d9=function(it){return it&&(it instanceof Array||typeof it=="array");},_3da=function(it){return opts.call(it)==="[object Function]";},_3db=function(it){return it!==undefined&&(it===null||typeof it=="object"||lang.isArray(it)||lang.isFunction(it));},_3dc=function(it){return it&&it!==undefined&&!lang.isString(it)&&!lang.isFunction(it)&&!(it.tagName&&it.tagName.toLowerCase()=="form")&&(lang.isArray(it)||isFinite(it.length));},_3dd=function(it){return it&&!lang.isFunction(it)&&/\{\s*\[native code\]\s*\}/.test(String(it));},_3de=function(_3df,_3e0){for(var i=1,l=arguments.length;i<l;i++){lang._mixin(_3df.prototype,arguments[i]);}return _3df;},_3e1=function(_3e2,_3e3){var pre=_3e4(arguments,2);var _3e5=lang.isString(_3e3);return function(){var args=_3e4(arguments);var f=_3e5?(_3e2||dojo.global)[_3e3]:_3e3;return f&&f.apply(_3e2||this,pre.concat(args));};},_3e6=function(_3e7,_3e8){if(arguments.length>2){return lang._hitchArgs.apply(dojo,arguments);}if(!_3e8){_3e8=_3e7;_3e7=null;}if(lang.isString(_3e8)){_3e7=_3e7||dojo.global;if(!_3e7[_3e8]){throw (["dojo.hitch: scope[\"",_3e8,"\"] is null (scope=\"",_3e7,"\")"].join(""));}return function(){return _3e7[_3e8].apply(_3e7,arguments||[]);};}return !_3e7?_3e8:function(){return _3e8.apply(_3e7,arguments||[]);};},_3e9=(function(){function TMP(){};return function(obj,_3ea){TMP.prototype=obj;var tmp=new TMP();TMP.prototype=null;if(_3ea){lang._mixin(tmp,_3ea);}return tmp;};})(),_3eb=function(obj,_3ec,_3ed){return (_3ed||[]).concat(Array.prototype.slice.call(obj,_3ec||0));},_3e4=has("ie")?(function(){function slow(obj,_3ee,_3ef){var arr=_3ef||[];for(var x=_3ee||0;x<obj.length;x++){arr.push(obj[x]);}return arr;};return function(obj){return ((obj.item)?slow:_3eb).apply(this,arguments);};})():_3eb,_3f0=function(_3f1){var arr=[null];return lang.hitch.apply(dojo,arr.concat(lang._toArray(arguments)));},_3f2=function(src){if(!src||typeof src!="object"||lang.isFunction(src)){return src;}if(src.nodeType&&"cloneNode" in src){return src.cloneNode(true);}if(src instanceof Date){return new Date(src.getTime());}if(src instanceof RegExp){return new RegExp(src);}var r,i,l;if(lang.isArray(src)){r=[];for(i=0,l=src.length;i<l;++i){if(i in src){r.push(_3f2(src[i]));}}}else{r=src.constructor?new src.constructor():{};}return lang._mixin(r,src,_3f2);},trim=String.prototype.trim?function(str){return str.trim();}:function(str){return str.replace(/^\s\s*/,"").replace(/\s\s*$/,"");},_3f3=/\{([^\}]+)\}/g,_3f4=function(tmpl,map,_3f5){return tmpl.replace(_3f5||_3f3,lang.isFunction(map)?map:function(_3f6,k){return _3d4(k,false,map);});},lang={_extraNames:_3c3,_mixin:_3c5,mixin:_3c9,setObject:_3d0,getObject:_3d4,exists:_3d7,isString:_3d8,isArray:_3d9,isFunction:_3da,isObject:_3db,isArrayLike:_3dc,isAlien:_3dd,extend:_3de,_hitchArgs:_3e1,hitch:_3e6,delegate:_3e9,_toArray:_3e4,partial:_3f0,clone:_3f2,trim:trim,replace:_3f4};1&&_3c9(dojo,lang);return lang;});},"dojo/Evented":function(){define(["./aspect","./on"],function(_3f7,on){"use strict";var _3f8=_3f7.after;function _3f9(){};_3f9.prototype={on:function(type,_3fa){return on.parse(this,type,_3fa,function(_3fb,type){return _3f8(_3fb,"on"+type,_3fa,true);});},emit:function(type,_3fc){var args=[this];args.push.apply(args,arguments);return on.emit.apply(on,args);}};return _3f9;});},"dojo/mouse":function(){define(["./_base/kernel","./on","./has","./dom","./_base/window"],function(dojo,on,has,dom,win){has.add("dom-quirks",win.doc&&win.doc.compatMode=="BackCompat");has.add("events-mouseenter",win.doc&&"onmouseenter" in win.doc.createElement("div"));var _3fd;if(has("dom-quirks")||!has("dom-addeventlistener")){_3fd={LEFT:1,MIDDLE:4,RIGHT:2,isButton:function(e,_3fe){return e.button&_3fe;},isLeft:function(e){return e.button&1;},isMiddle:function(e){return e.button&4;},isRight:function(e){return e.button&2;}};}else{_3fd={LEFT:0,MIDDLE:1,RIGHT:2,isButton:function(e,_3ff){return e.button==_3ff;},isLeft:function(e){return e.button==0;},isMiddle:function(e){return e.button==1;},isRight:function(e){return e.button==2;}};}dojo.mouseButtons=_3fd;function _400(type,_401){var _402=function(node,_403){return on(node,type,function(evt){if(!dom.isDescendant(evt.relatedTarget,_401?evt.target:node)){return _403.call(this,evt);}});};if(!_401){_402.bubble=_400(type,true);}return _402;};return {enter:_400("mouseover"),leave:_400("mouseout"),isLeft:_3fd.isLeft,isMiddle:_3fd.isMiddle,isRight:_3fd.isRight};});},"dojo/topic":function(){define(["./Evented"],function(_404){var hub=new _404;return {publish:function(_405,_406){return hub.emit.apply(hub,arguments);},subscribe:function(_407,_408){return hub.on.apply(hub,arguments);}};});},"dojo/_base/xhr":function(){define(["./kernel","./sniff","require","../io-query","../dom","../dom-form","./Deferred","./json","./lang","./array","../on"],function(dojo,has,_409,ioq,dom,_40a,_40b,json,lang,_40c,on){has.add("native-xhr",function(){return typeof XMLHttpRequest!=="undefined";});if(1){dojo._xhrObj=_409.getXhr;}else{if(has("native-xhr")){dojo._xhrObj=function(){try{return new XMLHttpRequest();}catch(e){throw new Error("XMLHTTP not available: "+e);}};}else{for(var _40d=["Msxml2.XMLHTTP","Microsoft.XMLHTTP","Msxml2.XMLHTTP.4.0"],_40e,i=0;i<3;){try{_40e=_40d[i++];if(new ActiveXObject(_40e)){break;}}catch(e){}}dojo._xhrObj=function(){return new ActiveXObject(_40e);};}}var cfg=dojo.config;dojo.objectToQuery=ioq.objectToQuery;dojo.queryToObject=ioq.queryToObject;dojo.fieldToObject=_40a.fieldToObject;dojo.formToObject=_40a.toObject;dojo.formToQuery=_40a.toQuery;dojo.formToJson=_40a.toJson;dojo._blockAsync=false;var _40f=dojo._contentHandlers=dojo.contentHandlers={"text":function(xhr){return xhr.responseText;},"json":function(xhr){return json.fromJson(xhr.responseText||null);},"json-comment-filtered":function(xhr){if(!dojo.config.useCommentedJson){console.warn("Consider using the standard mimetype:application/json."+" json-commenting can introduce security issues. To"+" decrease the chances of hijacking, use the standard the 'json' handler and"+" prefix your json with: {}&&\n"+"Use djConfig.useCommentedJson=true to turn off this message.");}var _410=xhr.responseText;var _411=_410.indexOf("/*");var _412=_410.lastIndexOf("*/");if(_411==-1||_412==-1){throw new Error("JSON was not comment filtered");}return json.fromJson(_410.substring(_411+2,_412));},"javascript":function(xhr){return dojo.eval(xhr.responseText);},"xml":function(xhr){var _413=xhr.responseXML;if(has("ie")){if((!_413||!_413.documentElement)){var ms=function(n){return "MSXML"+n+".DOMDocument";};var dp=["Microsoft.XMLDOM",ms(6),ms(4),ms(3),ms(2)];_40c.some(dp,function(p){try{var dom=new ActiveXObject(p);dom.async=false;dom.loadXML(xhr.responseText);_413=dom;}catch(e){return false;}return true;});}}return _413;},"json-comment-optional":function(xhr){if(xhr.responseText&&/^[^{\[]*\/\*/.test(xhr.responseText)){return _40f["json-comment-filtered"](xhr);}else{return _40f["json"](xhr);}}};dojo._ioSetArgs=function(args,_414,_415,_416){var _417={args:args,url:args.url};var _418=null;if(args.form){var form=dom.byId(args.form);var _419=form.getAttributeNode("action");_417.url=_417.url||(_419?_419.value:null);_418=_40a.toObject(form);}var _41a=[{}];if(_418){_41a.push(_418);}if(args.content){_41a.push(args.content);}if(args.preventCache){_41a.push({"dojo.preventCache":new Date().valueOf()});}_417.query=ioq.objectToQuery(lang.mixin.apply(null,_41a));_417.handleAs=args.handleAs||"text";var d=new _40b(_414);d.addCallbacks(_415,function(_41b){return _416(_41b,d);});var ld=args.load;if(ld&&lang.isFunction(ld)){d.addCallback(function(_41c){return ld.call(args,_41c,_417);});}var err=args.error;if(err&&lang.isFunction(err)){d.addErrback(function(_41d){return err.call(args,_41d,_417);});}var _41e=args.handle;if(_41e&&lang.isFunction(_41e)){d.addBoth(function(_41f){return _41e.call(args,_41f,_417);});}if(cfg.ioPublish&&dojo.publish&&_417.args.ioPublish!==false){d.addCallbacks(function(res){dojo.publish("/dojo/io/load",[d,res]);return res;},function(res){dojo.publish("/dojo/io/error",[d,res]);return res;});d.addBoth(function(res){dojo.publish("/dojo/io/done",[d,res]);return res;});}d.ioArgs=_417;return d;};var _420=function(dfd){dfd.canceled=true;var xhr=dfd.ioArgs.xhr;var _421=typeof xhr.abort;if(_421=="function"||_421=="object"||_421=="unknown"){xhr.abort();}var err=dfd.ioArgs.error;if(!err){err=new Error("xhr cancelled");err.dojoType="cancel";}return err;};var _422=function(dfd){var ret=_40f[dfd.ioArgs.handleAs](dfd.ioArgs.xhr);return ret===undefined?null:ret;};var _423=function(_424,dfd){if(!dfd.ioArgs.args.failOk){console.error(_424);}return _424;};var _425=null;var _426=[];var _427=0;var _428=function(dfd){if(_427<=0){_427=0;if(cfg.ioPublish&&dojo.publish&&(!dfd||dfd&&dfd.ioArgs.args.ioPublish!==false)){dojo.publish("/dojo/io/stop");}}};var _429=function(){var now=(new Date()).getTime();if(!dojo._blockAsync){for(var i=0,tif;i<_426.length&&(tif=_426[i]);i++){var dfd=tif.dfd;var func=function(){if(!dfd||dfd.canceled||!tif.validCheck(dfd)){_426.splice(i--,1);_427-=1;}else{if(tif.ioCheck(dfd)){_426.splice(i--,1);tif.resHandle(dfd);_427-=1;}else{if(dfd.startTime){if(dfd.startTime+(dfd.ioArgs.args.timeout||0)<now){_426.splice(i--,1);var err=new Error("timeout exceeded");err.dojoType="timeout";dfd.errback(err);dfd.cancel();_427-=1;}}}}};if(dojo.config.debugAtAllCosts){func.call(this);}else{func.call(this);}}}_428(dfd);if(!_426.length){clearInterval(_425);_425=null;}};dojo._ioCancelAll=function(){try{_40c.forEach(_426,function(i){try{i.dfd.cancel();}catch(e){}});}catch(e){}};if(has("ie")){on(window,"unload",dojo._ioCancelAll);}dojo._ioNotifyStart=function(dfd){if(cfg.ioPublish&&dojo.publish&&dfd.ioArgs.args.ioPublish!==false){if(!_427){dojo.publish("/dojo/io/start");}_427+=1;dojo.publish("/dojo/io/send",[dfd]);}};dojo._ioWatch=function(dfd,_42a,_42b,_42c){var args=dfd.ioArgs.args;if(args.timeout){dfd.startTime=(new Date()).getTime();}_426.push({dfd:dfd,validCheck:_42a,ioCheck:_42b,resHandle:_42c});if(!_425){_425=setInterval(_429,50);}if(args.sync){_429();}};var _42d="application/x-www-form-urlencoded";var _42e=function(dfd){return dfd.ioArgs.xhr.readyState;};var _42f=function(dfd){return 4==dfd.ioArgs.xhr.readyState;};var _430=function(dfd){var xhr=dfd.ioArgs.xhr;if(dojo._isDocumentOk(xhr)){dfd.callback(dfd);}else{var err=new Error("Unable to load "+dfd.ioArgs.url+" status:"+xhr.status);err.status=xhr.status;err.responseText=xhr.responseText;err.xhr=xhr;dfd.errback(err);}};dojo._ioAddQueryToUrl=function(_431){if(_431.query.length){_431.url+=(_431.url.indexOf("?")==-1?"?":"&")+_431.query;_431.query=null;}};dojo.xhr=function(_432,args,_433){var dfd=dojo._ioSetArgs(args,_420,_422,_423);var _434=dfd.ioArgs;var xhr=_434.xhr=dojo._xhrObj(_434.args);if(!xhr){dfd.cancel();return dfd;}if("postData" in args){_434.query=args.postData;}else{if("putData" in args){_434.query=args.putData;}else{if("rawBody" in args){_434.query=args.rawBody;}else{if((arguments.length>2&&!_433)||"POST|PUT".indexOf(_432.toUpperCase())==-1){dojo._ioAddQueryToUrl(_434);}}}}xhr.open(_432,_434.url,args.sync!==true,args.user||undefined,args.password||undefined);if(args.headers){for(var hdr in args.headers){if(hdr.toLowerCase()==="content-type"&&!args.contentType){args.contentType=args.headers[hdr];}else{if(args.headers[hdr]){xhr.setRequestHeader(hdr,args.headers[hdr]);}}}}if(args.contentType!==false){xhr.setRequestHeader("Content-Type",args.contentType||_42d);}if(!args.headers||!("X-Requested-With" in args.headers)){xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");}dojo._ioNotifyStart(dfd);if(dojo.config.debugAtAllCosts){xhr.send(_434.query);}else{try{xhr.send(_434.query);}catch(e){_434.error=e;dfd.cancel();}}dojo._ioWatch(dfd,_42e,_42f,_430);xhr=null;return dfd;};dojo.xhrGet=function(args){return dojo.xhr("GET",args);};dojo.rawXhrPost=dojo.xhrPost=function(args){return dojo.xhr("POST",args,true);};dojo.rawXhrPut=dojo.xhrPut=function(args){return dojo.xhr("PUT",args,true);};dojo.xhrDelete=function(args){return dojo.xhr("DELETE",args);};dojo._isDocumentOk=function(http){var stat=http.status||0;stat=(stat>=200&&stat<300)||stat==304||stat==1223||!stat;return stat;};dojo._getText=function(url){var _435;dojo.xhrGet({url:url,sync:true,load:function(text){_435=text;}});return _435;};lang.mixin(dojo.xhr,{_xhrObj:dojo._xhrObj,fieldToObject:_40a.fieldToObject,formToObject:_40a.toObject,objectToQuery:ioq.objectToQuery,formToQuery:_40a.toQuery,formToJson:_40a.toJson,queryToObject:ioq.queryToObject,contentHandlers:_40f,_ioSetArgs:dojo._ioSetArgs,_ioCancelAll:dojo._ioCancelAll,_ioNotifyStart:dojo._ioNotifyStart,_ioWatch:dojo._ioWatch,_ioAddQueryToUrl:dojo._ioAddQueryToUrl,_isDocumentOk:dojo._isDocumentOk,_getText:dojo._getText,get:dojo.xhrGet,post:dojo.xhrPost,put:dojo.xhrPut,del:dojo.xhrDelete});return dojo.xhr;});},"dojo/_base/unload":function(){define(["./kernel","./connect"],function(dojo,_436){var win=window;dojo.addOnWindowUnload=function(obj,_437){if(!dojo.windowUnloaded){_436.connect(win,"unload",(dojo.windowUnloaded=function(){}));}_436.connect(win,"unload",obj,_437);};dojo.addOnUnload=function(obj,_438){_436.connect(win,"beforeunload",obj,_438);};return {addOnWindowUnload:dojo.addOnWindowUnload,addOnUnload:dojo.addOnUnload};});},"dojo/loadInit":function(){define(["./_base/loader"],function(_439){return {dynamic:0,normalize:function(id){return id;},load:_439.loadInit};});},"dojo/_base/NodeList":function(){define(["./kernel","../query","./array","./html","../NodeList-dom"],function(dojo,_43a,_43b){var _43c=_43a.NodeList;var nlp=_43c.prototype;nlp.connect=_43c._adaptAsForEach(function(){return dojo.connect.apply(this,arguments);});nlp.coords=_43c._adaptAsMap(dojo.coords);_43c.events=["blur","focus","change","click","error","keydown","keypress","keyup","load","mousedown","mouseenter","mouseleave","mousemove","mouseout","mouseover","mouseup","submit"];_43b.forEach(_43c.events,function(evt){var _43d="on"+evt;nlp[_43d]=function(a,b){return this.connect(_43d,a,b);};});dojo.NodeList=_43c;return dojo.NodeList;});},"dojo/_base/Color":function(){define(["./kernel","./lang","./array","./config"],function(dojo,lang,_43e,_43f){var _440=dojo.Color=function(_441){if(_441){this.setColor(_441);}};_440.named={"black":[0,0,0],"silver":[192,192,192],"gray":[128,128,128],"white":[255,255,255],"maroon":[128,0,0],"red":[255,0,0],"purple":[128,0,128],"fuchsia":[255,0,255],"green":[0,128,0],"lime":[0,255,0],"olive":[128,128,0],"yellow":[255,255,0],"navy":[0,0,128],"blue":[0,0,255],"teal":[0,128,128],"aqua":[0,255,255],"transparent":_43f.transparentColor||[0,0,0,0]};lang.extend(_440,{r:255,g:255,b:255,a:1,_set:function(r,g,b,a){var t=this;t.r=r;t.g=g;t.b=b;t.a=a;},setColor:function(_442){if(lang.isString(_442)){_440.fromString(_442,this);}else{if(lang.isArray(_442)){_440.fromArray(_442,this);}else{this._set(_442.r,_442.g,_442.b,_442.a);if(!(_442 instanceof _440)){this.sanitize();}}}return this;},sanitize:function(){return this;},toRgb:function(){var t=this;return [t.r,t.g,t.b];},toRgba:function(){var t=this;return [t.r,t.g,t.b,t.a];},toHex:function(){var arr=_43e.map(["r","g","b"],function(x){var s=this[x].toString(16);return s.length<2?"0"+s:s;},this);return "#"+arr.join("");},toCss:function(_443){var t=this,rgb=t.r+", "+t.g+", "+t.b;return (_443?"rgba("+rgb+", "+t.a:"rgb("+rgb)+")";},toString:function(){return this.toCss(true);}});_440.blendColors=dojo.blendColors=function(_444,end,_445,obj){var t=obj||new _440();_43e.forEach(["r","g","b","a"],function(x){t[x]=_444[x]+(end[x]-_444[x])*_445;if(x!="a"){t[x]=Math.round(t[x]);}});return t.sanitize();};_440.fromRgb=dojo.colorFromRgb=function(_446,obj){var m=_446.toLowerCase().match(/^rgba?\(([\s\.,0-9]+)\)/);return m&&_440.fromArray(m[1].split(/\s*,\s*/),obj);};_440.fromHex=dojo.colorFromHex=function(_447,obj){var t=obj||new _440(),bits=(_447.length==4)?4:8,mask=(1<<bits)-1;_447=Number("0x"+_447.substr(1));if(isNaN(_447)){return null;}_43e.forEach(["b","g","r"],function(x){var c=_447&mask;_447>>=bits;t[x]=bits==4?17*c:c;});t.a=1;return t;};_440.fromArray=dojo.colorFromArray=function(a,obj){var t=obj||new _440();t._set(Number(a[0]),Number(a[1]),Number(a[2]),Number(a[3]));if(isNaN(t.a)){t.a=1;}return t.sanitize();};_440.fromString=dojo.colorFromString=function(str,obj){var a=_440.named[str];return a&&_440.fromArray(a,obj)||_440.fromRgb(str,obj)||_440.fromHex(str,obj);};return _440;});},"dojo/selector/_loader":function(){define(["../has","require"],function(has,_448){"use strict";var _449=document.createElement("div");has.add("dom-qsa2.1",!!_449.querySelectorAll);has.add("dom-qsa3",function(){try{_449.innerHTML="<p class='TEST'></p>";return _449.querySelectorAll(".TEST:empty").length==1;}catch(e){}});var _44a;var acme="./acme",lite="./lite";return {load:function(id,_44b,_44c,_44d){var req=_448;id=id=="default"?has("config-selectorEngine")||"css3":id;id=id=="css2"||id=="lite"?lite:id=="css2.1"?has("dom-qsa2.1")?lite:acme:id=="css3"?has("dom-qsa3")?lite:acme:id=="acme"?acme:(req=_44b)&&id;if(id.charAt(id.length-1)=="?"){id=id.substring(0,id.length-1);var _44e=true;}if(_44e&&(has("dom-compliant-qsa")||_44a)){return _44c(_44a);}req([id],function(_44f){if(id!="./lite"){_44a=_44f;}_44c(_44f);});}};});},"dojo/on":function(){define(["./has!dom-addeventlistener?:./aspect","./_base/kernel","./has"],function(_450,dojo,has){"use strict";if(1){var _451=window.ScriptEngineMajorVersion;has.add("jscript",_451&&(_451()+ScriptEngineMinorVersion()/10));has.add("event-orientationchange",has("touch")&&!has("android"));}var on=function(_452,type,_453,_454){if(_452.on){return _452.on(type,_453);}return on.parse(_452,type,_453,_455,_454,this);};on.pausable=function(_456,type,_457,_458){var _459;var _45a=on(_456,type,function(){if(!_459){return _457.apply(this,arguments);}},_458);_45a.pause=function(){_459=true;};_45a.resume=function(){_459=false;};return _45a;};on.once=function(_45b,type,_45c,_45d){var _45e=on(_45b,type,function(){_45e.remove();return _45c.apply(this,arguments);});return _45e;};on.parse=function(_45f,type,_460,_461,_462,_463){if(type.call){return type.call(_463,_45f,_460);}if(type.indexOf(",")>-1){var _464=type.split(/\s*,\s*/);var _465=[];var i=0;var _466;while(_466=_464[i++]){_465.push(_461(_45f,_466,_460,_462,_463));}_465.remove=function(){for(var i=0;i<_465.length;i++){_465[i].remove();}};return _465;}return _461(_45f,type,_460,_462,_463);};var _467=/^touch/;function _455(_468,type,_469,_46a,_46b){var _46c=type.match(/(.*):(.*)/);if(_46c){type=_46c[2];_46c=_46c[1];return on.selector(_46c,type).call(_46b,_468,_469);}if(has("touch")){if(_467.test(type)){_469=_46d(_469);}if(!has("event-orientationchange")&&(type=="orientationchange")){type="resize";_468=window;_469=_46d(_469);}}if(_468.addEventListener){var _46e=type in _46f;_468.addEventListener(_46e?_46f[type]:type,_469,_46e);return {remove:function(){_468.removeEventListener(type,_469,_46e);}};}type="on"+type;if(_470&&_468.attachEvent){return _470(_468,type,_469);}throw new Error("Target must be an event emitter");};on.selector=function(_471,_472,_473){return function(_474,_475){var _476=this;var _477=_472.bubble;if(_477){_472=_477;}else{if(_473!==false){_473=true;}}return on(_474,_472,function(_478){var _479=_478.target;_476=_476&&_476.matches?_476:dojo.query;while(!_476.matches(_479,_471,_474)){if(_479==_474||!_473||!(_479=_479.parentNode)){return;}}return _475.call(_479,_478);});};};function _47a(){this.cancelable=false;};function _47b(){this.bubbles=false;};var _47c=[].slice,_47d=on.emit=function(_47e,type,_47f){var args=_47c.call(arguments,2);var _480="on"+type;if("parentNode" in _47e){var _481=args[0]={};for(var i in _47f){_481[i]=_47f[i];}_481.preventDefault=_47a;_481.stopPropagation=_47b;_481.target=_47e;_481.type=type;_47f=_481;}do{_47e[_480]&&_47e[_480].apply(_47e,args);}while(_47f&&_47f.bubbles&&(_47e=_47e.parentNode));return _47f&&_47f.cancelable&&_47f;};var _46f={};if(has("dom-addeventlistener")){_46f={focusin:"focus",focusout:"blur"};if(has("opera")){_46f.keydown="keypress";}on.emit=function(_482,type,_483){if(_482.dispatchEvent&&document.createEvent){var _484=document.createEvent("HTMLEvents");_484.initEvent(type,!!_483.bubbles,!!_483.cancelable);for(var i in _483){var _485=_483[i];if(!(i in _484)){_484[i]=_483[i];}}return _482.dispatchEvent(_484)&&_484;}return _47d.apply(on,arguments);};}else{on._fixEvent=function(evt,_486){if(!evt){var w=_486&&(_486.ownerDocument||_486.document||_486).parentWindow||window;evt=w.event;}if(!evt){return (evt);}if(!evt.target){evt.target=evt.srcElement;evt.currentTarget=(_486||evt.srcElement);if(evt.type=="mouseover"){evt.relatedTarget=evt.fromElement;}if(evt.type=="mouseout"){evt.relatedTarget=evt.toElement;}if(!evt.stopPropagation){evt.stopPropagation=_487;evt.preventDefault=_488;}switch(evt.type){case "keypress":var c=("charCode" in evt?evt.charCode:evt.keyCode);if(c==10){c=0;evt.keyCode=13;}else{if(c==13||c==27){c=0;}else{if(c==3){c=99;}}}evt.charCode=c;_489(evt);break;}}return evt;};var _48a=function(_48b){this.handle=_48b;};_48a.prototype.remove=function(){delete _dojoIEListeners_[this.handle];};var _48c=function(_48d){return function(evt){evt=on._fixEvent(evt,this);return _48d.call(this,evt);};};var _470=function(_48e,type,_48f){_48f=_48c(_48f);if(((_48e.ownerDocument?_48e.ownerDocument.parentWindow:_48e.parentWindow||_48e.window||window)!=top||has("jscript")<5.8)&&!has("config-_allow_leaks")){if(typeof _dojoIEListeners_=="undefined"){_dojoIEListeners_=[];}var _490=_48e[type];if(!_490||!_490.listeners){var _491=_490;_48e[type]=_490=Function("event","var callee = arguments.callee; for(var i = 0; i<callee.listeners.length; i++){var listener = _dojoIEListeners_[callee.listeners[i]]; if(listener){listener.call(this,event);}}");_490.listeners=[];_490.global=this;if(_491){_490.listeners.push(_dojoIEListeners_.push(_491)-1);}}var _492;_490.listeners.push(_492=(_490.global._dojoIEListeners_.push(_48f)-1));return new _48a(_492);}return _450.after(_48e,type,_48f,true);};var _489=function(evt){evt.keyChar=evt.charCode?String.fromCharCode(evt.charCode):"";evt.charOrCode=evt.keyChar||evt.keyCode;};var _487=function(){this.cancelBubble=true;};var _488=on._preventDefault=function(){this.bubbledKeyCode=this.keyCode;if(this.ctrlKey){try{this.keyCode=0;}catch(e){}}this.returnValue=false;};}if(has("touch")){var _493=function(){};var _494=window.orientation;var _46d=function(_495){return function(_496){var _497=_496.corrected;if(!_497){var type=_496.type;try{delete _496.type;}catch(e){}if(_496.type){_493.prototype=_496;var _497=new _493;_497.preventDefault=function(){_496.preventDefault();};_497.stopPropagation=function(){_496.stopPropagation();};}else{_497=_496;_497.type=type;}_496.corrected=_497;if(type=="resize"){if(_494==window.orientation){return null;}_494=window.orientation;_497.type="orientationchange";return _495.call(this,_497);}if(!("rotation" in _497)){_497.rotation=0;_497.scale=1;}var _498=_497.changedTouches[0];for(var i in _498){delete _497[i];_497[i]=_498[i];}}return _495.call(this,_497);};};}return on;});},"dojo/_base/sniff":function(){define(["./kernel","../has"],function(dojo,has){if(!1){return has;}dojo.isBrowser=true,dojo._name="browser";var _499=has.add,n=navigator,dua=n.userAgent,dav=n.appVersion,tv=parseFloat(dav),_49a,_49b,_49c,_49d,_49e,_49f,_4a0,_4a1,_4a2,isIE,isFF,_4a3,_4a4,_4a5,_4a6;if(dua.indexOf("AdobeAIR")>=0){_49b=1;}_49c=(dav.indexOf("Konqueror")>=0)?tv:0;_49d=parseFloat(dua.split("WebKit/")[1])||undefined;_49e=parseFloat(dua.split("Chrome/")[1])||undefined;_49f=dav.indexOf("Macintosh")>=0;_4a4=/iPhone|iPod|iPad/.test(dua);_4a5=parseFloat(dua.split("Android ")[1])||undefined;_4a6=typeof opera!="undefined"&&opera.wiiremote;var _4a7=Math.max(dav.indexOf("WebKit"),dav.indexOf("Safari"),0);if(_4a7&&!_49e){_4a0=parseFloat(dav.split("Version/")[1]);if(!_4a0||parseFloat(dav.substr(_4a7+7))<=419.3){_4a0=2;}}if(!has("dojo-webkit")){if(dua.indexOf("Opera")>=0){_49a=tv;if(_49a>=9.8){_49a=parseFloat(dua.split("Version/")[1])||tv;}}if(dua.indexOf("Gecko")>=0&&!_49c&&!_49d){_4a1=_4a2=tv;}if(_4a2){isFF=parseFloat(dua.split("Firefox/")[1]||dua.split("Minefield/")[1])||undefined;}if(document.all&&!_49a){isIE=parseFloat(dav.split("MSIE ")[1])||undefined;var mode=document.documentMode;if(mode&&mode!=5&&Math.floor(isIE)!=mode){isIE=mode;}}}_4a3=document.compatMode=="BackCompat";_499("opera",dojo.isOpera=_49a);_499("air",dojo.isAIR=_49b);_499("khtml",dojo.isKhtml=_49c);_499("webkit",dojo.isWebKit=_49d);_499("chrome",dojo.isChrome=_49e);_499("mac",dojo.isMac=_49f);_499("safari",dojo.isSafari=_4a0);_499("mozilla",dojo.isMozilla=dojo.isMoz=_4a1);_499("ie",dojo.isIE=isIE);_499("ff",dojo.isFF=isFF);_499("quirks",dojo.isQuirks=_4a3);_499("ios",dojo.isIos=_4a4);_499("android",dojo.isAndroid=_4a5);dojo.locale=dojo.locale||(isIE?n.userLanguage:n.language).toLowerCase();return has;});},"dojo/_base/array":function(){define("dojo/_base/array",["./kernel","../has","./lang"],function(dojo,has,lang){var _4a8={},u,_4a9;function _4aa(){_4a8={};};function _4ab(fn){return _4a8[fn]=new Function("item","index","array",fn);};function _4ac(some){var _4ad=!some;return function(a,fn,o){var i=0,l=a&&a.length||0,_4ae;if(l&&typeof a=="string"){a=a.split("");}if(typeof fn=="string"){fn=_4a8[fn]||_4ab(fn);}if(o){for(;i<l;++i){_4ae=!fn.call(o,a[i],i,a);if(some^_4ae){return !_4ae;}}}else{for(;i<l;++i){_4ae=!fn(a[i],i,a);if(some^_4ae){return !_4ae;}}}return _4ad;};};function _4af(up){var _4b0=1,_4b1=0,_4b2=0;if(!up){_4b0=_4b1=_4b2=-1;}return function(a,x,from,last){if(last&&_4b0>0){return _4a9.lastIndexOf(a,x,from);}var l=a&&a.length||0,end=up?l+_4b2:_4b1,i;if(from===u){i=up?_4b1:l+_4b2;}else{if(from<0){i=l+from;if(i<0){i=_4b1;}}else{i=from>=l?l+_4b2:from;}}if(l&&typeof a=="string"){a=a.split("");}for(;i!=end;i+=_4b0){if(a[i]==x){return i;}}return -1;};};function _4b3(a,fn,o){var i=0,l=a&&a.length||0;if(l&&typeof a=="string"){a=a.split("");}if(typeof fn=="string"){fn=_4a8[fn]||_4ab(fn);}if(o){for(;i<l;++i){fn.call(o,a[i],i,a);}}else{for(;i<l;++i){fn(a[i],i,a);}}};function map(a,fn,o,Ctr){var i=0,l=a&&a.length||0,out=new (Ctr||Array)(l);if(l&&typeof a=="string"){a=a.split("");}if(typeof fn=="string"){fn=_4a8[fn]||_4ab(fn);}if(o){for(;i<l;++i){out[i]=fn.call(o,a[i],i,a);}}else{for(;i<l;++i){out[i]=fn(a[i],i,a);}}return out;};function _4b4(a,fn,o){var i=0,l=a&&a.length||0,out=[],_4b5;if(l&&typeof a=="string"){a=a.split("");}if(typeof fn=="string"){fn=_4a8[fn]||_4ab(fn);}if(o){for(;i<l;++i){_4b5=a[i];if(fn.call(o,_4b5,i,a)){out.push(_4b5);}}}else{for(;i<l;++i){_4b5=a[i];if(fn(_4b5,i,a)){out.push(_4b5);}}}return out;};_4a9={every:_4ac(false),some:_4ac(true),indexOf:_4af(true),lastIndexOf:_4af(false),forEach:_4b3,map:map,filter:_4b4,clearCache:_4aa};1&&lang.mixin(dojo,_4a9);return _4a9;});},"dojo/_base/json":function(){define(["./kernel","../json"],function(dojo,json){dojo.fromJson=function(js){return eval("("+js+")");};dojo._escapeString=json.stringify;dojo.toJsonIndentStr="\t";dojo.toJson=function(it,_4b6){return json.stringify(it,function(key,_4b7){if(_4b7){var tf=_4b7.__json__||_4b7.json;if(typeof tf=="function"){return tf.call(_4b7);}}return _4b7;},_4b6&&dojo.toJsonIndentStr);};return dojo;});},"dojo/_base/window":function(){define(["./kernel","../has","./sniff"],function(dojo,has){dojo.doc=this["document"]||null;dojo.body=function(){return dojo.doc.body||dojo.doc.getElementsByTagName("body")[0];};dojo.setContext=function(_4b8,_4b9){dojo.global=ret.global=_4b8;dojo.doc=ret.doc=_4b9;};dojo.withGlobal=function(_4ba,_4bb,_4bc,_4bd){var _4be=dojo.global;try{dojo.global=ret.global=_4ba;return dojo.withDoc.call(null,_4ba.document,_4bb,_4bc,_4bd);}finally{dojo.global=ret.global=_4be;}};dojo.withDoc=function(_4bf,_4c0,_4c1,_4c2){var _4c3=dojo.doc,oldQ=dojo.isQuirks,_4c4=dojo.isIE,isIE,mode,pwin;try{dojo.doc=ret.doc=_4bf;dojo.isQuirks=has.add("quirks",dojo.doc.compatMode=="BackCompat",true,true);if(has("ie")){if((pwin=_4bf.parentWindow)&&pwin.navigator){isIE=parseFloat(pwin.navigator.appVersion.split("MSIE ")[1])||undefined;mode=_4bf.documentMode;if(mode&&mode!=5&&Math.floor(isIE)!=mode){isIE=mode;}dojo.isIE=has.add("ie",isIE,true,true);}}if(_4c1&&typeof _4c0=="string"){_4c0=_4c1[_4c0];}return _4c0.apply(_4c1,_4c2||[]);}finally{dojo.doc=ret.doc=_4c3;dojo.isQuirks=has.add("quirks",oldQ,true,true);dojo.isIE=has.add("ie",_4c4,true,true);}};var ret={global:dojo.global,doc:dojo.doc,body:dojo.body,setContext:dojo.setContext,withGlobal:dojo.withGlobal,withDoc:dojo.withDoc};return ret;});},"dojo/dom-class":function(){define(["./_base/lang","./_base/array","./dom"],function(lang,_4c5,dom){var _4c6="className";var cls,_4c7=/\s+/,a1=[""];function _4c8(s){if(typeof s=="string"||s instanceof String){if(s&&!_4c7.test(s)){a1[0]=s;return a1;}var a=s.split(_4c7);if(a.length&&!a[0]){a.shift();}if(a.length&&!a[a.length-1]){a.pop();}return a;}if(!s){return [];}return _4c5.filter(s,function(x){return x;});};var _4c9={};cls={contains:function containsClass(node,_4ca){return ((" "+dom.byId(node)[_4c6]+" ").indexOf(" "+_4ca+" ")>=0);},add:function addClass(node,_4cb){node=dom.byId(node);_4cb=_4c8(_4cb);var cls=node[_4c6],_4cc;cls=cls?" "+cls+" ":" ";_4cc=cls.length;for(var i=0,len=_4cb.length,c;i<len;++i){c=_4cb[i];if(c&&cls.indexOf(" "+c+" ")<0){cls+=c+" ";}}if(_4cc<cls.length){node[_4c6]=cls.substr(1,cls.length-2);}},remove:function removeClass(node,_4cd){node=dom.byId(node);var cls;if(_4cd!==undefined){_4cd=_4c8(_4cd);cls=" "+node[_4c6]+" ";for(var i=0,len=_4cd.length;i<len;++i){cls=cls.replace(" "+_4cd[i]+" "," ");}cls=lang.trim(cls);}else{cls="";}if(node[_4c6]!=cls){node[_4c6]=cls;}},replace:function replaceClass(node,_4ce,_4cf){node=dom.byId(node);_4c9[_4c6]=node[_4c6];cls.remove(_4c9,_4cf);cls.add(_4c9,_4ce);if(node[_4c6]!==_4c9[_4c6]){node[_4c6]=_4c9[_4c6];}},toggle:function toggleClass(node,_4d0,_4d1){node=dom.byId(node);if(_4d1===undefined){_4d0=_4c8(_4d0);for(var i=0,len=_4d0.length,c;i<len;++i){c=_4d0[i];cls[cls.contains(node,c)?"remove":"add"](node,c);}}else{cls[_4d1?"add":"remove"](node,_4d0);}return _4d1;}};return cls;});},"dojo/_base/config":function(){define(["../has","require"],function(has,_4d2){var _4d3={};if(1){var src=_4d2.rawConfig,p;for(p in src){_4d3[p]=src[p];}}else{var _4d4=function(_4d5,_4d6,_4d7){for(p in _4d5){p!="has"&&has.add(_4d6+p,_4d5[p],0,_4d7);}};_4d3=1?_4d2.rawConfig:this.dojoConfig||this.djConfig||{};_4d4(_4d3,"config",1);_4d4(_4d3.has,"",1);}return _4d3;});},"dojo/_base/event":function(){define(["./kernel","../on","../has","../dom-geometry"],function(dojo,on,has,dom){if(on._fixEvent){var _4d8=on._fixEvent;on._fixEvent=function(evt,se){evt=_4d8(evt,se);if(evt){dom.normalizeEvent(evt);}return evt;};}dojo.fixEvent=function(evt,_4d9){if(on._fixEvent){return on._fixEvent(evt,_4d9);}return evt;};dojo.stopEvent=function(evt){if(has("dom-addeventlistener")||(evt&&evt.preventDefault)){evt.preventDefault();evt.stopPropagation();}else{evt=evt||window.event;evt.cancelBubble=true;on._preventDefault.call(evt);}};return {fix:dojo.fixEvent,stop:dojo.stopEvent};});},"dojo/main":function(){define(["./_base/kernel","./has","require","./_base/sniff","./_base/lang","./_base/array","./ready","./_base/declare","./_base/connect","./_base/Deferred","./_base/json","./_base/Color","./has!dojo-firebug?./_firebug/firebug","./_base/browser","./_base/loader"],function(dojo,has,_4da,_4db,lang,_4dc,_4dd){if(dojo.config.isDebug){_4da(["./_firebug/firebug"]);}true||has.add("dojo-config-require",1);if(1){var deps=dojo.config.require;if(deps){deps=_4dc.map(lang.isArray(deps)?deps:[deps],function(item){return item.replace(/\./g,"/");});if(dojo.isAsync){_4da(deps);}else{_4dd(1,function(){_4da(deps);});}}}return dojo;});},"dojo/ready":function(){define(["./_base/kernel","./has","require","./domReady","./_base/lang"],function(dojo,has,_4de,_4df,lang){var _4e0=0,_4e1,_4e2=[],_4e3=0,_4e4=function(){_4e0=1;dojo._postLoad=dojo.config.afterOnLoad=true;if(_4e2.length){_4e1(_4e5);}},_4e5=function(){if(_4e0&&!_4e3&&_4e2.length){_4e3=1;var f=_4e2.shift();try{f();}finally{_4e3=0;}_4e3=0;if(_4e2.length){_4e1(_4e5);}}};if(1){_4de.on("idle",_4e5);_4e1=function(){if(_4de.idle()){_4e5();}};}else{_4e1=function(){_4de.ready(_4e5);};}var _4e6=dojo.ready=dojo.addOnLoad=function(_4e7,_4e8,_4e9){var _4ea=lang._toArray(arguments);if(typeof _4e7!="number"){_4e9=_4e8;_4e8=_4e7;_4e7=1000;}else{_4ea.shift();}_4e9=_4e9?lang.hitch.apply(dojo,_4ea):function(){_4e8();};_4e9.priority=_4e7;for(var i=0;i<_4e2.length&&_4e7>=_4e2[i].priority;i++){}_4e2.splice(i,0,_4e9);_4e1();};true||has.add("dojo-config-addOnLoad",1);if(1){var dca=dojo.config.addOnLoad;if(dca){_4e6[(lang.isArray(dca)?"apply":"call")](dojo,dca);}}if(1&&dojo.config.parseOnLoad&&!dojo.isAsync){_4e6(99,function(){if(!dojo.parser){dojo.deprecated("Add explicit require(['dojo/parser']);","","2.0");_4de(["dojo/parser"]);}});}if(1){_4df(_4e4);}else{_4e4();}return _4e6;});},"dojo/aspect":function(){define([],function(){"use strict";var _4eb=0;function _4ec(_4ed,type,_4ee,_4ef){var _4f0=_4ed[type];var _4f1=type=="around";var _4f2;if(_4f1){var _4f3=_4ee(function(){return _4f0.advice(this,arguments);});_4f2={remove:function(){_4f2.cancelled=true;},advice:function(_4f4,args){return _4f2.cancelled?_4f0.advice(_4f4,args):_4f3.apply(_4f4,args);}};}else{_4f2={remove:function(){var _4f5=_4f2.previous;var next=_4f2.next;if(!next&&!_4f5){delete _4ed[type];}else{if(_4f5){_4f5.next=next;}else{_4ed[type]=next;}if(next){next.previous=_4f5;}}},id:_4eb++,advice:_4ee,receiveArguments:_4ef};}if(_4f0&&!_4f1){if(type=="after"){var next=_4f0;while(next){_4f0=next;next=next.next;}_4f0.next=_4f2;_4f2.previous=_4f0;}else{if(type=="before"){_4ed[type]=_4f2;_4f2.next=_4f0;_4f0.previous=_4f2;}}}else{_4ed[type]=_4f2;}return _4f2;};function _4f6(type){return function(_4f7,_4f8,_4f9,_4fa){var _4fb=_4f7[_4f8],_4fc;if(!_4fb||_4fb.target!=_4f7){_4f7[_4f8]=_4fc=function(){var _4fd=_4eb;var args=arguments;var _4fe=_4fc.before;while(_4fe){args=_4fe.advice.apply(this,args)||args;_4fe=_4fe.next;}if(_4fc.around){var _4ff=_4fc.around.advice(this,args);}var _500=_4fc.after;while(_500&&_500.id<_4fd){_4ff=_500.receiveArguments?_500.advice.apply(this,args)||_4ff:_500.advice.call(this,_4ff);_500=_500.next;}return _4ff;};if(_4fb){_4fc.around={advice:function(_501,args){return _4fb.apply(_501,args);}};}_4fc.target=_4f7;}var _502=_4ec((_4fc||_4fb),type,_4f9,_4fa);_4f9=null;return _502;};};return {before:_4f6("before"),around:_4f6("around"),after:_4f6("after")};});},"dojo/_base/connect":function(){define(["./kernel","../on","../topic","../aspect","./event","../mouse","./sniff","./lang","../keys"],function(_503,on,hub,_504,_505,_506,has,lang){has.add("events-keypress-typed",function(){var _507={charCode:0};try{_507=document.createEvent("KeyboardEvent");(_507.initKeyboardEvent||_507.initKeyEvent).call(_507,"keypress",true,true,null,false,false,false,false,9,3);}catch(e){}return _507.charCode==0&&!has("opera");});function _508(obj,_509,_50a,_50b,_50c){_50b=lang.hitch(_50a,_50b);if(!obj||!(obj.addEventListener||obj.attachEvent)){return _504.after(obj||_503.global,_509,_50b,true);}if(typeof _509=="string"&&_509.substring(0,2)=="on"){_509=_509.substring(2);}if(!obj){obj=_503.global;}if(!_50c){switch(_509){case "keypress":_509=_50d;break;case "mouseenter":_509=_506.enter;break;case "mouseleave":_509=_506.leave;break;}}return on(obj,_509,_50b,_50c);};var _50e={106:42,111:47,186:59,187:43,188:44,189:45,190:46,191:47,192:96,219:91,220:92,221:93,222:39,229:113};var _50f=has("mac")?"metaKey":"ctrlKey";var _510=function(evt,_511){var faux=lang.mixin({},evt,_511);_512(faux);faux.preventDefault=function(){evt.preventDefault();};faux.stopPropagation=function(){evt.stopPropagation();};return faux;};function _512(evt){evt.keyChar=evt.charCode?String.fromCharCode(evt.charCode):"";evt.charOrCode=evt.keyChar||evt.keyCode;};var _50d;if(has("events-keypress-typed")){var _513=function(e,code){try{return (e.keyCode=code);}catch(e){return 0;}};_50d=function(_514,_515){var _516=on(_514,"keydown",function(evt){var k=evt.keyCode;var _517=(k!=13||(has("ie")>=9&&!has("quirks")))&&k!=32&&(k!=27||!has("ie"))&&(k<48||k>90)&&(k<96||k>111)&&(k<186||k>192)&&(k<219||k>222)&&k!=229;if(_517||evt.ctrlKey){var c=_517?0:k;if(evt.ctrlKey){if(k==3||k==13){return _515.call(evt.currentTarget,evt);}else{if(c>95&&c<106){c-=48;}else{if((!evt.shiftKey)&&(c>=65&&c<=90)){c+=32;}else{c=_50e[c]||c;}}}}var faux=_510(evt,{type:"keypress",faux:true,charCode:c});_515.call(evt.currentTarget,faux);if(has("ie")){_513(evt,faux.keyCode);}}});var _518=on(_514,"keypress",function(evt){var c=evt.charCode;c=c>=32?c:0;evt=_510(evt,{charCode:c,faux:true});return _515.call(this,evt);});return {remove:function(){_516.remove();_518.remove();}};};}else{if(has("opera")){_50d=function(_519,_51a){return on(_519,"keypress",function(evt){var c=evt.which;if(c==3){c=99;}c=c<32&&!evt.shiftKey?0:c;if(evt.ctrlKey&&!evt.shiftKey&&c>=65&&c<=90){c+=32;}return _51a.call(this,_510(evt,{charCode:c}));});};}else{_50d=function(_51b,_51c){return on(_51b,"keypress",function(evt){_512(evt);return _51c.call(this,evt);});};}}var _51d={_keypress:_50d,connect:function(obj,_51e,_51f,_520,_521){var a=arguments,args=[],i=0;args.push(typeof a[0]=="string"?null:a[i++],a[i++]);var a1=a[i+1];args.push(typeof a1=="string"||typeof a1=="function"?a[i++]:null,a[i++]);for(var l=a.length;i<l;i++){args.push(a[i]);}return _508.apply(this,args);},disconnect:function(_522){if(_522){_522.remove();}},subscribe:function(_523,_524,_525){return hub.subscribe(_523,lang.hitch(_524,_525));},publish:function(_526,args){return hub.publish.apply(hub,[_526].concat(args));},connectPublisher:function(_527,obj,_528){var pf=function(){_51d.publish(_527,arguments);};return _528?_51d.connect(obj,_528,pf):_51d.connect(obj,pf);},isCopyKey:function(e){return e[_50f];}};_51d.unsubscribe=_51d.disconnect;1&&lang.mixin(_503,_51d);return _51d;});}}});(function(){var _529=this.require;_529({cache:{}});!_529.async&&_529(["dojo"]);_529.boot&&_529.apply(null,_529.boot);})();
\ No newline at end of file
diff --git a/http/samples/cometd/src-web/dojo/io/script.js b/http/samples/cometd/src-web/dojo/io/script.js
new file mode 100644
index 0000000..b040b9b
--- /dev/null
+++ b/http/samples/cometd/src-web/dojo/io/script.js
@@ -0,0 +1,114 @@
+/*
+	Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+	Available via Academic Free License >= 2.1 OR the modified BSD license.
+	see: http://dojotoolkit.org/license for details
+*/
+
+//>>built
+define("dojo/io/script",["../main"],function(_1){
+_1.getObject("io",true,_1);
+var _2=_1.isIE?"onreadystatechange":"load",_3=/complete|loaded/;
+_1.io.script={get:function(_4){
+var _5=this._makeScriptDeferred(_4);
+var _6=_5.ioArgs;
+_1._ioAddQueryToUrl(_6);
+_1._ioNotifyStart(_5);
+if(this._canAttach(_6)){
+var _7=this.attach(_6.id,_6.url,_4.frameDoc);
+if(!_6.jsonp&&!_6.args.checkString){
+var _8=_1.connect(_7,_2,function(_9){
+if(_9.type=="load"||_3.test(_7.readyState)){
+_1.disconnect(_8);
+_6.scriptLoaded=_9;
+}
+});
+}
+}
+_1._ioWatch(_5,this._validCheck,this._ioCheck,this._resHandle);
+return _5;
+},attach:function(id,_a,_b){
+var _c=(_b||_1.doc);
+var _d=_c.createElement("script");
+_d.type="text/javascript";
+_d.src=_a;
+_d.id=id;
+_d.async=true;
+_d.charset="utf-8";
+return _c.getElementsByTagName("head")[0].appendChild(_d);
+},remove:function(id,_e){
+_1.destroy(_1.byId(id,_e));
+if(this["jsonp_"+id]){
+delete this["jsonp_"+id];
+}
+},_makeScriptDeferred:function(_f){
+var dfd=_1._ioSetArgs(_f,this._deferredCancel,this._deferredOk,this._deferredError);
+var _10=dfd.ioArgs;
+_10.id=_1._scopeName+"IoScript"+(this._counter++);
+_10.canDelete=false;
+_10.jsonp=_f.callbackParamName||_f.jsonp;
+if(_10.jsonp){
+_10.query=_10.query||"";
+if(_10.query.length>0){
+_10.query+="&";
+}
+_10.query+=_10.jsonp+"="+(_f.frameDoc?"parent.":"")+_1._scopeName+".io.script.jsonp_"+_10.id+"._jsonpCallback";
+_10.frameDoc=_f.frameDoc;
+_10.canDelete=true;
+dfd._jsonpCallback=this._jsonpCallback;
+this["jsonp_"+_10.id]=dfd;
+}
+return dfd;
+},_deferredCancel:function(dfd){
+dfd.canceled=true;
+if(dfd.ioArgs.canDelete){
+_1.io.script._addDeadScript(dfd.ioArgs);
+}
+},_deferredOk:function(dfd){
+var _11=dfd.ioArgs;
+if(_11.canDelete){
+_1.io.script._addDeadScript(_11);
+}
+return _11.json||_11.scriptLoaded||_11;
+},_deferredError:function(_12,dfd){
+if(dfd.ioArgs.canDelete){
+if(_12.dojoType=="timeout"){
+_1.io.script.remove(dfd.ioArgs.id,dfd.ioArgs.frameDoc);
+}else{
+_1.io.script._addDeadScript(dfd.ioArgs);
+}
+}
+return _12;
+},_deadScripts:[],_counter:1,_addDeadScript:function(_13){
+_1.io.script._deadScripts.push({id:_13.id,frameDoc:_13.frameDoc});
+_13.frameDoc=null;
+},_validCheck:function(dfd){
+var _14=_1.io.script;
+var _15=_14._deadScripts;
+if(_15&&_15.length>0){
+for(var i=0;i<_15.length;i++){
+_14.remove(_15[i].id,_15[i].frameDoc);
+_15[i].frameDoc=null;
+}
+_1.io.script._deadScripts=[];
+}
+return true;
+},_ioCheck:function(dfd){
+var _16=dfd.ioArgs;
+if(_16.json||(_16.scriptLoaded&&!_16.args.checkString)){
+return true;
+}
+var _17=_16.args.checkString;
+return _17&&eval("typeof("+_17+") != 'undefined'");
+},_resHandle:function(dfd){
+if(_1.io.script._ioCheck(dfd)){
+dfd.callback(dfd);
+}else{
+dfd.errback(new Error("inconceivable dojo.io.script._resHandle error"));
+}
+},_canAttach:function(_18){
+return true;
+},_jsonpCallback:function(_19){
+this.ioArgs.json=_19;
+}};
+return _1.io.script;
+});
diff --git a/http/samples/cometd/src-web/dojox/cometd.js b/http/samples/cometd/src-web/dojox/cometd.js
new file mode 100644
index 0000000..4a0d51a
--- /dev/null
+++ b/http/samples/cometd/src-web/dojox/cometd.js
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2010 the original author or authors.
+ *
+ * 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.
+ */
+
+dojo.provide('dojox.cometd');
+dojo.registerModulePath('org','../org');
+dojo.require('org.cometd');
+dojo.require('dojo.io.script');
+
+// Remap cometd JSON functions to dojo JSON functions
+org.cometd.JSON.toJSON = dojo.toJson;
+org.cometd.JSON.fromJSON = dojo.fromJson;
+
+dojox.Cometd = function(name)
+{
+    var cometd = new org.cometd.Cometd(name);
+
+    function LongPollingTransport()
+    {
+        var _super = new org.cometd.LongPollingTransport();
+        var that = org.cometd.Transport.derive(_super);
+
+        that.xhrSend = function(packet)
+        {
+            var deferred = dojo.rawXhrPost({
+                url: packet.url,
+                sync: packet.sync === true,
+                contentType: 'application/json;charset=UTF-8',
+                headers: packet.headers,
+                postData: packet.body,
+                withCredentials: true,
+                handleAs: 'json',
+                load: packet.onSuccess,
+                error: function(error)
+                {
+                    packet.onError(error.message, deferred ? deferred.ioArgs.error : error);
+                }
+            });
+            return deferred.ioArgs.xhr;
+        };
+
+        return that;
+    }
+
+    function CallbackPollingTransport()
+    {
+        var _super = new org.cometd.CallbackPollingTransport();
+        var that = org.cometd.Transport.derive(_super);
+
+        that.jsonpSend = function(packet)
+        {
+            var deferred = dojo.io.script.get({
+                url: packet.url,
+                sync: packet.sync === true,
+                callbackParamName: 'jsonp',
+                content: {
+                    // In callback-polling, the content must be sent via the 'message' parameter
+                    message: packet.body
+                },
+                load: packet.onSuccess,
+                error: function(error)
+                {
+                    packet.onError(error.message, deferred ? deferred.ioArgs.error : error);
+                }
+            });
+            return undefined;
+        };
+
+        return that;
+    }
+
+    // Registration order is important
+    if (org.cometd.WebSocket)
+    {
+        cometd.registerTransport('websocket', new org.cometd.WebSocketTransport());
+    }
+    cometd.registerTransport('long-polling', new LongPollingTransport());
+    cometd.registerTransport('callback-polling', new CallbackPollingTransport());
+
+    return cometd;
+};
+
+// The default cometd instance
+dojox.cometd = new dojox.Cometd();
+
+// Create a compatibility API for dojox.cometd instance with
+// the original API.
+
+dojox.cometd._init = dojox.cometd.init;
+
+dojox.cometd._unsubscribe = dojox.cometd.unsubscribe;
+
+dojox.cometd.unsubscribe = function(channelOrToken, objOrFunc, funcName)
+{
+    if (typeof channelOrToken === 'string')
+    {
+        throw "Deprecated function unsubscribe(string). Use unsubscribe(object) passing as argument the return value of subscribe()";
+    }
+
+    dojox.cometd._unsubscribe(channelOrToken);
+};
+
+dojox.cometd._metaHandshakeEvent = function(event)
+{
+    event.action = "handshake";
+    dojo.publish("/cometd/meta", [event]);
+};
+
+dojox.cometd._metaConnectEvent = function(event)
+{
+    event.action = "connect";
+    dojo.publish("/cometd/meta", [event]);
+};
+
+dojox.cometd.addListener('/meta/handshake', dojox.cometd, dojox.cometd._metaHandshakeEvent);
+dojox.cometd.addListener('/meta/connect', dojox.cometd, dojox.cometd._metaConnectEvent);
diff --git a/http/samples/cometd/src-web/org/cometd.js b/http/samples/cometd/src-web/org/cometd.js
new file mode 100644
index 0000000..a914359
--- /dev/null
+++ b/http/samples/cometd/src-web/org/cometd.js
@@ -0,0 +1,2982 @@
+/*
+ * Copyright (c) 2010 the original author or authors.
+ *
+ * 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.
+ */
+
+if (typeof dojo !== 'undefined')
+{
+    dojo.provide('org.cometd');
+}
+else
+{
+    // Namespaces for the cometd implementation
+    this.org = this.org || {};
+    org.cometd = {};
+}
+
+org.cometd.JSON = {};
+org.cometd.JSON.toJSON = org.cometd.JSON.fromJSON = function(object)
+{
+    throw 'Abstract';
+};
+
+org.cometd.Utils = {};
+
+org.cometd.Utils.isString = function(value)
+{
+    if (value === undefined || value === null)
+    {
+        return false;
+    }
+    return typeof value === 'string' ||  value instanceof String;
+};
+
+org.cometd.Utils.isArray = function(value)
+{
+    if (value === undefined || value === null)
+    {
+        return false;
+    }
+    return value instanceof Array;
+};
+
+/**
+ * Returns whether the given element is contained into the given array.
+ * @param element the element to check presence for
+ * @param array the array to check for the element presence
+ * @return the index of the element, if present, or a negative index if the element is not present
+ */
+org.cometd.Utils.inArray = function(element, array)
+{
+    for (var i = 0; i < array.length; ++i)
+    {
+        if (element === array[i])
+        {
+            return i;
+        }
+    }
+    return -1;
+};
+
+org.cometd.Utils.setTimeout = function(cometd, funktion, delay)
+{
+    return window.setTimeout(function()
+    {
+        try
+        {
+            funktion();
+        }
+        catch (x)
+        {
+            cometd._debug('Exception invoking timed function', funktion, x);
+        }
+    }, delay);
+};
+
+org.cometd.Utils.clearTimeout = function(timeoutHandle)
+{
+    window.clearTimeout(timeoutHandle);
+};
+
+/**
+ * A registry for transports used by the Cometd object.
+ */
+org.cometd.TransportRegistry = function()
+{
+    var _types = [];
+    var _transports = {};
+
+    this.getTransportTypes = function()
+    {
+        return _types.slice(0);
+    };
+
+    this.findTransportTypes = function(version, crossDomain, url)
+    {
+        var result = [];
+        for (var i = 0; i < _types.length; ++i)
+        {
+            var type = _types[i];
+            if (_transports[type].accept(version, crossDomain, url) === true)
+            {
+                result.push(type);
+            }
+        }
+        return result;
+    };
+
+    this.negotiateTransport = function(types, version, crossDomain, url)
+    {
+        for (var i = 0; i < _types.length; ++i)
+        {
+            var type = _types[i];
+            for (var j = 0; j < types.length; ++j)
+            {
+                if (type === types[j])
+                {
+                    var transport = _transports[type];
+                    if (transport.accept(version, crossDomain, url) === true)
+                    {
+                        return transport;
+                    }
+                }
+            }
+        }
+        return null;
+    };
+
+    this.add = function(type, transport, index)
+    {
+        var existing = false;
+        for (var i = 0; i < _types.length; ++i)
+        {
+            if (_types[i] === type)
+            {
+                existing = true;
+                break;
+            }
+        }
+
+        if (!existing)
+        {
+            if (typeof index !== 'number')
+            {
+                _types.push(type);
+            }
+            else
+            {
+                _types.splice(index, 0, type);
+            }
+            _transports[type] = transport;
+        }
+
+        return !existing;
+    };
+
+    this.find = function(type)
+    {
+        for (var i = 0; i < _types.length; ++i)
+        {
+            if (_types[i] === type)
+            {
+                return _transports[type];
+            }
+        }
+        return null;
+    };
+
+    this.remove = function(type)
+    {
+        for (var i = 0; i < _types.length; ++i)
+        {
+            if (_types[i] === type)
+            {
+                _types.splice(i, 1);
+                var transport = _transports[type];
+                delete _transports[type];
+                return transport;
+            }
+        }
+        return null;
+    };
+
+    this.clear = function()
+    {
+        _types = [];
+        _transports = {};
+    };
+
+    this.reset = function()
+    {
+        for (var i = 0; i < _types.length; ++i)
+        {
+            _transports[_types[i]].reset();
+        }
+    };
+};
+
+/**
+ * Base object with the common functionality for transports.
+ */
+org.cometd.Transport = function()
+{
+    var _type;
+    var _cometd;
+
+    /**
+     * Function invoked just after a transport has been successfully registered.
+     * @param type the type of transport (for example 'long-polling')
+     * @param cometd the cometd object this transport has been registered to
+     * @see #unregistered()
+     */
+    this.registered = function(type, cometd)
+    {
+        _type = type;
+        _cometd = cometd;
+    };
+
+    /**
+     * Function invoked just after a transport has been successfully unregistered.
+     * @see #registered(type, cometd)
+     */
+    this.unregistered = function()
+    {
+        _type = null;
+        _cometd = null;
+    };
+
+    this._debug = function()
+    {
+        _cometd._debug.apply(_cometd, arguments);
+    };
+
+    this._mixin = function()
+    {
+        return _cometd._mixin.apply(_cometd, arguments);
+    };
+
+    this.getConfiguration = function()
+    {
+        return _cometd.getConfiguration();
+    };
+
+    this.getAdvice = function()
+    {
+        return _cometd.getAdvice();
+    };
+
+    this.setTimeout = function(funktion, delay)
+    {
+        return org.cometd.Utils.setTimeout(_cometd, funktion, delay);
+    };
+
+    this.clearTimeout = function(handle)
+    {
+        org.cometd.Utils.clearTimeout(handle);
+    };
+
+    /**
+     * Converts the given response into an array of bayeux messages
+     * @param response the response to convert
+     * @return an array of bayeux messages obtained by converting the response
+     */
+    this.convertToMessages = function (response)
+    {
+        if (org.cometd.Utils.isString(response))
+        {
+            try
+            {
+                return org.cometd.JSON.fromJSON(response);
+            }
+            catch(x)
+            {
+                this._debug('Could not convert to JSON the following string', '"' + response + '"');
+                throw x;
+            }
+        }
+        if (org.cometd.Utils.isArray(response))
+        {
+            return response;
+        }
+        if (response === undefined || response === null)
+        {
+            return [];
+        }
+        if (response instanceof Object)
+        {
+            return [response];
+        }
+        throw 'Conversion Error ' + response + ', typeof ' + (typeof response);
+    };
+
+    /**
+     * Returns whether this transport can work for the given version and cross domain communication case.
+     * @param version a string indicating the transport version
+     * @param crossDomain a boolean indicating whether the communication is cross domain
+     * @return true if this transport can work for the given version and cross domain communication case,
+     * false otherwise
+     */
+    this.accept = function(version, crossDomain, url)
+    {
+        throw 'Abstract';
+    };
+
+    /**
+     * Returns the type of this transport.
+     * @see #registered(type, cometd)
+     */
+    this.getType = function()
+    {
+        return _type;
+    };
+
+    this.send = function(envelope, metaConnect)
+    {
+        throw 'Abstract';
+    };
+
+    this.reset = function()
+    {
+        this._debug('Transport', _type, 'reset');
+    };
+
+    this.abort = function()
+    {
+        this._debug('Transport', _type, 'aborted');
+    };
+
+    this.toString = function()
+    {
+        return this.getType();
+    };
+};
+
+org.cometd.Transport.derive = function(baseObject)
+{
+    function F() {}
+    F.prototype = baseObject;
+    return new F();
+};
+
+/**
+ * Base object with the common functionality for transports based on requests.
+ * The key responsibility is to allow at most 2 outstanding requests to the server,
+ * to avoid that requests are sent behind a long poll.
+ * To achieve this, we have one reserved request for the long poll, and all other
+ * requests are serialized one after the other.
+ */
+org.cometd.RequestTransport = function()
+{
+    var _super = new org.cometd.Transport();
+    var _self = org.cometd.Transport.derive(_super);
+    var _requestIds = 0;
+    var _metaConnectRequest = null;
+    var _requests = [];
+    var _envelopes = [];
+
+    function _coalesceEnvelopes(envelope)
+    {
+        while (_envelopes.length > 0)
+        {
+            var envelopeAndRequest = _envelopes[0];
+            var newEnvelope = envelopeAndRequest[0];
+            var newRequest = envelopeAndRequest[1];
+            if (newEnvelope.url === envelope.url &&
+                    newEnvelope.sync === envelope.sync)
+            {
+                _envelopes.shift();
+                envelope.messages = envelope.messages.concat(newEnvelope.messages);
+                this._debug('Coalesced', newEnvelope.messages.length, 'messages from request', newRequest.id);
+                continue;
+            }
+            break;
+        }
+    }
+
+    function _transportSend(envelope, request)
+    {
+        this.transportSend(envelope, request);
+        request.expired = false;
+
+        if (!envelope.sync)
+        {
+            var maxDelay = this.getConfiguration().maxNetworkDelay;
+            var delay = maxDelay;
+            if (request.metaConnect === true)
+            {
+                delay += this.getAdvice().timeout;
+            }
+
+            this._debug('Transport', this.getType(), 'waiting at most', delay, 'ms for the response, maxNetworkDelay', maxDelay);
+
+            var self = this;
+            request.timeout = this.setTimeout(function()
+            {
+                request.expired = true;
+                if (request.xhr)
+                {
+                    request.xhr.abort();
+                }
+                var errorMessage = 'Request ' + request.id + ' of transport ' + self.getType() + ' exceeded ' + delay + ' ms max network delay';
+                self._debug(errorMessage);
+                self.complete(request, false, request.metaConnect);
+                envelope.onFailure(request.xhr, envelope.messages, 'timeout', errorMessage);
+            }, delay);
+        }
+    }
+
+    function _queueSend(envelope)
+    {
+        var requestId = ++_requestIds;
+        var request = {
+            id: requestId,
+            metaConnect: false
+        };
+
+        // Consider the metaConnect requests which should always be present
+        if (_requests.length < this.getConfiguration().maxConnections - 1)
+        {
+            _requests.push(request);
+            _transportSend.call(this, envelope, request);
+        }
+        else
+        {
+            this._debug('Transport', this.getType(), 'queueing request', requestId, 'envelope', envelope);
+            _envelopes.push([envelope, request]);
+        }
+    }
+
+    function _metaConnectComplete(request)
+    {
+        var requestId = request.id;
+        this._debug('Transport', this.getType(), 'metaConnect complete, request', requestId);
+        if (_metaConnectRequest !== null && _metaConnectRequest.id !== requestId)
+        {
+            throw 'Longpoll request mismatch, completing request ' + requestId;
+        }
+
+        // Reset metaConnect request
+        _metaConnectRequest = null;
+    }
+
+    function _complete(request, success)
+    {
+        var index = org.cometd.Utils.inArray(request, _requests);
+        // The index can be negative if the request has been aborted
+        if (index >= 0)
+        {
+            _requests.splice(index, 1);
+        }
+
+        if (_envelopes.length > 0)
+        {
+            var envelopeAndRequest = _envelopes.shift();
+            var nextEnvelope = envelopeAndRequest[0];
+            var nextRequest = envelopeAndRequest[1];
+            this._debug('Transport dequeued request', nextRequest.id);
+            if (success)
+            {
+                if (this.getConfiguration().autoBatch)
+                {
+                    _coalesceEnvelopes.call(this, nextEnvelope);
+                }
+                _queueSend.call(this, nextEnvelope);
+                this._debug('Transport completed request', request.id, nextEnvelope);
+            }
+            else
+            {
+                // Keep the semantic of calling response callbacks asynchronously after the request
+                var self = this;
+                this.setTimeout(function()
+                {
+                    self.complete(nextRequest, false, nextRequest.metaConnect);
+                    nextEnvelope.onFailure(nextRequest.xhr, nextEnvelope.messages, 'error', 'Previous request failed');
+                }, 0);
+            }
+        }
+    }
+
+    _self.complete = function(request, success, metaConnect)
+    {
+        if (metaConnect)
+        {
+            _metaConnectComplete.call(this, request);
+        }
+        else
+        {
+            _complete.call(this, request, success);
+        }
+    };
+
+    /**
+     * Performs the actual send depending on the transport type details.
+     * @param envelope the envelope to send
+     * @param request the request information
+     */
+    _self.transportSend = function(envelope, request)
+    {
+        throw 'Abstract';
+    };
+
+    _self.transportSuccess = function(envelope, request, responses)
+    {
+        if (!request.expired)
+        {
+            this.clearTimeout(request.timeout);
+            this.complete(request, true, request.metaConnect);
+            if (responses && responses.length > 0)
+            {
+                envelope.onSuccess(responses);
+            }
+            else
+            {
+                envelope.onFailure(request.xhr, envelope.messages, 'Empty HTTP response');
+            }
+        }
+    };
+
+    _self.transportFailure = function(envelope, request, reason, exception)
+    {
+        if (!request.expired)
+        {
+            this.clearTimeout(request.timeout);
+            this.complete(request, false, request.metaConnect);
+            envelope.onFailure(request.xhr, envelope.messages, reason, exception);
+        }
+    };
+
+    function _metaConnectSend(envelope)
+    {
+        if (_metaConnectRequest !== null)
+        {
+            throw 'Concurrent metaConnect requests not allowed, request id=' + _metaConnectRequest.id + ' not yet completed';
+        }
+
+        var requestId = ++_requestIds;
+        this._debug('Transport', this.getType(), 'metaConnect send, request', requestId, 'envelope', envelope);
+        var request = {
+            id: requestId,
+            metaConnect: true
+        };
+        _transportSend.call(this, envelope, request);
+        _metaConnectRequest = request;
+    }
+
+    _self.send = function(envelope, metaConnect)
+    {
+        if (metaConnect)
+        {
+            _metaConnectSend.call(this, envelope);
+        }
+        else
+        {
+            _queueSend.call(this, envelope);
+        }
+    };
+
+    _self.abort = function()
+    {
+        _super.abort();
+        for (var i = 0; i < _requests.length; ++i)
+        {
+            var request = _requests[i];
+            this._debug('Aborting request', request);
+            if (request.xhr)
+            {
+                request.xhr.abort();
+            }
+        }
+        if (_metaConnectRequest)
+        {
+            this._debug('Aborting metaConnect request', _metaConnectRequest);
+            if (_metaConnectRequest.xhr)
+            {
+                _metaConnectRequest.xhr.abort();
+            }
+        }
+        this.reset();
+    };
+
+    _self.reset = function()
+    {
+        _super.reset();
+        _metaConnectRequest = null;
+        _requests = [];
+        _envelopes = [];
+    };
+
+    return _self;
+};
+
+org.cometd.LongPollingTransport = function()
+{
+    var _super = new org.cometd.RequestTransport();
+    var _self = org.cometd.Transport.derive(_super);
+    // By default, support cross domain
+    var _supportsCrossDomain = true;
+
+    _self.accept = function(version, crossDomain, url)
+    {
+        return _supportsCrossDomain || !crossDomain;
+    };
+
+    _self.xhrSend = function(packet)
+    {
+        throw 'Abstract';
+    };
+
+    _self.transportSend = function(envelope, request)
+    {
+        this._debug('Transport', this.getType(), 'sending request', request.id, 'envelope', envelope);
+
+        var self = this;
+        try
+        {
+            var sameStack = true;
+            request.xhr = this.xhrSend({
+                transport: this,
+                url: envelope.url,
+                sync: envelope.sync,
+                headers: this.getConfiguration().requestHeaders,
+                body: org.cometd.JSON.toJSON(envelope.messages),
+                onSuccess: function(response)
+                {
+                    self._debug('Transport', self.getType(), 'received response', response);
+                    var success = false;
+                    try
+                    {
+                        var received = self.convertToMessages(response);
+                        if (received.length === 0)
+                        {
+                            _supportsCrossDomain = false;
+                            self.transportFailure(envelope, request, 'no response', null);
+                        }
+                        else
+                        {
+                            success = true;
+                            self.transportSuccess(envelope, request, received);
+                        }
+                    }
+                    catch(x)
+                    {
+                        self._debug(x);
+                        if (!success)
+                        {
+                            _supportsCrossDomain = false;
+                            self.transportFailure(envelope, request, 'bad response', x);
+                        }
+                    }
+                },
+                onError: function(reason, exception)
+                {
+                    _supportsCrossDomain = false;
+                    if (sameStack)
+                    {
+                        // Keep the semantic of calling response callbacks asynchronously after the request
+                        self.setTimeout(function()
+                        {
+                            self.transportFailure(envelope, request, reason, exception);
+                        }, 0);
+                    }
+                    else
+                    {
+                        self.transportFailure(envelope, request, reason, exception);
+                    }
+                }
+            });
+            sameStack = false;
+        }
+        catch (x)
+        {
+            _supportsCrossDomain = false;
+            // Keep the semantic of calling response callbacks asynchronously after the request
+            this.setTimeout(function()
+            {
+                self.transportFailure(envelope, request, 'error', x);
+            }, 0);
+        }
+    };
+
+    _self.reset = function()
+    {
+        _super.reset();
+        _supportsCrossDomain = true;
+    };
+
+    return _self;
+};
+
+org.cometd.CallbackPollingTransport = function()
+{
+    var _super = new org.cometd.RequestTransport();
+    var _self = org.cometd.Transport.derive(_super);
+    var _maxLength = 2000;
+
+    _self.accept = function(version, crossDomain, url)
+    {
+        return true;
+    };
+
+    _self.jsonpSend = function(packet)
+    {
+        throw 'Abstract';
+    };
+
+    _self.transportSend = function(envelope, request)
+    {
+        var self = this;
+
+        // Microsoft Internet Explorer has a 2083 URL max length
+        // We must ensure that we stay within that length
+        var start = 0;
+        var length = envelope.messages.length;
+        var lengths = [];
+        while (length > 0)
+        {
+            // Encode the messages because all brackets, quotes, commas, colons, etc
+            // present in the JSON will be URL encoded, taking many more characters
+            var json = org.cometd.JSON.toJSON(envelope.messages.slice(start, start + length));
+            var urlLength = envelope.url.length + encodeURI(json).length;
+
+            // Let's stay on the safe side and use 2000 instead of 2083
+            // also because we did not count few characters among which
+            // the parameter name 'message' and the parameter 'jsonp',
+            // which sum up to about 50 chars
+            if (urlLength > _maxLength)
+            {
+                if (length === 1)
+                {
+                    var x = 'Bayeux message too big (' + urlLength + ' bytes, max is ' + _maxLength + ') ' +
+                            'for transport ' + this.getType();
+                    // Keep the semantic of calling response callbacks asynchronously after the request
+                    this.setTimeout(function()
+                    {
+                        self.transportFailure(envelope, request, 'error', x);
+                    }, 0);
+                    return;
+                }
+
+                --length;
+                continue;
+            }
+
+            lengths.push(length);
+            start += length;
+            length = envelope.messages.length - start;
+        }
+
+        // Here we are sure that the messages can be sent within the URL limit
+
+        var envelopeToSend = envelope;
+        if (lengths.length > 1)
+        {
+            var begin = 0;
+            var end = lengths[0];
+            this._debug('Transport', this.getType(), 'split', envelope.messages.length, 'messages into', lengths.join(' + '));
+            envelopeToSend = this._mixin(false, {}, envelope);
+            envelopeToSend.messages = envelope.messages.slice(begin, end);
+            envelopeToSend.onSuccess = envelope.onSuccess;
+            envelopeToSend.onFailure = envelope.onFailure;
+
+            for (var i = 1; i < lengths.length; ++i)
+            {
+                var nextEnvelope = this._mixin(false, {}, envelope);
+                begin = end;
+                end += lengths[i];
+                nextEnvelope.messages = envelope.messages.slice(begin, end);
+                nextEnvelope.onSuccess = envelope.onSuccess;
+                nextEnvelope.onFailure = envelope.onFailure;
+                this.send(nextEnvelope, request.metaConnect);
+            }
+        }
+
+        this._debug('Transport', this.getType(), 'sending request', request.id, 'envelope', envelopeToSend);
+
+        try
+        {
+            var sameStack = true;
+            this.jsonpSend({
+                transport: this,
+                url: envelopeToSend.url,
+                sync: envelopeToSend.sync,
+                headers: this.getConfiguration().requestHeaders,
+                body: org.cometd.JSON.toJSON(envelopeToSend.messages),
+                onSuccess: function(responses)
+                {
+                    var success = false;
+                    try
+                    {
+                        var received = self.convertToMessages(responses);
+                        if (received.length === 0)
+                        {
+                            self.transportFailure(envelopeToSend, request, 'no response');
+                        }
+                        else
+                        {
+                            success=true;
+                            self.transportSuccess(envelopeToSend, request, received);
+                        }
+                    }
+                    catch (x)
+                    {
+                        self._debug(x);
+                        if (!success)
+                        {
+                            self.transportFailure(envelopeToSend, request, 'bad response', x);
+                        }
+                    }
+                },
+                onError: function(reason, exception)
+                {
+                    if (sameStack)
+                    {
+                        // Keep the semantic of calling response callbacks asynchronously after the request
+                        self.setTimeout(function()
+                        {
+                            self.transportFailure(envelopeToSend, request, reason, exception);
+                        }, 0);
+                    }
+                    else
+                    {
+                        self.transportFailure(envelopeToSend, request, reason, exception);
+                    }
+                }
+            });
+            sameStack = false;
+        }
+        catch (xx)
+        {
+            // Keep the semantic of calling response callbacks asynchronously after the request
+            this.setTimeout(function()
+            {
+                self.transportFailure(envelopeToSend, request, 'error', xx);
+            }, 0);
+        }
+    };
+
+    return _self;
+};
+
+org.cometd.WebSocketTransport = function()
+{
+    var _super = new org.cometd.Transport();
+    var _self = org.cometd.Transport.derive(_super);
+    var _cometd;
+    // By default, support WebSocket
+    var _supportsWebSocket = true;
+    // Whether we were able to establish a WebSocket connection
+    var _webSocketSupported = false;
+    // Envelopes that have been sent
+    var _envelopes = {};
+    // Timeouts for messages that have been sent
+    var _timeouts = {};
+    var _webSocket = null;
+    var _opened = false;
+    var _connected = false;
+    var _successCallback;
+
+    function _websocketConnect()
+    {
+        // Mangle the URL, changing the scheme from 'http' to 'ws'
+        var url = _cometd.getURL().replace(/^http/, 'ws');
+        this._debug('Transport', this.getType(), 'connecting to URL', url);
+
+        var self = this;
+        var connectTimer = null;
+
+        var connectTimeout = _cometd.getConfiguration().connectTimeout;
+        if (connectTimeout > 0)
+        {
+            connectTimer = this.setTimeout(function()
+            {
+                connectTimer = null;
+                if (!_opened)
+                {
+                    self._debug('Transport', self.getType(), 'timed out while connecting to URL', url, ':', connectTimeout, 'ms');
+                    self.onClose(1002, 'Connect Timeout');
+                }
+            }, connectTimeout);
+        }
+
+        var webSocket = new org.cometd.WebSocket(url);
+        webSocket.onopen = function()
+        {
+            self._debug('WebSocket opened', webSocket);
+            if (connectTimer)
+            {
+                self.clearTimeout(connectTimer);
+                connectTimer = null;
+            }
+            if (webSocket !== _webSocket)
+            {
+                // It's possible that the onopen callback is invoked
+                // with a delay so that we have already reconnected
+                self._debug('Ignoring open event, WebSocket', _webSocket);
+                return;
+            }
+            self.onOpen();
+        };
+        webSocket.onclose = function(event)
+        {
+            var code = event ? event.code : 1000;
+            var reason = event ? event.reason : undefined;
+            self._debug('WebSocket closed', code, '/', reason, webSocket);
+            if (connectTimer)
+            {
+                self.clearTimeout(connectTimer);
+                connectTimer = null;
+            }
+            if (webSocket !== _webSocket)
+            {
+                // The onclose callback may be invoked when the server sends
+                // the close message reply, but after we have already reconnected
+                self._debug('Ignoring close event, WebSocket', _webSocket);
+                return;
+            }
+            self.onClose(code, reason);
+        };
+        webSocket.onerror = function()
+        {
+            webSocket.onclose({ code: 1002 });
+        };
+        webSocket.onmessage = function(message)
+        {
+            self._debug('WebSocket message', message, webSocket);
+            if (webSocket !== _webSocket)
+            {
+                self._debug('Ignoring message event, WebSocket', _webSocket);
+                return;
+            }
+            self.onMessage(message);
+        };
+
+        _webSocket = webSocket;
+        this._debug('Transport', this.getType(), 'configured callbacks on', webSocket);
+    }
+
+    function _webSocketSend(envelope, metaConnect)
+    {
+        var json = org.cometd.JSON.toJSON(envelope.messages);
+
+        _webSocket.send(json);
+        this._debug('Transport', this.getType(), 'sent', envelope, 'metaConnect =', metaConnect);
+
+        // Manage the timeout waiting for the response
+        var maxDelay = this.getConfiguration().maxNetworkDelay;
+        var delay = maxDelay;
+        if (metaConnect)
+        {
+            delay += this.getAdvice().timeout;
+            _connected = true;
+        }
+
+        var messageIds = [];
+        for (var i = 0; i < envelope.messages.length; ++i)
+        {
+            var message = envelope.messages[i];
+            if (message.id)
+            {
+                messageIds.push(message.id);
+                var self = this;
+                _timeouts[message.id] = this.setTimeout(function()
+                {
+                    if (_webSocket)
+                    {
+                        _webSocket.close(1000, 'Timeout');
+                    }
+                }, delay);
+            }
+        }
+
+        this._debug('Transport', this.getType(), 'waiting at most', delay, 'ms for messages', messageIds, 'maxNetworkDelay', maxDelay, ', timeouts:', _timeouts);
+    }
+
+    function _send(envelope, metaConnect)
+    {
+        try
+        {
+            if (_webSocket === null)
+            {
+                _websocketConnect.call(this);
+            }
+            // We may have a non-null _webSocket, but not be open yet so
+            // to avoid out of order deliveries, we check if we are open
+            else if (_opened)
+            {
+                _webSocketSend.call(this, envelope, metaConnect);
+            }
+        }
+        catch (x)
+        {
+            // Keep the semantic of calling response callbacks asynchronously after the request
+            this.setTimeout(function()
+            {
+                envelope.onFailure(_webSocket, envelope.messages, 'error', x);
+            }, 0);
+        }
+    }
+
+    _self.onOpen = function()
+    {
+        this._debug('Transport', this.getType(), 'opened', _webSocket);
+        _opened = true;
+        _webSocketSupported = true;
+
+        this._debug('Sending pending messages', _envelopes);
+        for (var key in _envelopes)
+        {
+            var element = _envelopes[key];
+            var envelope = element[0];
+            var metaConnect = element[1];
+            // Store the success callback, which is independent from the envelope,
+            // so that it can be used to notify arrival of messages.
+            _successCallback = envelope.onSuccess;
+            _webSocketSend.call(this, envelope, metaConnect);
+        }
+    };
+
+    _self.onMessage = function(wsMessage)
+    {
+        this._debug('Transport', this.getType(), 'received websocket message', wsMessage, _webSocket);
+
+        var close = false;
+        var messages = this.convertToMessages(wsMessage.data);
+        var messageIds = [];
+        for (var i = 0; i < messages.length; ++i)
+        {
+            var message = messages[i];
+
+            // Detect if the message is a response to a request we made.
+            // If it's a meta message, for sure it's a response;
+            // otherwise it's a publish message and publish responses lack the data field
+            if (/^\/meta\//.test(message.channel) || message.data === undefined)
+            {
+                if (message.id)
+                {
+                    messageIds.push(message.id);
+
+                    var timeout = _timeouts[message.id];
+                    if (timeout)
+                    {
+                        this.clearTimeout(timeout);
+                        delete _timeouts[message.id];
+                        this._debug('Transport', this.getType(), 'removed timeout for message', message.id, ', timeouts', _timeouts);
+                    }
+                }
+            }
+
+            if ('/meta/connect' === message.channel)
+            {
+                _connected = false;
+            }
+            if ('/meta/disconnect' === message.channel && !_connected)
+            {
+                close = true;
+            }
+        }
+
+        // Remove the envelope corresponding to the messages
+        var removed = false;
+        for (var j = 0; j < messageIds.length; ++j)
+        {
+            var id = messageIds[j];
+            for (var key in _envelopes)
+            {
+                var ids = key.split(',');
+                var index = org.cometd.Utils.inArray(id, ids);
+                if (index >= 0)
+                {
+                    removed = true;
+                    ids.splice(index, 1);
+                    var envelope = _envelopes[key][0];
+                    var metaConnect = _envelopes[key][1];
+                    delete _envelopes[key];
+                    if (ids.length > 0)
+                    {
+                        _envelopes[ids.join(',')] = [envelope, metaConnect];
+                    }
+                    break;
+                }
+            }
+        }
+        if (removed)
+        {
+            this._debug('Transport', this.getType(), 'removed envelope, envelopes', _envelopes);
+        }
+
+        _successCallback.call(this, messages);
+
+        if (close)
+        {
+            _webSocket.close(1000, 'Disconnect');
+        }
+    };
+
+    _self.onClose = function(code, reason)
+    {
+        this._debug('Transport', this.getType(), 'closed', code, reason, _webSocket);
+
+        // Remember if we were able to connect
+        // This close event could be due to server shutdown, and if it restarts we want to try websocket again
+        _supportsWebSocket = _webSocketSupported;
+
+        for (var id in _timeouts)
+        {
+            this.clearTimeout(_timeouts[id]);
+        }
+        _timeouts = {};
+
+        for (var key in _envelopes)
+        {
+            var envelope = _envelopes[key][0];
+            var metaConnect = _envelopes[key][1];
+            if (metaConnect)
+            {
+                _connected = false;
+            }
+            envelope.onFailure(_webSocket, envelope.messages, 'closed ' + code + '/' + reason);
+        }
+        _envelopes = {};
+
+        if (_webSocket !== null && _opened)
+        {
+            _webSocket.close(1000, 'Close');
+        }
+        _opened = false;
+        _webSocket = null;
+    };
+
+    _self.registered = function(type, cometd)
+    {
+        _super.registered(type, cometd);
+        _cometd = cometd;
+    };
+
+    _self.accept = function(version, crossDomain, url)
+    {
+        // Using !! to return a boolean (and not the WebSocket object)
+        return _supportsWebSocket && !!org.cometd.WebSocket && _cometd.websocketEnabled !== false;
+    };
+
+    _self.send = function(envelope, metaConnect)
+    {
+        this._debug('Transport', this.getType(), 'sending', envelope, 'metaConnect =', metaConnect);
+
+        // Store the envelope in any case; if the websocket cannot be opened, we fail it in close()
+        var messageIds = [];
+        for (var i = 0; i < envelope.messages.length; ++i)
+        {
+            var message = envelope.messages[i];
+            if (message.id)
+            {
+                messageIds.push(message.id);
+            }
+        }
+        _envelopes[messageIds.join(',')] = [envelope, metaConnect];
+        this._debug('Transport', this.getType(), 'stored envelope, envelopes', _envelopes);
+
+        _send.call(this, envelope, metaConnect);
+    };
+
+    _self.reset = function()
+    {
+        _super.reset();
+        if (_webSocket !== null && _opened)
+        {
+            _webSocket.close(1000, 'Reset');
+        }
+        _supportsWebSocket = true;
+        _webSocketSupported = false;
+        _timeouts = {};
+        _envelopes = {};
+        _webSocket = null;
+        _opened = false;
+        _successCallback = null;
+    };
+
+    return _self;
+};
+
+/**
+ * The constructor for a Cometd object, identified by an optional name.
+ * The default name is the string 'default'.
+ * In the rare case a page needs more than one Bayeux conversation,
+ * a new instance can be created via:
+ * <pre>
+ * var bayeuxUrl2 = ...;
+ *
+ * // Dojo style
+ * var cometd2 = new dojox.Cometd('another_optional_name');
+ *
+ * // jQuery style
+ * var cometd2 = new $.Cometd('another_optional_name');
+ *
+ * cometd2.init({url: bayeuxUrl2});
+ * </pre>
+ * @param name the optional name of this cometd object
+ */
+// IMPLEMENTATION NOTES:
+// Be very careful in not changing the function order and pass this file every time through JSLint (http://jslint.com)
+// The only implied globals must be "dojo", "org" and "window", and check that there are no "unused" warnings
+// Failing to pass JSLint may result in shrinkers/minifiers to create an unusable file.
+org.cometd.Cometd = function(name)
+{
+    var _cometd = this;
+    var _name = name || 'default';
+    var _crossDomain = false;
+    var _transports = new org.cometd.TransportRegistry();
+    var _transport;
+    var _status = 'disconnected';
+    var _messageId = 0;
+    var _clientId = null;
+    var _batch = 0;
+    var _messageQueue = [];
+    var _internalBatch = false;
+    var _listeners = {};
+    var _backoff = 0;
+    var _scheduledSend = null;
+    var _extensions = [];
+    var _advice = {};
+    var _handshakeProps;
+    var _reestablish = false;
+    var _connected = false;
+    var _config = {
+        connectTimeout: 0,
+        maxConnections: 2,
+        backoffIncrement: 1000,
+        maxBackoff: 60000,
+        logLevel: 'info',
+        reverseIncomingExtensions: true,
+        maxNetworkDelay: 10000,
+        requestHeaders: {},
+        appendMessageTypeToURL: true,
+        autoBatch: false,
+        advice: {
+            timeout: 60000,
+            interval: 0,
+            reconnect: 'retry'
+        }
+    };
+
+    /**
+     * Mixes in the given objects into the target object by copying the properties.
+     * @param deep if the copy must be deep
+     * @param target the target object
+     * @param objects the objects whose properties are copied into the target
+     */
+    this._mixin = function(deep, target, objects)
+    {
+        var result = target || {};
+
+        // Skip first 2 parameters (deep and target), and loop over the others
+        for (var i = 2; i < arguments.length; ++i)
+        {
+            var object = arguments[i];
+
+            if (object === undefined || object === null)
+            {
+                continue;
+            }
+
+            for (var propName in object)
+            {
+                var prop = object[propName];
+                var targ = result[propName];
+
+                // Avoid infinite loops
+                if (prop === target)
+                {
+                    continue;
+                }
+                // Do not mixin undefined values
+                if (prop === undefined)
+                {
+                    continue;
+                }
+
+                if (deep && typeof prop === 'object' && prop !== null)
+                {
+                    if (prop instanceof Array)
+                    {
+                        result[propName] = this._mixin(deep, targ instanceof Array ? targ : [], prop);
+                    }
+                    else
+                    {
+                        var source = typeof targ === 'object' && !(targ instanceof Array) ? targ : {};
+                        result[propName] = this._mixin(deep, source, prop);
+                    }
+                }
+                else
+                {
+                    result[propName] = prop;
+                }
+            }
+        }
+
+        return result;
+    };
+
+    function _isString(value)
+    {
+        return org.cometd.Utils.isString(value);
+    }
+
+    function _isFunction(value)
+    {
+        if (value === undefined || value === null)
+        {
+            return false;
+        }
+        return typeof value === 'function';
+    }
+
+    function _log(level, args)
+    {
+        if (window.console)
+        {
+            var logger = window.console[level];
+            if (_isFunction(logger))
+            {
+                logger.apply(window.console, args);
+            }
+        }
+    }
+
+    this._warn = function()
+    {
+        _log('warn', arguments);
+    };
+
+    this._info = function()
+    {
+        if (_config.logLevel !== 'warn')
+        {
+            _log('info', arguments);
+        }
+    };
+
+    this._debug = function()
+    {
+        if (_config.logLevel === 'debug')
+        {
+            _log('debug', arguments);
+        }
+    };
+
+    /**
+     * Returns whether the given hostAndPort is cross domain.
+     * The default implementation checks against window.location.host
+     * but this function can be overridden to make it work in non-browser
+     * environments.
+     *
+     * @param hostAndPort the host and port in format host:port
+     * @return whether the given hostAndPort is cross domain
+     */
+    this._isCrossDomain = function(hostAndPort)
+    {
+        return hostAndPort && hostAndPort !== window.location.host;
+    };
+
+    function _configure(configuration)
+    {
+        _cometd._debug('Configuring cometd object with', configuration);
+        // Support old style param, where only the Bayeux server URL was passed
+        if (_isString(configuration))
+        {
+            configuration = { url: configuration };
+        }
+        if (!configuration)
+        {
+            configuration = {};
+        }
+
+        _config = _cometd._mixin(false, _config, configuration);
+
+        if (!_config.url)
+        {
+            throw 'Missing required configuration parameter \'url\' specifying the Bayeux server URL';
+        }
+
+        // Check if we're cross domain
+        // [1] = protocol://, [2] = host:port, [3] = host, [4] = IPv6_host, [5] = IPv4_host, [6] = :port, [7] = port, [8] = uri, [9] = rest
+        var urlParts = /(^https?:\/\/)?(((\[[^\]]+\])|([^:\/\?#]+))(:(\d+))?)?([^\?#]*)(.*)?/.exec(_config.url);
+        var hostAndPort = urlParts[2];
+        var uri = urlParts[8];
+        var afterURI = urlParts[9];
+        _crossDomain = _cometd._isCrossDomain(hostAndPort);
+
+        // Check if appending extra path is supported
+        if (_config.appendMessageTypeToURL)
+        {
+            if (afterURI !== undefined && afterURI.length > 0)
+            {
+                _cometd._info('Appending message type to URI ' + uri + afterURI + ' is not supported, disabling \'appendMessageTypeToURL\' configuration');
+                _config.appendMessageTypeToURL = false;
+            }
+            else
+            {
+                var uriSegments = uri.split('/');
+                var lastSegmentIndex = uriSegments.length - 1;
+                if (uri.match(/\/$/))
+                {
+                    lastSegmentIndex -= 1;
+                }
+                if (uriSegments[lastSegmentIndex].indexOf('.') >= 0)
+                {
+                    // Very likely the CometD servlet's URL pattern is mapped to an extension, such as *.cometd
+                    // It will be difficult to add the extra path in this case
+                    _cometd._info('Appending message type to URI ' + uri + ' is not supported, disabling \'appendMessageTypeToURL\' configuration');
+                    _config.appendMessageTypeToURL = false;
+                }
+            }
+        }
+    }
+
+    function _clearSubscriptions()
+    {
+        for (var channel in _listeners)
+        {
+            var subscriptions = _listeners[channel];
+            for (var i = 0; i < subscriptions.length; ++i)
+            {
+                var subscription = subscriptions[i];
+                if (subscription && !subscription.listener)
+                {
+                    delete subscriptions[i];
+                    _cometd._debug('Removed subscription', subscription, 'for channel', channel);
+                }
+            }
+        }
+    }
+
+    function _setStatus(newStatus)
+    {
+        if (_status !== newStatus)
+        {
+            _cometd._debug('Status', _status, '->', newStatus);
+            _status = newStatus;
+        }
+    }
+
+    function _isDisconnected()
+    {
+        return _status === 'disconnecting' || _status === 'disconnected';
+    }
+
+    function _nextMessageId()
+    {
+        return ++_messageId;
+    }
+
+    function _applyExtension(scope, callback, name, message, outgoing)
+    {
+        try
+        {
+            return callback.call(scope, message);
+        }
+        catch (x)
+        {
+            _cometd._debug('Exception during execution of extension', name, x);
+            var exceptionCallback = _cometd.onExtensionException;
+            if (_isFunction(exceptionCallback))
+            {
+                _cometd._debug('Invoking extension exception callback', name, x);
+                try
+                {
+                    exceptionCallback.call(_cometd, x, name, outgoing, message);
+                }
+                catch(xx)
+                {
+                    _cometd._info('Exception during execution of exception callback in extension', name, xx);
+                }
+            }
+            return message;
+        }
+    }
+
+    function _applyIncomingExtensions(message)
+    {
+        for (var i = 0; i < _extensions.length; ++i)
+        {
+            if (message === undefined || message === null)
+            {
+                break;
+            }
+
+            var index = _config.reverseIncomingExtensions ? _extensions.length - 1 - i : i;
+            var extension = _extensions[index];
+            var callback = extension.extension.incoming;
+            if (_isFunction(callback))
+            {
+                var result = _applyExtension(extension.extension, callback, extension.name, message, false);
+                message = result === undefined ? message : result;
+            }
+        }
+        return message;
+    }
+
+    function _applyOutgoingExtensions(message)
+    {
+        for (var i = 0; i < _extensions.length; ++i)
+        {
+            if (message === undefined || message === null)
+            {
+                break;
+            }
+
+            var extension = _extensions[i];
+            var callback = extension.extension.outgoing;
+            if (_isFunction(callback))
+            {
+                var result = _applyExtension(extension.extension, callback, extension.name, message, true);
+                message = result === undefined ? message : result;
+            }
+        }
+        return message;
+    }
+
+    function _notify(channel, message)
+    {
+        var subscriptions = _listeners[channel];
+        if (subscriptions && subscriptions.length > 0)
+        {
+            for (var i = 0; i < subscriptions.length; ++i)
+            {
+                var subscription = subscriptions[i];
+                // Subscriptions may come and go, so the array may have 'holes'
+                if (subscription)
+                {
+                    try
+                    {
+                        subscription.callback.call(subscription.scope, message);
+                    }
+                    catch (x)
+                    {
+                        _cometd._debug('Exception during notification', subscription, message, x);
+                        var listenerCallback = _cometd.onListenerException;
+                        if (_isFunction(listenerCallback))
+                        {
+                            _cometd._debug('Invoking listener exception callback', subscription, x);
+                            try
+                            {
+                                listenerCallback.call(_cometd, x, subscription.handle, subscription.listener, message);
+                            }
+                            catch (xx)
+                            {
+                                _cometd._info('Exception during execution of listener callback', subscription, xx);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    function _notifyListeners(channel, message)
+    {
+        // Notify direct listeners
+        _notify(channel, message);
+
+        // Notify the globbing listeners
+        var channelParts = channel.split('/');
+        var last = channelParts.length - 1;
+        for (var i = last; i > 0; --i)
+        {
+            var channelPart = channelParts.slice(0, i).join('/') + '/*';
+            // We don't want to notify /foo/* if the channel is /foo/bar/baz,
+            // so we stop at the first non recursive globbing
+            if (i === last)
+            {
+                _notify(channelPart, message);
+            }
+            // Add the recursive globber and notify
+            channelPart += '*';
+            _notify(channelPart, message);
+        }
+    }
+
+    function _cancelDelayedSend()
+    {
+        if (_scheduledSend !== null)
+        {
+            org.cometd.Utils.clearTimeout(_scheduledSend);
+        }
+        _scheduledSend = null;
+    }
+
+    function _delayedSend(operation)
+    {
+        _cancelDelayedSend();
+        var delay = _advice.interval + _backoff;
+        _cometd._debug('Function scheduled in', delay, 'ms, interval =', _advice.interval, 'backoff =', _backoff, operation);
+        _scheduledSend = org.cometd.Utils.setTimeout(_cometd, operation, delay);
+    }
+
+    // Needed to break cyclic dependencies between function definitions
+    var _handleMessages;
+    var _handleFailure;
+
+    /**
+     * Delivers the messages to the CometD server
+     * @param messages the array of messages to send
+     * @param longpoll true if this send is a long poll
+     */
+    function _send(sync, messages, longpoll, extraPath)
+    {
+        // We must be sure that the messages have a clientId.
+        // This is not guaranteed since the handshake may take time to return
+        // (and hence the clientId is not known yet) and the application
+        // may create other messages.
+        for (var i = 0; i < messages.length; ++i)
+        {
+            var message = messages[i];
+            message.id = '' + _nextMessageId();
+            if (_clientId)
+            {
+                message.clientId = _clientId;
+            }
+            message = _applyOutgoingExtensions(message);
+            if (message !== undefined && message !== null)
+            {
+                messages[i] = message;
+            }
+            else
+            {
+                messages.splice(i--, 1);
+            }
+        }
+        if (messages.length === 0)
+        {
+            return;
+        }
+
+        var url = _config.url;
+        if (_config.appendMessageTypeToURL)
+        {
+            // If url does not end with '/', then append it
+            if (!url.match(/\/$/))
+            {
+                url = url + '/';
+            }
+            if (extraPath)
+            {
+                url = url + extraPath;
+            }
+        }
+
+        var envelope = {
+            url: url,
+            sync: sync,
+            messages: messages,
+            onSuccess: function(rcvdMessages)
+            {
+                try
+                {
+                    _handleMessages.call(_cometd, rcvdMessages);
+                }
+                catch (x)
+                {
+                    _cometd._debug('Exception during handling of messages', x);
+                }
+            },
+            onFailure: function(conduit, messages, reason, exception)
+            {
+                try
+                {
+                    _handleFailure.call(_cometd, conduit, messages, reason, exception);
+                }
+                catch (x)
+                {
+                    _cometd._debug('Exception during handling of failure', x);
+                }
+            }
+        };
+        _cometd._debug('Send', envelope);
+        _transport.send(envelope, longpoll);
+    }
+
+    function _queueSend(message)
+    {
+        if (_batch > 0 || _internalBatch === true)
+        {
+            _messageQueue.push(message);
+        }
+        else
+        {
+            _send(false, [message], false);
+        }
+    }
+
+    /**
+     * Sends a complete bayeux message.
+     * This method is exposed as a public so that extensions may use it
+     * to send bayeux message directly, for example in case of re-sending
+     * messages that have already been sent but that for some reason must
+     * be resent.
+     */
+    this.send = _queueSend;
+
+    function _resetBackoff()
+    {
+        _backoff = 0;
+    }
+
+    function _increaseBackoff()
+    {
+        if (_backoff < _config.maxBackoff)
+        {
+            _backoff += _config.backoffIncrement;
+        }
+    }
+
+    /**
+     * Starts a the batch of messages to be sent in a single request.
+     * @see #_endBatch(sendMessages)
+     */
+    function _startBatch()
+    {
+        ++_batch;
+    }
+
+    function _flushBatch()
+    {
+        var messages = _messageQueue;
+        _messageQueue = [];
+        if (messages.length > 0)
+        {
+            _send(false, messages, false);
+        }
+    }
+
+    /**
+     * Ends the batch of messages to be sent in a single request,
+     * optionally sending messages present in the message queue depending
+     * on the given argument.
+     * @see #_startBatch()
+     */
+    function _endBatch()
+    {
+        --_batch;
+        if (_batch < 0)
+        {
+            throw 'Calls to startBatch() and endBatch() are not paired';
+        }
+
+        if (_batch === 0 && !_isDisconnected() && !_internalBatch)
+        {
+            _flushBatch();
+        }
+    }
+
+    /**
+     * Sends the connect message
+     */
+    function _connect()
+    {
+        if (!_isDisconnected())
+        {
+            var message = {
+                channel: '/meta/connect',
+                connectionType: _transport.getType()
+            };
+
+            // In case of reload or temporary loss of connection
+            // we want the next successful connect to return immediately
+            // instead of being held by the server, so that connect listeners
+            // can be notified that the connection has been re-established
+            if (!_connected)
+            {
+                message.advice = { timeout: 0 };
+            }
+
+            _setStatus('connecting');
+            _cometd._debug('Connect sent', message);
+            _send(false, [message], true, 'connect');
+            _setStatus('connected');
+        }
+    }
+
+    function _delayedConnect()
+    {
+        _setStatus('connecting');
+        _delayedSend(function()
+        {
+            _connect();
+        });
+    }
+
+    function _updateAdvice(newAdvice)
+    {
+        if (newAdvice)
+        {
+            _advice = _cometd._mixin(false, {}, _config.advice, newAdvice);
+            _cometd._debug('New advice', _advice);
+        }
+    }
+
+    function _disconnect(abort)
+    {
+        _cancelDelayedSend();
+        if (abort)
+        {
+            _transport.abort();
+        }
+        _clientId = null;
+        _setStatus('disconnected');
+        _batch = 0;
+        _resetBackoff();
+
+        // Fail any existing queued message
+        if (_messageQueue.length > 0)
+        {
+            _handleFailure.call(_cometd, undefined, _messageQueue, 'error', 'Disconnected');
+            _messageQueue = [];
+        }
+    }
+
+    /**
+     * Sends the initial handshake message
+     */
+    function _handshake(handshakeProps)
+    {
+        _clientId = null;
+
+        _clearSubscriptions();
+
+        // Reset the transports if we're not retrying the handshake
+        if (_isDisconnected())
+        {
+            _transports.reset();
+            _updateAdvice(_config.advice);
+        }
+        else
+        {
+            // We are retrying the handshake, either because another handshake failed
+            // and we're backing off, or because the server timed us out and asks us to
+            // re-handshake: in both cases, make sure that if the handshake succeeds
+            // the next action is a connect.
+            _updateAdvice(_cometd._mixin(false, _advice, {reconnect: 'retry'}));
+        }
+
+        _batch = 0;
+
+        // Mark the start of an internal batch.
+        // This is needed because handshake and connect are async.
+        // It may happen that the application calls init() then subscribe()
+        // and the subscribe message is sent before the connect message, if
+        // the subscribe message is not held until the connect message is sent.
+        // So here we start a batch to hold temporarily any message until
+        // the connection is fully established.
+        _internalBatch = true;
+
+        // Save the properties provided by the user, so that
+        // we can reuse them during automatic re-handshake
+        _handshakeProps = handshakeProps;
+
+        var version = '1.0';
+
+        // Figure out the transports to send to the server
+        var transportTypes = _transports.findTransportTypes(version, _crossDomain, _config.url);
+
+        var bayeuxMessage = {
+            version: version,
+            minimumVersion: '0.9',
+            channel: '/meta/handshake',
+            supportedConnectionTypes: transportTypes,
+            advice: {
+                timeout: _advice.timeout,
+                interval: _advice.interval
+            }
+        };
+        // Do not allow the user to mess with the required properties,
+        // so merge first the user properties and *then* the bayeux message
+        var message = _cometd._mixin(false, {}, _handshakeProps, bayeuxMessage);
+
+        // Pick up the first available transport as initial transport
+        // since we don't know if the server supports it
+        _transport = _transports.negotiateTransport(transportTypes, version, _crossDomain, _config.url);
+        _cometd._debug('Initial transport is', _transport.getType());
+
+        // We started a batch to hold the application messages,
+        // so here we must bypass it and send immediately.
+        _setStatus('handshaking');
+        _cometd._debug('Handshake sent', message);
+        _send(false, [message], false, 'handshake');
+    }
+
+    function _delayedHandshake()
+    {
+        _setStatus('handshaking');
+
+        // We will call _handshake() which will reset _clientId, but we want to avoid
+        // that between the end of this method and the call to _handshake() someone may
+        // call publish() (or other methods that call _queueSend()).
+        _internalBatch = true;
+
+        _delayedSend(function()
+        {
+            _handshake(_handshakeProps);
+        });
+    }
+
+    function _failHandshake(message)
+    {
+        _notifyListeners('/meta/handshake', message);
+        _notifyListeners('/meta/unsuccessful', message);
+
+        // Only try again if we haven't been disconnected and
+        // the advice permits us to retry the handshake
+        var retry = !_isDisconnected() && _advice.reconnect !== 'none';
+        if (retry)
+        {
+            _increaseBackoff();
+            _delayedHandshake();
+        }
+        else
+        {
+            _disconnect(false);
+        }
+    }
+
+    function _handshakeResponse(message)
+    {
+        if (message.successful)
+        {
+            // Save clientId, figure out transport, then follow the advice to connect
+            _clientId = message.clientId;
+
+            var newTransport = _transports.negotiateTransport(message.supportedConnectionTypes, message.version, _crossDomain, _config.url);
+            if (newTransport === null)
+            {
+                throw 'Could not negotiate transport with server; client ' +
+                      _transports.findTransportTypes(message.version, _crossDomain, _config.url) +
+                      ', server ' + message.supportedConnectionTypes;
+            }
+            else if (_transport !== newTransport)
+            {
+                _cometd._debug('Transport', _transport, '->', newTransport);
+                _transport = newTransport;
+            }
+
+            // End the internal batch and allow held messages from the application
+            // to go to the server (see _handshake() where we start the internal batch).
+            _internalBatch = false;
+            _flushBatch();
+
+            // Here the new transport is in place, as well as the clientId, so
+            // the listeners can perform a publish() if they want.
+            // Notify the listeners before the connect below.
+            message.reestablish = _reestablish;
+            _reestablish = true;
+            _notifyListeners('/meta/handshake', message);
+
+            var action = _isDisconnected() ? 'none' : _advice.reconnect;
+            switch (action)
+            {
+                case 'retry':
+                    _resetBackoff();
+                    _delayedConnect();
+                    break;
+                case 'none':
+                    _disconnect(false);
+                    break;
+                default:
+                    throw 'Unrecognized advice action ' + action;
+            }
+        }
+        else
+        {
+            _failHandshake(message);
+        }
+    }
+
+    function _handshakeFailure(xhr, message)
+    {
+        _failHandshake({
+            successful: false,
+            failure: true,
+            channel: '/meta/handshake',
+            request: message,
+            xhr: xhr,
+            advice: {
+                reconnect: 'retry',
+                interval: _backoff
+            }
+        });
+    }
+
+    function _failConnect(message)
+    {
+        // Notify the listeners after the status change but before the next action
+        _notifyListeners('/meta/connect', message);
+        _notifyListeners('/meta/unsuccessful', message);
+
+        // This may happen when the server crashed, the current clientId
+        // will be invalid, and the server will ask to handshake again
+        // Listeners can call disconnect(), so check the state after they run
+        var action = _isDisconnected() ? 'none' : _advice.reconnect;
+        switch (action)
+        {
+            case 'retry':
+                _delayedConnect();
+                _increaseBackoff();
+                break;
+            case 'handshake':
+                // The current transport may be failed (e.g. network disconnection)
+                // Reset the transports so the new handshake picks up the right one
+                _transports.reset();
+                _resetBackoff();
+                _delayedHandshake();
+                break;
+            case 'none':
+                _disconnect(false);
+                break;
+            default:
+                throw 'Unrecognized advice action' + action;
+        }
+    }
+
+    function _connectResponse(message)
+    {
+        _connected = message.successful;
+
+        if (_connected)
+        {
+            _notifyListeners('/meta/connect', message);
+
+            // Normally, the advice will say "reconnect: 'retry', interval: 0"
+            // and the server will hold the request, so when a response returns
+            // we immediately call the server again (long polling)
+            // Listeners can call disconnect(), so check the state after they run
+            var action = _isDisconnected() ? 'none' : _advice.reconnect;
+            switch (action)
+            {
+                case 'retry':
+                    _resetBackoff();
+                    _delayedConnect();
+                    break;
+                case 'none':
+                    _disconnect(false);
+                    break;
+                default:
+                    throw 'Unrecognized advice action ' + action;
+            }
+        }
+        else
+        {
+            _failConnect(message);
+        }
+    }
+
+    function _connectFailure(xhr, message)
+    {
+        _connected = false;
+        _failConnect({
+            successful: false,
+            failure: true,
+            channel: '/meta/connect',
+            request: message,
+            xhr: xhr,
+            advice: {
+                reconnect: 'retry',
+                interval: _backoff
+            }
+        });
+    }
+
+    function _failDisconnect(message)
+    {
+        _disconnect(true);
+        _notifyListeners('/meta/disconnect', message);
+        _notifyListeners('/meta/unsuccessful', message);
+    }
+
+    function _disconnectResponse(message)
+    {
+        if (message.successful)
+        {
+            _disconnect(false);
+            _notifyListeners('/meta/disconnect', message);
+        }
+        else
+        {
+            _failDisconnect(message);
+        }
+    }
+
+    function _disconnectFailure(xhr, message)
+    {
+        _failDisconnect({
+            successful: false,
+            failure: true,
+            channel: '/meta/disconnect',
+            request: message,
+            xhr: xhr,
+            advice: {
+                reconnect: 'none',
+                interval: 0
+            }
+        });
+    }
+
+    function _failSubscribe(message)
+    {
+        _notifyListeners('/meta/subscribe', message);
+        _notifyListeners('/meta/unsuccessful', message);
+    }
+
+    function _subscribeResponse(message)
+    {
+        if (message.successful)
+        {
+            _notifyListeners('/meta/subscribe', message);
+        }
+        else
+        {
+            _failSubscribe(message);
+        }
+    }
+
+    function _subscribeFailure(xhr, message)
+    {
+        _failSubscribe({
+            successful: false,
+            failure: true,
+            channel: '/meta/subscribe',
+            request: message,
+            xhr: xhr,
+            advice: {
+                reconnect: 'none',
+                interval: 0
+            }
+        });
+    }
+
+    function _failUnsubscribe(message)
+    {
+        _notifyListeners('/meta/unsubscribe', message);
+        _notifyListeners('/meta/unsuccessful', message);
+    }
+
+    function _unsubscribeResponse(message)
+    {
+        if (message.successful)
+        {
+            _notifyListeners('/meta/unsubscribe', message);
+        }
+        else
+        {
+            _failUnsubscribe(message);
+        }
+    }
+
+    function _unsubscribeFailure(xhr, message)
+    {
+        _failUnsubscribe({
+            successful: false,
+            failure: true,
+            channel: '/meta/unsubscribe',
+            request: message,
+            xhr: xhr,
+            advice: {
+                reconnect: 'none',
+                interval: 0
+            }
+        });
+    }
+
+    function _failMessage(message)
+    {
+        _notifyListeners('/meta/publish', message);
+        _notifyListeners('/meta/unsuccessful', message);
+    }
+
+    function _messageResponse(message)
+    {
+        if (message.successful === undefined)
+        {
+            if (message.data)
+            {
+                // It is a plain message, and not a bayeux meta message
+                _notifyListeners(message.channel, message);
+            }
+            else
+            {
+                _cometd._debug('Unknown message', message);
+            }
+        }
+        else
+        {
+            if (message.successful)
+            {
+                _notifyListeners('/meta/publish', message);
+            }
+            else
+            {
+                _failMessage(message);
+            }
+        }
+    }
+
+    function _messageFailure(xhr, message)
+    {
+        _failMessage({
+            successful: false,
+            failure: true,
+            channel: message.channel,
+            request: message,
+            xhr: xhr,
+            advice: {
+                reconnect: 'none',
+                interval: 0
+            }
+        });
+    }
+
+    function _receive(message)
+    {
+        message = _applyIncomingExtensions(message);
+        if (message === undefined || message === null)
+        {
+            return;
+        }
+
+        _updateAdvice(message.advice);
+
+        var channel = message.channel;
+        switch (channel)
+        {
+            case '/meta/handshake':
+                _handshakeResponse(message);
+                break;
+            case '/meta/connect':
+                _connectResponse(message);
+                break;
+            case '/meta/disconnect':
+                _disconnectResponse(message);
+                break;
+            case '/meta/subscribe':
+                _subscribeResponse(message);
+                break;
+            case '/meta/unsubscribe':
+                _unsubscribeResponse(message);
+                break;
+            default:
+                _messageResponse(message);
+                break;
+        }
+    }
+
+    /**
+     * Receives a message.
+     * This method is exposed as a public so that extensions may inject
+     * messages simulating that they had been received.
+     */
+    this.receive = _receive;
+
+    _handleMessages = function(rcvdMessages)
+    {
+        _cometd._debug('Received', rcvdMessages);
+
+        for (var i = 0; i < rcvdMessages.length; ++i)
+        {
+            var message = rcvdMessages[i];
+            _receive(message);
+        }
+    };
+
+    _handleFailure = function(conduit, messages, reason, exception)
+    {
+        _cometd._debug('handleFailure', conduit, messages, reason, exception);
+
+        for (var i = 0; i < messages.length; ++i)
+        {
+            var message = messages[i];
+            var channel = message.channel;
+            switch (channel)
+            {
+                case '/meta/handshake':
+                    _handshakeFailure(conduit, message);
+                    break;
+                case '/meta/connect':
+                    _connectFailure(conduit, message);
+                    break;
+                case '/meta/disconnect':
+                    _disconnectFailure(conduit, message);
+                    break;
+                case '/meta/subscribe':
+                    _subscribeFailure(conduit, message);
+                    break;
+                case '/meta/unsubscribe':
+                    _unsubscribeFailure(conduit, message);
+                    break;
+                default:
+                    _messageFailure(conduit, message);
+                    break;
+            }
+        }
+    };
+
+    function _hasSubscriptions(channel)
+    {
+        var subscriptions = _listeners[channel];
+        if (subscriptions)
+        {
+            for (var i = 0; i < subscriptions.length; ++i)
+            {
+                if (subscriptions[i])
+                {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    function _resolveScopedCallback(scope, callback)
+    {
+        var delegate = {
+            scope: scope,
+            method: callback
+        };
+        if (_isFunction(scope))
+        {
+            delegate.scope = undefined;
+            delegate.method = scope;
+        }
+        else
+        {
+            if (_isString(callback))
+            {
+                if (!scope)
+                {
+                    throw 'Invalid scope ' + scope;
+                }
+                delegate.method = scope[callback];
+                if (!_isFunction(delegate.method))
+                {
+                    throw 'Invalid callback ' + callback + ' for scope ' + scope;
+                }
+            }
+            else if (!_isFunction(callback))
+            {
+                throw 'Invalid callback ' + callback;
+            }
+        }
+        return delegate;
+    }
+
+    function _addListener(channel, scope, callback, isListener)
+    {
+        // The data structure is a map<channel, subscription[]>, where each subscription
+        // holds the callback to be called and its scope.
+
+        var delegate = _resolveScopedCallback(scope, callback);
+        _cometd._debug('Adding listener on', channel, 'with scope', delegate.scope, 'and callback', delegate.method);
+
+        var subscription = {
+            channel: channel,
+            scope: delegate.scope,
+            callback: delegate.method,
+            listener: isListener
+        };
+
+        var subscriptions = _listeners[channel];
+        if (!subscriptions)
+        {
+            subscriptions = [];
+            _listeners[channel] = subscriptions;
+        }
+
+        // Pushing onto an array appends at the end and returns the id associated with the element increased by 1.
+        // Note that if:
+        // a.push('a'); var hb=a.push('b'); delete a[hb-1]; var hc=a.push('c');
+        // then:
+        // hc==3, a.join()=='a',,'c', a.length==3
+        var subscriptionID = subscriptions.push(subscription) - 1;
+        subscription.id = subscriptionID;
+        subscription.handle = [channel, subscriptionID];
+
+        _cometd._debug('Added listener', subscription, 'for channel', channel, 'having id =', subscriptionID);
+
+        // The subscription to allow removal of the listener is made of the channel and the index
+        return subscription.handle;
+    }
+
+    function _removeListener(subscription)
+    {
+        var subscriptions = _listeners[subscription[0]];
+        if (subscriptions)
+        {
+            delete subscriptions[subscription[1]];
+            _cometd._debug('Removed listener', subscription);
+        }
+    }
+
+    //
+    // PUBLIC API
+    //
+
+    /**
+     * Registers the given transport under the given transport type.
+     * The optional index parameter specifies the "priority" at which the
+     * transport is registered (where 0 is the max priority).
+     * If a transport with the same type is already registered, this function
+     * does nothing and returns false.
+     * @param type the transport type
+     * @param transport the transport object
+     * @param index the index at which this transport is to be registered
+     * @return true if the transport has been registered, false otherwise
+     * @see #unregisterTransport(type)
+     */
+    this.registerTransport = function(type, transport, index)
+    {
+        var result = _transports.add(type, transport, index);
+        if (result)
+        {
+            this._debug('Registered transport', type);
+
+            if (_isFunction(transport.registered))
+            {
+                transport.registered(type, this);
+            }
+        }
+        return result;
+    };
+
+    /**
+     * @return an array of all registered transport types
+     */
+    this.getTransportTypes = function()
+    {
+        return _transports.getTransportTypes();
+    };
+
+    /**
+     * Unregisters the transport with the given transport type.
+     * @param type the transport type to unregister
+     * @return the transport that has been unregistered,
+     * or null if no transport was previously registered under the given transport type
+     */
+    this.unregisterTransport = function(type)
+    {
+        var transport = _transports.remove(type);
+        if (transport !== null)
+        {
+            this._debug('Unregistered transport', type);
+
+            if (_isFunction(transport.unregistered))
+            {
+                transport.unregistered();
+            }
+        }
+        return transport;
+    };
+
+    this.unregisterTransports = function()
+    {
+        _transports.clear();
+    };
+
+    this.findTransport = function(name)
+    {
+        return _transports.find(name);
+    };
+
+    /**
+     * Configures the initial Bayeux communication with the Bayeux server.
+     * Configuration is passed via an object that must contain a mandatory field <code>url</code>
+     * of type string containing the URL of the Bayeux server.
+     * @param configuration the configuration object
+     */
+    this.configure = function(configuration)
+    {
+        _configure.call(this, configuration);
+    };
+
+    /**
+     * Configures and establishes the Bayeux communication with the Bayeux server
+     * via a handshake and a subsequent connect.
+     * @param configuration the configuration object
+     * @param handshakeProps an object to be merged with the handshake message
+     * @see #configure(configuration)
+     * @see #handshake(handshakeProps)
+     */
+    this.init = function(configuration, handshakeProps)
+    {
+        this.configure(configuration);
+        this.handshake(handshakeProps);
+    };
+
+    /**
+     * Establishes the Bayeux communication with the Bayeux server
+     * via a handshake and a subsequent connect.
+     * @param handshakeProps an object to be merged with the handshake message
+     */
+    this.handshake = function(handshakeProps)
+    {
+        _setStatus('disconnected');
+        _reestablish = false;
+        _handshake(handshakeProps);
+    };
+
+    /**
+     * Disconnects from the Bayeux server.
+     * It is possible to suggest to attempt a synchronous disconnect, but this feature
+     * may only be available in certain transports (for example, long-polling may support
+     * it, callback-polling certainly does not).
+     * @param sync whether attempt to perform a synchronous disconnect
+     * @param disconnectProps an object to be merged with the disconnect message
+     */
+    this.disconnect = function(sync, disconnectProps)
+    {
+        if (_isDisconnected())
+        {
+            return;
+        }
+
+        if (disconnectProps === undefined)
+        {
+            if (typeof sync !== 'boolean')
+            {
+                disconnectProps = sync;
+                sync = false;
+            }
+        }
+
+        var bayeuxMessage = {
+            channel: '/meta/disconnect'
+        };
+        var message = this._mixin(false, {}, disconnectProps, bayeuxMessage);
+        _setStatus('disconnecting');
+        _send(sync === true, [message], false, 'disconnect');
+    };
+
+    /**
+     * Marks the start of a batch of application messages to be sent to the server
+     * in a single request, obtaining a single response containing (possibly) many
+     * application reply messages.
+     * Messages are held in a queue and not sent until {@link #endBatch()} is called.
+     * If startBatch() is called multiple times, then an equal number of endBatch()
+     * calls must be made to close and send the batch of messages.
+     * @see #endBatch()
+     */
+    this.startBatch = function()
+    {
+        _startBatch();
+    };
+
+    /**
+     * Marks the end of a batch of application messages to be sent to the server
+     * in a single request.
+     * @see #startBatch()
+     */
+    this.endBatch = function()
+    {
+        _endBatch();
+    };
+
+    /**
+     * Executes the given callback in the given scope, surrounded by a {@link #startBatch()}
+     * and {@link #endBatch()} calls.
+     * @param scope the scope of the callback, may be omitted
+     * @param callback the callback to be executed within {@link #startBatch()} and {@link #endBatch()} calls
+     */
+    this.batch = function(scope, callback)
+    {
+        var delegate = _resolveScopedCallback(scope, callback);
+        this.startBatch();
+        try
+        {
+            delegate.method.call(delegate.scope);
+            this.endBatch();
+        }
+        catch (x)
+        {
+            this._debug('Exception during execution of batch', x);
+            this.endBatch();
+            throw x;
+        }
+    };
+
+    /**
+     * Adds a listener for bayeux messages, performing the given callback in the given scope
+     * when a message for the given channel arrives.
+     * @param channel the channel the listener is interested to
+     * @param scope the scope of the callback, may be omitted
+     * @param callback the callback to call when a message is sent to the channel
+     * @returns the subscription handle to be passed to {@link #removeListener(object)}
+     * @see #removeListener(subscription)
+     */
+    this.addListener = function(channel, scope, callback)
+    {
+        if (arguments.length < 2)
+        {
+            throw 'Illegal arguments number: required 2, got ' + arguments.length;
+        }
+        if (!_isString(channel))
+        {
+            throw 'Illegal argument type: channel must be a string';
+        }
+
+        return _addListener(channel, scope, callback, true);
+    };
+
+    /**
+     * Removes the subscription obtained with a call to {@link #addListener(string, object, function)}.
+     * @param subscription the subscription to unsubscribe.
+     * @see #addListener(channel, scope, callback)
+     */
+    this.removeListener = function(subscription)
+    {
+        if (!org.cometd.Utils.isArray(subscription))
+        {
+            throw 'Invalid argument: expected subscription, not ' + subscription;
+        }
+
+        _removeListener(subscription);
+    };
+
+    /**
+     * Removes all listeners registered with {@link #addListener(channel, scope, callback)} or
+     * {@link #subscribe(channel, scope, callback)}.
+     */
+    this.clearListeners = function()
+    {
+        _listeners = {};
+    };
+
+    /**
+     * Subscribes to the given channel, performing the given callback in the given scope
+     * when a message for the channel arrives.
+     * @param channel the channel to subscribe to
+     * @param scope the scope of the callback, may be omitted
+     * @param callback the callback to call when a message is sent to the channel
+     * @param subscribeProps an object to be merged with the subscribe message
+     * @return the subscription handle to be passed to {@link #unsubscribe(object)}
+     */
+    this.subscribe = function(channel, scope, callback, subscribeProps)
+    {
+        if (arguments.length < 2)
+        {
+            throw 'Illegal arguments number: required 2, got ' + arguments.length;
+        }
+        if (!_isString(channel))
+        {
+            throw 'Illegal argument type: channel must be a string';
+        }
+        if (_isDisconnected())
+        {
+            throw 'Illegal state: already disconnected';
+        }
+
+        // Normalize arguments
+        if (_isFunction(scope))
+        {
+            subscribeProps = callback;
+            callback = scope;
+            scope = undefined;
+        }
+
+        // Only send the message to the server if this client has not yet subscribed to the channel
+        var send = !_hasSubscriptions(channel);
+
+        var subscription = _addListener(channel, scope, callback, false);
+
+        if (send)
+        {
+            // Send the subscription message after the subscription registration to avoid
+            // races where the server would send a message to the subscribers, but here
+            // on the client the subscription has not been added yet to the data structures
+            var bayeuxMessage = {
+                channel: '/meta/subscribe',
+                subscription: channel
+            };
+            var message = this._mixin(false, {}, subscribeProps, bayeuxMessage);
+            _queueSend(message);
+        }
+
+        return subscription;
+    };
+
+    /**
+     * Unsubscribes the subscription obtained with a call to {@link #subscribe(string, object, function)}.
+     * @param subscription the subscription to unsubscribe.
+     */
+    this.unsubscribe = function(subscription, unsubscribeProps)
+    {
+        if (arguments.length < 1)
+        {
+            throw 'Illegal arguments number: required 1, got ' + arguments.length;
+        }
+        if (_isDisconnected())
+        {
+            throw 'Illegal state: already disconnected';
+        }
+
+        // Remove the local listener before sending the message
+        // This ensures that if the server fails, this client does not get notifications
+        this.removeListener(subscription);
+
+        var channel = subscription[0];
+        // Only send the message to the server if this client unsubscribes the last subscription
+        if (!_hasSubscriptions(channel))
+        {
+            var bayeuxMessage = {
+                channel: '/meta/unsubscribe',
+                subscription: channel
+            };
+            var message = this._mixin(false, {}, unsubscribeProps, bayeuxMessage);
+            _queueSend(message);
+        }
+    };
+
+    /**
+     * Removes all subscriptions added via {@link #subscribe(channel, scope, callback, subscribeProps)},
+     * but does not remove the listeners added via {@link addListener(channel, scope, callback)}.
+     */
+    this.clearSubscriptions = function()
+    {
+        _clearSubscriptions();
+    };
+
+    /**
+     * Publishes a message on the given channel, containing the given content.
+     * @param channel the channel to publish the message to
+     * @param content the content of the message
+     * @param publishProps an object to be merged with the publish message
+     */
+    this.publish = function(channel, content, publishProps)
+    {
+        if (arguments.length < 1)
+        {
+            throw 'Illegal arguments number: required 1, got ' + arguments.length;
+        }
+        if (!_isString(channel))
+        {
+            throw 'Illegal argument type: channel must be a string';
+        }
+        if (_isDisconnected())
+        {
+            throw 'Illegal state: already disconnected';
+        }
+
+        var bayeuxMessage = {
+            channel: channel,
+            data: content
+        };
+        var message = this._mixin(false, {}, publishProps, bayeuxMessage);
+        _queueSend(message);
+    };
+
+    /**
+     * Returns a string representing the status of the bayeux communication with the Bayeux server.
+     */
+    this.getStatus = function()
+    {
+        return _status;
+    };
+
+    /**
+     * Returns whether this instance has been disconnected.
+     */
+    this.isDisconnected = _isDisconnected;
+
+    /**
+     * Sets the backoff period used to increase the backoff time when retrying an unsuccessful or failed message.
+     * Default value is 1 second, which means if there is a persistent failure the retries will happen
+     * after 1 second, then after 2 seconds, then after 3 seconds, etc. So for example with 15 seconds of
+     * elapsed time, there will be 5 retries (at 1, 3, 6, 10 and 15 seconds elapsed).
+     * @param period the backoff period to set
+     * @see #getBackoffIncrement()
+     */
+    this.setBackoffIncrement = function(period)
+    {
+        _config.backoffIncrement = period;
+    };
+
+    /**
+     * Returns the backoff period used to increase the backoff time when retrying an unsuccessful or failed message.
+     * @see #setBackoffIncrement(period)
+     */
+    this.getBackoffIncrement = function()
+    {
+        return _config.backoffIncrement;
+    };
+
+    /**
+     * Returns the backoff period to wait before retrying an unsuccessful or failed message.
+     */
+    this.getBackoffPeriod = function()
+    {
+        return _backoff;
+    };
+
+    /**
+     * Sets the log level for console logging.
+     * Valid values are the strings 'error', 'warn', 'info' and 'debug', from
+     * less verbose to more verbose.
+     * @param level the log level string
+     */
+    this.setLogLevel = function(level)
+    {
+        _config.logLevel = level;
+    };
+
+    /**
+     * Registers an extension whose callbacks are called for every incoming message
+     * (that comes from the server to this client implementation) and for every
+     * outgoing message (that originates from this client implementation for the
+     * server).
+     * The format of the extension object is the following:
+     * <pre>
+     * {
+     *     incoming: function(message) { ... },
+     *     outgoing: function(message) { ... }
+     * }
+     * </pre>
+     * Both properties are optional, but if they are present they will be called
+     * respectively for each incoming message and for each outgoing message.
+     * @param name the name of the extension
+     * @param extension the extension to register
+     * @return true if the extension was registered, false otherwise
+     * @see #unregisterExtension(name)
+     */
+    this.registerExtension = function(name, extension)
+    {
+        if (arguments.length < 2)
+        {
+            throw 'Illegal arguments number: required 2, got ' + arguments.length;
+        }
+        if (!_isString(name))
+        {
+            throw 'Illegal argument type: extension name must be a string';
+        }
+
+        var existing = false;
+        for (var i = 0; i < _extensions.length; ++i)
+        {
+            var existingExtension = _extensions[i];
+            if (existingExtension.name === name)
+            {
+                existing = true;
+                break;
+            }
+        }
+        if (!existing)
+        {
+            _extensions.push({
+                name: name,
+                extension: extension
+            });
+            this._debug('Registered extension', name);
+
+            // Callback for extensions
+            if (_isFunction(extension.registered))
+            {
+                extension.registered(name, this);
+            }
+
+            return true;
+        }
+        else
+        {
+            this._info('Could not register extension with name', name, 'since another extension with the same name already exists');
+            return false;
+        }
+    };
+
+    /**
+     * Unregister an extension previously registered with
+     * {@link #registerExtension(name, extension)}.
+     * @param name the name of the extension to unregister.
+     * @return true if the extension was unregistered, false otherwise
+     */
+    this.unregisterExtension = function(name)
+    {
+        if (!_isString(name))
+        {
+            throw 'Illegal argument type: extension name must be a string';
+        }
+
+        var unregistered = false;
+        for (var i = 0; i < _extensions.length; ++i)
+        {
+            var extension = _extensions[i];
+            if (extension.name === name)
+            {
+                _extensions.splice(i, 1);
+                unregistered = true;
+                this._debug('Unregistered extension', name);
+
+                // Callback for extensions
+                var ext = extension.extension;
+                if (_isFunction(ext.unregistered))
+                {
+                    ext.unregistered();
+                }
+
+                break;
+            }
+        }
+        return unregistered;
+    };
+
+    /**
+     * Find the extension registered with the given name.
+     * @param name the name of the extension to find
+     * @return the extension found or null if no extension with the given name has been registered
+     */
+    this.getExtension = function(name)
+    {
+        for (var i = 0; i < _extensions.length; ++i)
+        {
+            var extension = _extensions[i];
+            if (extension.name === name)
+            {
+                return extension.extension;
+            }
+        }
+        return null;
+    };
+
+    /**
+     * Returns the name assigned to this Cometd object, or the string 'default'
+     * if no name has been explicitly passed as parameter to the constructor.
+     */
+    this.getName = function()
+    {
+        return _name;
+    };
+
+    /**
+     * Returns the clientId assigned by the Bayeux server during handshake.
+     */
+    this.getClientId = function()
+    {
+        return _clientId;
+    };
+
+    /**
+     * Returns the URL of the Bayeux server.
+     */
+    this.getURL = function()
+    {
+        return _config.url;
+    };
+
+    this.getTransport = function()
+    {
+        return _transport;
+    };
+
+    this.getConfiguration = function()
+    {
+        return this._mixin(true, {}, _config);
+    };
+
+    this.getAdvice = function()
+    {
+        return this._mixin(true, {}, _advice);
+    };
+
+    // WebSocket handling for Firefox, which deploys WebSocket
+    // under the name of MozWebSocket in Firefox 6, 7, 8 and 9
+    org.cometd.WebSocket = window.WebSocket;
+    if (!org.cometd.WebSocket)
+    {
+        org.cometd.WebSocket = window.MozWebSocket;
+    }
+};
+
diff --git a/http/samples/cometd/src/main/java/org/apache/felix/http/samples/cometd/Activator.java b/http/samples/cometd/src/main/java/org/apache/felix/http/samples/cometd/Activator.java
index 5da3117..182b45e 100644
--- a/http/samples/cometd/src/main/java/org/apache/felix/http/samples/cometd/Activator.java
+++ b/http/samples/cometd/src/main/java/org/apache/felix/http/samples/cometd/Activator.java
@@ -17,23 +17,28 @@
 package org.apache.felix.http.samples.cometd;
 
 
+import java.util.Hashtable;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+
+import org.apache.felix.http.cometd.CometdService;
+import org.cometd.bayeux.server.BayeuxServer;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.http.HttpService;
+import org.osgi.service.http.NamespaceException;
 import org.osgi.util.tracker.ServiceTracker;
 import org.osgi.util.tracker.ServiceTrackerCustomizer;
-import javax.servlet.Servlet;
-import javax.servlet.ServletException;
-import java.util.Hashtable;
-import org.apache.felix.http.cometd.CometdService;
-import org.cometd.Bayeux;
 
 public final class Activator
     implements BundleActivator, ServiceTrackerCustomizer
 {
     private BundleContext context;
     private ServiceTracker cometdServiceTracker;
+    private ServiceTracker httpServiceTracker;
     private ServiceRegistration reg;
     
     public void start(BundleContext context)
@@ -42,6 +47,8 @@
         this.context = context;
         this.cometdServiceTracker = new ServiceTracker(this.context, CometdService.class.getName(), this);
         this.cometdServiceTracker.open();
+        this.httpServiceTracker = new ServiceTracker(this.context, HttpService.class.getName(), new HTTPServiceCustomizer());
+        this.httpServiceTracker.open();
     }
 
     public void stop(BundleContext context)
@@ -50,6 +57,9 @@
         if (this.cometdServiceTracker != null) {
             this.cometdServiceTracker.close();
         }
+        if (this.httpServiceTracker != null) {
+        	this.httpServiceTracker.close();
+        }
         this.unregister();
     }
 
@@ -73,15 +83,16 @@
 
     private void register(CometdService cometdService) {
         try {
-            Bayeux bayeux = cometdService.getBayeux();
-            if (bayeux != null) {
+            BayeuxServer bayeuxServer = cometdService.getBayeuxServer();
+            if (bayeuxServer != null) {
                 Hashtable<String, String> props = new Hashtable<String, String>();
                 props.put("alias", "/system/time");
-                this.reg = context.registerService(Servlet.class.getName(), new TimeServlet(bayeux), props);
+                // whiteboard servlet registration
+                this.reg = context.registerService(Servlet.class.getName(), new TimeServlet(bayeuxServer), props);
                 doLog("Connect a browser to http://<host>:<port>/system/time to view the time.");
             }
             else {
-                doLog("Failed to get bayeux");
+                doLog("Failed to get bayeux server");
             }
         }
         catch (ServletException e) {
@@ -100,4 +111,27 @@
     {
         System.out.println("## Activator:   " + message);
     }
+    
+    class HTTPServiceCustomizer implements ServiceTrackerCustomizer {
+
+		public Object addingService(ServiceReference reference) {
+			HttpService httpService = (HttpService) context.getService(reference);
+			try {
+				httpService.registerResources("/js", "/src-web", null);
+			} catch (NamespaceException e) {
+				e.printStackTrace();
+			}
+			return null;
+		}
+
+		public void modifiedService(ServiceReference reference, Object service) {
+			
+		}
+
+		public void removedService(ServiceReference reference, Object service) {
+			HttpService httpService = (HttpService) context.getService(reference);
+			httpService.unregister("/js");
+		}
+    	
+    }
 }
diff --git a/http/samples/cometd/src/main/java/org/apache/felix/http/samples/cometd/TimeServlet.java b/http/samples/cometd/src/main/java/org/apache/felix/http/samples/cometd/TimeServlet.java
index f970edb..4876f2e 100644
--- a/http/samples/cometd/src/main/java/org/apache/felix/http/samples/cometd/TimeServlet.java
+++ b/http/samples/cometd/src/main/java/org/apache/felix/http/samples/cometd/TimeServlet.java
@@ -16,11 +16,6 @@
  */
 package org.apache.felix.http.samples.cometd;
 
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.text.SimpleDateFormat;
@@ -29,9 +24,18 @@
 import java.util.List;
 import java.util.Timer;
 import java.util.TimerTask;
-import org.cometd.Bayeux;
-import org.cometd.Channel;
-import org.cometd.Client;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.cometd.bayeux.server.BayeuxServer;
+import org.cometd.bayeux.server.ConfigurableServerChannel;
+import org.cometd.bayeux.server.LocalSession;
+import org.cometd.bayeux.server.ServerChannel;
+import org.cometd.bayeux.server.ServerMessage;
 
 public class TimeServlet
     extends HttpServlet
@@ -42,31 +46,93 @@
         Time
     };
 
-    private Bayeux bayeux;
-    private Client client;
-    private List<Channel> channels;
+    private BayeuxServer bayeuxServer;
+    private LocalSession session;
+    private List<ServerChannel> channels;
     private Timer updateTimer;
     private SimpleDateFormat logDateFormat;
     private String html =
         "<html>\n" +
         "  <head>\n" +
         "    <title>System Information</title>\n" +
-        "    <script type='text/javascript' src='/dojo/dojo/dojo.js'></script>\n" +
+        "    <script type='text/javascript' src='/js/dojo/dojo.js'></script>\n" +
         "    <script type='text/javascript'>\n" +
         "      dojo.require('dojox.cometd');\n" +
-        "      dojo.addOnLoad(init);\n" +
-        "      dojo.addOnUnload(destroy);\n" +
-        "      function init() {\n" +
-        "        dojox.cometd.init('/system/cometd');\n" +
-        "        dojox.cometd.subscribe('/System/Time', updateTime);\n" +
-        "      }\n" +
-        "      function destroy() {\n" +
-        "        dojox.cometd.unsubscribe('/System/Time');\n" +
-        "        dojox.cometd.disconnect();\n" +
-        "      }\n" +
-        "      function updateTime(message) {\n" +
-        "          document.getElementById('systemTime').innerHTML = message.data;\n" +
-        "      }\n" +
+        "dojo.addOnLoad(function()\n" + 
+        "{\n" + 
+        "    var cometd = dojox.cometd;\n" + 
+        "\n" + 
+        "    function _connectionEstablished()\n" + 
+        "    {\n" + 
+        "        dojo.byId('body').innerHTML += '<div>CometD Connection Established</div>';\n" + 
+        "    }\n" + 
+        "\n" + 
+        "    function _connectionBroken()\n" + 
+        "    {\n" + 
+        "        dojo.byId('body').innerHTML += '<div>CometD Connection Broken</div>';\n" + 
+        "    }\n" + 
+        "\n" + 
+        "    function _connectionClosed()\n" + 
+        "    {\n" + 
+        "        dojo.byId('body').innerHTML += '<div>CometD Connection Closed</div>';\n" + 
+        "    }\n" + 
+        "\n" + 
+        "    // Function that manages the connection status with the Bayeux server\n" + 
+        "    var _connected = false;\n" + 
+        "    function _metaConnect(message)\n" + 
+        "    {\n" + 
+        "        if (cometd.isDisconnected())\n" + 
+        "        {\n" + 
+        "            _connected = false;\n" + 
+        "            _connectionClosed();\n" + 
+        "            return;\n" + 
+        "        }\n" + 
+        "\n" + 
+        "        var wasConnected = _connected;\n" + 
+        "        _connected = message.successful === true;\n" + 
+        "        if (!wasConnected && _connected)\n" + 
+        "        {\n" + 
+        "            _connectionEstablished();\n" + 
+        "        }\n" + 
+        "        else if (wasConnected && !_connected)\n" + 
+        "        {\n" + 
+        "            _connectionBroken();\n" + 
+        "        }\n" + 
+        "    }\n" + 
+        "\n" + 
+        "    // Function invoked when first contacting the server and\n" + 
+        "    // when the server has lost the state of this client\n" + 
+        "    function _metaHandshake(handshake)\n" + 
+        "    {\n" + 
+        "        if (handshake.successful === true)\n" + 
+        "        {\n" + 
+        "            cometd.batch(function()\n" + 
+        "            {\n" + 
+        "                cometd.subscribe('/System/Time', function(message)\n" + 
+        "                {\n" + 
+        "                    dojo.byId('systemTime').innerHTML = '<div>' + message.data + '</div>';\n" + 
+        "                });\n" + 
+        "            });\n" + 
+        "        }\n" + 
+        "    }\n" + 
+        "\n" + 
+        "    // Disconnect when the page unloads\n" + 
+        "    dojo.addOnUnload(function()\n" + 
+        "    {\n" + 
+        "        cometd.disconnect(true);\n" + 
+        "    });\n" + 
+        "\n" + 
+        "    var cometURL = \"http://localhost:8080/system/cometd\";\n" + 
+        "    cometd.configure({\n" + 
+        "        url: cometURL,\n" + 
+        "        logLevel: 'debug'\n" + 
+        "    });\n" + 
+        "\n" + 
+        "    cometd.addListener('/meta/handshake', _metaHandshake);\n" + 
+        "    cometd.addListener('/meta/connect', _metaConnect);\n" + 
+        "\n" + 
+        "    cometd.handshake();\n" + 
+        "});\n" + 
         "    </script>\n" +
         "  </head>\n" +
         "  <body>\n" +
@@ -74,17 +140,25 @@
         "  </body>\n" +
         "</html>\n";
 
-    public TimeServlet(Bayeux bayeux)
+    public TimeServlet(BayeuxServer bayeuxServer)
     {
-        this.bayeux = bayeux;
-        this.client = this.bayeux.newClient(this.getClass().getName());
-        this.channels = new ArrayList<Channel>();
+        this.bayeuxServer = bayeuxServer;
+        this.channels = new ArrayList<ServerChannel>();
         for (SystemTopics topic : SystemTopics.values()) {
-            this.channels.add(topic.ordinal(), this.bayeux.getChannel("/System/" + topic, true));
+        	boolean created = bayeuxServer.createIfAbsent("/System/" + topic, new ServerChannel.Initializer() {
+				public void configureChannel(ConfigurableServerChannel channel) {
+					channel.setPersistent(true);
+				}
+        	});
+        	if (created) {
+        		this.channels.add(topic.ordinal(), this.bayeuxServer.getChannel("/System/" + topic));
+        	}
         }
-        this.updateTimer = new Timer("System.Time.ClientNotifier");
-        this.updateTimer.scheduleAtFixedRate(new ClientNotifier(), 1000, 1000);
         this.logDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+		this.updateTimer = new Timer("System.Time.ClientNotifier");
+		this.updateTimer.scheduleAtFixedRate(new ClientNotifier(), 1000, 1000);
+		this.session = bayeuxServer.newLocalSession(TimeServlet.class.getName());
+		this.session.handshake();
     }
 
     @Override
@@ -100,6 +174,7 @@
     {
         doLog("Destroyed servlet");
         this.updateTimer.cancel();
+        this.session.disconnect();
         super.destroy();
     }
 
@@ -131,8 +206,12 @@
                     default:
                         topicData = "unknown topic: " + topic.toString();
                 }
-                channels.get(topic.ordinal()).publish(client, topicData, null);
+                ServerMessage.Mutable message = bayeuxServer.newMessage();
+                message.setChannel(channels.get(topic.ordinal()).getId());
+                message.setData(topicData);
+                channels.get(topic.ordinal()).publish(session, topicData, null);
             }
         }
     }
+
 }
