[Tynstep-svn] r202 - in trunk/step: step-core step-core/src/main/resources step-parent step-web step-web/src/main/java/com/tyndalehouse/step/rest step-web/src/main/java/com/tyndalehouse/step/rest/controllers step-web/src/main/java/com/tyndalehouse/step/rest/framework step-web/src/main/webapp step-web/src/main/webapp/js step-web/src/main/webapp/libs step-web/src/main/webapp/libs/timeline_ajax step-web/src/main/webapp/libs/timeline_ajax/content step-web/src/main/webapp/libs/timeline_ajax/images step-web/src/main/webapp/libs/timeline_ajax/scripts step-web/src/main/webapp/libs/timeline_ajax/styles step-web/src/main/webapp/libs/timeline_js step-web/src/main/webapp/libs/timeline_js/images step-web/src/main/webapp/libs/timeline_js/scripts step-web/src/main/webapp/libs/timeline_js/scripts/l10n step-web/src/main/webapp/libs/timeline_js/scripts/l10n/cs step-web/src/main/webapp/libs/timeline_js/scripts/l10n/de step-web/src/main/webapp/libs/timeline_js/scripts/l10n/en step-web/src/main/webapp/libs/timeline_js/scripts/l10n/es step-web/src/main/webapp/libs/timeline_js/scripts/l10n/fr step-web/src/main/webapp/libs/timeline_js/scripts/l10n/it step-web/src/main/webapp/libs/timeline_js/scripts/l10n/nl step-web/src/main/webapp/libs/timeline_js/scripts/l10n/ru step-web/src/main/webapp/libs/timeline_js/scripts/l10n/se step-web/src/main/webapp/libs/timeline_js/scripts/l10n/tr step-web/src/main/webapp/libs/timeline_js/scripts/l10n/vi step-web/src/main/webapp/libs/timeline_js/scripts/l10n/zh step-web/src/test/java/com/tyndalehouse/step/rest step-web/src/test/java/com/tyndalehouse/step/rest/controllers step-web/src/test/java/com/tyndalehouse/step/rest/framework

ChrisBurrell at crosswire.org ChrisBurrell at crosswire.org
Fri Jan 7 15:52:32 MST 2011


Author: ChrisBurrell
Date: 2011-01-07 15:52:32 -0700 (Fri, 07 Jan 2011)
New Revision: 202

Added:
   trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/ControllerCacheKey.java
   trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/StepRequest.java
   trunk/step/step-web/src/main/webapp/js/initLib.js
   trunk/step/step-web/src/main/webapp/js/timeline.js
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/content/
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/content/history.html
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-arrow-point-down.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-arrow-point-left.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-arrow-point-right.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-arrow-point-up.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-bottom-left.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-bottom-right.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-bottom.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-left.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-right.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-top-left.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-top-right.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-top.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/close-button.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/copy.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/message-bottom-left.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/message-bottom-right.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/message-left.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/message-right.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/message-top-left.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/message-top-right.png
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/scripts/
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/scripts/signal.js
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/simile-ajax-api.js
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/simile-ajax-bundle.js
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/styles/
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/styles/graphics-ie6.css
   trunk/step/step-web/src/main/webapp/libs/timeline_ajax/styles/graphics.css
   trunk/step/step-web/src/main/webapp/libs/timeline_js/
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/blue-circle.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-bottom-arrow.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-bottom-left.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-bottom-right.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-bottom.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-left-arrow.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-left.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-right-arrow.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-right.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-top-arrow.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-top-left.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-top-right.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-top.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/close-button.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/copyright-vertical.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/copyright.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/dark-blue-circle.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/dark-green-circle.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/dark-red-circle.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/dull-blue-circle.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/dull-green-circle.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/dull-red-circle.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/gray-circle.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/green-circle.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/message-bottom-left.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/message-bottom-right.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/message-left.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/message-right.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/message-top-left.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/message-top-right.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/progress-running.gif
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/red-circle.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/images/top-bubble.png
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/cs/
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/cs/labellers.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/cs/timeline.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/de/
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/de/labellers.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/de/timeline.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/en/
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/en/labellers.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/en/timeline.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/es/
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/es/labellers.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/es/timeline.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/fr/
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/fr/labellers.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/fr/timeline.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/it/
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/it/labellers.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/it/timeline.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/nl/
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/nl/labellers.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/nl/timeline.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/ru/
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/ru/labellers.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/ru/timeline.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/se/
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/se/labellers.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/se/timeline.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/tr/
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/tr/labellers.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/tr/timeline.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/vi/
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/vi/labellers.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/vi/timeline.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/zh/
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/zh/labellers.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/zh/timeline.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/timeline-api.js
   trunk/step/step-web/src/main/webapp/libs/timeline_js/timeline-bundle.css
   trunk/step/step-web/src/main/webapp/libs/timeline_js/timeline-bundle.js
   trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/controllers/BibleControllerTest.java
   trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/framework/
   trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/framework/StepRequestTest.java
Removed:
   trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/JsonExceptionResolver.java
Modified:
   trunk/step/step-core/pom.xml
   trunk/step/step-core/src/main/resources/step.core.properties
   trunk/step/step-parent/pom.xml
   trunk/step/step-web/pom.xml
   trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/FrontController.java
   trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/TimelineController.java
   trunk/step/step-web/src/main/webapp/index.jsp
   trunk/step/step-web/src/main/webapp/js/init.js
   trunk/step/step-web/src/main/webapp/js/passage.js
   trunk/step/step-web/src/main/webapp/js/passage_toolbar.js
   trunk/step/step-web/src/main/webapp/js/util.js
   trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/controllers/FrontControllerTest.java
Log:


Modified: trunk/step/step-core/pom.xml
===================================================================
--- trunk/step/step-core/pom.xml	2011-01-07 21:08:34 UTC (rev 201)
+++ trunk/step/step-core/pom.xml	2011-01-07 22:52:32 UTC (rev 202)
@@ -17,12 +17,6 @@
 
 	<dependencies>
 		<dependency>
-			<groupId>junit</groupId>
-			<artifactId>junit</artifactId>
-			<scope>test</scope>
-		</dependency>
-
-		<dependency>
 			<groupId>org.slf4j</groupId>
 			<artifactId>slf4j-api</artifactId>
 		</dependency>

Modified: trunk/step/step-core/src/main/resources/step.core.properties
===================================================================
--- trunk/step/step-core/src/main/resources/step.core.properties	2011-01-07 21:08:34 UTC (rev 201)
+++ trunk/step/step-core/src/main/resources/step.core.properties	2011-01-07 22:52:32 UTC (rev 202)
@@ -1,3 +1,6 @@
+# Front controller properties
+cache.enabled=true
+
 #list of installers in the format: host,package,catalog
 installer.1=www.crosswire.org,/ftpmirror/pub/sword/packages/rawzip,/ftpmirror/pub/sword/raw
 installer.2=ftp.bible.org,/sword/packages/rawzip,/sword/raw

Modified: trunk/step/step-parent/pom.xml
===================================================================
--- trunk/step/step-parent/pom.xml	2011-01-07 21:08:34 UTC (rev 201)
+++ trunk/step/step-parent/pom.xml	2011-01-07 22:52:32 UTC (rev 202)
@@ -48,6 +48,11 @@
 		<mockito.version>1.8.5</mockito.version>
 	</properties>
 
+	<url>http://crosswire.org/wiki/Frontends:TyndaleStep</url>
+	<issueManagement>
+		<system>JIRA</system>
+		<url>http://crosswire.org/bugs</url>
+	</issueManagement>
 	<scm>
 		<connection>scm:svn:http://crosswire.org/svn/tynstep/trunk</connection>
 		<developerConnection>scm:svn:https://crosswire.org/svn/tynstep/trunk</developerConnection>
@@ -243,10 +248,20 @@
 		</dependencies>
 	</dependencyManagement>
 
-
-
+	<dependencies>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+		
 	<organization>
+		<name>Tyndale House</name>
+		<url>http://http://www.tyndale.cam.ac.uk/</url>
 	</organization>
+	
+	
 	<build>
 		<pluginManagement>
 			<plugins>
@@ -262,12 +277,19 @@
 				<plugin>
 					<groupId>org.apache.maven.plugins</groupId>
 					<artifactId>maven-surefire-plugin</artifactId>
-					<version>2.5</version>
+					<version>2.7.1</version>
 					<configuration>
 						<junitArtifactName>junit:junit-dep</junitArtifactName>
 						<parallel>classes</parallel>
 						<threadCount>4</threadCount>
 					</configuration>
+					<dependencies>
+						<dependency>
+							<groupId>org.apache.maven.surefire</groupId>
+							<artifactId>surefire-junit47</artifactId>
+							<version>2.7.1</version>
+						</dependency>
+					</dependencies>
 				</plugin>
 
 				<plugin>
@@ -356,11 +378,11 @@
 				<plugin>
 					<groupId>org.codehaus.mojo</groupId>
 					<artifactId>cobertura-maven-plugin</artifactId>
-					<version>2.3</version>
+					<version>2.4</version>
 					<configuration>
 						<check>
-							<branchRate>85</branchRate>
-							<lineRate>85</lineRate>
+							<branchRate>70</branchRate>
+							<lineRate>70</lineRate>
 							<haltOnFailure>false</haltOnFailure>
 							<totalBranchRate>60</totalBranchRate>
 							<totalLineRate>60</totalLineRate>

Modified: trunk/step/step-web/pom.xml
===================================================================
--- trunk/step/step-web/pom.xml	2011-01-07 21:08:34 UTC (rev 201)
+++ trunk/step/step-web/pom.xml	2011-01-07 22:52:32 UTC (rev 202)
@@ -72,11 +72,6 @@
 
 		<!-- test dependencies -->
 		<dependency>
-			<groupId>junit</groupId>
-			<artifactId>junit</artifactId>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
 			<groupId>org.mockito</groupId>
 			<artifactId>mockito-core</artifactId>
 		</dependency>

Deleted: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/JsonExceptionResolver.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/JsonExceptionResolver.java	2011-01-07 21:08:34 UTC (rev 201)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/JsonExceptionResolver.java	2011-01-07 22:52:32 UTC (rev 202)
@@ -1,22 +0,0 @@
-package com.tyndalehouse.step.rest;
-
-/**
- * A JSon exception resolver
- * 
- * @author Chris
- * 
- */
-public class JsonExceptionResolver /* implements HandlerExceptionResolver */{
-    // private final Logger logger = LoggerFactory.getLogger(getClass());
-    //
-    // public ModelAndView resolveException(final HttpServletRequest request, final HttpServletResponse response,
-    // final Object handler, final Exception exception) {
-    //
-    // this.logger.error(exception.getMessage(), exception);
-    //
-    // final ModelAndView mav = new ModelAndView();
-    // mav.setViewName("MappingJacksonJsonView");
-    // mav.addObject("error", exception.getMessage());
-    // return mav;
-    // }
-}

Modified: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/FrontController.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/FrontController.java	2011-01-07 21:08:34 UTC (rev 201)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/FrontController.java	2011-01-07 22:52:32 UTC (rev 202)
@@ -23,7 +23,10 @@
 import com.google.inject.Inject;
 import com.google.inject.Injector;
 import com.google.inject.Singleton;
+import com.google.inject.name.Named;
 import com.tyndalehouse.step.core.exceptions.StepInternalException;
+import com.tyndalehouse.step.rest.framework.ControllerCacheKey;
+import com.tyndalehouse.step.rest.framework.StepRequest;
 
 /**
  * The FrontController acts like a minimal REST server. The paths are resolved as follows:
@@ -40,90 +43,154 @@
     private static final char PACKAGE_SEPARATOR = '.';
     private static final long serialVersionUID = 7898656504631346047L;
     private static final String CONTROLLER_SUFFIX = "Controller";
+    // TODO EH cache here too?
     private final Map<String, String> contextPath = new HashMap<String, String>();
+    private final Map<String, byte[]> resultsCache = new HashMap<String, byte[]>();
     private final transient Injector guiceInjector;
     // TODO but also check threadsafety and whether we should share this object
     private final transient ObjectMapper jsonMapper = new ObjectMapper();
+
+    // TODO investigate EH cache here
     private final Map<String, Method> methodNames = new HashMap<String, Method>();
     private final Map<String, Object> controllers = new HashMap<String, Object>();
+    private final boolean isCacheEnabled;
 
     /**
      * creates the front controller which will dispatch all the requests
      * 
      * @param guiceInjector the injector used to call the relevant controllers
+     * @param isCacheEnabled indicates whether responses should be cached for fast retrieval
+     * 
      */
     @Inject
-    public FrontController(final Injector guiceInjector) {
+    public FrontController(final Injector guiceInjector, @Named("cache.enabled") final Boolean isCacheEnabled) {
         this.guiceInjector = guiceInjector;
+        this.isCacheEnabled = Boolean.TRUE.equals(isCacheEnabled);
     }
 
     @Override
-    protected void doGet(final HttpServletRequest req, final HttpServletResponse response) {
-        // fast string manipulation... (?)
-        final String requestURI = req.getRequestURI();
-        LOGGER.debug("Processing {}", requestURI);
+    protected void doGet(final HttpServletRequest request, final HttpServletResponse response) {
+        StepRequest sr = null;
+        try {
+            sr = parseRequest(request);
+            byte[] jsonEncoded = null;
 
-        final int requestStart = getPath(req).length() + 1;
-        final int endOfControllerName = requestURI.indexOf('/', requestStart);
-        final int startOfMethodName = endOfControllerName + 1;
-        final String controllerName = requestURI.substring(requestStart, endOfControllerName);
-        final String methodName = requestURI.substring(startOfMethodName,
-                requestURI.indexOf('/', startOfMethodName));
-        final int endOfMethodName = startOfMethodName + methodName.length();
+            // in here we want to retrieve from the cache.
+            final ControllerCacheKey cacheKey = sr.getCacheKey();
 
-        LOGGER.debug("Request parsed as controller: [{}], method [{}]", controllerName, methodName);
+            // check results cache here -- TODO - use servlet caching instead?
+            if (this.isCacheEnabled) {
+                LOGGER.debug("Checking cache...");
+                jsonEncoded = this.resultsCache.get(cacheKey.getResultsKey());
+            }
 
+            // cache miss?
+            if (jsonEncoded == null) {
+                LOGGER.debug("The cache was missed so invoking method now...");
+                jsonEncoded = invokeMethod(sr);
+            }
+            setupHeaders(response, jsonEncoded.length);
+            response.getOutputStream().write(jsonEncoded);
+            cache(jsonEncoded, sr.getControllerName(), sr.getMethodName(), sr.getArgs());
+            // CHECKSTYLE:OFF We allow catching errors here, since we are at the top of the structure
+        } catch (final Exception e) {
+            // CHECKSTYLE:ON
+            doError(response, e, sr);
+        }
+    }
+
+    /**
+     * Invokes the method on the controller instance and returns JSON-ed results
+     * 
+     * @param sr the STEP Request containing all pertinent information
+     * @return byte array representation of the return value
+     */
+    byte[] invokeMethod(final StepRequest sr) {
+
         // controller instance on which to call a method
-        final Object controllerInstance = getController(controllerName);
+        final Object controllerInstance = getController(sr.getControllerName());
 
-        // some arguments to be passsed through
-        final Object[] args = getArgs(requestURI, endOfMethodName + 1);
-
         // resolve method
-        final Method controllerMethod = getControllerMethod(methodName, controllerInstance, args);
+        final Method controllerMethod = getControllerMethod(sr.getMethodName(), controllerInstance,
+                sr.getArgs(), sr.getCacheKey().getMethodKey());
 
+        // invoke the three together
         try {
-            // invoke the three together
-            final Object returnVal = controllerMethod.invoke(controllerInstance, args);
-            final String jsonReturnValue = this.jsonMapper.writeValueAsString(returnVal);
+            final Object returnVal = controllerMethod.invoke(controllerInstance, (Object[]) sr.getArgs());
+            return getEncodedJsonResponse(returnVal);
+        } catch (final IllegalAccessException e) {
+            throw new StepInternalException(sr.toString(), e);
+        } catch (final InvocationTargetException e) {
+            throw new StepInternalException(sr.toString(), e);
+        }
 
-            final byte[] jsonEncoded = jsonReturnValue.getBytes(UTF_8_ENCODING);
+        // TODO remove dead code once I have proven this doesn't get used
+        // catch (final NoSuchMethodError e) {
+        // throw new StepInternalException(sr.toString(), e);
+        // }
+    }
 
-            // put results in cache if method is annotated. We don't need to do that
-            // afterwards...
-            setupHeaders(response, jsonEncoded.length);
-            response.getOutputStream().write(jsonEncoded);
-            // response.getOutputStream().flush();
-            // response.getOutputStream().close();
-
-            // perhaps we want to cache things...
-            // TODO
-
-        } catch (final StepInternalException e) {
-            // TODO handle this slightly differently?
-            doError(e);
-        } catch (final NoSuchMethodError e) {
-            doError(e);
-        } catch (final IllegalAccessException e) {
-            doError(e);
-        } catch (final InvocationTargetException e) {
-            doError(e);
+    /**
+     * Returns a json response that is encoded
+     * 
+     * @param responseValue the value that should be encoded
+     * @return the encoded form of the JSON response
+     */
+    byte[] getEncodedJsonResponse(final Object responseValue) {
+        try {
+            return this.jsonMapper.writeValueAsString(responseValue).getBytes(UTF_8_ENCODING);
         } catch (final JsonGenerationException e) {
-            doError(e);
+            throw new StepInternalException(e.getMessage(), e);
         } catch (final JsonMappingException e) {
-            doError(e);
+            throw new StepInternalException(e.getMessage(), e);
         } catch (final IOException e) {
-            doError(e);
+            throw new StepInternalException(e.getMessage(), e);
         }
     }
 
     /**
+     * Returns the step request object containing the relevant information about the STEP Request
+     * 
+     * @param request the HTTP request
+     * @return the StepRequest encapsulating key data
+     */
+    StepRequest parseRequest(final HttpServletRequest request) {
+        final String requestURI = request.getRequestURI();
+
+        LOGGER.debug("Parsing {}", requestURI);
+
+        final int requestStart = getPath(request).length() + 1;
+        final int endOfControllerName = requestURI.indexOf('/', requestStart);
+        final int startOfMethodName = endOfControllerName + 1;
+        final String controllerName = requestURI.substring(requestStart, endOfControllerName);
+        final String methodName = requestURI.substring(startOfMethodName,
+                requestURI.indexOf('/', startOfMethodName));
+        final int endOfMethodName = startOfMethodName + methodName.length();
+
+        LOGGER.debug("Request parsed as controller: [{}], method [{}]", controllerName, methodName);
+        return new StepRequest(controllerName, methodName, getArgs(requestURI, endOfMethodName + 1));
+    }
+
+    /**
+     * TODO caches the results for future use
+     * 
+     * @param jsonEncoded json encoding of the response
+     * @param controllerName the name of the controller that was ino
+     * @param methodName the method name that was called
+     * @param args the arguments that were passed
+     */
+    void cache(final byte[] jsonEncoded, final String controllerName, final String methodName,
+            final Object[] args) {
+        // TODO using EH Cache
+    }
+
+    /**
      * sets up the headers and the length of the message
      * 
      * @param response the response
      * @param length the length of the message
      */
-    private void setupHeaders(final HttpServletResponse response, final int length) {
+    void setupHeaders(final HttpServletResponse response, final int length) {
         // we ensure that headers are set up appropriately
         response.addDateHeader("Date", System.currentTimeMillis());
         response.setCharacterEncoding(UTF_8_ENCODING);
@@ -134,13 +201,28 @@
     /**
      * deals with an error whilst executing the request
      * 
+     * @param response the response
+     * 
      * @param e the exception
+     * @param sr the step request
      */
-    private void doError(final Throwable e) {
-        LOGGER.error(e.getMessage(), e);
+    void doError(final HttpServletResponse response, final Throwable e, final StepRequest sr) {
+        String requestId = null;
+        try {
+            requestId = sr == null ? "Failed to parse request?" : sr.getCacheKey().getResultsKey();
+            if (e != null) {
+                final byte[] errorMessage = this.getEncodedJsonResponse(e.getMessage());
+                response.getOutputStream().write(errorMessage);
+                setupHeaders(response, errorMessage.length);
 
-        // TODO deal with error here:
-
+                LOGGER.error("An internal error has occurred for [{}]", requestId, e);
+            }
+            // CHECKSTYLE:OFF We allow catching errors here, since we are at the top of the structure
+        } catch (final Exception unableToSendError) {
+            // CHECKSTYLE:ON
+            LOGGER.error("Unable to output error for request" + requestId, unableToSendError);
+            LOGGER.error("Due to original Throwable", e);
+        }
     }
 
     /**
@@ -184,15 +266,13 @@
      * @param methodName the method name
      * @param controllerInstance the instance of the controller
      * @param args the list of arguments, required to resolve the correct method if they have arguments
+     * @param cacheKey the key to retrieve in the cache
      * @return the method to be invoked
      */
-    Method getControllerMethod(final String methodName, final Object controllerInstance, final Object[] args) {
+    Method getControllerMethod(final String methodName, final Object controllerInstance, final Object[] args,
+            final String cacheKey) {
         final Class<? extends Object> controllerClass = controllerInstance.getClass();
 
-        // try cache first
-        final String cacheKey = getCacheKey(controllerClass.getName(), methodName, args == null ? 0
-                : args.length);
-
         // retrieve method from cache, or put in cache if not there
         Method controllerMethod = this.methodNames.get(cacheKey);
         if (controllerMethod == null) {
@@ -228,22 +308,6 @@
     }
 
     /**
-     * returns the cache key to resolve from the cache
-     * 
-     * @param controllerName the controller name
-     * @param methodName the method name
-     * @param numArgs the number of arguments affects which method is returned
-     * @return the key to the method as expected in the cache.
-     */
-    String getCacheKey(final String controllerName, final String methodName, final int numArgs) {
-        final StringBuilder cacheKeyBuffer = new StringBuilder(controllerName.length() + methodName.length());
-        cacheKeyBuffer.append(controllerName);
-        cacheKeyBuffer.append(methodName);
-        cacheKeyBuffer.append(numArgs);
-        return cacheKeyBuffer.toString();
-    }
-
-    /**
      * gets the arguments out of the requestURI String
      * 
      * @param requestURI the request URI string
@@ -291,4 +355,5 @@
         }
         return path;
     }
+
 }

Modified: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/TimelineController.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/TimelineController.java	2011-01-07 21:08:34 UTC (rev 201)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/controllers/TimelineController.java	2011-01-07 22:52:32 UTC (rev 202)
@@ -18,29 +18,28 @@
     private static final Logger LOGGER = LoggerFactory.getLogger(TimelineController.class);
 
     /**
-     * a REST method to retrieve events between two dates The arrays match in index, and go by three (timebandId, from,
-     * to), (timebandId, from, to), ...
+     * a REST method to retrieve events between two dates The arrays match in index, and go by three
+     * (timebandId, from, to), (timebandId, from, to), ...
      * 
      * @param timebandId the timeband ids
      * @param from the from dates
      * @param to the to dates
      * @return all versions of modules that are considered to be Bibles. TODO work out UK date format mappings
      */
-    // @RequestMapping("/events")
     public String getEvents(final String[] timebandId, final Date from, final Date to) {
         LOGGER.debug("Retrieving events between [{}] and [{}]", from, to);
         return timebandId[0];
     }
 
     /**
-     * Retrieves events based on a biblical reference. This method also needs to return an origin and a scale for the
-     * timeline to be displayed properly as it might well be that the UI has carried out a different search
+     * Retrieves events based on a biblical reference. This method also needs to return an origin and a scale
+     * for the timeline to be displayed properly as it might well be that the UI has carried out a different
+     * search
      * 
      * @param bibleReference the bible reference that might have a set of events related to it
-     * @return a list of events to be shown on a timeline, including the origin of the timeline and the scale of the
-     *         timeline
+     * @return a list of events to be shown on a timeline, including the origin of the timeline and the scale
+     *         of the timeline
      */
-    // @RequestMapping("/eventsFromReference")
     public String getEventsFromReference(final String bibleReference) {
 
         return null;

Added: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/ControllerCacheKey.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/ControllerCacheKey.java	                        (rev 0)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/ControllerCacheKey.java	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,36 @@
+package com.tyndalehouse.step.rest.framework;
+
+/**
+ * This is a holder object for multiple variants of a cache key
+ * 
+ * @author Chris
+ */
+public class ControllerCacheKey {
+    private final String methodKey;
+    private final String resultsKey;
+
+    /**
+     * This contructs a cache key
+     * 
+     * @param methodKey the key to retrieve a particular method
+     * @param resultsKey the key to retrieve the results that we had previously
+     */
+    public ControllerCacheKey(final String methodKey, final String resultsKey) {
+        this.methodKey = methodKey;
+        this.resultsKey = resultsKey;
+    }
+
+    /**
+     * @return the methodKey
+     */
+    public String getMethodKey() {
+        return this.methodKey;
+    }
+
+    /**
+     * @return the resultsKey
+     */
+    public String getResultsKey() {
+        return this.resultsKey;
+    }
+}

Added: trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/StepRequest.java
===================================================================
--- trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/StepRequest.java	                        (rev 0)
+++ trunk/step/step-web/src/main/java/com/tyndalehouse/step/rest/framework/StepRequest.java	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,95 @@
+package com.tyndalehouse.step.rest.framework;
+
+/**
+ * A simple class that hold request information, provides various cache keys
+ * 
+ * @author Chris
+ * 
+ */
+public class StepRequest {
+    private static final Object ARG_SEPARATOR = '-';
+
+    private final String controllerName;
+    private final String methodName;
+    private final String[] args;
+
+    /**
+     * Creates a request holder object containing the relevant information about a request
+     * 
+     * @param controllerName the controller name
+     * @param methodName the method name
+     * @param args the arguments that should be passed to the method
+     */
+    public StepRequest(final String controllerName, final String methodName, final String[] args) {
+        this.controllerName = controllerName;
+        this.methodName = methodName;
+        this.args = args == null ? new String[] {} : args;
+    }
+
+    /**
+     * returns the cache key to resolve from the cache
+     * 
+     * @return the key to the method as expected in the cache.
+     */
+    public ControllerCacheKey getCacheKey() {
+        final String methodKey;
+        final String resultsKey;
+
+        // generate the shorter key
+        final StringBuilder cacheKeyBuffer = new StringBuilder(this.controllerName.length()
+                + this.methodName.length());
+        cacheKeyBuffer.append(this.controllerName);
+        cacheKeyBuffer.append(this.methodName);
+        cacheKeyBuffer.append(this.args.length);
+
+        // get the shorter key now
+        methodKey = cacheKeyBuffer.toString();
+
+        // now get a slightly longer key by extending it
+        for (int ii = 0; ii < this.args.length; ii++) {
+            cacheKeyBuffer.append(this.args[ii]);
+            cacheKeyBuffer.append(ARG_SEPARATOR);
+        }
+        resultsKey = cacheKeyBuffer.toString();
+        return new ControllerCacheKey(methodKey, resultsKey);
+    }
+
+    /**
+     * @return the controllerName
+     */
+    public String getControllerName() {
+        return this.controllerName;
+    }
+
+    /**
+     * @return the methodName
+     */
+    public String getMethodName() {
+        return this.methodName;
+    }
+
+    /**
+     * @return the args
+     */
+    public String[] getArgs() {
+        return this.args;
+    }
+
+    /**
+     * @return an message describibg the step request
+     */
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append(this.controllerName);
+        sb.append('.');
+        sb.append(this.methodName);
+        sb.append('(');
+
+        for (int ii = 0; ii < this.args.length; ii++) {
+            sb.append(this.args.length);
+            sb.append(',');
+        }
+        return sb.toString();
+    }
+}

Modified: trunk/step/step-web/src/main/webapp/index.jsp
===================================================================
--- trunk/step/step-web/src/main/webapp/index.jsp	2011-01-07 21:08:34 UTC (rev 201)
+++ trunk/step/step-web/src/main/webapp/index.jsp	2011-01-07 22:52:32 UTC (rev 202)
@@ -10,18 +10,23 @@
     <link rel="stylesheet" type="text/css" href="css/initial-layout.css" />
     <link rel="stylesheet" type="text/css" href="css/initial-fonts.css" />
     <link rel="stylesheet" type="text/css" href="css/passage.css" />
-    
+
+	<script src="js/initLib.js"></script>   
+    <script src="libs/timeline_js/timeline-api.js?bundle=true" type="text/javascript"></script>
     <script src="libs/jquery-1.4.2.min.js" type="text/javascript"></script>
     <script src="libs/jquery-ui-1.8.5.custom.min.js" type="text/javascript"></script>
     <script src="libs/jquery.layout-latest.js" type="text/javascript"></script>
     <script src="libs/jquery-shout.js" type="text/javascript"></script>
+    
     <script src="js/util.js" type="text/javascript"></script>
     <script src="js/passage_toolbar.js" type="text/javascript"></script>
     <script src="js/passage.js" type="text/javascript"></script>
     <script src="js/bookmark.js" type="text/javascript"></script>
     <script src="js/lexicon_definition.js" type="text/javascript"></script>
     <script src="js/ui_hooks.js" type="text/javascript"></script>
+    <script src="js/timeline.js" type="text/javascript"></script>
     <script src="js/init.js" type="text/javascript"></script>
+    
 </HEAD>
 <body>
 
@@ -65,6 +70,8 @@
 	
 </div>
 
+<div id="bottomSection" class="timeline">No modules have yet been loaded.</div>
+
 <div id="loading"><img alt="Loading..." src="images/wait16.gif" />Loading...</div>
 <div id="error" class="ui-state-highlight">A placeholder for error messages</div>
 

Modified: trunk/step/step-web/src/main/webapp/js/init.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/init.js	2011-01-07 21:08:34 UTC (rev 201)
+++ trunk/step/step-web/src/main/webapp/js/init.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -8,10 +8,11 @@
 
 function init() {
 	$(document).ready(function() {
-		initLayout();
+		var mainAppLayout = initLayout();
 		initGlobalHandlers();
 		initDefaultValues();
 		initLexicon();
+		initTimeline(mainAppLayout);
 		initBookmarks();
 		initData();
 	});
@@ -23,7 +24,7 @@
 function initLayout() {
 
 	//do outerlayout first
-	$('body').layout({
+	var mainAppLayout = $('body').layout({
 		name : 'outerLayout', 
 		spacing_open: 2,
 		autoResize : true, // try to maintain pane-percentages
@@ -33,6 +34,7 @@
 		west__paneSelector : '#leftColumn',
 		center__paneSelector : '.bookmarks',
 		east__paneSelector : '#rightColumn',
+		south__paneSelector: '#bottomSection',
 		west__size : .45, // percentage size expresses as a decimal
 		east__size : .45,
 		north__minSize : 0,
@@ -40,6 +42,10 @@
 		north__spacing_open : 0,
 		north__spacing_closed : 0,
 		north__initClosed: true,
+		south__size : .5,
+		south__spacing_closed: 2,
+		south__resizable : false,
+		south__initClosed : true,
 		minSize : 130,
 		noRoomToOpenAction : "hide"
 	});
@@ -62,6 +68,8 @@
 		south__size : 30,
 		noRoomToOpenAction : "hide"
 	});
+	
+	return mainAppLayout;
 }
 
 function initDefaultValues() {
@@ -230,8 +238,12 @@
 	new Bookmark($("#bookmarkPane"));
 }
 
+function initTimeline(mainAppLayout) {
+	new TimelineWidget($("#bottomSection"), mainAppLayout);
+}
 
 function raiseError(error) {
 	$("#error").text(error);
 	$('body').layout().open("north");
 }
+

Added: trunk/step/step-web/src/main/webapp/js/initLib.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/initLib.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/js/initLib.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,8 @@
+/**
+ * This file is used for setting up variables used by external libraries 
+ */
+
+//Set up timeline:
+Timeline_ajax_url="libs/timeline_ajax/simile-ajax-api.js";
+Timeline_urlPrefix="libs/timeline_js/";
+Timeline_parameters="bundle=true";

Modified: trunk/step/step-web/src/main/webapp/js/passage.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/passage.js	2011-01-07 21:08:34 UTC (rev 201)
+++ trunk/step/step-web/src/main/webapp/js/passage.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -110,6 +110,8 @@
 		//send to server
 		$.get(url, function (text) {
 			//we get html back, so we insert into passage:
+			
+			
 			self.passage.html(text.value);
 			
 			//passage change was successful, so we let the rest of the UI know

Modified: trunk/step/step-web/src/main/webapp/js/passage_toolbar.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/passage_toolbar.js	2011-01-07 21:08:34 UTC (rev 201)
+++ trunk/step/step-web/src/main/webapp/js/passage_toolbar.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -35,13 +35,22 @@
 		}
 		toolbarId++;
 	});
+	
+	//finally create a timeline button
+	this.createTimelineButton();
 }
 
-//function split( val ) {
-//	return val.split( /,\s*/ );
-//}
-function extractLast( term ) {
-	return split( term ).pop();
+Toolbar.prototype.createTimelineButton = function() {
+	this.toolbarContainer.append("<input id='timeline" + toolbarId
+			+ "' type='checkbox' class='timelineButton'><label for='timeline" + toolbarId + 
+			"'>Timeline</label></input>");
+
+	var timelineSelector = $('#timeline' + toolbarId);
+	timelineSelector.button();
+	
+	timelineSelector.click(function() {
+		$.shout("show-timeline");
+	});
 }
 
 Toolbar.prototype.createInterlinearDropdown = function(toolbarId, strongedVersions, interlinearButton) {

Added: trunk/step/step-web/src/main/webapp/js/timeline.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/timeline.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/js/timeline.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,152 @@
+/**
+ * Code for showing and interacting with the timeline
+ */
+
+function TimelineWidget(rootElement, mainAppLayout) {
+	this.rootElement = rootElement;
+	var self = this;
+	$(rootElement).hear("show-timeline", function(selfElement) {
+		//first show the bottom pane...
+		mainAppLayout.open("south");
+		
+		self.onLoad();
+		$(window).resize(self.onResize);
+	});
+	
+	$(rootElement).hear("hide-timeline", function(selfElement) {
+		//first show the bottom pane...
+		mainAppLayout.close("south");
+	
+		
+		
+//		$(window).resize(self.onResize);
+	});
+	
+	//do the removal of the timeline
+}
+
+var tl;
+TimelineWidget.prototype.onLoad = function() {
+    var eventSource = new Timeline.DefaultEventSource();
+    
+    var zones = [
+        {   start:    "Fri Nov 22 1963 00:00:00 GMT-0600",
+            end:      "Mon Nov 25 1963 00:00:00 GMT-0600",
+            magnify:  10,
+            unit:     Timeline.DateTime.DAY
+        },
+        {   start:    "Fri Nov 22 1963 09:00:00 GMT-0600",
+            end:      "Sun Nov 24 1963 00:00:00 GMT-0600",
+            magnify:  5,
+            unit:     Timeline.DateTime.HOUR
+        },
+        {   start:    "Fri Nov 22 1963 11:00:00 GMT-0600",
+            end:      "Sat Nov 23 1963 00:00:00 GMT-0600",
+            magnify:  5,
+            unit:     Timeline.DateTime.MINUTE,
+            multiple: 10
+        },
+        {   start:    "Fri Nov 22 1963 12:00:00 GMT-0600",
+            end:      "Fri Nov 22 1963 14:00:00 GMT-0600",
+            magnify:  3,
+            unit:     Timeline.DateTime.MINUTE,
+            multiple: 5
+        }
+    ];
+    var zones2 = [
+        {   start:    "Fri Nov 22 1963 00:00:00 GMT-0600",
+            end:      "Mon Nov 25 1963 00:00:00 GMT-0600",
+            magnify:  10,
+            unit:     Timeline.DateTime.WEEK
+        },
+        {   start:    "Fri Nov 22 1963 09:00:00 GMT-0600",
+            end:      "Sun Nov 24 1963 00:00:00 GMT-0600",
+            magnify:  5,
+            unit:     Timeline.DateTime.DAY
+        },
+        {   start:    "Fri Nov 22 1963 11:00:00 GMT-0600",
+            end:      "Sat Nov 23 1963 00:00:00 GMT-0600",
+            magnify:  5,
+            unit:     Timeline.DateTime.MINUTE,
+            multiple: 60
+        },
+        {   start:    "Fri Nov 22 1963 12:00:00 GMT-0600",
+            end:      "Fri Nov 22 1963 14:00:00 GMT-0600",
+            magnify:  3,
+            unit:     Timeline.DateTime.MINUTE,
+            multiple: 15
+        }
+    ];
+    
+    var theme = Timeline.ClassicTheme.create();
+    theme.event.bubble.width = 250;
+    
+    var date = "Fri Nov 22 1963 13:00:00 GMT-0600"
+    var bandInfos = [
+        Timeline.createHotZoneBandInfo({
+            width:          "80%", 
+            intervalUnit:   Timeline.DateTime.WEEK, 
+            intervalPixels: 220,
+            zones:          zones,
+            eventSource:    eventSource,
+            date:           date,
+            timeZone:       -6,
+            theme:          theme
+        }),
+        Timeline.createHotZoneBandInfo({
+            width:          "20%", 
+            intervalUnit:   Timeline.DateTime.MONTH, 
+            intervalPixels: 200,
+            zones:          zones2, 
+            eventSource:    eventSource,
+            date:           date, 
+            timeZone:       -6,
+            overview:       true,
+            theme:          theme
+        })
+    ];
+    bandInfos[1].syncWith = 0;
+    bandInfos[1].highlight = true;
+    
+    for (var i = 0; i < bandInfos.length; i++) {
+        bandInfos[i].decorators = [
+            new Timeline.SpanHighlightDecorator({
+                startDate:  "Fri Nov 22 1963 12:30:00 GMT-0600",
+                endDate:    "Fri Nov 22 1963 13:00:00 GMT-0600",
+                color:      "#FFC080", // set color explicitly
+                opacity:    50,
+                startLabel: "shot",
+                endLabel:   "t.o.d.",
+                theme:      theme
+            }),
+            new Timeline.PointHighlightDecorator({
+                date:       "Fri Nov 22 1963 14:38:00 GMT-0600",
+                opacity:    50,
+                theme:      theme
+                // use the color from the css file
+            }),
+            new Timeline.PointHighlightDecorator({
+                date:       "Sun Nov 24 1963 13:00:00 GMT-0600",
+                opacity:    50,
+                theme:      theme
+                // use the color from the css file
+            })
+        ];
+    }
+    
+    if(!tl) {
+    	tl = Timeline.create(this.rootElement[0], bandInfos, Timeline.HORIZONTAL);    	
+    }
+//    tl.loadXML("jfk.xml", function(xml, url) { eventSource.loadXML(xml, url); });
+//    setupFilterHighlightControls(document.getElementById("controls"), tl, [0,1], theme);
+}
+
+var resizeTimerID = null;
+TimelineWidget.prototype.onResize = function() {
+    if (resizeTimerID == null) {
+        resizeTimerID = window.setTimeout(function() {
+            resizeTimerID = null;
+            tl.layout();
+        }, 500);
+    }
+}
\ No newline at end of file

Modified: trunk/step/step-web/src/main/webapp/js/util.js
===================================================================
--- trunk/step/step-web/src/main/webapp/js/util.js	2011-01-07 21:08:34 UTC (rev 201)
+++ trunk/step/step-web/src/main/webapp/js/util.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -27,4 +27,8 @@
 		textbox.autocomplete( "search", "" );
 		textbox.focus();
 	});
-}
\ No newline at end of file
+}
+
+function extractLast( term ) {
+	return split( term ).pop();
+}

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/content/history.html
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_ajax/content/history.html	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_ajax/content/history.html	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,7 @@
+<html>
+<head>
+    <title>Dummy Page for Keeping Track of History</title>
+</head>
+<body>
+</body>
+</html>
\ No newline at end of file

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-arrow-point-down.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-arrow-point-down.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-arrow-point-left.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-arrow-point-left.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-arrow-point-right.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-arrow-point-right.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-arrow-point-up.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-arrow-point-up.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-bottom-left.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-bottom-left.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-bottom-right.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-bottom-right.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-bottom.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-bottom.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-left.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-left.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-right.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-right.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-top-left.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-top-left.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-top-right.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-top-right.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-top.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/bubble-top.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/close-button.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/close-button.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/copy.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/copy.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/message-bottom-left.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/message-bottom-left.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/message-bottom-right.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/message-bottom-right.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/message-left.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/message-left.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/message-right.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/message-right.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/message-top-left.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/message-top-left.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/message-top-right.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/images/message-top-right.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/scripts/signal.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_ajax/scripts/signal.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_ajax/scripts/signal.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,43 @@
+/*==================================================
+ *  This file is used to detect that all outstanding
+ *  javascript files have been loaded. You can put
+ *  a function reference into SimileAjax_onLoad
+ *  to have it executed once all javascript files
+ *  have loaded.
+ *==================================================
+ */
+(function() {
+    var substring = SimileAjax.urlPrefix + "scripts/signal.js";
+    var heads = document.documentElement.getElementsByTagName("head");
+    for (var h = 0; h < heads.length; h++) {
+        var node = heads[h].firstChild;
+        while (node != null) {
+            if (node.nodeType == 1 && node.tagName.toLowerCase() == "script") {
+                var url = node.src;
+                var i = url.indexOf(substring);
+                if (i >= 0) {
+                    heads[h].removeChild(node); // remove it so we won't hit it again
+
+                    var count = parseInt(url.substr(url.indexOf(substring) + substring.length + 1));
+                    SimileAjax.loadingScriptsCount -= count;
+                    if (SimileAjax.loadingScriptsCount == 0) {
+                        var f = null;
+                        if (typeof SimileAjax_onLoad == "string") {
+                            f = eval(SimileAjax_onLoad);
+                            SimileAjax_onLoad = null;
+                        } else if (typeof SimileAjax_onLoad == "function") {
+                            f = SimileAjax_onLoad;
+                            SimileAjax_onLoad = null;
+                        }
+                        
+                        if (f != null) {
+                            f();
+                        }
+                    }
+                    return;
+                }
+            }
+            node = node.nextSibling;
+        }
+    }
+})();

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/simile-ajax-api.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_ajax/simile-ajax-api.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_ajax/simile-ajax-api.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,212 @@
+/*==================================================
+ *  Simile Ajax API
+ *
+ *  Include this file in your HTML file as follows:
+ *
+ *    <script src="http://simile.mit.edu/ajax/api/simile-ajax-api.js" type="text/javascript"></script>
+ *
+ *==================================================
+ */
+
+if (typeof SimileAjax == "undefined") {
+    var SimileAjax = {
+        loaded:                 false,
+        loadingScriptsCount:    0,
+        error:                  null,
+        params:                 { bundle:"true" }
+    };
+    
+    SimileAjax.Platform = new Object();
+        /*
+            HACK: We need these 2 things here because we cannot simply append
+            a <script> element containing code that accesses SimileAjax.Platform
+            to initialize it because IE executes that <script> code first
+            before it loads ajax.js and platform.js.
+        */
+        
+    var getHead = function(doc) {
+        return doc.getElementsByTagName("head")[0];
+    };
+    
+    SimileAjax.findScript = function(doc, substring) {
+        var heads = doc.documentElement.getElementsByTagName("head");
+        for (var h = 0; h < heads.length; h++) {
+            var node = heads[h].firstChild;
+            while (node != null) {
+                if (node.nodeType == 1 && node.tagName.toLowerCase() == "script") {
+                    var url = node.src;
+                    var i = url.indexOf(substring);
+                    if (i >= 0) {
+                        return url;
+                    }
+                }
+                node = node.nextSibling;
+            }
+        }
+        return null;
+    };
+    SimileAjax.includeJavascriptFile = function(doc, url, onerror, charset) {
+        onerror = onerror || "";
+        if (doc.body == null) {
+            try {
+                var q = "'" + onerror.replace( /'/g, '&apos' ) + "'"; // "
+                doc.write("<script src='" + url + "' onerror="+ q +
+                          (charset ? " charset='"+ charset +"'" : "") +
+                          " type='text/javascript'>"+ onerror + "</script>");
+                return;
+            } catch (e) {
+                // fall through
+            }
+        }
+
+        var script = doc.createElement("script");
+        if (onerror) {
+            try { script.innerHTML = onerror; } catch(e) {}
+            script.setAttribute("onerror", onerror);
+        }
+        if (charset) {
+            script.setAttribute("charset", charset);
+        }
+        script.type = "text/javascript";
+        script.language = "JavaScript";
+        script.src = url;
+        return getHead(doc).appendChild(script);
+    };
+    SimileAjax.includeJavascriptFiles = function(doc, urlPrefix, filenames) {
+        for (var i = 0; i < filenames.length; i++) {
+            SimileAjax.includeJavascriptFile(doc, urlPrefix + filenames[i]);
+        }
+        SimileAjax.loadingScriptsCount += filenames.length;
+        SimileAjax.includeJavascriptFile(doc, SimileAjax.urlPrefix + "scripts/signal.js?" + filenames.length);
+    };
+    SimileAjax.includeCssFile = function(doc, url) {
+        if (doc.body == null) {
+            try {
+                doc.write("<link rel='stylesheet' href='" + url + "' type='text/css'/>");
+                return;
+            } catch (e) {
+                // fall through
+            }
+        }
+        
+        var link = doc.createElement("link");
+        link.setAttribute("rel", "stylesheet");
+        link.setAttribute("type", "text/css");
+        link.setAttribute("href", url);
+        getHead(doc).appendChild(link);
+    };
+    SimileAjax.includeCssFiles = function(doc, urlPrefix, filenames) {
+        for (var i = 0; i < filenames.length; i++) {
+            SimileAjax.includeCssFile(doc, urlPrefix + filenames[i]);
+        }
+    };
+    
+    /**
+     * Append into urls each string in suffixes after prefixing it with urlPrefix.
+     * @param {Array} urls
+     * @param {String} urlPrefix
+     * @param {Array} suffixes
+     */
+    SimileAjax.prefixURLs = function(urls, urlPrefix, suffixes) {
+        for (var i = 0; i < suffixes.length; i++) {
+            urls.push(urlPrefix + suffixes[i]);
+        }
+    };
+
+    /**
+     * Parse out the query parameters from a URL
+     * @param {String} url    the url to parse, or location.href if undefined
+     * @param {Object} to     optional object to extend with the parameters
+     * @param {Object} types  optional object mapping keys to value types
+     *        (String, Number, Boolean or Array, String by default)
+     * @return a key/value Object whose keys are the query parameter names
+     * @type Object
+     */
+    SimileAjax.parseURLParameters = function(url, to, types) {
+        to = to || {};
+        types = types || {};
+        
+        if (typeof url == "undefined") {
+            url = location.href;
+        }
+        var q = url.indexOf("?");
+        if (q < 0) {
+            return to;
+        }
+        url = (url+"#").slice(q+1, url.indexOf("#")); // toss the URL fragment
+        
+        var params = url.split("&"), param, parsed = {};
+        var decode = window.decodeURIComponent || unescape;
+        for (var i = 0; param = params[i]; i++) {
+            var eq = param.indexOf("=");
+            var name = decode(param.slice(0,eq));
+            var old = parsed[name];
+            if (typeof old == "undefined") {
+                old = [];
+            } else if (!(old instanceof Array)) {
+                old = [old];
+            }
+            parsed[name] = old.concat(decode(param.slice(eq+1)));
+        }
+        for (var i in parsed) {
+            if (!parsed.hasOwnProperty(i)) continue;
+            var type = types[i] || String;
+            var data = parsed[i];
+            if (!(data instanceof Array)) {
+                data = [data];
+            }
+            if (type === Boolean && data[0] == "false") {
+                to[i] = false; // because Boolean("false") === true
+            } else {
+                to[i] = type.apply(this, data);
+            }
+        }
+        return to;
+    };
+
+    (function() {
+        var javascriptFiles = [
+            "jquery-1.2.6.min.js",
+            "platform.js",
+            "debug.js",
+            "xmlhttp.js",
+            "json.js",
+            "dom.js",
+            "graphics.js",
+            "date-time.js",
+            "string.js",
+            "html.js",
+            "data-structure.js",
+            "units.js",
+            
+            "ajax.js",
+            "history.js",
+            "window-manager.js"
+        ];
+        var cssFiles = [
+            "graphics.css"
+        ];
+        
+        if (typeof SimileAjax_urlPrefix == "string") {
+            SimileAjax.urlPrefix = SimileAjax_urlPrefix;
+        } else {
+            var url = SimileAjax.findScript(document, "simile-ajax-api.js");
+            if (url == null) {
+                SimileAjax.error = new Error("Failed to derive URL prefix for Simile Ajax API code files");
+                return;
+            }
+
+            SimileAjax.urlPrefix = url.substr(0, url.indexOf("simile-ajax-api.js"));
+        }
+
+        SimileAjax.parseURLParameters(url, SimileAjax.params, {bundle:Boolean});
+        if (SimileAjax.params.bundle) {
+            SimileAjax.includeJavascriptFiles(document, SimileAjax.urlPrefix, [ "simile-ajax-bundle.js" ]);
+        } else {
+            SimileAjax.includeJavascriptFiles(document, SimileAjax.urlPrefix + "scripts/", javascriptFiles);
+        }
+        SimileAjax.includeCssFiles(document, SimileAjax.urlPrefix + "styles/", cssFiles);
+        
+        SimileAjax.loaded = true;
+    })();
+}

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/simile-ajax-bundle.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_ajax/simile-ajax-bundle.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_ajax/simile-ajax-bundle.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,2623 @@
+
+
+/* jquery-1.2.6.min.js */
+(function(){var _jQuery=window.jQuery,_$=window.$;
+var jQuery=window.jQuery=window.$=function(selector,context){return new jQuery.fn.init(selector,context);
+};
+var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,isSimple=/^.[^:#\[\.]*$/,undefined;
+jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;
+if(selector.nodeType){this[0]=selector;
+this.length=1;
+return this;
+}if(typeof selector=="string"){var match=quickExpr.exec(selector);
+if(match&&(match[1]||!context)){if(match[1]){selector=jQuery.clean([match[1]],context);
+}else{var elem=document.getElementById(match[3]);
+if(elem){if(elem.id!=match[3]){return jQuery().find(selector);
+}return jQuery(elem);
+}selector=[];
+}}else{return jQuery(context).find(selector);
+}}else{if(jQuery.isFunction(selector)){return jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);
+}}return this.setArray(jQuery.makeArray(selector));
+},jquery:"1.2.6",size:function(){return this.length;
+},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];
+},pushStack:function(elems){var ret=jQuery(elems);
+ret.prevObject=this;
+return ret;
+},setArray:function(elems){this.length=0;
+Array.prototype.push.apply(this,elems);
+return this;
+},each:function(callback,args){return jQuery.each(this,callback,args);
+},index:function(elem){var ret=-1;
+return jQuery.inArray(elem&&elem.jquery?elem[0]:elem,this);
+},attr:function(name,value,type){var options=name;
+if(name.constructor==String){if(value===undefined){return this[0]&&jQuery[type||"attr"](this[0],name);
+}else{options={};
+options[name]=value;
+}}return this.each(function(i){for(name in options){jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));
+}});
+},css:function(key,value){if((key=="width"||key=="height")&&parseFloat(value)<0){value=undefined;
+}return this.attr(key,value,"curCSS");
+},text:function(text){if(typeof text!="object"&&text!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));
+}var ret="";
+jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8){ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);
+}});
+});
+return ret;
+},wrapAll:function(html){if(this[0]){jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;
+while(elem.firstChild){elem=elem.firstChild;
+}return elem;
+}).append(this);
+}return this;
+},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);
+});
+},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);
+});
+},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1){this.appendChild(elem);
+}});
+},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1){this.insertBefore(elem,this.firstChild);
+}});
+},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);
+});
+},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);
+});
+},end:function(){return this.prevObject||jQuery([]);
+},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);
+});
+return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);
+},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");
+container.appendChild(clone);
+return jQuery.clean([container.innerHTML])[0];
+}else{return this.cloneNode(true);
+}});
+var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined){this[expando]=null;
+}});
+if(events===true){this.find("*").andSelf().each(function(i){if(this.nodeType==3){return ;
+}var events=jQuery.data(this,"events");
+for(var type in events){for(var handler in events[type]){jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);
+}}});
+}return ret;
+},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);
+})||jQuery.multiFilter(selector,this));
+},not:function(selector){if(selector.constructor==String){if(isSimple.test(selector)){return this.pushStack(jQuery.multiFilter(selector,this,true));
+}else{selector=jQuery.multiFilter(selector,this);
+}}var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;
+return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;
+});
+},add:function(selector){return this.pushStack(jQuery.unique(jQuery.merge(this.get(),typeof selector=="string"?jQuery(selector):jQuery.makeArray(selector))));
+},is:function(selector){return !!selector&&jQuery.multiFilter(selector,this).length>0;
+},hasClass:function(selector){return this.is("."+selector);
+},val:function(value){if(value==undefined){if(this.length){var elem=this[0];
+if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";
+if(index<0){return null;
+}for(var i=one?index:0,max=one?index+1:options.length;
+i<max;
+i++){var option=options[i];
+if(option.selected){value=jQuery.browser.msie&&!option.attributes.value.specified?option.text:option.value;
+if(one){return value;
+}values.push(value);
+}}return values;
+}else{return(this[0].value||"").replace(/\r/g,"");
+}}return undefined;
+}if(value.constructor==Number){value+="";
+}return this.each(function(){if(this.nodeType!=1){return ;
+}if(value.constructor==Array&&/radio|checkbox/.test(this.type)){this.checked=(jQuery.inArray(this.value,value)>=0||jQuery.inArray(this.name,value)>=0);
+}else{if(jQuery.nodeName(this,"select")){var values=jQuery.makeArray(value);
+jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);
+});
+if(!values.length){this.selectedIndex=-1;
+}}else{this.value=value;
+}}});
+},html:function(value){return value==undefined?(this[0]?this[0].innerHTML:null):this.empty().append(value);
+},replaceWith:function(value){return this.after(value).remove();
+},eq:function(i){return this.slice(i,i+1);
+},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));
+},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);
+}));
+},andSelf:function(){return this.add(this.prevObject);
+},data:function(key,value){var parts=key.split(".");
+parts[1]=parts[1]?"."+parts[1]:"";
+if(value===undefined){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);
+if(data===undefined&&this.length){data=jQuery.data(this[0],key);
+}return data===undefined&&parts[1]?this.data(parts[0]):data;
+}else{return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);
+});
+}},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);
+});
+},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;
+return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);
+if(reverse){elems.reverse();
+}}var obj=this;
+if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr")){obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));
+}var scripts=jQuery([]);
+jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;
+if(jQuery.nodeName(elem,"script")){scripts=scripts.add(elem);
+}else{if(elem.nodeType==1){scripts=scripts.add(jQuery("script",elem).remove());
+}callback.call(obj,elem);
+}});
+scripts.each(evalScript);
+});
+}};
+jQuery.fn.init.prototype=jQuery.fn;
+function evalScript(i,elem){if(elem.src){jQuery.ajax({url:elem.src,async:false,dataType:"script"});
+}else{jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");
+}if(elem.parentNode){elem.parentNode.removeChild(elem);
+}}function now(){return +new Date;
+}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;
+if(target.constructor==Boolean){deep=target;
+target=arguments[1]||{};
+i=2;
+}if(typeof target!="object"&&typeof target!="function"){target={};
+}if(length==i){target=this;
+--i;
+}for(;
+i<length;
+i++){if((options=arguments[i])!=null){for(var name in options){var src=target[name],copy=options[name];
+if(target===copy){continue;
+}if(deep&&copy&&typeof copy=="object"&&!copy.nodeType){target[name]=jQuery.extend(deep,src||(copy.length!=null?[]:{}),copy);
+}else{if(copy!==undefined){target[name]=copy;
+}}}}}return target;
+};
+var expando="jQuery"+now(),uuid=0,windowData={},exclude=/z-?index|font-?weight|opacity|zoom|line-?height/i,defaultView=document.defaultView||{};
+jQuery.extend({noConflict:function(deep){window.$=_$;
+if(deep){window.jQuery=_jQuery;
+}return jQuery;
+},isFunction:function(fn){return !!fn&&typeof fn!="string"&&!fn.nodeName&&fn.constructor!=Array&&/^[\s[]?function/.test(fn+"");
+},isXMLDoc:function(elem){return elem.documentElement&&!elem.body||elem.tagName&&elem.ownerDocument&&!elem.ownerDocument.body;
+},globalEval:function(data){data=jQuery.trim(data);
+if(data){var head=document.getElementsByTagName("head")[0]||document.documentElement,script=document.createElement("script");
+script.type="text/javascript";
+if(jQuery.browser.msie){script.text=data;
+}else{script.appendChild(document.createTextNode(data));
+}head.insertBefore(script,head.firstChild);
+head.removeChild(script);
+}},nodeName:function(elem,name){return elem.nodeName&&elem.nodeName.toUpperCase()==name.toUpperCase();
+},cache:{},data:function(elem,name,data){elem=elem==window?windowData:elem;
+var id=elem[expando];
+if(!id){id=elem[expando]=++uuid;
+}if(name&&!jQuery.cache[id]){jQuery.cache[id]={};
+}if(data!==undefined){jQuery.cache[id][name]=data;
+}return name?jQuery.cache[id][name]:id;
+},removeData:function(elem,name){elem=elem==window?windowData:elem;
+var id=elem[expando];
+if(name){if(jQuery.cache[id]){delete jQuery.cache[id][name];
+name="";
+for(name in jQuery.cache[id]){break;
+}if(!name){jQuery.removeData(elem);
+}}}else{try{delete elem[expando];
+}catch(e){if(elem.removeAttribute){elem.removeAttribute(expando);
+}}delete jQuery.cache[id];
+}},each:function(object,callback,args){var name,i=0,length=object.length;
+if(args){if(length==undefined){for(name in object){if(callback.apply(object[name],args)===false){break;
+}}}else{for(;
+i<length;
+){if(callback.apply(object[i++],args)===false){break;
+}}}}else{if(length==undefined){for(name in object){if(callback.call(object[name],name,object[name])===false){break;
+}}}else{for(var value=object[0];
+i<length&&callback.call(value,i,value)!==false;
+value=object[++i]){}}}return object;
+},prop:function(elem,value,type,i,name){if(jQuery.isFunction(value)){value=value.call(elem,i);
+}return value&&value.constructor==Number&&type=="curCSS"&&!exclude.test(name)?value+"px":value;
+},className:{add:function(elem,classNames){jQuery.each((classNames||"").split(/\s+/),function(i,className){if(elem.nodeType==1&&!jQuery.className.has(elem.className,className)){elem.className+=(elem.className?" ":"")+className;
+}});
+},remove:function(elem,classNames){if(elem.nodeType==1){elem.className=classNames!=undefined?jQuery.grep(elem.className.split(/\s+/),function(className){return !jQuery.className.has(classNames,className);
+}).join(" "):"";
+}},has:function(elem,className){return jQuery.inArray(className,(elem.className||elem).toString().split(/\s+/))>-1;
+}},swap:function(elem,options,callback){var old={};
+for(var name in options){old[name]=elem.style[name];
+elem.style[name]=options[name];
+}callback.call(elem);
+for(var name in options){elem.style[name]=old[name];
+}},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];
+function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;
+var padding=0,border=0;
+jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;
+border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;
+});
+val-=Math.round(padding+border);
+}if(jQuery(elem).is(":visible")){getWH();
+}else{jQuery.swap(elem,props,getWH);
+}return Math.max(0,val);
+}return jQuery.curCSS(elem,name,force);
+},curCSS:function(elem,name,force){var ret,style=elem.style;
+function color(elem){if(!jQuery.browser.safari){return false;
+}var ret=defaultView.getComputedStyle(elem,null);
+return !ret||ret.getPropertyValue("color")=="";
+}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(style,"opacity");
+return ret==""?"1":ret;
+}if(jQuery.browser.opera&&name=="display"){var save=style.outline;
+style.outline="0 solid black";
+style.outline=save;
+}if(name.match(/float/i)){name=styleFloat;
+}if(!force&&style&&style[name]){ret=style[name];
+}else{if(defaultView.getComputedStyle){if(name.match(/float/i)){name="float";
+}name=name.replace(/([A-Z])/g,"-$1").toLowerCase();
+var computedStyle=defaultView.getComputedStyle(elem,null);
+if(computedStyle&&!color(elem)){ret=computedStyle.getPropertyValue(name);
+}else{var swap=[],stack=[],a=elem,i=0;
+for(;
+a&&color(a);
+a=a.parentNode){stack.unshift(a);
+}for(;
+i<stack.length;
+i++){if(color(stack[i])){swap[i]=stack[i].style.display;
+stack[i].style.display="block";
+}}ret=name=="display"&&swap[stack.length-1]!=null?"none":(computedStyle&&computedStyle.getPropertyValue(name))||"";
+for(i=0;
+i<swap.length;
+i++){if(swap[i]!=null){stack[i].style.display=swap[i];
+}}}if(name=="opacity"&&ret==""){ret="1";
+}}else{if(elem.currentStyle){var camelCase=name.replace(/\-(\w)/g,function(all,letter){return letter.toUpperCase();
+});
+ret=elem.currentStyle[name]||elem.currentStyle[camelCase];
+if(!/^\d+(px)?$/i.test(ret)&&/^\d/.test(ret)){var left=style.left,rsLeft=elem.runtimeStyle.left;
+elem.runtimeStyle.left=elem.currentStyle.left;
+style.left=ret||0;
+ret=style.pixelLeft+"px";
+style.left=left;
+elem.runtimeStyle.left=rsLeft;
+}}}}return ret;
+},clean:function(elems,context){var ret=[];
+context=context||document;
+if(typeof context.createElement=="undefined"){context=context.ownerDocument||context[0]&&context[0].ownerDocument||document;
+}jQuery.each(elems,function(i,elem){if(!elem){return ;
+}if(elem.constructor==Number){elem+="";
+}if(typeof elem=="string"){elem=elem.replace(/(<(\w+)[^>]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+"></"+tag+">";
+});
+var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");
+var wrap=!tags.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!tags.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!tags.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!tags.indexOf("<td")||!tags.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!tags.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||jQuery.browser.msie&&[1,"div<div>","</div>"]||[0,"",""];
+div.innerHTML=wrap[1]+elem+wrap[2];
+while(wrap[0]--){div=div.lastChild;
+}if(jQuery.browser.msie){var tbody=!tags.indexOf("<table")&&tags.indexOf("<tbody")<0?div.firstChild&&div.firstChild.childNodes:wrap[1]=="<table>"&&tags.indexOf("<tbody")<0?div.childNodes:[];
+for(var j=tbody.length-1;
+j>=0;
+--j){if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length){tbody[j].parentNode.removeChild(tbody[j]);
+}}if(/^\s/.test(elem)){div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);
+}}elem=jQuery.makeArray(div.childNodes);
+}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select"))){return ;
+}if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options){ret.push(elem);
+}else{ret=jQuery.merge(ret,elem);
+}});
+return ret;
+},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8){return undefined;
+}var notxml=!jQuery.isXMLDoc(elem),set=value!==undefined,msie=jQuery.browser.msie;
+name=notxml&&jQuery.props[name]||name;
+if(elem.tagName){var special=/href|src|style/.test(name);
+if(name=="selected"&&jQuery.browser.safari){elem.parentNode.selectedIndex;
+}if(name in elem&&notxml&&!special){if(set){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode){throw"type property can't be changed";
+}elem[name]=value;
+}if(jQuery.nodeName(elem,"form")&&elem.getAttributeNode(name)){return elem.getAttributeNode(name).nodeValue;
+}return elem[name];
+}if(msie&&notxml&&name=="style"){return jQuery.attr(elem.style,"cssText",value);
+}if(set){elem.setAttribute(name,""+value);
+}var attr=msie&&notxml&&special?elem.getAttribute(name,2):elem.getAttribute(name);
+return attr===null?undefined:attr;
+}if(msie&&name=="opacity"){if(set){elem.zoom=1;
+elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(value)+""=="NaN"?"":"alpha(opacity="+value*100+")");
+}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100)+"":"";
+}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();
+});
+if(set){elem[name]=value;
+}return elem[name];
+},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");
+},makeArray:function(array){var ret=[];
+if(array!=null){var i=array.length;
+if(i==null||array.split||array.setInterval||array.call){ret[0]=array;
+}else{while(i){ret[--i]=array[i];
+}}}return ret;
+},inArray:function(elem,array){for(var i=0,length=array.length;
+i<length;
+i++){if(array[i]===elem){return i;
+}}return -1;
+},merge:function(first,second){var i=0,elem,pos=first.length;
+if(jQuery.browser.msie){while(elem=second[i++]){if(elem.nodeType!=8){first[pos++]=elem;
+}}}else{while(elem=second[i++]){first[pos++]=elem;
+}}return first;
+},unique:function(array){var ret=[],done={};
+try{for(var i=0,length=array.length;
+i<length;
+i++){var id=jQuery.data(array[i]);
+if(!done[id]){done[id]=true;
+ret.push(array[i]);
+}}}catch(e){ret=array;
+}return ret;
+},grep:function(elems,callback,inv){var ret=[];
+for(var i=0,length=elems.length;
+i<length;
+i++){if(!inv!=!callback(elems[i],i)){ret.push(elems[i]);
+}}return ret;
+},map:function(elems,callback){var ret=[];
+for(var i=0,length=elems.length;
+i<length;
+i++){var value=callback(elems[i],i);
+if(value!=null){ret[ret.length]=value;
+}}return ret.concat.apply([],ret);
+}});
+var userAgent=navigator.userAgent.toLowerCase();
+jQuery.browser={version:(userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[])[1],safari:/webkit/.test(userAgent),opera:/opera/.test(userAgent),msie:/msie/.test(userAgent)&&!/opera/.test(userAgent),mozilla:/mozilla/.test(userAgent)&&!/(compatible|webkit)/.test(userAgent)};
+var styleFloat=jQuery.browser.msie?"styleFloat":"cssFloat";
+jQuery.extend({boxModel:!jQuery.browser.msie||document.compatMode=="CSS1Compat",props:{"for":"htmlFor","class":"className","float":styleFloat,cssFloat:styleFloat,styleFloat:styleFloat,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing"}});
+jQuery.each({parent:function(elem){return elem.parentNode;
+},parents:function(elem){return jQuery.dir(elem,"parentNode");
+},next:function(elem){return jQuery.nth(elem,2,"nextSibling");
+},prev:function(elem){return jQuery.nth(elem,2,"previousSibling");
+},nextAll:function(elem){return jQuery.dir(elem,"nextSibling");
+},prevAll:function(elem){return jQuery.dir(elem,"previousSibling");
+},siblings:function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);
+},children:function(elem){return jQuery.sibling(elem.firstChild);
+},contents:function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);
+}},function(name,fn){jQuery.fn[name]=function(selector){var ret=jQuery.map(this,fn);
+if(selector&&typeof selector=="string"){ret=jQuery.multiFilter(selector,ret);
+}return this.pushStack(jQuery.unique(ret));
+};
+});
+jQuery.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(name,original){jQuery.fn[name]=function(){var args=arguments;
+return this.each(function(){for(var i=0,length=args.length;
+i<length;
+i++){jQuery(args[i])[original](this);
+}});
+};
+});
+jQuery.each({removeAttr:function(name){jQuery.attr(this,name,"");
+if(this.nodeType==1){this.removeAttribute(name);
+}},addClass:function(classNames){jQuery.className.add(this,classNames);
+},removeClass:function(classNames){jQuery.className.remove(this,classNames);
+},toggleClass:function(classNames){jQuery.className[jQuery.className.has(this,classNames)?"remove":"add"](this,classNames);
+},remove:function(selector){if(!selector||jQuery.filter(selector,[this]).r.length){jQuery("*",this).add(this).each(function(){jQuery.event.remove(this);
+jQuery.removeData(this);
+});
+if(this.parentNode){this.parentNode.removeChild(this);
+}}},empty:function(){jQuery(">*",this).remove();
+while(this.firstChild){this.removeChild(this.firstChild);
+}}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);
+};
+});
+jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();
+jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");
+};
+});
+function num(elem,prop){return elem[0]&&parseInt(jQuery.curCSS(elem[0],prop,true),10)||0;
+}var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");
+jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);
+},"#":function(a,i,m){return a.getAttribute("id")==m[2];
+},":":{lt:function(a,i,m){return i<m[3]-0;
+},gt:function(a,i,m){return i>m[3]-0;
+},nth:function(a,i,m){return m[3]-0==i;
+},eq:function(a,i,m){return m[3]-0==i;
+},first:function(a,i){return i==0;
+},last:function(a,i,m,r){return i==r.length-1;
+},even:function(a,i){return i%2==0;
+},odd:function(a,i){return i%2;
+},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;
+},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;
+},"only-child":function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");
+},parent:function(a){return a.firstChild;
+},empty:function(a){return !a.firstChild;
+},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;
+},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";
+},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";
+},enabled:function(a){return !a.disabled;
+},disabled:function(a){return a.disabled;
+},checked:function(a){return a.checked;
+},selected:function(a){return a.selected||jQuery.attr(a,"selected");
+},text:function(a){return"text"==a.type;
+},radio:function(a){return"radio"==a.type;
+},checkbox:function(a){return"checkbox"==a.type;
+},file:function(a){return"file"==a.type;
+},password:function(a){return"password"==a.type;
+},submit:function(a){return"submit"==a.type;
+},image:function(a){return"image"==a.type;
+},reset:function(a){return"reset"==a.type;
+},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");
+},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);
+},has:function(a,i,m){return jQuery.find(m[3],a).length;
+},header:function(a){return/h\d/i.test(a.nodeName);
+},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;
+}).length;
+}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];
+while(expr&&expr!=old){old=expr;
+var f=jQuery.filter(expr,elems,not);
+expr=f.t.replace(/^\s*,\s*/,"");
+cur=not?elems=f.r:jQuery.merge(cur,f.r);
+}return cur;
+},find:function(t,context){if(typeof t!="string"){return[t];
+}if(context&&context.nodeType!=1&&context.nodeType!=9){return[];
+}context=context||document;
+var ret=[context],done=[],last,nodeName;
+while(t&&last!=t){var r=[];
+last=t;
+t=jQuery.trim(t);
+var foundToken=false,re=quickChild,m=re.exec(t);
+if(m){nodeName=m[1].toUpperCase();
+for(var i=0;
+ret[i];
+i++){for(var c=ret[i].firstChild;
+c;
+c=c.nextSibling){if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName)){r.push(c);
+}}}ret=r;
+t=t.replace(re,"");
+if(t.indexOf(" ")==0){continue;
+}foundToken=true;
+}else{re=/^([>+~])\s*(\w*)/i;
+if((m=re.exec(t))!=null){r=[];
+var merge={};
+nodeName=m[2].toUpperCase();
+m=m[1];
+for(var j=0,rl=ret.length;
+j<rl;
+j++){var n=m=="~"||m=="+"?ret[j].nextSibling:ret[j].firstChild;
+for(;
+n;
+n=n.nextSibling){if(n.nodeType==1){var id=jQuery.data(n);
+if(m=="~"&&merge[id]){break;
+}if(!nodeName||n.nodeName.toUpperCase()==nodeName){if(m=="~"){merge[id]=true;
+}r.push(n);
+}if(m=="+"){break;
+}}}}ret=r;
+t=jQuery.trim(t.replace(re,""));
+foundToken=true;
+}}if(t&&!foundToken){if(!t.indexOf(",")){if(context==ret[0]){ret.shift();
+}done=jQuery.merge(done,ret);
+r=ret=[context];
+t=" "+t.substr(1,t.length);
+}else{var re2=quickID;
+var m=re2.exec(t);
+if(m){m=[0,m[2],m[3],m[1]];
+}else{re2=quickClass;
+m=re2.exec(t);
+}m[2]=m[2].replace(/\\/g,"");
+var elem=ret[ret.length-1];
+if(m[1]=="#"&&elem&&elem.getElementById&&!jQuery.isXMLDoc(elem)){var oid=elem.getElementById(m[2]);
+if((jQuery.browser.msie||jQuery.browser.opera)&&oid&&typeof oid.id=="string"&&oid.id!=m[2]){oid=jQuery('[@id="'+m[2]+'"]',elem)[0];
+}ret=r=oid&&(!m[3]||jQuery.nodeName(oid,m[3]))?[oid]:[];
+}else{for(var i=0;
+ret[i];
+i++){var tag=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];
+if(tag=="*"&&ret[i].nodeName.toLowerCase()=="object"){tag="param";
+}r=jQuery.merge(r,ret[i].getElementsByTagName(tag));
+}if(m[1]=="."){r=jQuery.classFilter(r,m[2]);
+}if(m[1]=="#"){var tmp=[];
+for(var i=0;
+r[i];
+i++){if(r[i].getAttribute("id")==m[2]){tmp=[r[i]];
+break;
+}}r=tmp;
+}ret=r;
+}t=t.replace(re2,"");
+}}if(t){var val=jQuery.filter(t,r);
+ret=r=val.r;
+t=jQuery.trim(val.t);
+}}if(t){ret=[];
+}if(ret&&context==ret[0]){ret.shift();
+}done=jQuery.merge(done,ret);
+return done;
+},classFilter:function(r,m,not){m=" "+m+" ";
+var tmp=[];
+for(var i=0;
+r[i];
+i++){var pass=(" "+r[i].className+" ").indexOf(m)>=0;
+if(!not&&pass||not&&!pass){tmp.push(r[i]);
+}}return tmp;
+},filter:function(t,r,not){var last;
+while(t&&t!=last){last=t;
+var p=jQuery.parse,m;
+for(var i=0;
+p[i];
+i++){m=p[i].exec(t);
+if(m){t=t.substring(m[0].length);
+m[2]=m[2].replace(/\\/g,"");
+break;
+}}if(!m){break;
+}if(m[1]==":"&&m[2]=="not"){r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);
+}else{if(m[1]=="."){r=jQuery.classFilter(r,m[2],not);
+}else{if(m[1]=="["){var tmp=[],type=m[3];
+for(var i=0,rl=r.length;
+i<rl;
+i++){var a=r[i],z=a[jQuery.props[m[2]]||m[2]];
+if(z==null||/href|src|selected/.test(m[2])){z=jQuery.attr(a,m[2])||"";
+}if((type==""&&!!z||type=="="&&z==m[5]||type=="!="&&z!=m[5]||type=="^="&&z&&!z.indexOf(m[5])||type=="$="&&z.substr(z.length-m[5].length)==m[5]||(type=="*="||type=="~=")&&z.indexOf(m[5])>=0)^not){tmp.push(a);
+}}r=tmp;
+}else{if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;
+for(var i=0,rl=r.length;
+i<rl;
+i++){var node=r[i],parentNode=node.parentNode,id=jQuery.data(parentNode);
+if(!merge[id]){var c=1;
+for(var n=parentNode.firstChild;
+n;
+n=n.nextSibling){if(n.nodeType==1){n.nodeIndex=c++;
+}}merge[id]=true;
+}var add=false;
+if(first==0){if(node.nodeIndex==last){add=true;
+}}else{if((node.nodeIndex-last)%first==0&&(node.nodeIndex-last)/first>=0){add=true;
+}}if(add^not){tmp.push(node);
+}}r=tmp;
+}else{var fn=jQuery.expr[m[1]];
+if(typeof fn=="object"){fn=fn[m[2]];
+}if(typeof fn=="string"){fn=eval("false||function(a,i){return "+fn+";}");
+}r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);
+},not);
+}}}}}return{r:r,t:t};
+},dir:function(elem,dir){var matched=[],cur=elem[dir];
+while(cur&&cur!=document){if(cur.nodeType==1){matched.push(cur);
+}cur=cur[dir];
+}return matched;
+},nth:function(cur,result,dir,elem){result=result||1;
+var num=0;
+for(;
+cur;
+cur=cur[dir]){if(cur.nodeType==1&&++num==result){break;
+}}return cur;
+},sibling:function(n,elem){var r=[];
+for(;
+n;
+n=n.nextSibling){if(n.nodeType==1&&n!=elem){r.push(n);
+}}return r;
+}});
+jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8){return ;
+}if(jQuery.browser.msie&&elem.setInterval){elem=window;
+}if(!handler.guid){handler.guid=this.guid++;
+}if(data!=undefined){var fn=handler;
+handler=this.proxy(fn,function(){return fn.apply(this,arguments);
+});
+handler.data=data;
+}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){if(typeof jQuery!="undefined"&&!jQuery.event.triggered){return jQuery.event.handle.apply(arguments.callee.elem,arguments);
+}});
+handle.elem=elem;
+jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");
+type=parts[0];
+handler.type=parts[1];
+var handlers=events[type];
+if(!handlers){handlers=events[type]={};
+if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener){elem.addEventListener(type,handle,false);
+}else{if(elem.attachEvent){elem.attachEvent("on"+type,handle);
+}}}}handlers[handler.guid]=handler;
+jQuery.event.global[type]=true;
+});
+elem=null;
+},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8){return ;
+}var events=jQuery.data(elem,"events"),ret,index;
+if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)==".")){for(var type in events){this.remove(elem,type+(types||""));
+}}else{if(types.type){handler=types.handler;
+types=types.type;
+}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");
+type=parts[0];
+if(events[type]){if(handler){delete events[type][handler.guid];
+}else{for(handler in events[type]){if(!parts[1]||events[type][handler].type==parts[1]){delete events[type][handler];
+}}}for(ret in events[type]){break;
+}if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener){elem.removeEventListener(type,jQuery.data(elem,"handle"),false);
+}else{if(elem.detachEvent){elem.detachEvent("on"+type,jQuery.data(elem,"handle"));
+}}}ret=null;
+delete events[type];
+}}});
+}for(ret in events){break;
+}if(!ret){var handle=jQuery.data(elem,"handle");
+if(handle){handle.elem=null;
+}jQuery.removeData(elem,"events");
+jQuery.removeData(elem,"handle");
+}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data);
+if(type.indexOf("!")>=0){type=type.slice(0,-1);
+var exclusive=true;
+}if(!elem){if(this.global[type]){jQuery("*").add([window,document]).trigger(type,data);
+}}else{if(elem.nodeType==3||elem.nodeType==8){return undefined;
+}var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;
+if(event){data.unshift({type:type,target:elem,preventDefault:function(){},stopPropagation:function(){},timeStamp:now()});
+data[0][expando]=true;
+}data[0].type=type;
+if(exclusive){data[0].exclusive=true;
+}var handle=jQuery.data(elem,"handle");
+if(handle){val=handle.apply(elem,data);
+}if((!fn||(jQuery.nodeName(elem,"a")&&type=="click"))&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false){val=false;
+}if(event){data.shift();
+}if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));
+if(ret!==undefined){val=ret;
+}}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,"a")&&type=="click")){this.triggered=true;
+try{elem[type]();
+}catch(e){}}this.triggered=false;
+}return val;
+},handle:function(event){var val,ret,namespace,all,handlers;
+event=arguments[0]=jQuery.event.fix(event||window.event);
+namespace=event.type.split(".");
+event.type=namespace[0];
+namespace=namespace[1];
+all=!namespace&&!event.exclusive;
+handlers=(jQuery.data(this,"events")||{})[event.type];
+for(var j in handlers){var handler=handlers[j];
+if(all||handler.type==namespace){event.handler=handler;
+event.data=handler.data;
+ret=handler.apply(this,arguments);
+if(val!==false){val=ret;
+}if(ret===false){event.preventDefault();
+event.stopPropagation();
+}}}return val;
+},fix:function(event){if(event[expando]==true){return event;
+}var originalEvent=event;
+event={originalEvent:originalEvent};
+var props="altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");
+for(var i=props.length;
+i;
+i--){event[props[i]]=originalEvent[props[i]];
+}event[expando]=true;
+event.preventDefault=function(){if(originalEvent.preventDefault){originalEvent.preventDefault();
+}originalEvent.returnValue=false;
+};
+event.stopPropagation=function(){if(originalEvent.stopPropagation){originalEvent.stopPropagation();
+}originalEvent.cancelBubble=true;
+};
+event.timeStamp=event.timeStamp||now();
+if(!event.target){event.target=event.srcElement||document;
+}if(event.target.nodeType==3){event.target=event.target.parentNode;
+}if(!event.relatedTarget&&event.fromElement){event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;
+}if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;
+event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);
+event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);
+}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode)){event.which=event.charCode||event.keyCode;
+}if(!event.metaKey&&event.ctrlKey){event.metaKey=event.ctrlKey;
+}if(!event.which&&event.button){event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));
+}return event;
+},proxy:function(fn,proxy){proxy.guid=fn.guid=fn.guid||proxy.guid||this.guid++;
+return proxy;
+},special:{ready:{setup:function(){bindReady();
+return ;
+},teardown:function(){return ;
+}},mouseenter:{setup:function(){if(jQuery.browser.msie){return false;
+}jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);
+return true;
+},teardown:function(){if(jQuery.browser.msie){return false;
+}jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);
+return true;
+},handler:function(event){if(withinElement(event,this)){return true;
+}event.type="mouseenter";
+return jQuery.event.handle.apply(this,arguments);
+}},mouseleave:{setup:function(){if(jQuery.browser.msie){return false;
+}jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);
+return true;
+},teardown:function(){if(jQuery.browser.msie){return false;
+}jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);
+return true;
+},handler:function(event){if(withinElement(event,this)){return true;
+}event.type="mouseleave";
+return jQuery.event.handle.apply(this,arguments);
+}}}};
+jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);
+});
+},one:function(type,data,fn){var one=jQuery.event.proxy(fn||data,function(event){jQuery(this).unbind(event,one);
+return(fn||data).apply(this,arguments);
+});
+return this.each(function(){jQuery.event.add(this,type,one,fn&&data);
+});
+},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);
+});
+},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);
+});
+},triggerHandler:function(type,data,fn){return this[0]&&jQuery.event.trigger(type,data,this[0],false,fn);
+},toggle:function(fn){var args=arguments,i=1;
+while(i<args.length){jQuery.event.proxy(fn,args[i++]);
+}return this.click(jQuery.event.proxy(fn,function(event){this.lastToggle=(this.lastToggle||0)%i;
+event.preventDefault();
+return args[this.lastToggle++].apply(this,arguments)||false;
+}));
+},hover:function(fnOver,fnOut){return this.bind("mouseenter",fnOver).bind("mouseleave",fnOut);
+},ready:function(fn){bindReady();
+if(jQuery.isReady){fn.call(document,jQuery);
+}else{jQuery.readyList.push(function(){return fn.call(this,jQuery);
+});
+}return this;
+}});
+jQuery.extend({isReady:false,readyList:[],ready:function(){if(!jQuery.isReady){jQuery.isReady=true;
+if(jQuery.readyList){jQuery.each(jQuery.readyList,function(){this.call(document);
+});
+jQuery.readyList=null;
+}jQuery(document).triggerHandler("ready");
+}}});
+var readyBound=false;
+function bindReady(){if(readyBound){return ;
+}readyBound=true;
+if(document.addEventListener&&!jQuery.browser.opera){document.addEventListener("DOMContentLoaded",jQuery.ready,false);
+}if(jQuery.browser.msie&&window==top){(function(){if(jQuery.isReady){return ;
+}try{document.documentElement.doScroll("left");
+}catch(error){setTimeout(arguments.callee,0);
+return ;
+}jQuery.ready();
+})();
+}if(jQuery.browser.opera){document.addEventListener("DOMContentLoaded",function(){if(jQuery.isReady){return ;
+}for(var i=0;
+i<document.styleSheets.length;
+i++){if(document.styleSheets[i].disabled){setTimeout(arguments.callee,0);
+return ;
+}}jQuery.ready();
+},false);
+}if(jQuery.browser.safari){var numStyles;
+(function(){if(jQuery.isReady){return ;
+}if(document.readyState!="loaded"&&document.readyState!="complete"){setTimeout(arguments.callee,0);
+return ;
+}if(numStyles===undefined){numStyles=jQuery("style, link[rel=stylesheet]").length;
+}if(document.styleSheets.length!=numStyles){setTimeout(arguments.callee,0);
+return ;
+}jQuery.ready();
+})();
+}jQuery.event.add(window,"load",jQuery.ready);
+}jQuery.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,change,select,submit,keydown,keypress,keyup,error").split(","),function(i,name){jQuery.fn[name]=function(fn){return fn?this.bind(name,fn):this.trigger(name);
+};
+});
+var withinElement=function(event,elem){var parent=event.relatedTarget;
+while(parent&&parent!=elem){try{parent=parent.parentNode;
+}catch(error){parent=elem;
+}}return parent==elem;
+};
+jQuery(window).bind("unload",function(){jQuery("*").add(document).unbind();
+});
+jQuery.fn.extend({_load:jQuery.fn.load,load:function(url,params,callback){if(typeof url!="string"){return this._load(url);
+}var off=url.indexOf(" ");
+if(off>=0){var selector=url.slice(off,url.length);
+url=url.slice(0,off);
+}callback=callback||function(){};
+var type="GET";
+if(params){if(jQuery.isFunction(params)){callback=params;
+params=null;
+}else{params=jQuery.param(params);
+type="POST";
+}}var self=this;
+jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified"){self.html(selector?jQuery("<div/>").append(res.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(selector):res.responseText);
+}self.each(callback,[res.responseText,status,res]);
+}});
+return this;
+},serialize:function(){return jQuery.param(this.serializeArray());
+},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;
+}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));
+}).map(function(i,elem){var val=jQuery(this).val();
+return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};
+}):{name:elem.name,value:val};
+}).get();
+}});
+jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);
+};
+});
+var jsc=now();
+jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;
+data=null;
+}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});
+},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");
+},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");
+},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;
+data={};
+}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});
+},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);
+},ajaxSettings:{url:location.href,global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));
+var jsonp,jsre=/=\?(&|$)/g,status,data,type=s.type.toUpperCase();
+if(s.data&&s.processData&&typeof s.data!="string"){s.data=jQuery.param(s.data);
+}if(s.dataType=="jsonp"){if(type=="GET"){if(!s.url.match(jsre)){s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";
+}}else{if(!s.data||!s.data.match(jsre)){s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";
+}}s.dataType="json";
+}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;
+if(s.data){s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");
+}s.url=s.url.replace(jsre,"="+jsonp+"$1");
+s.dataType="script";
+window[jsonp]=function(tmp){data=tmp;
+success();
+complete();
+window[jsonp]=undefined;
+try{delete window[jsonp];
+}catch(e){}if(head){head.removeChild(script);
+}};
+}if(s.dataType=="script"&&s.cache==null){s.cache=false;
+}if(s.cache===false&&type=="GET"){var ts=now();
+var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");
+s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");
+}if(s.data&&type=="GET"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;
+s.data=null;
+}if(s.global&&!jQuery.active++){jQuery.event.trigger("ajaxStart");
+}var remote=/^(?:\w+:)?\/\/([^\/?#]+)/;
+if(s.dataType=="script"&&type=="GET"&&remote.test(s.url)&&remote.exec(s.url)[1]!=location.host){var head=document.getElementsByTagName("head")[0];
+var script=document.createElement("script");
+script.src=s.url;
+if(s.scriptCharset){script.charset=s.scriptCharset;
+}if(!jsonp){var done=false;
+script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;
+success();
+complete();
+head.removeChild(script);
+}};
+}head.appendChild(script);
+return undefined;
+}var requestDone=false;
+var xhr=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();
+if(s.username){xhr.open(type,s.url,s.async,s.username,s.password);
+}else{xhr.open(type,s.url,s.async);
+}try{if(s.data){xhr.setRequestHeader("Content-Type",s.contentType);
+}if(s.ifModified){xhr.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");
+}xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");
+xhr.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);
+}catch(e){}if(s.beforeSend&&s.beforeSend(xhr,s)===false){s.global&&jQuery.active--;
+xhr.abort();
+return false;
+}if(s.global){jQuery.event.trigger("ajaxSend",[xhr,s]);
+}var onreadystatechange=function(isTimeout){if(!requestDone&&xhr&&(xhr.readyState==4||isTimeout=="timeout")){requestDone=true;
+if(ival){clearInterval(ival);
+ival=null;
+}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xhr)&&"error"||s.ifModified&&jQuery.httpNotModified(xhr,s.url)&&"notmodified"||"success";
+if(status=="success"){try{data=jQuery.httpData(xhr,s.dataType,s.dataFilter);
+}catch(e){status="parsererror";
+}}if(status=="success"){var modRes;
+try{modRes=xhr.getResponseHeader("Last-Modified");
+}catch(e){}if(s.ifModified&&modRes){jQuery.lastModified[s.url]=modRes;
+}if(!jsonp){success();
+}}else{jQuery.handleError(s,xhr,status);
+}complete();
+if(s.async){xhr=null;
+}}};
+if(s.async){var ival=setInterval(onreadystatechange,13);
+if(s.timeout>0){setTimeout(function(){if(xhr){xhr.abort();
+if(!requestDone){onreadystatechange("timeout");
+}}},s.timeout);
+}}try{xhr.send(s.data);
+}catch(e){jQuery.handleError(s,xhr,null,e);
+}if(!s.async){onreadystatechange();
+}function success(){if(s.success){s.success(data,status);
+}if(s.global){jQuery.event.trigger("ajaxSuccess",[xhr,s]);
+}}function complete(){if(s.complete){s.complete(xhr,status);
+}if(s.global){jQuery.event.trigger("ajaxComplete",[xhr,s]);
+}if(s.global&&!--jQuery.active){jQuery.event.trigger("ajaxStop");
+}}return xhr;
+},handleError:function(s,xhr,status,e){if(s.error){s.error(xhr,status,e);
+}if(s.global){jQuery.event.trigger("ajaxError",[xhr,s,e]);
+}},active:0,httpSuccess:function(xhr){try{return !xhr.status&&location.protocol=="file:"||(xhr.status>=200&&xhr.status<300)||xhr.status==304||xhr.status==1223||jQuery.browser.safari&&xhr.status==undefined;
+}catch(e){}return false;
+},httpNotModified:function(xhr,url){try{var xhrRes=xhr.getResponseHeader("Last-Modified");
+return xhr.status==304||xhrRes==jQuery.lastModified[url]||jQuery.browser.safari&&xhr.status==undefined;
+}catch(e){}return false;
+},httpData:function(xhr,type,filter){var ct=xhr.getResponseHeader("content-type"),xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0,data=xml?xhr.responseXML:xhr.responseText;
+if(xml&&data.documentElement.tagName=="parsererror"){throw"parsererror";
+}if(filter){data=filter(data,type);
+}if(type=="script"){jQuery.globalEval(data);
+}if(type=="json"){data=eval("("+data+")");
+}return data;
+},param:function(a){var s=[];
+if(a.constructor==Array||a.jquery){jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));
+});
+}else{for(var j in a){if(a[j]&&a[j].constructor==Array){jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));
+});
+}else{s.push(encodeURIComponent(j)+"="+encodeURIComponent(jQuery.isFunction(a[j])?a[j]():a[j]));
+}}}return s.join("&").replace(/%20/g,"+");
+}});
+jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";
+if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");
+this.style.display=elem.css("display");
+if(this.style.display=="none"){this.style.display="block";
+}elem.remove();
+}}).end();
+},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");
+this.style.display="none";
+}).end();
+},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle.apply(this,arguments):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();
+});
+},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);
+},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);
+},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);
+},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);
+},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);
+},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);
+},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);
+return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1){return false;
+}var opt=jQuery.extend({},optall),p,hidden=jQuery(this).is(":hidden"),self=this;
+for(p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden){return opt.complete.call(this);
+}if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");
+opt.overflow=this.style.overflow;
+}}if(opt.overflow!=null){this.style.overflow="hidden";
+}opt.curAnim=jQuery.extend({},prop);
+jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);
+if(/toggle|show|hide/.test(val)){e[val=="toggle"?hidden?"show":"hide":val](prop);
+}else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;
+if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";
+if(unit!="px"){self.style[name]=(end||1)+unit;
+start=((end||1)/e.cur(true))*start;
+self.style[name]=start+unit;
+}if(parts[1]){end=((parts[1]=="-="?-1:1)*end)+start;
+}e.custom(start,end,unit);
+}else{e.custom(start,val,"");
+}}});
+return true;
+});
+},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;
+type="fx";
+}if(!type||(typeof type=="string"&&!fn)){return queue(this[0],type);
+}return this.each(function(){if(fn.constructor==Array){queue(this,type,fn);
+}else{queue(this,type).push(fn);
+if(queue(this,type).length==1){fn.call(this);
+}}});
+},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;
+if(clearQueue){this.queue([]);
+}this.each(function(){for(var i=timers.length-1;
+i>=0;
+i--){if(timers[i].elem==this){if(gotoEnd){timers[i](true);
+}timers.splice(i,1);
+}}});
+if(!gotoEnd){this.dequeue();
+}return this;
+}});
+var queue=function(elem,type,array){if(elem){type=type||"fx";
+var q=jQuery.data(elem,type+"queue");
+if(!q||array){q=jQuery.data(elem,type+"queue",jQuery.makeArray(array));
+}}return q;
+};
+jQuery.fn.dequeue=function(type){type=type||"fx";
+return this.each(function(){var q=queue(this,type);
+q.shift();
+if(q.length){q[0].call(this);
+}});
+};
+jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};
+opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:jQuery.fx.speeds[opt.duration])||jQuery.fx.speeds.def;
+opt.old=opt.complete;
+opt.complete=function(){if(opt.queue!==false){jQuery(this).dequeue();
+}if(jQuery.isFunction(opt.old)){opt.old.call(this);
+}};
+return opt;
+},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;
+},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;
+}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;
+this.elem=elem;
+this.prop=prop;
+if(!options.orig){options.orig={};
+}}});
+jQuery.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this);
+}(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);
+if(this.prop=="height"||this.prop=="width"){this.elem.style.display="block";
+}},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null){return this.elem[this.prop];
+}var r=parseFloat(jQuery.css(this.elem,this.prop,force));
+return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;
+},custom:function(from,to,unit){this.startTime=now();
+this.start=from;
+this.end=to;
+this.unit=unit||this.unit||"px";
+this.now=this.start;
+this.pos=this.state=0;
+this.update();
+var self=this;
+function t(gotoEnd){return self.step(gotoEnd);
+}t.elem=this.elem;
+jQuery.timers.push(t);
+if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;
+for(var i=0;
+i<timers.length;
+i++){if(!timers[i]()){timers.splice(i--,1);
+}}if(!timers.length){clearInterval(jQuery.timerId);
+jQuery.timerId=null;
+}},13);
+}},show:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);
+this.options.show=true;
+this.custom(0,this.cur());
+if(this.prop=="width"||this.prop=="height"){this.elem.style[this.prop]="1px";
+}jQuery(this.elem).show();
+},hide:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);
+this.options.hide=true;
+this.custom(this.cur(),0);
+},step:function(gotoEnd){var t=now();
+if(gotoEnd||t>this.options.duration+this.startTime){this.now=this.end;
+this.pos=this.state=1;
+this.update();
+this.options.curAnim[this.prop]=true;
+var done=true;
+for(var i in this.options.curAnim){if(this.options.curAnim[i]!==true){done=false;
+}}if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;
+this.elem.style.display=this.options.display;
+if(jQuery.css(this.elem,"display")=="none"){this.elem.style.display="block";
+}}if(this.options.hide){this.elem.style.display="none";
+}if(this.options.hide||this.options.show){for(var p in this.options.curAnim){jQuery.attr(this.elem.style,p,this.options.orig[p]);
+}}}if(done){this.options.complete.call(this.elem);
+}return false;
+}else{var n=t-this.startTime;
+this.state=n/this.options.duration;
+this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);
+this.now=this.start+((this.end-this.start)*this.pos);
+this.update();
+}return true;
+}};
+jQuery.extend(jQuery.fx,{speeds:{slow:600,fast:200,def:400},step:{scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;
+},scrollTop:function(fx){fx.elem.scrollTop=fx.now;
+},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);
+},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;
+}}});
+jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;
+if(elem){with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),css=jQuery.curCSS,fixed=css(elem,"position")=="fixed";
+if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();
+add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));
+add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);
+}else{add(elem.offsetLeft,elem.offsetTop);
+while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);
+if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2){border(offsetParent);
+}if(!fixed&&css(offsetParent,"position")=="fixed"){fixed=true;
+}offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;
+offsetParent=offsetParent.offsetParent;
+}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(css(parent,"display"))){add(-parent.scrollLeft,-parent.scrollTop);
+}if(mozilla&&css(parent,"overflow")!="visible"){border(parent);
+}parent=parent.parentNode;
+}if((safari2&&(fixed||css(offsetChild,"position")=="absolute"))||(mozilla&&css(offsetChild,"position")!="absolute")){add(-doc.body.offsetLeft,-doc.body.offsetTop);
+}if(fixed){add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));
+}}results={top:top,left:left};
+}}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));
+}function add(l,t){left+=parseInt(l,10)||0;
+top+=parseInt(t,10)||0;
+}return results;
+};
+jQuery.fn.extend({position:function(){var left=0,top=0,results;
+if(this[0]){var offsetParent=this.offsetParent(),offset=this.offset(),parentOffset=/^body|html$/i.test(offsetParent[0].tagName)?{top:0,left:0}:offsetParent.offset();
+offset.top-=num(this,"marginTop");
+offset.left-=num(this,"marginLeft");
+parentOffset.top+=num(offsetParent,"borderTopWidth");
+parentOffset.left+=num(offsetParent,"borderLeftWidth");
+results={top:offset.top-parentOffset.top,left:offset.left-parentOffset.left};
+}return results;
+},offsetParent:function(){var offsetParent=this[0].offsetParent;
+while(offsetParent&&(!/^body|html$/i.test(offsetParent.tagName)&&jQuery.css(offsetParent,"position")=="static")){offsetParent=offsetParent.offsetParent;
+}return jQuery(offsetParent);
+}});
+jQuery.each(["Left","Top"],function(i,name){var method="scroll"+name;
+jQuery.fn[method]=function(val){if(!this[0]){return ;
+}return val!=undefined?this.each(function(){this==window||this==document?window.scrollTo(!i?val:jQuery(window).scrollLeft(),i?val:jQuery(window).scrollTop()):this[method]=val;
+}):this[0]==window||this[0]==document?self[i?"pageYOffset":"pageXOffset"]||jQuery.boxModel&&document.documentElement[method]||document.body[method]:this[0][method];
+};
+});
+jQuery.each(["Height","Width"],function(i,name){var tl=i?"Left":"Top",br=i?"Right":"Bottom";
+jQuery.fn["inner"+name]=function(){return this[name.toLowerCase()]()+num(this,"padding"+tl)+num(this,"padding"+br);
+};
+jQuery.fn["outer"+name]=function(margin){return this["inner"+name]()+num(this,"border"+tl+"Width")+num(this,"border"+br+"Width")+(margin?num(this,"margin"+tl)+num(this,"margin"+br):0);
+};
+});
+})();
+
+
+/* platform.js */
+SimileAjax.version="pre 2.3.0";
+SimileAjax.jQuery=jQuery.noConflict(true);
+if(typeof window["$"]=="undefined"){window.$=SimileAjax.jQuery;
+}SimileAjax.Platform.os={isMac:false,isWin:false,isWin32:false,isUnix:false};
+SimileAjax.Platform.browser={isIE:false,isNetscape:false,isMozilla:false,isFirefox:false,isOpera:false,isSafari:false,majorVersion:0,minorVersion:0};
+(function(){var C=navigator.appName.toLowerCase();
+var A=navigator.userAgent.toLowerCase();
+SimileAjax.Platform.os.isMac=(A.indexOf("mac")!=-1);
+SimileAjax.Platform.os.isWin=(A.indexOf("win")!=-1);
+SimileAjax.Platform.os.isWin32=SimileAjax.Platform.isWin&&(A.indexOf("95")!=-1||A.indexOf("98")!=-1||A.indexOf("nt")!=-1||A.indexOf("win32")!=-1||A.indexOf("32bit")!=-1);
+SimileAjax.Platform.os.isUnix=(A.indexOf("x11")!=-1);
+SimileAjax.Platform.browser.isIE=(C.indexOf("microsoft")!=-1);
+SimileAjax.Platform.browser.isNetscape=(C.indexOf("netscape")!=-1);
+SimileAjax.Platform.browser.isMozilla=(A.indexOf("mozilla")!=-1);
+SimileAjax.Platform.browser.isFirefox=(A.indexOf("firefox")!=-1);
+SimileAjax.Platform.browser.isOpera=(C.indexOf("opera")!=-1);
+SimileAjax.Platform.browser.isSafari=(C.indexOf("safari")!=-1);
+var E=function(G){var F=G.split(".");
+SimileAjax.Platform.browser.majorVersion=parseInt(F[0]);
+SimileAjax.Platform.browser.minorVersion=parseInt(F[1]);
+};
+var B=function(H,G,I){var F=H.indexOf(G,I);
+return F>=0?F:H.length;
+};
+if(SimileAjax.Platform.browser.isMozilla){var D=A.indexOf("mozilla/");
+if(D>=0){E(A.substring(D+8,B(A," ",D)));
+}}if(SimileAjax.Platform.browser.isIE){var D=A.indexOf("msie ");
+if(D>=0){E(A.substring(D+5,B(A,";",D)));
+}}if(SimileAjax.Platform.browser.isNetscape){var D=A.indexOf("rv:");
+if(D>=0){E(A.substring(D+3,B(A,")",D)));
+}}if(SimileAjax.Platform.browser.isFirefox){var D=A.indexOf("firefox/");
+if(D>=0){E(A.substring(D+8,B(A," ",D)));
+}}if(!("localeCompare" in String.prototype)){String.prototype.localeCompare=function(F){if(this<F){return -1;
+}else{if(this>F){return 1;
+}else{return 0;
+}}};
+}})();
+SimileAjax.Platform.getDefaultLocale=function(){return SimileAjax.Platform.clientLocale;
+};
+
+
+/* ajax.js */
+SimileAjax.ListenerQueue=function(A){this._listeners=[];
+this._wildcardHandlerName=A;
+};
+SimileAjax.ListenerQueue.prototype.add=function(A){this._listeners.push(A);
+};
+SimileAjax.ListenerQueue.prototype.remove=function(C){var A=this._listeners;
+for(var B=0;
+B<A.length;
+B++){if(A[B]==C){A.splice(B,1);
+break;
+}}};
+SimileAjax.ListenerQueue.prototype.fire=function(C,B){var A=[].concat(this._listeners);
+for(var D=0;
+D<A.length;
+D++){var E=A[D];
+if(C in E){try{E[C].apply(E,B);
+}catch(F){SimileAjax.Debug.exception("Error firing event of name "+C,F);
+}}else{if(this._wildcardHandlerName!=null&&this._wildcardHandlerName in E){try{E[this._wildcardHandlerName].apply(E,[C]);
+}catch(F){SimileAjax.Debug.exception("Error firing event of name "+C+" to wildcard handler",F);
+}}}}};
+
+
+/* data-structure.js */
+SimileAjax.Set=function(A){this._hash={};
+this._count=0;
+if(A instanceof Array){for(var B=0;
+B<A.length;
+B++){this.add(A[B]);
+}}else{if(A instanceof SimileAjax.Set){this.addSet(A);
+}}};
+SimileAjax.Set.prototype.add=function(A){if(!(A in this._hash)){this._hash[A]=true;
+this._count++;
+return true;
+}return false;
+};
+SimileAjax.Set.prototype.addSet=function(B){for(var A in B._hash){this.add(A);
+}};
+SimileAjax.Set.prototype.remove=function(A){if(A in this._hash){delete this._hash[A];
+this._count--;
+return true;
+}return false;
+};
+SimileAjax.Set.prototype.removeSet=function(B){for(var A in B._hash){this.remove(A);
+}};
+SimileAjax.Set.prototype.retainSet=function(B){for(var A in this._hash){if(!B.contains(A)){delete this._hash[A];
+this._count--;
+}}};
+SimileAjax.Set.prototype.contains=function(A){return(A in this._hash);
+};
+SimileAjax.Set.prototype.size=function(){return this._count;
+};
+SimileAjax.Set.prototype.toArray=function(){var A=[];
+for(var B in this._hash){A.push(B);
+}return A;
+};
+SimileAjax.Set.prototype.visit=function(A){for(var B in this._hash){if(A(B)==true){break;
+}}};
+SimileAjax.SortedArray=function(B,A){this._a=(A instanceof Array)?A:[];
+this._compare=B;
+};
+SimileAjax.SortedArray.prototype.add=function(C){var A=this;
+var B=this.find(function(D){return A._compare(D,C);
+});
+if(B<this._a.length){this._a.splice(B,0,C);
+}else{this._a.push(C);
+}};
+SimileAjax.SortedArray.prototype.remove=function(C){var A=this;
+var B=this.find(function(D){return A._compare(D,C);
+});
+while(B<this._a.length&&this._compare(this._a[B],C)==0){if(this._a[B]==C){this._a.splice(B,1);
+return true;
+}else{B++;
+}}return false;
+};
+SimileAjax.SortedArray.prototype.removeAll=function(){this._a=[];
+};
+SimileAjax.SortedArray.prototype.elementAt=function(A){return this._a[A];
+};
+SimileAjax.SortedArray.prototype.length=function(){return this._a.length;
+};
+SimileAjax.SortedArray.prototype.find=function(D){var B=0;
+var A=this._a.length;
+while(B<A){var C=Math.floor((B+A)/2);
+var E=D(this._a[C]);
+if(C==B){return E<0?B+1:B;
+}else{if(E<0){B=C;
+}else{A=C;
+}}}return B;
+};
+SimileAjax.SortedArray.prototype.getFirst=function(){return(this._a.length>0)?this._a[0]:null;
+};
+SimileAjax.SortedArray.prototype.getLast=function(){return(this._a.length>0)?this._a[this._a.length-1]:null;
+};
+SimileAjax.EventIndex=function(B){var A=this;
+this._unit=(B!=null)?B:SimileAjax.NativeDateUnit;
+this._events=new SimileAjax.SortedArray(function(C,D){return A._unit.compare(C.getStart(),D.getStart());
+});
+this._idToEvent={};
+this._indexed=true;
+};
+SimileAjax.EventIndex.prototype.getUnit=function(){return this._unit;
+};
+SimileAjax.EventIndex.prototype.getEvent=function(A){return this._idToEvent[A];
+};
+SimileAjax.EventIndex.prototype.add=function(A){this._events.add(A);
+this._idToEvent[A.getID()]=A;
+this._indexed=false;
+};
+SimileAjax.EventIndex.prototype.removeAll=function(){this._events.removeAll();
+this._idToEvent={};
+this._indexed=false;
+};
+SimileAjax.EventIndex.prototype.getCount=function(){return this._events.length();
+};
+SimileAjax.EventIndex.prototype.getIterator=function(A,B){if(!this._indexed){this._index();
+}return new SimileAjax.EventIndex._Iterator(this._events,A,B,this._unit);
+};
+SimileAjax.EventIndex.prototype.getReverseIterator=function(A,B){if(!this._indexed){this._index();
+}return new SimileAjax.EventIndex._ReverseIterator(this._events,A,B,this._unit);
+};
+SimileAjax.EventIndex.prototype.getAllIterator=function(){return new SimileAjax.EventIndex._AllIterator(this._events);
+};
+SimileAjax.EventIndex.prototype.getEarliestDate=function(){var A=this._events.getFirst();
+return(A==null)?null:A.getStart();
+};
+SimileAjax.EventIndex.prototype.getLatestDate=function(){var A=this._events.getLast();
+if(A==null){return null;
+}if(!this._indexed){this._index();
+}var C=A._earliestOverlapIndex;
+var B=this._events.elementAt(C).getEnd();
+for(var D=C+1;
+D<this._events.length();
+D++){B=this._unit.later(B,this._events.elementAt(D).getEnd());
+}return B;
+};
+SimileAjax.EventIndex.prototype._index=function(){var E=this._events.length();
+for(var F=0;
+F<E;
+F++){var D=this._events.elementAt(F);
+D._earliestOverlapIndex=F;
+}var G=1;
+for(var F=0;
+F<E;
+F++){var D=this._events.elementAt(F);
+var C=D.getEnd();
+G=Math.max(G,F+1);
+while(G<E){var A=this._events.elementAt(G);
+var B=A.getStart();
+if(this._unit.compare(B,C)<0){A._earliestOverlapIndex=F;
+G++;
+}else{break;
+}}}this._indexed=true;
+};
+SimileAjax.EventIndex._Iterator=function(A,C,D,B){this._events=A;
+this._startDate=C;
+this._endDate=D;
+this._unit=B;
+this._currentIndex=A.find(function(E){return B.compare(E.getStart(),C);
+});
+if(this._currentIndex-1>=0){this._currentIndex=this._events.elementAt(this._currentIndex-1)._earliestOverlapIndex;
+}this._currentIndex--;
+this._maxIndex=A.find(function(E){return B.compare(E.getStart(),D);
+});
+this._hasNext=false;
+this._next=null;
+this._findNext();
+};
+SimileAjax.EventIndex._Iterator.prototype={hasNext:function(){return this._hasNext;
+},next:function(){if(this._hasNext){var A=this._next;
+this._findNext();
+return A;
+}else{return null;
+}},_findNext:function(){var B=this._unit;
+while((++this._currentIndex)<this._maxIndex){var A=this._events.elementAt(this._currentIndex);
+if(B.compare(A.getStart(),this._endDate)<0&&B.compare(A.getEnd(),this._startDate)>0){this._next=A;
+this._hasNext=true;
+return ;
+}}this._next=null;
+this._hasNext=false;
+}};
+SimileAjax.EventIndex._ReverseIterator=function(A,C,D,B){this._events=A;
+this._startDate=C;
+this._endDate=D;
+this._unit=B;
+this._minIndex=A.find(function(E){return B.compare(E.getStart(),C);
+});
+if(this._minIndex-1>=0){this._minIndex=this._events.elementAt(this._minIndex-1)._earliestOverlapIndex;
+}this._maxIndex=A.find(function(E){return B.compare(E.getStart(),D);
+});
+this._currentIndex=this._maxIndex;
+this._hasNext=false;
+this._next=null;
+this._findNext();
+};
+SimileAjax.EventIndex._ReverseIterator.prototype={hasNext:function(){return this._hasNext;
+},next:function(){if(this._hasNext){var A=this._next;
+this._findNext();
+return A;
+}else{return null;
+}},_findNext:function(){var B=this._unit;
+while((--this._currentIndex)>=this._minIndex){var A=this._events.elementAt(this._currentIndex);
+if(B.compare(A.getStart(),this._endDate)<0&&B.compare(A.getEnd(),this._startDate)>0){this._next=A;
+this._hasNext=true;
+return ;
+}}this._next=null;
+this._hasNext=false;
+}};
+SimileAjax.EventIndex._AllIterator=function(A){this._events=A;
+this._index=0;
+};
+SimileAjax.EventIndex._AllIterator.prototype={hasNext:function(){return this._index<this._events.length();
+},next:function(){return this._index<this._events.length()?this._events.elementAt(this._index++):null;
+}};
+
+
+/* date-time.js */
+SimileAjax.DateTime=new Object();
+SimileAjax.DateTime.MILLISECOND=0;
+SimileAjax.DateTime.SECOND=1;
+SimileAjax.DateTime.MINUTE=2;
+SimileAjax.DateTime.HOUR=3;
+SimileAjax.DateTime.DAY=4;
+SimileAjax.DateTime.WEEK=5;
+SimileAjax.DateTime.MONTH=6;
+SimileAjax.DateTime.YEAR=7;
+SimileAjax.DateTime.DECADE=8;
+SimileAjax.DateTime.CENTURY=9;
+SimileAjax.DateTime.MILLENNIUM=10;
+SimileAjax.DateTime.EPOCH=-1;
+SimileAjax.DateTime.ERA=-2;
+SimileAjax.DateTime.gregorianUnitLengths=[];
+(function(){var B=SimileAjax.DateTime;
+var A=B.gregorianUnitLengths;
+A[B.MILLISECOND]=1;
+A[B.SECOND]=1000;
+A[B.MINUTE]=A[B.SECOND]*60;
+A[B.HOUR]=A[B.MINUTE]*60;
+A[B.DAY]=A[B.HOUR]*24;
+A[B.WEEK]=A[B.DAY]*7;
+A[B.MONTH]=A[B.DAY]*31;
+A[B.YEAR]=A[B.DAY]*365;
+A[B.DECADE]=A[B.YEAR]*10;
+A[B.CENTURY]=A[B.YEAR]*100;
+A[B.MILLENNIUM]=A[B.YEAR]*1000;
+})();
+SimileAjax.DateTime._dateRegexp=new RegExp("^(-?)([0-9]{4})("+["(-?([0-9]{2})(-?([0-9]{2}))?)","(-?([0-9]{3}))","(-?W([0-9]{2})(-?([1-7]))?)"].join("|")+")?$");
+SimileAjax.DateTime._timezoneRegexp=new RegExp("Z|(([-+])([0-9]{2})(:?([0-9]{2}))?)$");
+SimileAjax.DateTime._timeRegexp=new RegExp("^([0-9]{2})(:?([0-9]{2})(:?([0-9]{2})(.([0-9]+))?)?)?$");
+SimileAjax.DateTime.setIso8601Date=function(G,C){var I=C.match(SimileAjax.DateTime._dateRegexp);
+if(!I){throw new Error("Invalid date string: "+C);
+}var B=(I[1]=="-")?-1:1;
+var J=B*I[2];
+var H=I[5];
+var D=I[7];
+var F=I[9];
+var A=I[11];
+var M=(I[13])?I[13]:1;
+G.setUTCFullYear(J);
+if(F){G.setUTCMonth(0);
+G.setUTCDate(Number(F));
+}else{if(A){G.setUTCMonth(0);
+G.setUTCDate(1);
+var L=G.getUTCDay();
+var K=(L)?L:7;
+var E=Number(M)+(7*Number(A));
+if(K<=4){G.setUTCDate(E+1-K);
+}else{G.setUTCDate(E+8-K);
+}}else{if(H){G.setUTCDate(1);
+G.setUTCMonth(H-1);
+}if(D){G.setUTCDate(D);
+}}}return G;
+};
+SimileAjax.DateTime.setIso8601Time=function(F,D){var G=D.match(SimileAjax.DateTime._timeRegexp);
+if(!G){SimileAjax.Debug.warn("Invalid time string: "+D);
+return false;
+}var A=G[1];
+var E=Number((G[3])?G[3]:0);
+var C=(G[5])?G[5]:0;
+var B=G[7]?(Number("0."+G[7])*1000):0;
+F.setUTCHours(A);
+F.setUTCMinutes(E);
+F.setUTCSeconds(C);
+F.setUTCMilliseconds(B);
+return F;
+};
+SimileAjax.DateTime.timezoneOffset=new Date().getTimezoneOffset();
+SimileAjax.DateTime.setIso8601=function(B,A){var D=null;
+var E=(A.indexOf("T")==-1)?A.split(" "):A.split("T");
+SimileAjax.DateTime.setIso8601Date(B,E[0]);
+if(E.length==2){var C=E[1].match(SimileAjax.DateTime._timezoneRegexp);
+if(C){if(C[0]=="Z"){D=0;
+}else{D=(Number(C[3])*60)+Number(C[5]);
+D*=((C[2]=="-")?1:-1);
+}E[1]=E[1].substr(0,E[1].length-C[0].length);
+}SimileAjax.DateTime.setIso8601Time(B,E[1]);
+}if(D==null){D=B.getTimezoneOffset();
+}B.setTime(B.getTime()+D*60000);
+return B;
+};
+SimileAjax.DateTime.parseIso8601DateTime=function(A){try{return SimileAjax.DateTime.setIso8601(new Date(0),A);
+}catch(B){return null;
+}};
+SimileAjax.DateTime.parseGregorianDateTime=function(F){if(F==null){return null;
+}else{if(F instanceof Date){return F;
+}}var B=F.toString();
+if(B.length>0&&B.length<8){var C=B.indexOf(" ");
+if(C>0){var A=parseInt(B.substr(0,C));
+var G=B.substr(C+1);
+if(G.toLowerCase()=="bc"){A=1-A;
+}}else{var A=parseInt(B);
+}var E=new Date(0);
+E.setUTCFullYear(A);
+return E;
+}try{return new Date(Date.parse(B));
+}catch(D){return null;
+}};
+SimileAjax.DateTime.roundDownToInterval=function(E,B,I,K,A){var F=I*SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR];
+var J=new Date(E.getTime()+F);
+var C=function(L){L.setUTCMilliseconds(0);
+L.setUTCSeconds(0);
+L.setUTCMinutes(0);
+L.setUTCHours(0);
+};
+var D=function(L){C(L);
+L.setUTCDate(1);
+L.setUTCMonth(0);
+};
+switch(B){case SimileAjax.DateTime.MILLISECOND:var H=J.getUTCMilliseconds();
+J.setUTCMilliseconds(H-(H%K));
+break;
+case SimileAjax.DateTime.SECOND:J.setUTCMilliseconds(0);
+var H=J.getUTCSeconds();
+J.setUTCSeconds(H-(H%K));
+break;
+case SimileAjax.DateTime.MINUTE:J.setUTCMilliseconds(0);
+J.setUTCSeconds(0);
+var H=J.getUTCMinutes();
+J.setTime(J.getTime()-(H%K)*SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.MINUTE]);
+break;
+case SimileAjax.DateTime.HOUR:J.setUTCMilliseconds(0);
+J.setUTCSeconds(0);
+J.setUTCMinutes(0);
+var H=J.getUTCHours();
+J.setUTCHours(H-(H%K));
+break;
+case SimileAjax.DateTime.DAY:C(J);
+break;
+case SimileAjax.DateTime.WEEK:C(J);
+var G=(J.getUTCDay()+7-A)%7;
+J.setTime(J.getTime()-G*SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.DAY]);
+break;
+case SimileAjax.DateTime.MONTH:C(J);
+J.setUTCDate(1);
+var H=J.getUTCMonth();
+J.setUTCMonth(H-(H%K));
+break;
+case SimileAjax.DateTime.YEAR:D(J);
+var H=J.getUTCFullYear();
+J.setUTCFullYear(H-(H%K));
+break;
+case SimileAjax.DateTime.DECADE:D(J);
+J.setUTCFullYear(Math.floor(J.getUTCFullYear()/10)*10);
+break;
+case SimileAjax.DateTime.CENTURY:D(J);
+J.setUTCFullYear(Math.floor(J.getUTCFullYear()/100)*100);
+break;
+case SimileAjax.DateTime.MILLENNIUM:D(J);
+J.setUTCFullYear(Math.floor(J.getUTCFullYear()/1000)*1000);
+break;
+}E.setTime(J.getTime()-F);
+};
+SimileAjax.DateTime.roundUpToInterval=function(C,F,D,A,B){var E=C.getTime();
+SimileAjax.DateTime.roundDownToInterval(C,F,D,A,B);
+if(C.getTime()<E){C.setTime(C.getTime()+SimileAjax.DateTime.gregorianUnitLengths[F]*A);
+}};
+SimileAjax.DateTime.incrementByInterval=function(A,D,B){B=(typeof B=="undefined")?0:B;
+var E=B*SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR];
+var C=new Date(A.getTime()+E);
+switch(D){case SimileAjax.DateTime.MILLISECOND:C.setTime(C.getTime()+1);
+break;
+case SimileAjax.DateTime.SECOND:C.setTime(C.getTime()+1000);
+break;
+case SimileAjax.DateTime.MINUTE:C.setTime(C.getTime()+SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.MINUTE]);
+break;
+case SimileAjax.DateTime.HOUR:C.setTime(C.getTime()+SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR]);
+break;
+case SimileAjax.DateTime.DAY:C.setUTCDate(C.getUTCDate()+1);
+break;
+case SimileAjax.DateTime.WEEK:C.setUTCDate(C.getUTCDate()+7);
+break;
+case SimileAjax.DateTime.MONTH:C.setUTCMonth(C.getUTCMonth()+1);
+break;
+case SimileAjax.DateTime.YEAR:C.setUTCFullYear(C.getUTCFullYear()+1);
+break;
+case SimileAjax.DateTime.DECADE:C.setUTCFullYear(C.getUTCFullYear()+10);
+break;
+case SimileAjax.DateTime.CENTURY:C.setUTCFullYear(C.getUTCFullYear()+100);
+break;
+case SimileAjax.DateTime.MILLENNIUM:C.setUTCFullYear(C.getUTCFullYear()+1000);
+break;
+}A.setTime(C.getTime()-E);
+};
+SimileAjax.DateTime.removeTimeZoneOffset=function(A,B){return new Date(A.getTime()+B*SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.HOUR]);
+};
+SimileAjax.DateTime.getTimezone=function(){var A=new Date().getTimezoneOffset();
+return A/-60;
+};
+
+
+/* debug.js */
+SimileAjax.Debug={silent:false};
+SimileAjax.Debug.log=function(B){var A;
+if("console" in window&&"log" in window.console){A=function(C){console.log(C);
+};
+}else{A=function(C){if(!SimileAjax.Debug.silent){alert(C);
+}};
+}SimileAjax.Debug.log=A;
+A(B);
+};
+SimileAjax.Debug.warn=function(B){var A;
+if("console" in window&&"warn" in window.console){A=function(C){console.warn(C);
+};
+}else{A=function(C){if(!SimileAjax.Debug.silent){alert(C);
+}};
+}SimileAjax.Debug.warn=A;
+A(B);
+};
+SimileAjax.Debug.exception=function(B,D){var A,C=SimileAjax.parseURLParameters();
+if(C.errors=="throw"||SimileAjax.params.errors=="throw"){A=function(F,E){throw (F);
+};
+}else{if("console" in window&&"error" in window.console){A=function(F,E){if(E!=null){console.error(E+" %o",F);
+}else{console.error(F);
+}throw (F);
+};
+}else{A=function(F,E){if(!SimileAjax.Debug.silent){alert("Caught exception: "+E+"\n\nDetails: "+("description" in F?F.description:F));
+}throw (F);
+};
+}}SimileAjax.Debug.exception=A;
+A(B,D);
+};
+SimileAjax.Debug.objectToString=function(A){return SimileAjax.Debug._objectToString(A,"");
+};
+SimileAjax.Debug._objectToString=function(D,C){var B=C+" ";
+if(typeof D=="object"){var A="{";
+for(E in D){A+=B+E+": "+SimileAjax.Debug._objectToString(D[E],B)+"\n";
+}A+=C+"}";
+return A;
+}else{if(typeof D=="array"){var A="[";
+for(var E=0;
+E<D.length;
+E++){A+=SimileAjax.Debug._objectToString(D[E],B)+"\n";
+}A+=C+"]";
+return A;
+}else{return D;
+}}};
+
+
+/* dom.js */
+SimileAjax.DOM=new Object();
+SimileAjax.DOM.registerEventWithObject=function(C,A,D,B){SimileAjax.DOM.registerEvent(C,A,function(F,E,G){return D[B].call(D,F,E,G);
+});
+};
+SimileAjax.DOM.registerEvent=function(C,B,D){var A=function(E){E=(E)?E:((event)?event:null);
+if(E){var F=(E.target)?E.target:((E.srcElement)?E.srcElement:null);
+if(F){F=(F.nodeType==1||F.nodeType==9)?F:F.parentNode;
+}return D(C,E,F);
+}return true;
+};
+if(SimileAjax.Platform.browser.isIE){C.attachEvent("on"+B,A);
+}else{C.addEventListener(B,A,false);
+}};
+SimileAjax.DOM.getPageCoordinates=function(B){var E=0;
+var D=0;
+if(B.nodeType!=1){B=B.parentNode;
+}var C=B;
+while(C!=null){E+=C.offsetLeft;
+D+=C.offsetTop;
+C=C.offsetParent;
+}var A=document.body;
+while(B!=null&&B!=A){if("scrollLeft" in B){E-=B.scrollLeft;
+D-=B.scrollTop;
+}B=B.parentNode;
+}return{left:E,top:D};
+};
+SimileAjax.DOM.getSize=function(B){var A=this.getStyle(B,"width");
+var C=this.getStyle(B,"height");
+if(A.indexOf("px")>-1){A=A.replace("px","");
+}if(C.indexOf("px")>-1){C=C.replace("px","");
+}return{w:A,h:C};
+};
+SimileAjax.DOM.getStyle=function(B,A){if(B.currentStyle){var C=B.currentStyle[A];
+}else{if(window.getComputedStyle){var C=document.defaultView.getComputedStyle(B,null).getPropertyValue(A);
+}else{var C="";
+}}return C;
+};
+SimileAjax.DOM.getEventRelativeCoordinates=function(B,C){if(SimileAjax.Platform.browser.isIE){if(B.type=="mousewheel"){var A=SimileAjax.DOM.getPageCoordinates(C);
+return{x:B.clientX-A.left,y:B.clientY-A.top};
+}else{return{x:B.offsetX,y:B.offsetY};
+}}else{var A=SimileAjax.DOM.getPageCoordinates(C);
+if((B.type=="DOMMouseScroll")&&SimileAjax.Platform.browser.isFirefox&&(SimileAjax.Platform.browser.majorVersion==2)){return{x:B.screenX-A.left,y:B.screenY-A.top};
+}else{return{x:B.pageX-A.left,y:B.pageY-A.top};
+}}};
+SimileAjax.DOM.getEventPageCoordinates=function(A){if(SimileAjax.Platform.browser.isIE){return{x:A.clientX+document.body.scrollLeft,y:A.clientY+document.body.scrollTop};
+}else{return{x:A.pageX,y:A.pageY};
+}};
+SimileAjax.DOM.hittest=function(A,C,B){return SimileAjax.DOM._hittest(document.body,A,C,B);
+};
+SimileAjax.DOM._hittest=function(C,L,K,A){var M=C.childNodes;
+outer:for(var G=0;
+G<M.length;
+G++){var H=M[G];
+for(var F=0;
+F<A.length;
+F++){if(H==A[F]){continue outer;
+}}if(H.offsetWidth==0&&H.offsetHeight==0){var B=SimileAjax.DOM._hittest(H,L,K,A);
+if(B!=H){return B;
+}}else{var J=0;
+var E=0;
+var D=H;
+while(D){J+=D.offsetTop;
+E+=D.offsetLeft;
+D=D.offsetParent;
+}if(E<=L&&J<=K&&(L-E)<H.offsetWidth&&(K-J)<H.offsetHeight){return SimileAjax.DOM._hittest(H,L,K,A);
+}else{if(H.nodeType==1&&H.tagName=="TR"){var I=SimileAjax.DOM._hittest(H,L,K,A);
+if(I!=H){return I;
+}}}}}return C;
+};
+SimileAjax.DOM.cancelEvent=function(A){A.returnValue=false;
+A.cancelBubble=true;
+if("preventDefault" in A){A.preventDefault();
+}};
+SimileAjax.DOM.appendClassName=function(D,A){var C=D.className.split(" ");
+for(var B=0;
+B<C.length;
+B++){if(C[B]==A){return ;
+}}C.push(A);
+D.className=C.join(" ");
+};
+SimileAjax.DOM.createInputElement=function(A){var B=document.createElement("div");
+B.innerHTML="<input type='"+A+"' />";
+return B.firstChild;
+};
+SimileAjax.DOM.createDOMFromTemplate=function(A){var B={};
+B.elmt=SimileAjax.DOM._createDOMFromTemplate(A,B,null);
+return B;
+};
+SimileAjax.DOM._createDOMFromTemplate=function(F,G,D){if(F==null){return null;
+}else{if(typeof F!="object"){var C=document.createTextNode(F);
+if(D!=null){D.appendChild(C);
+}return C;
+}else{var A=null;
+if("tag" in F){var J=F.tag;
+if(D!=null){if(J=="tr"){A=D.insertRow(D.rows.length);
+}else{if(J=="td"){A=D.insertCell(D.cells.length);
+}}}if(A==null){A=J=="input"?SimileAjax.DOM.createInputElement(F.type):document.createElement(J);
+if(D!=null){D.appendChild(A);
+}}}else{A=F.elmt;
+if(D!=null){D.appendChild(A);
+}}for(var B in F){var H=F[B];
+if(B=="field"){G[H]=A;
+}else{if(B=="className"){A.className=H;
+}else{if(B=="id"){A.id=H;
+}else{if(B=="title"){A.title=H;
+}else{if(B=="type"&&A.tagName=="input"){}else{if(B=="style"){for(n in H){var I=H[n];
+if(n=="float"){n=SimileAjax.Platform.browser.isIE?"styleFloat":"cssFloat";
+}A.style[n]=I;
+}}else{if(B=="children"){for(var E=0;
+E<H.length;
+E++){SimileAjax.DOM._createDOMFromTemplate(H[E],G,A);
+}}else{if(B!="tag"&&B!="elmt"){A.setAttribute(B,H);
+}}}}}}}}}return A;
+}}};
+SimileAjax.DOM._cachedParent=null;
+SimileAjax.DOM.createElementFromString=function(A){if(SimileAjax.DOM._cachedParent==null){SimileAjax.DOM._cachedParent=document.createElement("div");
+}SimileAjax.DOM._cachedParent.innerHTML=A;
+return SimileAjax.DOM._cachedParent.firstChild;
+};
+SimileAjax.DOM.createDOMFromString=function(A,C,D){var B=typeof A=="string"?document.createElement(A):A;
+B.innerHTML=C;
+var E={elmt:B};
+SimileAjax.DOM._processDOMChildrenConstructedFromString(E,B,D!=null?D:{});
+return E;
+};
+SimileAjax.DOM._processDOMConstructedFromString=function(D,A,B){var E=A.id;
+if(E!=null&&E.length>0){A.removeAttribute("id");
+if(E in B){var C=A.parentNode;
+C.insertBefore(B[E],A);
+C.removeChild(A);
+D[E]=B[E];
+return ;
+}else{D[E]=A;
+}}if(A.hasChildNodes()){SimileAjax.DOM._processDOMChildrenConstructedFromString(D,A,B);
+}};
+SimileAjax.DOM._processDOMChildrenConstructedFromString=function(E,B,D){var C=B.firstChild;
+while(C!=null){var A=C.nextSibling;
+if(C.nodeType==1){SimileAjax.DOM._processDOMConstructedFromString(E,C,D);
+}C=A;
+}};
+
+
+/* graphics.js */
+SimileAjax.Graphics=new Object();
+SimileAjax.Graphics.pngIsTranslucent=(!SimileAjax.Platform.browser.isIE)||(SimileAjax.Platform.browser.majorVersion>6);
+if(!SimileAjax.Graphics.pngIsTranslucent){SimileAjax.includeCssFile(document,SimileAjax.urlPrefix+"styles/graphics-ie6.css");
+}SimileAjax.Graphics._createTranslucentImage1=function(A,C){var B=document.createElement("img");
+B.setAttribute("src",A);
+if(C!=null){B.style.verticalAlign=C;
+}return B;
+};
+SimileAjax.Graphics._createTranslucentImage2=function(A,C){var B=document.createElement("img");
+B.style.width="1px";
+B.style.height="1px";
+B.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+A+"', sizingMethod='image')";
+B.style.verticalAlign=(C!=null)?C:"middle";
+return B;
+};
+SimileAjax.Graphics.createTranslucentImage=SimileAjax.Graphics.pngIsTranslucent?SimileAjax.Graphics._createTranslucentImage1:SimileAjax.Graphics._createTranslucentImage2;
+SimileAjax.Graphics._createTranslucentImageHTML1=function(A,B){return'<img src="'+A+'"'+(B!=null?' style="vertical-align: '+B+';"':"")+" />";
+};
+SimileAjax.Graphics._createTranslucentImageHTML2=function(A,C){var B="width: 1px; height: 1px; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+A+"', sizingMethod='image');"+(C!=null?" vertical-align: "+C+";":"");
+return"<img src='"+A+"' style=\""+B+'" />';
+};
+SimileAjax.Graphics.createTranslucentImageHTML=SimileAjax.Graphics.pngIsTranslucent?SimileAjax.Graphics._createTranslucentImageHTML1:SimileAjax.Graphics._createTranslucentImageHTML2;
+SimileAjax.Graphics.setOpacity=function(B,A){if(SimileAjax.Platform.browser.isIE){B.style.filter="progid:DXImageTransform.Microsoft.Alpha(Style=0,Opacity="+A+")";
+}else{var C=(A/100).toString();
+B.style.opacity=C;
+B.style.MozOpacity=C;
+}};
+SimileAjax.Graphics.bubbleConfig={containerCSSClass:"simileAjax-bubble-container",innerContainerCSSClass:"simileAjax-bubble-innerContainer",contentContainerCSSClass:"simileAjax-bubble-contentContainer",borderGraphicSize:50,borderGraphicCSSClassPrefix:"simileAjax-bubble-border-",arrowGraphicTargetOffset:33,arrowGraphicLength:100,arrowGraphicWidth:49,arrowGraphicCSSClassPrefix:"simileAjax-bubble-arrow-",closeGraphicCSSClass:"simileAjax-bubble-close",extraPadding:20};
+SimileAjax.Graphics.createBubbleForContentAndPoint=function(F,E,C,B,D,A){if(typeof B!="number"){B=300;
+}if(typeof A!="number"){A=0;
+}F.style.position="absolute";
+F.style.left="-5000px";
+F.style.top="0px";
+F.style.width=B+"px";
+document.body.appendChild(F);
+window.setTimeout(function(){var H=F.scrollWidth+10;
+var J=F.scrollHeight+10;
+var G=0;
+if(A>0&&J>A){J=A;
+G=H-25;
+}var I=SimileAjax.Graphics.createBubbleForPoint(E,C,H,J,D);
+document.body.removeChild(F);
+F.style.position="static";
+F.style.left="";
+F.style.top="";
+if(G>0){var K=document.createElement("div");
+F.style.width="";
+K.style.width=G+"px";
+K.appendChild(F);
+I.content.appendChild(K);
+}else{F.style.width=H+"px";
+I.content.appendChild(F);
+}},200);
+};
+SimileAjax.Graphics.createBubbleForPoint=function(B,A,J,N,F){J=parseInt(J,10);
+N=parseInt(N,10);
+var E=SimileAjax.Graphics.bubbleConfig;
+var M=SimileAjax.Graphics.pngIsTranslucent?"pngTranslucent":"pngNotTranslucent";
+var L=J+2*E.borderGraphicSize;
+var O=N+2*E.borderGraphicSize;
+var K=function(S){return S+" "+S+"-"+M;
+};
+var H=document.createElement("div");
+H.className=K(E.containerCSSClass);
+H.style.width=J+"px";
+H.style.height=N+"px";
+var D=document.createElement("div");
+D.className=K(E.innerContainerCSSClass);
+H.appendChild(D);
+var I=function(){if(!Q._closed){document.body.removeChild(Q._div);
+Q._doc=null;
+Q._div=null;
+Q._content=null;
+Q._closed=true;
+}};
+var Q={_closed:false};
+var R=SimileAjax.WindowManager.pushLayer(I,true,H);
+Q._div=H;
+Q.close=function(){SimileAjax.WindowManager.popLayer(R);
+};
+var G=function(T){var S=document.createElement("div");
+S.className=K(E.borderGraphicCSSClassPrefix+T);
+D.appendChild(S);
+};
+G("top-left");
+G("top-right");
+G("bottom-left");
+G("bottom-right");
+G("left");
+G("right");
+G("top");
+G("bottom");
+var C=document.createElement("div");
+C.className=K(E.contentContainerCSSClass);
+D.appendChild(C);
+Q.content=C;
+var P=document.createElement("div");
+P.className=K(E.closeGraphicCSSClass);
+D.appendChild(P);
+SimileAjax.WindowManager.registerEventWithObject(P,"click",Q,"close");
+(function(){var Y=SimileAjax.Graphics.getWindowDimensions();
+var T=Y.w;
+var U=Y.h;
+var V=Math.ceil(E.arrowGraphicWidth/2);
+var Z=function(b){var a=document.createElement("div");
+a.className=K(E.arrowGraphicCSSClassPrefix+"point-"+b);
+D.appendChild(a);
+return a;
+};
+if(B-V-E.borderGraphicSize-E.extraPadding>0&&B+V+E.borderGraphicSize+E.extraPadding<T){var X=B-Math.round(J/2);
+X=B<(T/2)?Math.max(X,E.extraPadding+E.borderGraphicSize):Math.min(X,T-E.extraPadding-E.borderGraphicSize-J);
+if((F&&F=="top")||(!F&&(A-E.arrowGraphicTargetOffset-N-E.borderGraphicSize-E.extraPadding>0))){var S=Z("down");
+S.style.left=(B-V-X)+"px";
+H.style.left=X+"px";
+H.style.top=(A-E.arrowGraphicTargetOffset-N)+"px";
+return ;
+}else{if((F&&F=="bottom")||(!F&&(A+E.arrowGraphicTargetOffset+N+E.borderGraphicSize+E.extraPadding<U))){var S=Z("up");
+S.style.left=(B-V-X)+"px";
+H.style.left=X+"px";
+H.style.top=(A+E.arrowGraphicTargetOffset)+"px";
+return ;
+}}}var W=A-Math.round(N/2);
+W=A<(U/2)?Math.max(W,E.extraPadding+E.borderGraphicSize):Math.min(W,U-E.extraPadding-E.borderGraphicSize-N);
+if((F&&F=="left")||(!F&&(B-E.arrowGraphicTargetOffset-J-E.borderGraphicSize-E.extraPadding>0))){var S=Z("right");
+S.style.top=(A-V-W)+"px";
+H.style.top=W+"px";
+H.style.left=(B-E.arrowGraphicTargetOffset-J)+"px";
+}else{var S=Z("left");
+S.style.top=(A-V-W)+"px";
+H.style.top=W+"px";
+H.style.left=(B+E.arrowGraphicTargetOffset)+"px";
+}})();
+document.body.appendChild(H);
+return Q;
+};
+SimileAjax.Graphics.getWindowDimensions=function(){if(typeof window.innerHeight=="number"){return{w:window.innerWidth,h:window.innerHeight};
+}else{if(document.documentElement&&document.documentElement.clientHeight){return{w:document.documentElement.clientWidth,h:document.documentElement.clientHeight};
+}else{if(document.body&&document.body.clientHeight){return{w:document.body.clientWidth,h:document.body.clientHeight};
+}}}};
+SimileAjax.Graphics.createMessageBubble=function(H){var G=H.createElement("div");
+if(SimileAjax.Graphics.pngIsTranslucent){var I=H.createElement("div");
+I.style.height="33px";
+I.style.background="url("+SimileAjax.urlPrefix+"images/message-top-left.png) top left no-repeat";
+I.style.paddingLeft="44px";
+G.appendChild(I);
+var D=H.createElement("div");
+D.style.height="33px";
+D.style.background="url("+SimileAjax.urlPrefix+"images/message-top-right.png) top right no-repeat";
+I.appendChild(D);
+var F=H.createElement("div");
+F.style.background="url("+SimileAjax.urlPrefix+"images/message-left.png) top left repeat-y";
+F.style.paddingLeft="44px";
+G.appendChild(F);
+var B=H.createElement("div");
+B.style.background="url("+SimileAjax.urlPrefix+"images/message-right.png) top right repeat-y";
+B.style.paddingRight="44px";
+F.appendChild(B);
+var C=H.createElement("div");
+B.appendChild(C);
+var E=H.createElement("div");
+E.style.height="55px";
+E.style.background="url("+SimileAjax.urlPrefix+"images/message-bottom-left.png) bottom left no-repeat";
+E.style.paddingLeft="44px";
+G.appendChild(E);
+var A=H.createElement("div");
+A.style.height="55px";
+A.style.background="url("+SimileAjax.urlPrefix+"images/message-bottom-right.png) bottom right no-repeat";
+E.appendChild(A);
+}else{G.style.border="2px solid #7777AA";
+G.style.padding="20px";
+G.style.background="white";
+SimileAjax.Graphics.setOpacity(G,90);
+var C=H.createElement("div");
+G.appendChild(C);
+}return{containerDiv:G,contentDiv:C};
+};
+SimileAjax.Graphics.createAnimation=function(B,E,D,C,A){return new SimileAjax.Graphics._Animation(B,E,D,C,A);
+};
+SimileAjax.Graphics._Animation=function(B,E,D,C,A){this.f=B;
+this.cont=(typeof A=="function")?A:function(){};
+this.from=E;
+this.to=D;
+this.current=E;
+this.duration=C;
+this.start=new Date().getTime();
+this.timePassed=0;
+};
+SimileAjax.Graphics._Animation.prototype.run=function(){var A=this;
+window.setTimeout(function(){A.step();
+},50);
+};
+SimileAjax.Graphics._Animation.prototype.step=function(){this.timePassed+=50;
+var A=this.timePassed/this.duration;
+var B=-Math.cos(A*Math.PI)/2+0.5;
+var D=B*(this.to-this.from)+this.from;
+try{this.f(D,D-this.current);
+}catch(C){}this.current=D;
+if(this.timePassed<this.duration){this.run();
+}else{this.f(this.to,0);
+this["cont"]();
+}};
+SimileAjax.Graphics.createStructuredDataCopyButton=function(F,B,D,E){var G=document.createElement("div");
+G.style.position="relative";
+G.style.display="inline";
+G.style.width=B+"px";
+G.style.height=D+"px";
+G.style.overflow="hidden";
+G.style.margin="2px";
+if(SimileAjax.Graphics.pngIsTranslucent){G.style.background="url("+F+") no-repeat";
+}else{G.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+F+"', sizingMethod='image')";
+}var A;
+if(SimileAjax.Platform.browser.isIE){A="filter:alpha(opacity=0)";
+}else{A="opacity: 0";
+}G.innerHTML="<textarea rows='1' autocomplete='off' value='none' style='"+A+"' />";
+var C=G.firstChild;
+C.style.width=B+"px";
+C.style.height=D+"px";
+C.onmousedown=function(H){H=(H)?H:((event)?event:null);
+if(H.button==2){C.value=E();
+C.select();
+}};
+return G;
+};
+SimileAjax.Graphics.getWidthHeight=function(C){var A,B;
+if(C.getBoundingClientRect==null){A=C.offsetWidth;
+B=C.offsetHeight;
+}else{var D=C.getBoundingClientRect();
+A=Math.ceil(D.right-D.left);
+B=Math.ceil(D.bottom-D.top);
+}return{width:A,height:B};
+};
+SimileAjax.Graphics.getFontRenderingContext=function(A,B){return new SimileAjax.Graphics._FontRenderingContext(A,B);
+};
+SimileAjax.Graphics._FontRenderingContext=function(A,B){this._elmt=A;
+this._elmt.style.visibility="hidden";
+if(typeof B=="string"){this._elmt.style.width=B;
+}else{if(typeof B=="number"){this._elmt.style.width=B+"px";
+}}};
+SimileAjax.Graphics._FontRenderingContext.prototype.dispose=function(){this._elmt=null;
+};
+SimileAjax.Graphics._FontRenderingContext.prototype.update=function(){this._elmt.innerHTML="A";
+this._lineHeight=this._elmt.offsetHeight;
+};
+SimileAjax.Graphics._FontRenderingContext.prototype.computeSize=function(D,B){var C=this._elmt;
+C.innerHTML=D;
+C.className=B===undefined?"":B;
+var A=SimileAjax.Graphics.getWidthHeight(C);
+C.className="";
+return A;
+};
+SimileAjax.Graphics._FontRenderingContext.prototype.getLineHeight=function(){return this._lineHeight;
+};
+
+
+/* history.js */
+SimileAjax.History={maxHistoryLength:10,historyFile:"__history__.html",enabled:true,_initialized:false,_listeners:new SimileAjax.ListenerQueue(),_actions:[],_baseIndex:0,_currentIndex:0,_plainDocumentTitle:document.title};
+SimileAjax.History.formatHistoryEntryTitle=function(A){return SimileAjax.History._plainDocumentTitle+" {"+A+"}";
+};
+SimileAjax.History.initialize=function(){if(SimileAjax.History._initialized){return ;
+}if(SimileAjax.History.enabled){var A=document.createElement("iframe");
+A.id="simile-ajax-history";
+A.style.position="absolute";
+A.style.width="10px";
+A.style.height="10px";
+A.style.top="0px";
+A.style.left="0px";
+A.style.visibility="hidden";
+A.src=SimileAjax.History.historyFile+"?0";
+document.body.appendChild(A);
+SimileAjax.DOM.registerEvent(A,"load",SimileAjax.History._handleIFrameOnLoad);
+SimileAjax.History._iframe=A;
+}SimileAjax.History._initialized=true;
+};
+SimileAjax.History.addListener=function(A){SimileAjax.History.initialize();
+SimileAjax.History._listeners.add(A);
+};
+SimileAjax.History.removeListener=function(A){SimileAjax.History.initialize();
+SimileAjax.History._listeners.remove(A);
+};
+SimileAjax.History.addAction=function(A){SimileAjax.History.initialize();
+SimileAjax.History._listeners.fire("onBeforePerform",[A]);
+window.setTimeout(function(){try{A.perform();
+SimileAjax.History._listeners.fire("onAfterPerform",[A]);
+if(SimileAjax.History.enabled){SimileAjax.History._actions=SimileAjax.History._actions.slice(0,SimileAjax.History._currentIndex-SimileAjax.History._baseIndex);
+SimileAjax.History._actions.push(A);
+SimileAjax.History._currentIndex++;
+var C=SimileAjax.History._actions.length-SimileAjax.History.maxHistoryLength;
+if(C>0){SimileAjax.History._actions=SimileAjax.History._actions.slice(C);
+SimileAjax.History._baseIndex+=C;
+}try{SimileAjax.History._iframe.contentWindow.location.search="?"+SimileAjax.History._currentIndex;
+}catch(B){var D=SimileAjax.History.formatHistoryEntryTitle(A.label);
+document.title=D;
+}}}catch(B){SimileAjax.Debug.exception(B,"Error adding action {"+A.label+"} to history");
+}},0);
+};
+SimileAjax.History.addLengthyAction=function(B,A,C){SimileAjax.History.addAction({perform:B,undo:A,label:C,uiLayer:SimileAjax.WindowManager.getBaseLayer(),lengthy:true});
+};
+SimileAjax.History._handleIFrameOnLoad=function(){try{var B=SimileAjax.History._iframe.contentWindow.location.search;
+var F=(B.length==0)?0:Math.max(0,parseInt(B.substr(1)));
+var D=function(){var G=F-SimileAjax.History._currentIndex;
+SimileAjax.History._currentIndex+=G;
+SimileAjax.History._baseIndex+=G;
+SimileAjax.History._iframe.contentWindow.location.search="?"+F;
+};
+if(F<SimileAjax.History._currentIndex){SimileAjax.History._listeners.fire("onBeforeUndoSeveral",[]);
+window.setTimeout(function(){while(SimileAjax.History._currentIndex>F&&SimileAjax.History._currentIndex>SimileAjax.History._baseIndex){SimileAjax.History._currentIndex--;
+var G=SimileAjax.History._actions[SimileAjax.History._currentIndex-SimileAjax.History._baseIndex];
+try{G.undo();
+}catch(H){SimileAjax.Debug.exception(H,"History: Failed to undo action {"+G.label+"}");
+}}SimileAjax.History._listeners.fire("onAfterUndoSeveral",[]);
+D();
+},0);
+}else{if(F>SimileAjax.History._currentIndex){SimileAjax.History._listeners.fire("onBeforeRedoSeveral",[]);
+window.setTimeout(function(){while(SimileAjax.History._currentIndex<F&&SimileAjax.History._currentIndex-SimileAjax.History._baseIndex<SimileAjax.History._actions.length){var G=SimileAjax.History._actions[SimileAjax.History._currentIndex-SimileAjax.History._baseIndex];
+try{G.perform();
+}catch(H){SimileAjax.Debug.exception(H,"History: Failed to redo action {"+G.label+"}");
+}SimileAjax.History._currentIndex++;
+}SimileAjax.History._listeners.fire("onAfterRedoSeveral",[]);
+D();
+},0);
+}else{var A=SimileAjax.History._currentIndex-SimileAjax.History._baseIndex-1;
+var E=(A>=0&&A<SimileAjax.History._actions.length)?SimileAjax.History.formatHistoryEntryTitle(SimileAjax.History._actions[A].label):SimileAjax.History._plainDocumentTitle;
+SimileAjax.History._iframe.contentWindow.document.title=E;
+document.title=E;
+}}}catch(C){}};
+SimileAjax.History.getNextUndoAction=function(){try{var A=SimileAjax.History._currentIndex-SimileAjax.History._baseIndex-1;
+return SimileAjax.History._actions[A];
+}catch(B){return null;
+}};
+SimileAjax.History.getNextRedoAction=function(){try{var A=SimileAjax.History._currentIndex-SimileAjax.History._baseIndex;
+return SimileAjax.History._actions[A];
+}catch(B){return null;
+}};
+
+
+/* html.js */
+SimileAjax.HTML=new Object();
+SimileAjax.HTML._e2uHash={};
+(function(){var A=SimileAjax.HTML._e2uHash;
+A["nbsp"]="\u00A0[space]";
+A["iexcl"]="\u00A1";
+A["cent"]="\u00A2";
+A["pound"]="\u00A3";
+A["curren"]="\u00A4";
+A["yen"]="\u00A5";
+A["brvbar"]="\u00A6";
+A["sect"]="\u00A7";
+A["uml"]="\u00A8";
+A["copy"]="\u00A9";
+A["ordf"]="\u00AA";
+A["laquo"]="\u00AB";
+A["not"]="\u00AC";
+A["shy"]="\u00AD";
+A["reg"]="\u00AE";
+A["macr"]="\u00AF";
+A["deg"]="\u00B0";
+A["plusmn"]="\u00B1";
+A["sup2"]="\u00B2";
+A["sup3"]="\u00B3";
+A["acute"]="\u00B4";
+A["micro"]="\u00B5";
+A["para"]="\u00B6";
+A["middot"]="\u00B7";
+A["cedil"]="\u00B8";
+A["sup1"]="\u00B9";
+A["ordm"]="\u00BA";
+A["raquo"]="\u00BB";
+A["frac14"]="\u00BC";
+A["frac12"]="\u00BD";
+A["frac34"]="\u00BE";
+A["iquest"]="\u00BF";
+A["Agrave"]="\u00C0";
+A["Aacute"]="\u00C1";
+A["Acirc"]="\u00C2";
+A["Atilde"]="\u00C3";
+A["Auml"]="\u00C4";
+A["Aring"]="\u00C5";
+A["AElig"]="\u00C6";
+A["Ccedil"]="\u00C7";
+A["Egrave"]="\u00C8";
+A["Eacute"]="\u00C9";
+A["Ecirc"]="\u00CA";
+A["Euml"]="\u00CB";
+A["Igrave"]="\u00CC";
+A["Iacute"]="\u00CD";
+A["Icirc"]="\u00CE";
+A["Iuml"]="\u00CF";
+A["ETH"]="\u00D0";
+A["Ntilde"]="\u00D1";
+A["Ograve"]="\u00D2";
+A["Oacute"]="\u00D3";
+A["Ocirc"]="\u00D4";
+A["Otilde"]="\u00D5";
+A["Ouml"]="\u00D6";
+A["times"]="\u00D7";
+A["Oslash"]="\u00D8";
+A["Ugrave"]="\u00D9";
+A["Uacute"]="\u00DA";
+A["Ucirc"]="\u00DB";
+A["Uuml"]="\u00DC";
+A["Yacute"]="\u00DD";
+A["THORN"]="\u00DE";
+A["szlig"]="\u00DF";
+A["agrave"]="\u00E0";
+A["aacute"]="\u00E1";
+A["acirc"]="\u00E2";
+A["atilde"]="\u00E3";
+A["auml"]="\u00E4";
+A["aring"]="\u00E5";
+A["aelig"]="\u00E6";
+A["ccedil"]="\u00E7";
+A["egrave"]="\u00E8";
+A["eacute"]="\u00E9";
+A["ecirc"]="\u00EA";
+A["euml"]="\u00EB";
+A["igrave"]="\u00EC";
+A["iacute"]="\u00ED";
+A["icirc"]="\u00EE";
+A["iuml"]="\u00EF";
+A["eth"]="\u00F0";
+A["ntilde"]="\u00F1";
+A["ograve"]="\u00F2";
+A["oacute"]="\u00F3";
+A["ocirc"]="\u00F4";
+A["otilde"]="\u00F5";
+A["ouml"]="\u00F6";
+A["divide"]="\u00F7";
+A["oslash"]="\u00F8";
+A["ugrave"]="\u00F9";
+A["uacute"]="\u00FA";
+A["ucirc"]="\u00FB";
+A["uuml"]="\u00FC";
+A["yacute"]="\u00FD";
+A["thorn"]="\u00FE";
+A["yuml"]="\u00FF";
+A["quot"]="\u0022";
+A["amp"]="\u0026";
+A["lt"]="\u003C";
+A["gt"]="\u003E";
+A["OElig"]="";
+A["oelig"]="\u0153";
+A["Scaron"]="\u0160";
+A["scaron"]="\u0161";
+A["Yuml"]="\u0178";
+A["circ"]="\u02C6";
+A["tilde"]="\u02DC";
+A["ensp"]="\u2002";
+A["emsp"]="\u2003";
+A["thinsp"]="\u2009";
+A["zwnj"]="\u200C";
+A["zwj"]="\u200D";
+A["lrm"]="\u200E";
+A["rlm"]="\u200F";
+A["ndash"]="\u2013";
+A["mdash"]="\u2014";
+A["lsquo"]="\u2018";
+A["rsquo"]="\u2019";
+A["sbquo"]="\u201A";
+A["ldquo"]="\u201C";
+A["rdquo"]="\u201D";
+A["bdquo"]="\u201E";
+A["dagger"]="\u2020";
+A["Dagger"]="\u2021";
+A["permil"]="\u2030";
+A["lsaquo"]="\u2039";
+A["rsaquo"]="\u203A";
+A["euro"]="\u20AC";
+A["fnof"]="\u0192";
+A["Alpha"]="\u0391";
+A["Beta"]="\u0392";
+A["Gamma"]="\u0393";
+A["Delta"]="\u0394";
+A["Epsilon"]="\u0395";
+A["Zeta"]="\u0396";
+A["Eta"]="\u0397";
+A["Theta"]="\u0398";
+A["Iota"]="\u0399";
+A["Kappa"]="\u039A";
+A["Lambda"]="\u039B";
+A["Mu"]="\u039C";
+A["Nu"]="\u039D";
+A["Xi"]="\u039E";
+A["Omicron"]="\u039F";
+A["Pi"]="\u03A0";
+A["Rho"]="\u03A1";
+A["Sigma"]="\u03A3";
+A["Tau"]="\u03A4";
+A["Upsilon"]="\u03A5";
+A["Phi"]="\u03A6";
+A["Chi"]="\u03A7";
+A["Psi"]="\u03A8";
+A["Omega"]="\u03A9";
+A["alpha"]="\u03B1";
+A["beta"]="\u03B2";
+A["gamma"]="\u03B3";
+A["delta"]="\u03B4";
+A["epsilon"]="\u03B5";
+A["zeta"]="\u03B6";
+A["eta"]="\u03B7";
+A["theta"]="\u03B8";
+A["iota"]="\u03B9";
+A["kappa"]="\u03BA";
+A["lambda"]="\u03BB";
+A["mu"]="\u03BC";
+A["nu"]="\u03BD";
+A["xi"]="\u03BE";
+A["omicron"]="\u03BF";
+A["pi"]="\u03C0";
+A["rho"]="\u03C1";
+A["sigmaf"]="\u03C2";
+A["sigma"]="\u03C3";
+A["tau"]="\u03C4";
+A["upsilon"]="\u03C5";
+A["phi"]="\u03C6";
+A["chi"]="\u03C7";
+A["psi"]="\u03C8";
+A["omega"]="\u03C9";
+A["thetasym"]="\u03D1";
+A["upsih"]="\u03D2";
+A["piv"]="\u03D6";
+A["bull"]="\u2022";
+A["hellip"]="\u2026";
+A["prime"]="\u2032";
+A["Prime"]="\u2033";
+A["oline"]="\u203E";
+A["frasl"]="\u2044";
+A["weierp"]="\u2118";
+A["image"]="\u2111";
+A["real"]="\u211C";
+A["trade"]="\u2122";
+A["alefsym"]="\u2135";
+A["larr"]="\u2190";
+A["uarr"]="\u2191";
+A["rarr"]="\u2192";
+A["darr"]="\u2193";
+A["harr"]="\u2194";
+A["crarr"]="\u21B5";
+A["lArr"]="\u21D0";
+A["uArr"]="\u21D1";
+A["rArr"]="\u21D2";
+A["dArr"]="\u21D3";
+A["hArr"]="\u21D4";
+A["forall"]="\u2200";
+A["part"]="\u2202";
+A["exist"]="\u2203";
+A["empty"]="\u2205";
+A["nabla"]="\u2207";
+A["isin"]="\u2208";
+A["notin"]="\u2209";
+A["ni"]="\u220B";
+A["prod"]="\u220F";
+A["sum"]="\u2211";
+A["minus"]="\u2212";
+A["lowast"]="\u2217";
+A["radic"]="\u221A";
+A["prop"]="\u221D";
+A["infin"]="\u221E";
+A["ang"]="\u2220";
+A["and"]="\u2227";
+A["or"]="\u2228";
+A["cap"]="\u2229";
+A["cup"]="\u222A";
+A["int"]="\u222B";
+A["there4"]="\u2234";
+A["sim"]="\u223C";
+A["cong"]="\u2245";
+A["asymp"]="\u2248";
+A["ne"]="\u2260";
+A["equiv"]="\u2261";
+A["le"]="\u2264";
+A["ge"]="\u2265";
+A["sub"]="\u2282";
+A["sup"]="\u2283";
+A["nsub"]="\u2284";
+A["sube"]="\u2286";
+A["supe"]="\u2287";
+A["oplus"]="\u2295";
+A["otimes"]="\u2297";
+A["perp"]="\u22A5";
+A["sdot"]="\u22C5";
+A["lceil"]="\u2308";
+A["rceil"]="\u2309";
+A["lfloor"]="\u230A";
+A["rfloor"]="\u230B";
+A["lang"]="\u2329";
+A["rang"]="\u232A";
+A["loz"]="\u25CA";
+A["spades"]="\u2660";
+A["clubs"]="\u2663";
+A["hearts"]="\u2665";
+A["diams"]="\u2666";
+})();
+SimileAjax.HTML.deEntify=function(C){var D=SimileAjax.HTML._e2uHash;
+var B=/&(\w+?);/;
+while(B.test(C)){var A=C.match(B);
+C=C.replace(B,D[A[1]]);
+}return C;
+};
+
+
+/* json.js */
+SimileAjax.JSON=new Object();
+(function(){var m={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"};
+var s={array:function(x){var a=["["],b,f,i,l=x.length,v;
+for(i=0;
+i<l;
+i+=1){v=x[i];
+f=s[typeof v];
+if(f){v=f(v);
+if(typeof v=="string"){if(b){a[a.length]=",";
+}a[a.length]=v;
+b=true;
+}}}a[a.length]="]";
+return a.join("");
+},"boolean":function(x){return String(x);
+},"null":function(x){return"null";
+},number:function(x){return isFinite(x)?String(x):"null";
+},object:function(x){if(x){if(x instanceof Array){return s.array(x);
+}var a=["{"],b,f,i,v;
+for(i in x){v=x[i];
+f=s[typeof v];
+if(f){v=f(v);
+if(typeof v=="string"){if(b){a[a.length]=",";
+}a.push(s.string(i),":",v);
+b=true;
+}}}a[a.length]="}";
+return a.join("");
+}return"null";
+},string:function(x){if(/["\\\x00-\x1f]/.test(x)){x=x.replace(/([\x00-\x1f\\"])/g,function(a,b){var c=m[b];
+if(c){return c;
+}c=b.charCodeAt();
+return"\\u00"+Math.floor(c/16).toString(16)+(c%16).toString(16);
+});
+}return'"'+x+'"';
+}};
+SimileAjax.JSON.toJSONString=function(o){if(o instanceof Object){return s.object(o);
+}else{if(o instanceof Array){return s.array(o);
+}else{return o.toString();
+}}};
+SimileAjax.JSON.parseJSON=function(){try{return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(this.replace(/"(\\.|[^"\\])*"/g,"")))&&eval("("+this+")");
+}catch(e){return false;
+}};
+})();
+
+
+/* string.js */
+String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"");
+};
+String.prototype.startsWith=function(A){return this.length>=A.length&&this.substr(0,A.length)==A;
+};
+String.prototype.endsWith=function(A){return this.length>=A.length&&this.substr(this.length-A.length)==A;
+};
+String.substitute=function(C,A){var D="";
+var F=0;
+while(F<C.length-1){var B=C.indexOf("%",F);
+if(B<0||B==C.length-1){break;
+}else{if(B>F&&C.charAt(B-1)=="\\"){D+=C.substring(F,B-1)+"%";
+F=B+1;
+}else{var E=parseInt(C.charAt(B+1));
+if(isNaN(E)||E>=A.length){D+=C.substring(F,B+2);
+}else{D+=C.substring(F,B)+A[E].toString();
+}F=B+2;
+}}}if(F<C.length){D+=C.substring(F);
+}return D;
+};
+
+
+/* units.js */
+SimileAjax.NativeDateUnit=new Object();
+SimileAjax.NativeDateUnit.makeDefaultValue=function(){return new Date();
+};
+SimileAjax.NativeDateUnit.cloneValue=function(A){return new Date(A.getTime());
+};
+SimileAjax.NativeDateUnit.getParser=function(A){if(typeof A=="string"){A=A.toLowerCase();
+}return(A=="iso8601"||A=="iso 8601")?SimileAjax.DateTime.parseIso8601DateTime:SimileAjax.DateTime.parseGregorianDateTime;
+};
+SimileAjax.NativeDateUnit.parseFromObject=function(A){return SimileAjax.DateTime.parseGregorianDateTime(A);
+};
+SimileAjax.NativeDateUnit.toNumber=function(A){return A.getTime();
+};
+SimileAjax.NativeDateUnit.fromNumber=function(A){return new Date(A);
+};
+SimileAjax.NativeDateUnit.compare=function(D,C){var B,A;
+if(typeof D=="object"){B=D.getTime();
+}else{B=Number(D);
+}if(typeof C=="object"){A=C.getTime();
+}else{A=Number(C);
+}return B-A;
+};
+SimileAjax.NativeDateUnit.earlier=function(B,A){return SimileAjax.NativeDateUnit.compare(B,A)<0?B:A;
+};
+SimileAjax.NativeDateUnit.later=function(B,A){return SimileAjax.NativeDateUnit.compare(B,A)>0?B:A;
+};
+SimileAjax.NativeDateUnit.change=function(A,B){return new Date(A.getTime()+B);
+};
+
+
+/* window-manager.js */
+SimileAjax.WindowManager={_initialized:false,_listeners:[],_draggedElement:null,_draggedElementCallback:null,_dropTargetHighlightElement:null,_lastCoords:null,_ghostCoords:null,_draggingMode:"",_dragging:false,_layers:[]};
+SimileAjax.WindowManager.initialize=function(){if(SimileAjax.WindowManager._initialized){return ;
+}SimileAjax.DOM.registerEvent(document.body,"mousedown",SimileAjax.WindowManager._onBodyMouseDown);
+SimileAjax.DOM.registerEvent(document.body,"mousemove",SimileAjax.WindowManager._onBodyMouseMove);
+SimileAjax.DOM.registerEvent(document.body,"mouseup",SimileAjax.WindowManager._onBodyMouseUp);
+SimileAjax.DOM.registerEvent(document,"keydown",SimileAjax.WindowManager._onBodyKeyDown);
+SimileAjax.DOM.registerEvent(document,"keyup",SimileAjax.WindowManager._onBodyKeyUp);
+SimileAjax.WindowManager._layers.push({index:0});
+SimileAjax.WindowManager._historyListener={onBeforeUndoSeveral:function(){},onAfterUndoSeveral:function(){},onBeforeUndo:function(){},onAfterUndo:function(){},onBeforeRedoSeveral:function(){},onAfterRedoSeveral:function(){},onBeforeRedo:function(){},onAfterRedo:function(){}};
+SimileAjax.History.addListener(SimileAjax.WindowManager._historyListener);
+SimileAjax.WindowManager._initialized=true;
+};
+SimileAjax.WindowManager.getBaseLayer=function(){SimileAjax.WindowManager.initialize();
+return SimileAjax.WindowManager._layers[0];
+};
+SimileAjax.WindowManager.getHighestLayer=function(){SimileAjax.WindowManager.initialize();
+return SimileAjax.WindowManager._layers[SimileAjax.WindowManager._layers.length-1];
+};
+SimileAjax.WindowManager.registerEventWithObject=function(D,A,E,B,C){SimileAjax.WindowManager.registerEvent(D,A,function(G,F,H){return E[B].call(E,G,F,H);
+},C);
+};
+SimileAjax.WindowManager.registerEvent=function(D,B,E,C){if(C==null){C=SimileAjax.WindowManager.getHighestLayer();
+}var A=function(G,F,I){if(SimileAjax.WindowManager._canProcessEventAtLayer(C)){SimileAjax.WindowManager._popToLayer(C.index);
+try{E(G,F,I);
+}catch(H){SimileAjax.Debug.exception(H);
+}}SimileAjax.DOM.cancelEvent(F);
+return false;
+};
+SimileAjax.DOM.registerEvent(D,B,A);
+};
+SimileAjax.WindowManager.pushLayer=function(C,D,B){var A={onPop:C,index:SimileAjax.WindowManager._layers.length,ephemeral:(D),elmt:B};
+SimileAjax.WindowManager._layers.push(A);
+return A;
+};
+SimileAjax.WindowManager.popLayer=function(B){for(var A=1;
+A<SimileAjax.WindowManager._layers.length;
+A++){if(SimileAjax.WindowManager._layers[A]==B){SimileAjax.WindowManager._popToLayer(A-1);
+break;
+}}};
+SimileAjax.WindowManager.popAllLayers=function(){SimileAjax.WindowManager._popToLayer(0);
+};
+SimileAjax.WindowManager.registerForDragging=function(B,C,A){SimileAjax.WindowManager.registerEvent(B,"mousedown",function(E,D,F){SimileAjax.WindowManager._handleMouseDown(E,D,C);
+},A);
+};
+SimileAjax.WindowManager._popToLayer=function(C){while(C+1<SimileAjax.WindowManager._layers.length){try{var A=SimileAjax.WindowManager._layers.pop();
+if(A.onPop!=null){A.onPop();
+}}catch(B){}}};
+SimileAjax.WindowManager._canProcessEventAtLayer=function(B){if(B.index==(SimileAjax.WindowManager._layers.length-1)){return true;
+}for(var A=B.index+1;
+A<SimileAjax.WindowManager._layers.length;
+A++){if(!SimileAjax.WindowManager._layers[A].ephemeral){return false;
+}}return true;
+};
+SimileAjax.WindowManager.cancelPopups=function(A){var F=(A)?SimileAjax.DOM.getEventPageCoordinates(A):{x:-1,y:-1};
+var E=SimileAjax.WindowManager._layers.length-1;
+while(E>0&&SimileAjax.WindowManager._layers[E].ephemeral){var D=SimileAjax.WindowManager._layers[E];
+if(D.elmt!=null){var C=D.elmt;
+var B=SimileAjax.DOM.getPageCoordinates(C);
+if(F.x>=B.left&&F.x<(B.left+C.offsetWidth)&&F.y>=B.top&&F.y<(B.top+C.offsetHeight)){break;
+}}E--;
+}SimileAjax.WindowManager._popToLayer(E);
+};
+SimileAjax.WindowManager._onBodyMouseDown=function(B,A,C){if(!("eventPhase" in A)||A.eventPhase==A.BUBBLING_PHASE){SimileAjax.WindowManager.cancelPopups(A);
+}};
+SimileAjax.WindowManager._handleMouseDown=function(B,A,C){SimileAjax.WindowManager._draggedElement=B;
+SimileAjax.WindowManager._draggedElementCallback=C;
+SimileAjax.WindowManager._lastCoords={x:A.clientX,y:A.clientY};
+SimileAjax.DOM.cancelEvent(A);
+return false;
+};
+SimileAjax.WindowManager._onBodyKeyDown=function(C,A,D){if(SimileAjax.WindowManager._dragging){if(A.keyCode==27){SimileAjax.WindowManager._cancelDragging();
+}else{if((A.keyCode==17||A.keyCode==16)&&SimileAjax.WindowManager._draggingMode!="copy"){SimileAjax.WindowManager._draggingMode="copy";
+var B=SimileAjax.Graphics.createTranslucentImage(SimileAjax.urlPrefix+"images/copy.png");
+B.style.position="absolute";
+B.style.left=(SimileAjax.WindowManager._ghostCoords.left-16)+"px";
+B.style.top=(SimileAjax.WindowManager._ghostCoords.top)+"px";
+document.body.appendChild(B);
+SimileAjax.WindowManager._draggingModeIndicatorElmt=B;
+}}}};
+SimileAjax.WindowManager._onBodyKeyUp=function(B,A,C){if(SimileAjax.WindowManager._dragging){if(A.keyCode==17||A.keyCode==16){SimileAjax.WindowManager._draggingMode="";
+if(SimileAjax.WindowManager._draggingModeIndicatorElmt!=null){document.body.removeChild(SimileAjax.WindowManager._draggingModeIndicatorElmt);
+SimileAjax.WindowManager._draggingModeIndicatorElmt=null;
+}}}};
+SimileAjax.WindowManager._onBodyMouseMove=function(C,M,B){if(SimileAjax.WindowManager._draggedElement!=null){var L=SimileAjax.WindowManager._draggedElementCallback;
+var G=SimileAjax.WindowManager._lastCoords;
+var J=M.clientX-G.x;
+var I=M.clientY-G.y;
+if(!SimileAjax.WindowManager._dragging){if(Math.abs(J)>5||Math.abs(I)>5){try{if("onDragStart" in L){L.onDragStart();
+}if("ghost" in L&&L.ghost){var P=SimileAjax.WindowManager._draggedElement;
+SimileAjax.WindowManager._ghostCoords=SimileAjax.DOM.getPageCoordinates(P);
+SimileAjax.WindowManager._ghostCoords.left+=J;
+SimileAjax.WindowManager._ghostCoords.top+=I;
+var K=P.cloneNode(true);
+K.style.position="absolute";
+K.style.left=SimileAjax.WindowManager._ghostCoords.left+"px";
+K.style.top=SimileAjax.WindowManager._ghostCoords.top+"px";
+K.style.zIndex=1000;
+SimileAjax.Graphics.setOpacity(K,50);
+document.body.appendChild(K);
+L._ghostElmt=K;
+}SimileAjax.WindowManager._dragging=true;
+SimileAjax.WindowManager._lastCoords={x:M.clientX,y:M.clientY};
+document.body.focus();
+}catch(H){SimileAjax.Debug.exception("WindowManager: Error handling mouse down",H);
+SimileAjax.WindowManager._cancelDragging();
+}}}else{try{SimileAjax.WindowManager._lastCoords={x:M.clientX,y:M.clientY};
+if("onDragBy" in L){L.onDragBy(J,I);
+}if("_ghostElmt" in L){var K=L._ghostElmt;
+SimileAjax.WindowManager._ghostCoords.left+=J;
+SimileAjax.WindowManager._ghostCoords.top+=I;
+K.style.left=SimileAjax.WindowManager._ghostCoords.left+"px";
+K.style.top=SimileAjax.WindowManager._ghostCoords.top+"px";
+if(SimileAjax.WindowManager._draggingModeIndicatorElmt!=null){var O=SimileAjax.WindowManager._draggingModeIndicatorElmt;
+O.style.left=(SimileAjax.WindowManager._ghostCoords.left-16)+"px";
+O.style.top=SimileAjax.WindowManager._ghostCoords.top+"px";
+}if("droppable" in L&&L.droppable){var N=SimileAjax.DOM.getEventPageCoordinates(M);
+var B=SimileAjax.DOM.hittest(N.x,N.y,[SimileAjax.WindowManager._ghostElmt,SimileAjax.WindowManager._dropTargetHighlightElement]);
+B=SimileAjax.WindowManager._findDropTarget(B);
+if(B!=SimileAjax.WindowManager._potentialDropTarget){if(SimileAjax.WindowManager._dropTargetHighlightElement!=null){document.body.removeChild(SimileAjax.WindowManager._dropTargetHighlightElement);
+SimileAjax.WindowManager._dropTargetHighlightElement=null;
+SimileAjax.WindowManager._potentialDropTarget=null;
+}var A=false;
+if(B!=null){if((!("canDropOn" in L)||L.canDropOn(B))&&(!("canDrop" in B)||B.canDrop(SimileAjax.WindowManager._draggedElement))){A=true;
+}}if(A){var E=4;
+var D=SimileAjax.DOM.getPageCoordinates(B);
+var F=document.createElement("div");
+F.style.border=E+"px solid yellow";
+F.style.backgroundColor="yellow";
+F.style.position="absolute";
+F.style.left=D.left+"px";
+F.style.top=D.top+"px";
+F.style.width=(B.offsetWidth-E*2)+"px";
+F.style.height=(B.offsetHeight-E*2)+"px";
+SimileAjax.Graphics.setOpacity(F,30);
+document.body.appendChild(F);
+SimileAjax.WindowManager._potentialDropTarget=B;
+SimileAjax.WindowManager._dropTargetHighlightElement=F;
+}}}}}catch(H){SimileAjax.Debug.exception("WindowManager: Error handling mouse move",H);
+SimileAjax.WindowManager._cancelDragging();
+}}SimileAjax.DOM.cancelEvent(M);
+return false;
+}};
+SimileAjax.WindowManager._onBodyMouseUp=function(B,A,E){if(SimileAjax.WindowManager._draggedElement!=null){try{if(SimileAjax.WindowManager._dragging){var C=SimileAjax.WindowManager._draggedElementCallback;
+if("onDragEnd" in C){C.onDragEnd();
+}if("droppable" in C&&C.droppable){var D=false;
+var E=SimileAjax.WindowManager._potentialDropTarget;
+if(E!=null){if((!("canDropOn" in C)||C.canDropOn(E))&&(!("canDrop" in E)||E.canDrop(SimileAjax.WindowManager._draggedElement))){if("onDropOn" in C){C.onDropOn(E);
+}E.ondrop(SimileAjax.WindowManager._draggedElement,SimileAjax.WindowManager._draggingMode);
+D=true;
+}}if(!D){}}}}finally{SimileAjax.WindowManager._cancelDragging();
+}SimileAjax.DOM.cancelEvent(A);
+return false;
+}};
+SimileAjax.WindowManager._cancelDragging=function(){var A=SimileAjax.WindowManager._draggedElementCallback;
+if("_ghostElmt" in A){var B=A._ghostElmt;
+document.body.removeChild(B);
+delete A._ghostElmt;
+}if(SimileAjax.WindowManager._dropTargetHighlightElement!=null){document.body.removeChild(SimileAjax.WindowManager._dropTargetHighlightElement);
+SimileAjax.WindowManager._dropTargetHighlightElement=null;
+}if(SimileAjax.WindowManager._draggingModeIndicatorElmt!=null){document.body.removeChild(SimileAjax.WindowManager._draggingModeIndicatorElmt);
+SimileAjax.WindowManager._draggingModeIndicatorElmt=null;
+}SimileAjax.WindowManager._draggedElement=null;
+SimileAjax.WindowManager._draggedElementCallback=null;
+SimileAjax.WindowManager._potentialDropTarget=null;
+SimileAjax.WindowManager._dropTargetHighlightElement=null;
+SimileAjax.WindowManager._lastCoords=null;
+SimileAjax.WindowManager._ghostCoords=null;
+SimileAjax.WindowManager._draggingMode="";
+SimileAjax.WindowManager._dragging=false;
+};
+SimileAjax.WindowManager._findDropTarget=function(A){while(A!=null){if("ondrop" in A&&(typeof A.ondrop)=="function"){break;
+}A=A.parentNode;
+}return A;
+};
+
+
+/* xmlhttp.js */
+SimileAjax.XmlHttp=new Object();
+SimileAjax.XmlHttp._onReadyStateChange=function(A,D,B){switch(A.readyState){case 4:try{if(A.status==0||A.status==200){if(B){B(A);
+}}else{if(D){D(A.statusText,A.status,A);
+}}}catch(C){SimileAjax.Debug.exception("XmlHttp: Error handling onReadyStateChange",C);
+}break;
+}};
+SimileAjax.XmlHttp._createRequest=function(){if(SimileAjax.Platform.browser.isIE){var B=["Msxml2.XMLHTTP","Microsoft.XMLHTTP","Msxml2.XMLHTTP.4.0"];
+for(var C=0;
+C<B.length;
+C++){try{var A=B[C];
+var D=function(){return new ActiveXObject(A);
+};
+var F=D();
+SimileAjax.XmlHttp._createRequest=D;
+return F;
+}catch(E){}}}try{var D=function(){return new XMLHttpRequest();
+};
+var F=D();
+SimileAjax.XmlHttp._createRequest=D;
+return F;
+}catch(E){throw new Error("Failed to create an XMLHttpRequest object");
+}};
+SimileAjax.XmlHttp.get=function(B,D,C){var A=SimileAjax.XmlHttp._createRequest();
+A.open("GET",B,true);
+A.onreadystatechange=function(){SimileAjax.XmlHttp._onReadyStateChange(A,D,C);
+};
+A.send(null);
+};
+SimileAjax.XmlHttp.post=function(C,A,E,D){var B=SimileAjax.XmlHttp._createRequest();
+B.open("POST",C,true);
+B.onreadystatechange=function(){SimileAjax.XmlHttp._onReadyStateChange(B,E,D);
+};
+B.send(A);
+};
+SimileAjax.XmlHttp._forceXML=function(A){try{A.overrideMimeType("text/xml");
+}catch(B){A.setrequestheader("Content-Type","text/xml");
+}};

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/styles/graphics-ie6.css
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_ajax/styles/graphics-ie6.css	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_ajax/styles/graphics-ie6.css	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,77 @@
+.simileAjax-bubble-border-left-pngNotTranslucent {
+    filter: expression(
+        "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + SimileAjax.urlPrefix + "images/bubble-left.png', sizingMethod='crop')"
+    );
+}
+
+.simileAjax-bubble-border-right-pngNotTranslucent {
+    filter: expression(
+        "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + SimileAjax.urlPrefix + "images/bubble-right.png', sizingMethod='crop')"
+    );
+}
+
+.simileAjax-bubble-border-top-pngNotTranslucent {
+    filter: expression(
+        "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + SimileAjax.urlPrefix + "images/bubble-top.png', sizingMethod='crop')"
+    );
+}
+
+.simileAjax-bubble-border-bottom-pngNotTranslucent {
+    filter: expression(
+        "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + SimileAjax.urlPrefix + "images/bubble-bottom.png', sizingMethod='crop')"
+    );
+}
+
+.simileAjax-bubble-border-top-left-pngNotTranslucent {
+    filter: expression(
+        "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + SimileAjax.urlPrefix + "images/bubble-top-left.png', sizingMethod='crop')"
+    );
+}
+
+.simileAjax-bubble-border-top-right-pngNotTranslucent {
+    filter: expression(
+        "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + SimileAjax.urlPrefix + "images/bubble-top-right.png', sizingMethod='crop')"
+    );
+}
+
+.simileAjax-bubble-border-bottom-left-pngNotTranslucent {
+    filter: expression(
+        "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + SimileAjax.urlPrefix + "images/bubble-bottom-left.png', sizingMethod='crop')"
+    );
+}
+
+.simileAjax-bubble-border-bottom-right-pngNotTranslucent {
+    filter: expression(
+        "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + SimileAjax.urlPrefix + "images/bubble-bottom-right.png', sizingMethod='crop')"
+    );
+}
+
+.simileAjax-bubble-arrow-point-left-pngNotTranslucent {
+    filter: expression(
+        "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + SimileAjax.urlPrefix + "images/bubble-arrow-point-left.png', sizingMethod='crop')"
+    );
+}
+
+.simileAjax-bubble-arrow-point-right-pngNotTranslucent {
+    filter: expression(
+        "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + SimileAjax.urlPrefix + "images/bubble-arrow-point-right.png', sizingMethod='crop')"
+    );
+}
+
+.simileAjax-bubble-arrow-point-up-pngNotTranslucent {
+    filter: expression(
+        "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + SimileAjax.urlPrefix + "images/bubble-arrow-point-up.png', sizingMethod='crop')"
+    );
+}
+
+.simileAjax-bubble-arrow-point-down-pngNotTranslucent {
+    filter: expression(
+        "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + SimileAjax.urlPrefix + "images/bubble-arrow-point-down.png', sizingMethod='crop')"
+    );
+}
+
+.simileAjax-bubble-close-pngNotTranslucent {
+    filter: expression(
+        "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + SimileAjax.urlPrefix + "images/close-button.png', sizingMethod='crop')"
+    );
+}

Added: trunk/step/step-web/src/main/webapp/libs/timeline_ajax/styles/graphics.css
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_ajax/styles/graphics.css	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_ajax/styles/graphics.css	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,171 @@
+div.simileAjax-bubble-container {
+    margin:     0px;
+    padding:    0px;
+    border:     none;
+    position:   absolute;
+    z-index:    1000;
+}
+
+div.simileAjax-bubble-innerContainer {
+    margin:     0px;
+    padding:    0px;
+    border:     none;
+    position:   relative;
+    width:      100%;
+    height:     100%;
+    overflow:   visible;
+}
+
+div.simileAjax-bubble-contentContainer {
+    margin:     0px;
+    padding:    0px;
+    border:     none;
+    position:   absolute;
+    left:       0px;
+    top:        0px;
+    width:      100%;
+    height:     100%;
+    overflow:   auto;
+    background: white;
+}
+
+div.simileAjax-bubble-border-left {
+    position:   absolute;
+    left:       -50px;
+    top:        0px;
+    width:      50px;
+    height:     100%;
+}
+div.simileAjax-bubble-border-left-pngTranslucent {
+    background: url(../images/bubble-left.png) top right repeat-y;
+}
+
+div.simileAjax-bubble-border-right {
+    position:   absolute;
+    right:      -50px;
+    top:        0px;
+    width:      50px;
+    height:     100%;
+}
+.simileAjax-bubble-border-right-pngTranslucent {
+    background: url(../images/bubble-right.png) top left repeat-y;
+}
+
+div.simileAjax-bubble-border-top {
+    position:   absolute;
+    top:        -50px;
+    left:       0px;
+    width:      100%;
+    height:     50px;
+}
+.simileAjax-bubble-border-top-pngTranslucent {
+    background: url(../images/bubble-top.png) bottom left repeat-x;
+}
+
+div.simileAjax-bubble-border-bottom {
+    position:   absolute;
+    bottom:     -50px;
+    left:       0px;
+    width:      100%;
+    height:     50px;
+}
+.simileAjax-bubble-border-bottom-pngTranslucent {
+    background: url(../images/bubble-bottom.png) top left repeat-x;
+}
+
+div.simileAjax-bubble-border-top-left {
+    position:   absolute;
+    top:        -50px;
+    left:       -50px;
+    width:      50px;
+    height:     50px;
+}
+.simileAjax-bubble-border-top-left-pngTranslucent {
+    background: url(../images/bubble-top-left.png) bottom right no-repeat;
+}
+
+div.simileAjax-bubble-border-top-right {
+    position:   absolute;
+    top:        -50px;
+    right:      -50px;
+    width:      50px;
+    height:     50px;
+}
+.simileAjax-bubble-border-top-right-pngTranslucent {
+    background: url(../images/bubble-top-right.png) bottom left no-repeat;
+}
+
+div.simileAjax-bubble-border-bottom-left {
+    position:   absolute;
+    bottom:     -50px;
+    left:       -50px;
+    width:      50px;
+    height:     50px;
+}
+.simileAjax-bubble-border-bottom-left-pngTranslucent {
+    background: url(../images/bubble-bottom-left.png) top right no-repeat;
+}
+
+div.simileAjax-bubble-border-bottom-right {
+    position:   absolute;
+    bottom:     -50px;
+    right:      -50px;
+    width:      50px;
+    height:     50px;
+}
+.simileAjax-bubble-border-bottom-right-pngTranslucent {
+    background: url(../images/bubble-bottom-right.png) top left no-repeat;
+}
+
+div.simileAjax-bubble-arrow-point-left {
+    position:   absolute;
+    left:       -100px;
+    width:      100px;
+    height:     49px;
+}
+.simileAjax-bubble-arrow-point-left-pngTranslucent {
+    background: url(../images/bubble-arrow-point-left.png) center right no-repeat;
+}
+
+div.simileAjax-bubble-arrow-point-right {
+    position:   absolute;
+    right:      -100px;
+    width:      100px;
+    height:     49px;
+}
+.simileAjax-bubble-arrow-point-right-pngTranslucent {
+    background: url(../images/bubble-arrow-point-right.png) center left no-repeat;
+}
+
+div.simileAjax-bubble-arrow-point-up {
+    position:   absolute;
+    top:        -100px;
+    width:      49px;
+    height:     100px;
+}
+.simileAjax-bubble-arrow-point-up-pngTranslucent {
+    background: url(../images/bubble-arrow-point-up.png) bottom center no-repeat;
+}
+
+div.simileAjax-bubble-arrow-point-down {
+    position:   absolute;
+    bottom:     -100px;
+    width:      49px;
+    height:     100px;
+}
+.simileAjax-bubble-arrow-point-down-pngTranslucent {
+    background: url(../images/bubble-arrow-point-down.png) bottom center no-repeat;
+}
+
+
+div.simileAjax-bubble-close {
+    position:   absolute;
+    right:      -10px;
+    top:        -12px;
+    width:      16px;
+    height:     16px;
+    cursor:     pointer;
+}
+.simileAjax-bubble-close-pngTranslucent {
+    background: url(../images/close-button.png) no-repeat;
+}

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/blue-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/blue-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-bottom-arrow.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-bottom-arrow.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-bottom-left.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-bottom-left.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-bottom-right.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-bottom-right.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-bottom.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-bottom.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-left-arrow.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-left-arrow.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-left.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-left.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-right-arrow.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-right-arrow.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-right.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-right.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-top-arrow.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-top-arrow.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-top-left.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-top-left.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-top-right.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-top-right.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-top.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/bubble-top.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/close-button.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/close-button.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/copyright-vertical.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/copyright-vertical.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/copyright.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/copyright.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/dark-blue-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/dark-blue-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/dark-green-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/dark-green-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/dark-red-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/dark-red-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/dull-blue-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/dull-blue-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/dull-green-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/dull-green-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/dull-red-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/dull-red-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/gray-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/gray-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/green-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/green-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/message-bottom-left.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/message-bottom-left.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/message-bottom-right.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/message-bottom-right.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/message-left.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/message-left.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/message-right.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/message-right.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/message-top-left.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/message-top-left.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/message-top-right.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/message-top-right.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/progress-running.gif
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/progress-running.gif
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/red-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/red-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/top-bubble.png
===================================================================
(Binary files differ)


Property changes on: trunk/step/step-web/src/main/webapp/libs/timeline_js/images/top-bubble.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/cs/labellers.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/cs/labellers.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/cs/labellers.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,30 @@
+/*==================================================
+ *  Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["cs"] = [
+    "Leden", "Únor", "Bøezen", "Duben", "Kvìten", "Èerven", "Èervenec", "Srpen", "Záøí", "Øíjen", "Listopad", "Prosinec"
+];
+
+Timeline.GregorianDateLabeller.dayNames["cs"] = [
+    "Ne", "Po", "Út", "St", "Èt", "Pá", "So"
+];
+
+Timeline.GregorianDateLabeller.labelIntervalFunctions["cs"] = function(date, intervalUnit) {
+    var text;
+    var emphasized = false;
+
+    var date2 = Timeline.DateTime.removeTimeZoneOffset(date, this._timeZone);
+    
+    switch(intervalUnit) {
+    case Timeline.DateTime.DAY:
+    case Timeline.DateTime.WEEK:
+        text = date2.getUTCDate() + ". " + (date2.getUTCMonth() + 1) + ".";
+        break;
+    default:
+        return this.defaultLabelInterval(date, intervalUnit);
+    }
+    
+    return { text: text, emphasized: emphasized };
+};

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/cs/timeline.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/cs/timeline.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/cs/timeline.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,9 @@
+/*==================================================
+ *  Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["cs"] = {
+    wikiLinkLabel:  "Diskuze"
+};
+

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/de/labellers.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/de/labellers.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/de/labellers.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,27 @@
+/*==================================================
+ *  Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["de"] = [
+    "Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"
+];
+
+Timeline.GregorianDateLabeller.labelIntervalFunctions["de"] = function(date, intervalUnit) {
+    var text;
+    var emphasized = false;
+    
+    var date2 = Timeline.DateTime.removeTimeZoneOffset(date, this._timeZone);
+    
+    switch(intervalUnit) {
+    case Timeline.DateTime.DAY:
+    case Timeline.DateTime.WEEK:
+        text = date2.getUTCDate() + ". " +
+            Timeline.GregorianDateLabeller.getMonthName(date2.getUTCMonth(), this._locale);
+        break;
+    default:
+        return this.defaultLabelInterval(date, intervalUnit);
+    }
+    
+    return { text: text, emphasized: emphasized };
+};
\ No newline at end of file

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/de/timeline.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/de/timeline.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/de/timeline.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,8 @@
+/*==================================================
+ *  Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["de"] = {
+    wikiLinkLabel:  "Diskutieren"
+};

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/en/labellers.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/en/labellers.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/en/labellers.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,12 @@
+/*==================================================
+ *  Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["en"] = [
+    "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+];
+
+Timeline.GregorianDateLabeller.dayNames["en"] = [
+    "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
+];

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/en/timeline.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/en/timeline.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/en/timeline.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,9 @@
+/*==================================================
+ *  Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["en"] = {
+    wikiLinkLabel:  "Discuss"
+};
+

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/es/labellers.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/es/labellers.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/es/labellers.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,8 @@
+/*==================================================
+ *  Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["es"] = [
+    "Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"
+];

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/es/timeline.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/es/timeline.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/es/timeline.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,9 @@
+/*==================================================
+ *  Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["es"] = {
+    wikiLinkLabel:  "Discute"
+};
+

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/fr/labellers.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/fr/labellers.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/fr/labellers.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,8 @@
+/*==================================================
+ *  Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["fr"] = [
+    "jan", "fev", "mar", "avr", "mai", "jui", "jui", "aou", "sep", "oct", "nov", "dec"
+];

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/fr/timeline.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/fr/timeline.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/fr/timeline.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,9 @@
+/*==================================================
+ *  Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["fr"] = {
+    wikiLinkLabel:  "Discute"
+};
+

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/it/labellers.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/it/labellers.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/it/labellers.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,8 @@
+/*==================================================
+ *  Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["it"] = [
+    "Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"
+];

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/it/timeline.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/it/timeline.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/it/timeline.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,9 @@
+/*==================================================
+ *  Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["it"] = {
+    wikiLinkLabel:  "Discuti"
+};
+

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/nl/labellers.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/nl/labellers.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/nl/labellers.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,11 @@
+/*==================================================
+ *  Localization of labellers.js
+ *==================================================
+ */
+
+/* The Dutch do not capitalize months
+*/
+
+Timeline.GregorianDateLabeller.monthNames["nl"] = [
+ "jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec"
+];

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/nl/timeline.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/nl/timeline.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/nl/timeline.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,9 @@
+/*==================================================
+ *  Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["nl"] = {
+    wikiLinkLabel:  "Discussieer"
+};
+

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/ru/labellers.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/ru/labellers.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/ru/labellers.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,10 @@
+/*==================================================
+ *  Localization of labellers.js
+ * 
+ *  UTF-8 encoded
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["ru"] = [
+    "Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек"
+];

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/ru/timeline.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/ru/timeline.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/ru/timeline.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,9 @@
+/*==================================================
+ *  Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["ru"] = {
+    wikiLinkLabel:  "обсудите"
+};
+

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/se/labellers.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/se/labellers.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/se/labellers.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,12 @@
+/*==================================================
+ *  Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["se"] = [
+    "Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"
+];
+
+Timeline.GregorianDateLabeller.dayNames["se"] = [
+    "Sön", "Mån", "Tis", "Ons", "Tors", "Fre", "Lör"
+];

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/se/timeline.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/se/timeline.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/se/timeline.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,9 @@
+/*==================================================
+ *  Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["se"] = {
+    wikiLinkLabel:  "Discuss"
+};
+

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/tr/labellers.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/tr/labellers.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/tr/labellers.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,8 @@
+/*==================================================
+ *  Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["tr"] = [
+    "Ock", "Åžbt", "Mrt", "Nsn", "Mys", "Hzr", "Tem", "AÄŸs", "Eyl", "Ekm", "Ksm", "Arl"
+];

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/tr/timeline.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/tr/timeline.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/tr/timeline.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,9 @@
+/*==================================================
+ *  Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["tr"] = {
+    wikiLinkLabel:  "Tartış"
+};
+

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/vi/labellers.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/vi/labellers.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/vi/labellers.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,26 @@
+/*==================================================
+ *  Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["vi"] = [
+    "Tháng 1", "Tháng 2", "Tháng 3", "Tháng 4", "Tháng 5", "Tháng 6", "Tháng 7", "Tháng 8", "Tháng 9", "Tháng 10", "Tháng 11", "Tháng 12"
+];
+
+Timeline.GregorianDateLabeller.labelIntervalFunctions["vi"] = function(date, intervalUnit) {
+    var text;
+    var emphasized = false;
+    
+    var date2 = Timeline.DateTime.removeTimeZoneOffset(date, this._timeZone);
+    
+    switch(intervalUnit) {
+    case Timeline.DateTime.DAY:
+    case Timeline.DateTime.WEEK:
+        text = date2.getUTCDate() + "/" + (date2.getUTCMonth() + 1);
+        break;
+    default:
+        return this.defaultLabelInterval(date, intervalUnit);
+    }
+    
+    return { text: text, emphasized: emphasized };
+};

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/vi/timeline.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/vi/timeline.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/vi/timeline.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,9 @@
+/*==================================================
+ *  Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["vi"] = {
+    wikiLinkLabel:  "Bàn luận"
+};
+

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/zh/labellers.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/zh/labellers.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/zh/labellers.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,27 @@
+/*==================================================
+ *  Localization of labellers.js
+ *==================================================
+ */
+
+Timeline.GregorianDateLabeller.monthNames["zh"] = [
+    "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"
+];
+
+Timeline.GregorianDateLabeller.labelIntervalFunctions["zh"] = function(date, intervalUnit) {
+    var text;
+    var emphasized = false;
+    
+    var date2 = Timeline.DateTime.removeTimeZoneOffset(date, this._timeZone);
+    
+    switch(intervalUnit) {
+    case Timeline.DateTime.DAY:
+    case Timeline.DateTime.WEEK:
+        text = Timeline.GregorianDateLabeller.getMonthName(date2.getUTCMonth(), this._locale) + 
+            date2.getUTCDate() + "æ—¥";
+        break;
+    default:
+        return this.defaultLabelInterval(date, intervalUnit);
+    }
+    
+    return { text: text, emphasized: emphasized };
+};
\ No newline at end of file

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/zh/timeline.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/zh/timeline.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/scripts/l10n/zh/timeline.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,9 @@
+/*==================================================
+ *  Common localization strings
+ *==================================================
+ */
+
+Timeline.strings["zh"] = {
+    wikiLinkLabel:  "讨论"
+};
+

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/timeline-api.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/timeline-api.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/timeline-api.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,280 @@
+/*==================================================
+ *  Timeline API
+ *
+ *  This file will load all the Javascript files
+ *  necessary to make the standard timeline work.
+ *  It also detects the default locale.
+ *
+ *  To run from the MIT copy of Timeline:
+ *  Include this file in your HTML file as follows:
+ *
+ *    <script src="http://static.simile.mit.edu/timeline/api-2.3.0/timeline-api.js" 
+ *     type="text/javascript"></script>
+ *
+ *
+ * To host the Timeline files on your own server:
+ *   1) Install the Timeline and Simile-Ajax files onto your webserver using
+ *      timeline_libraries.zip or timeline_source.zip
+ * 
+ *   2) Set global js variables used to send parameters to this script:
+ *        Timeline_ajax_url -- url for simile-ajax-api.js
+ *        Timeline_urlPrefix -- url for the *directory* that contains timeline-api.js
+ *          Include trailing slash
+ *        Timeline_parameters='bundle=true'; // you must set bundle to true if you are using
+ *                                           // timeline_libraries.zip since only the
+ *                                           // bundled libraries are included
+ *      
+ * eg your html page would include
+ *
+ *   <script>
+ *     Timeline_ajax_url="http://YOUR_SERVER/javascripts/timeline/timeline_ajax/simile-ajax-api.js";
+ *     Timeline_urlPrefix='http://YOUR_SERVER/javascripts/timeline/timeline_js/';       
+ *     Timeline_parameters='bundle=true';
+ *   </script>
+ *   <script src="http://YOUR_SERVER/javascripts/timeline/timeline_js/timeline-api.js"    
+ *     type="text/javascript">
+ *   </script>
+ *
+ * SCRIPT PARAMETERS
+ * This script auto-magically figures out locale and has defaults for other parameters 
+ * To set parameters explicity, set js global variable Timeline_parameters or include as
+ * parameters on the url using GET style. Eg the two next lines pass the same parameters:
+ *     Timeline_parameters='bundle=true';                    // pass parameter via js variable
+ *     <script src="http://....timeline-api.js?bundle=true"  // pass parameter via url
+ * 
+ * Parameters 
+ *   timeline-use-local-resources -- 
+ *   bundle -- true: use the single js bundle file; false: load individual files (for debugging)
+ *   locales -- 
+ *   defaultLocale --
+ *   forceLocale -- force locale to be a particular value--used for debugging. Normally locale is determined
+ *                  by browser's and server's locale settings.
+ *================================================== 
+ */
+
+(function() {
+    var useLocalResources = false;
+    if (document.location.search.length > 0) {
+        var params = document.location.search.substr(1).split("&");
+        for (var i = 0; i < params.length; i++) {
+            if (params[i] == "timeline-use-local-resources") {
+                useLocalResources = true;
+            }
+        }
+    };
+    
+    var loadMe = function() {
+        if ("Timeline" in window) {
+            return;
+        }
+        
+        window.Timeline = new Object();
+        window.Timeline.DateTime = window.SimileAjax.DateTime; // for backward compatibility
+    
+        var bundle = false;
+        var javascriptFiles = [
+            "timeline.js",
+            "band.js",
+            "themes.js",
+            "ethers.js",
+            "ether-painters.js",
+            "event-utils.js",
+            "labellers.js",
+            "sources.js",
+            "original-painter.js",
+            "detailed-painter.js",
+            "overview-painter.js",
+            "compact-painter.js",
+            "decorators.js",
+            "units.js"
+        ];
+        var cssFiles = [
+            "timeline.css",
+            "ethers.css",
+            "events.css"
+        ];
+        
+        var localizedJavascriptFiles = [
+            "timeline.js",
+            "labellers.js"
+        ];
+        var localizedCssFiles = [
+        ];
+        
+        // ISO-639 language codes, ISO-3166 country codes (2 characters)
+        var supportedLocales = [
+            "cs",       // Czech
+            "de",       // German
+            "en",       // English
+            "es",       // Spanish
+            "fr",       // French
+            "it",       // Italian
+            "nl",       // Dutch (The Netherlands)
+            "ru",       // Russian
+            "se",       // Swedish
+            "tr",       // Turkish
+            "vi",       // Vietnamese
+            "zh"        // Chinese
+        ];
+        
+        try {
+            var desiredLocales = [ "en" ],
+                defaultServerLocale = "en",
+                forceLocale = null;
+            
+            var parseURLParameters = function(parameters) {
+                var params = parameters.split("&");
+                for (var p = 0; p < params.length; p++) {
+                    var pair = params[p].split("=");
+                    if (pair[0] == "locales") {
+                        desiredLocales = desiredLocales.concat(pair[1].split(","));
+                    } else if (pair[0] == "defaultLocale") {
+                        defaultServerLocale = pair[1];
+                    } else if (pair[0] == "forceLocale") {
+                        forceLocale = pair[1];
+                        desiredLocales = desiredLocales.concat(pair[1].split(","));                        
+                    } else if (pair[0] == "bundle") {
+                        bundle = pair[1] != "false";
+                    }
+                }
+            };
+            
+            (function() {
+                if (typeof Timeline_urlPrefix == "string") {
+                    Timeline.urlPrefix = Timeline_urlPrefix;
+                    if (typeof Timeline_parameters == "string") {
+                        parseURLParameters(Timeline_parameters);
+                    }
+                } else {
+                    var heads = document.documentElement.getElementsByTagName("head");
+                    for (var h = 0; h < heads.length; h++) {
+                        var scripts = heads[h].getElementsByTagName("script");
+                        for (var s = 0; s < scripts.length; s++) {
+                            var url = scripts[s].src;
+                            var i = url.indexOf("timeline-api.js");
+                            if (i >= 0) {
+                                Timeline.urlPrefix = url.substr(0, i);
+                                var q = url.indexOf("?");
+                                if (q > 0) {
+                                    parseURLParameters(url.substr(q + 1));
+                                }
+                                return;
+                            }
+                        }
+                    }
+                    throw new Error("Failed to derive URL prefix for Timeline API code files");
+                }
+            })();
+            
+            var includeJavascriptFiles = function(urlPrefix, filenames) {
+                SimileAjax.includeJavascriptFiles(document, urlPrefix, filenames);
+            }
+            var includeCssFiles = function(urlPrefix, filenames) {
+                SimileAjax.includeCssFiles(document, urlPrefix, filenames);
+            }
+            
+            /*
+             *  Include non-localized files
+             */
+            if (bundle) {
+                includeJavascriptFiles(Timeline.urlPrefix, [ "timeline-bundle.js" ]);
+                includeCssFiles(Timeline.urlPrefix, [ "timeline-bundle.css" ]);
+            } else {
+                includeJavascriptFiles(Timeline.urlPrefix + "scripts/", javascriptFiles);
+                includeCssFiles(Timeline.urlPrefix + "styles/", cssFiles);
+            }
+            
+            /*
+             *  Include localized files
+             */
+            var loadLocale = [];
+            loadLocale[defaultServerLocale] = true;
+            
+            var tryExactLocale = function(locale) {
+                for (var l = 0; l < supportedLocales.length; l++) {
+                    if (locale == supportedLocales[l]) {
+                        loadLocale[locale] = true;
+                        return true;
+                    }
+                }
+                return false;
+            }
+            var tryLocale = function(locale) {
+                if (tryExactLocale(locale)) {
+                    return locale;
+                }
+                
+                var dash = locale.indexOf("-");
+                if (dash > 0 && tryExactLocale(locale.substr(0, dash))) {
+                    return locale.substr(0, dash);
+                }
+                
+                return null;
+            }
+            
+            for (var l = 0; l < desiredLocales.length; l++) {
+                tryLocale(desiredLocales[l]);
+            }
+            
+            var defaultClientLocale = defaultServerLocale;
+            var defaultClientLocales = ("language" in navigator ? navigator.language : navigator.browserLanguage).split(";");
+            for (var l = 0; l < defaultClientLocales.length; l++) {
+                var locale = tryLocale(defaultClientLocales[l]);
+                if (locale != null) {
+                    defaultClientLocale = locale;
+                    break;
+                }
+            }
+            
+            for (var l = 0; l < supportedLocales.length; l++) {
+                var locale = supportedLocales[l];
+                if (loadLocale[locale]) {
+                    includeJavascriptFiles(Timeline.urlPrefix + "scripts/l10n/" + locale + "/", localizedJavascriptFiles);
+                    includeCssFiles(Timeline.urlPrefix + "styles/l10n/" + locale + "/", localizedCssFiles);
+                }
+            }
+            
+            if (forceLocale == null) {
+              Timeline.serverLocale = defaultServerLocale;
+              Timeline.clientLocale = defaultClientLocale;
+            } else {
+              Timeline.serverLocale = forceLocale;
+              Timeline.clientLocale = forceLocale;
+            }            	
+        } catch (e) {
+            alert(e);
+        }
+    };
+    
+    /*
+     *  Load SimileAjax if it's not already loaded
+     */
+    if (typeof SimileAjax == "undefined") {
+        window.SimileAjax_onLoad = loadMe;
+        
+        var url = useLocalResources ?
+            "http://127.0.0.1:9999/ajax/api/simile-ajax-api.js?bundle=false" :
+            "http://static.simile.mit.edu/ajax/api-2.2.0/simile-ajax-api.js";
+        if (typeof Timeline_ajax_url == "string") {
+           url = Timeline_ajax_url;
+        }
+        var createScriptElement = function() {
+            var script = document.createElement("script");
+            script.type = "text/javascript";
+            script.language = "JavaScript";
+            script.src = url;
+            document.getElementsByTagName("head")[0].appendChild(script);
+        }
+        if (document.body == null) {
+            try {
+                document.write("<script src='" + url + "' type='text/javascript'></script>");
+            } catch (e) {
+                createScriptElement();
+            }
+        } else {
+            createScriptElement();
+        }
+    } else {
+        loadMe();
+    }
+})();

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/timeline-bundle.css
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/timeline-bundle.css	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/timeline-bundle.css	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,229 @@
+
+
+/*------------------- Horizontal / Vertical lines ----------------*/
+
+/* style for ethers */
+.timeline-ether-lines{border-color:#666; border-style:dotted; position:absolute;}
+.timeline-horizontal .timeline-ether-lines{border-width:0 0 0 1px; height:100%; top: 0; width: 1px;}
+.timeline-vertical .timeline-ether-lines{border-width:1px 0 0; height:1px; left: 0; width: 100%;}
+
+
+
+/*---------------- Weekends ---------------------------*/
+.timeline-ether-weekends{
+	position:absolute;
+	background-color:#FFFFE0;
+}
+
+.timeline-vertical .timeline-ether-weekends{left:0;width:100%;}
+.timeline-horizontal .timeline-ether-weekends{top:0; height:100%;}
+
+
+/*-------------------------- HIGHLIGHT DECORATORS -------------------*/
+/* Used for decorators, not used for Timeline Highlight              */
+.timeline-highlight-decorator,
+.timeline-highlight-point-decorator{
+	position:absolute;
+	overflow:hidden;
+}
+
+/* Width of horizontal decorators and Height of vertical decorators is
+   set in the decorator function params */
+.timeline-horizontal .timeline-highlight-point-decorator,
+.timeline-horizontal .timeline-highlight-decorator{
+	top:0;
+  height:100%;
+}
+
+.timeline-vertical .timeline-highlight-point-decorator,
+.timeline-vertical .timeline-highlight-decorator{
+	width:100%;
+	left:0;
+}
+
+.timeline-highlight-decorator{background-color:#FFC080;}
+.timeline-highlight-point-decorator{background-color:#ff5;}
+
+
+/*---------------------------- LABELS -------------------------*/
+.timeline-highlight-label {
+  position:absolute; overflow:hidden; font-size:200%;
+  font-weight:bold; color:#999; }
+
+
+/*---------------- VERTICAL LABEL -------------------*/
+.timeline-horizontal .timeline-highlight-label {top:0; height:100%;}
+.timeline-horizontal .timeline-highlight-label td {vertical-align:middle;}
+.timeline-horizontal .timeline-highlight-label-start {text-align:right;}
+.timeline-horizontal .timeline-highlight-label-end {text-align:left;}
+
+
+/*---------------- HORIZONTAL LABEL -------------------*/
+.timeline-vertical .timeline-highlight-label {left:0;width:100%;}
+.timeline-vertical .timeline-highlight-label td {vertical-align:top;}
+.timeline-vertical .timeline-highlight-label-start {text-align:center;}
+.timeline-vertical .timeline-highlight-label-end {text-align:center;}
+
+
+/*-------------------------------- DATE LABELS --------------------------------*/
+.timeline-date-label {
+  position: absolute;
+  border: solid #aaa;
+  color: #aaa;
+  width: 5em;
+  height: 1.5em;}
+.timeline-date-label-em {color: #000;}
+
+/* horizontal */
+.timeline-horizontal .timeline-date-label{padding-left:2px;}
+.timeline-horizontal .timeline-date-label{border-width:0 0 0 1px;}
+.timeline-horizontal .timeline-date-label-em{height:2em}
+
+/* vertical */
+.timeline-vertical .timeline-date-label{padding-top:2px;}
+.timeline-vertical .timeline-date-label{border-width:1px 0 0;}
+.timeline-vertical .timeline-date-label-em{width:7em}
+
+
+/*------------------------------- Ether.highlight -------------------------*/
+.timeline-ether-highlight{position:absolute; background-color:#fff;}
+.timeline-horizontal .timeline-ether-highlight{top:2px;}
+.timeline-vertical .timeline-ether-highlight{left:2px;}
+
+
+/*------------------------------ EVENTS ------------------------------------*/
+.timeline-event-icon, .timeline-event-label,.timeline-event-tape{
+	position:absolute;
+	cursor:pointer;
+}
+
+.timeline-event-tape,
+.timeline-small-event-tape,
+.timeline-small-event-icon{
+	background-color:#58A0DC;
+	overflow:hidden;
+}
+
+.timeline-small-event-tape,
+.timeline-small-event-icon{
+	position:absolute;
+}
+
+.timeline-small-event-icon{width:1px; height:6px;}
+
+  
+/*--------------------------------- TIMELINE-------------------------*/
+.timeline-ether-bg{width:100%; height:100%;}
+.timeline-band-0 .timeline-ether-bg{background-color:#eee}
+.timeline-band-1 .timeline-ether-bg{background-color:#ddd}
+.timeline-band-2 .timeline-ether-bg{background-color:#ccc}
+.timeline-band-3 .timeline-ether-bg{background-color:#aaa}
+.timeline-duration-event {
+    position: absolute;
+    overflow: hidden;
+    border: 1px solid blue;
+}
+
+.timeline-instant-event2 {
+    position: absolute;
+    overflow: hidden;
+    border-left: 1px solid blue;
+    padding-left: 2px;
+}
+
+.timeline-instant-event {
+    position: absolute;
+    overflow: hidden;
+}
+
+.timeline-event-bubble-title {
+    font-weight: bold;
+    border-bottom: 1px solid #888;
+    margin-bottom: 0.5em;
+}
+
+.timeline-event-bubble-body {
+}
+
+.timeline-event-bubble-wiki {
+    margin:     0.5em;
+    text-align: right;
+    color:      #A0A040;
+}
+.timeline-event-bubble-wiki a {
+    color:      #A0A040;
+}
+
+.timeline-event-bubble-time {
+    color: #aaa;
+}
+
+.timeline-event-bubble-image {
+    float: right;
+    padding-left: 5px;
+    padding-bottom: 5px;
+}.timeline-container {
+    position: relative;
+    overflow: hidden;
+}
+
+.timeline-copyright {
+    position: absolute;
+    bottom: 0px;
+    left: 0px;
+    z-index: 1000;
+    cursor: pointer;
+}
+
+.timeline-message-container {
+    position:   absolute;
+    top:        30%;
+    left:       35%;
+    right:      35%;
+    z-index:    1000;
+    display:    none;
+}
+.timeline-message {
+    font-size:      120%;
+    font-weight:    bold;
+    text-align:     center;
+}
+.timeline-message img {
+    vertical-align: middle;
+}
+
+.timeline-band {
+    position:   absolute;
+    background: #eee;
+    z-index:    10;
+}
+
+.timeline-band-inner {
+    position: relative;
+    width: 100%;
+    height: 100%;
+}
+
+.timeline-band-input {
+    position:   absolute;
+    width:      1em;
+    height:     1em;
+    overflow:   hidden;
+    z-index:    0;
+}
+.timeline-band-input input{
+    width:      0;
+}
+
+.timeline-band-layer {
+    position:   absolute;
+    width:      100%;
+    height:     100%;
+}
+
+.timeline-band-layer-inner {
+    position:   relative;
+    width:      100%;
+    height:     100%;
+}
+

Added: trunk/step/step-web/src/main/webapp/libs/timeline_js/timeline-bundle.js
===================================================================
--- trunk/step/step-web/src/main/webapp/libs/timeline_js/timeline-bundle.js	                        (rev 0)
+++ trunk/step/step-web/src/main/webapp/libs/timeline_js/timeline-bundle.js	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,2835 @@
+
+
+/* band.js */
+Timeline._Band=function(B,G,C){if(B.autoWidth&&typeof G.width=="string"){G.width=G.width.indexOf("%")>-1?0:parseInt(G.width);
+}this._timeline=B;
+this._bandInfo=G;
+this._index=C;
+this._locale=("locale" in G)?G.locale:Timeline.getDefaultLocale();
+this._timeZone=("timeZone" in G)?G.timeZone:0;
+this._labeller=("labeller" in G)?G.labeller:(("createLabeller" in B.getUnit())?B.getUnit().createLabeller(this._locale,this._timeZone):new Timeline.GregorianDateLabeller(this._locale,this._timeZone));
+this._theme=G.theme;
+this._zoomIndex=("zoomIndex" in G)?G.zoomIndex:0;
+this._zoomSteps=("zoomSteps" in G)?G.zoomSteps:null;
+this._dragging=false;
+this._changing=false;
+this._originalScrollSpeed=5;
+this._scrollSpeed=this._originalScrollSpeed;
+this._onScrollListeners=[];
+var A=this;
+this._syncWithBand=null;
+this._syncWithBandHandler=function(H){A._onHighlightBandScroll();
+};
+this._selectorListener=function(H){A._onHighlightBandScroll();
+};
+var E=this._timeline.getDocument().createElement("div");
+E.className="timeline-band-input";
+this._timeline.addDiv(E);
+this._keyboardInput=document.createElement("input");
+this._keyboardInput.type="text";
+E.appendChild(this._keyboardInput);
+SimileAjax.DOM.registerEventWithObject(this._keyboardInput,"keydown",this,"_onKeyDown");
+SimileAjax.DOM.registerEventWithObject(this._keyboardInput,"keyup",this,"_onKeyUp");
+this._div=this._timeline.getDocument().createElement("div");
+this._div.id="timeline-band-"+C;
+this._div.className="timeline-band timeline-band-"+C;
+this._timeline.addDiv(this._div);
+SimileAjax.DOM.registerEventWithObject(this._div,"mousedown",this,"_onMouseDown");
+SimileAjax.DOM.registerEventWithObject(this._div,"mousemove",this,"_onMouseMove");
+SimileAjax.DOM.registerEventWithObject(this._div,"mouseup",this,"_onMouseUp");
+SimileAjax.DOM.registerEventWithObject(this._div,"mouseout",this,"_onMouseOut");
+SimileAjax.DOM.registerEventWithObject(this._div,"dblclick",this,"_onDblClick");
+var F=this._theme!=null?this._theme.mouseWheel:"scroll";
+if(F==="zoom"||F==="scroll"||this._zoomSteps){if(SimileAjax.Platform.browser.isFirefox){SimileAjax.DOM.registerEventWithObject(this._div,"DOMMouseScroll",this,"_onMouseScroll");
+}else{SimileAjax.DOM.registerEventWithObject(this._div,"mousewheel",this,"_onMouseScroll");
+}}this._innerDiv=this._timeline.getDocument().createElement("div");
+this._innerDiv.className="timeline-band-inner";
+this._div.appendChild(this._innerDiv);
+this._ether=G.ether;
+G.ether.initialize(this,B);
+this._etherPainter=G.etherPainter;
+G.etherPainter.initialize(this,B);
+this._eventSource=G.eventSource;
+if(this._eventSource){this._eventListener={onAddMany:function(){A._onAddMany();
+},onClear:function(){A._onClear();
+}};
+this._eventSource.addListener(this._eventListener);
+}this._eventPainter=G.eventPainter;
+this._eventTracksNeeded=0;
+this._eventTrackIncrement=0;
+G.eventPainter.initialize(this,B);
+this._decorators=("decorators" in G)?G.decorators:[];
+for(var D=0;
+D<this._decorators.length;
+D++){this._decorators[D].initialize(this,B);
+}};
+Timeline._Band.SCROLL_MULTIPLES=5;
+Timeline._Band.prototype.dispose=function(){this.closeBubble();
+if(this._eventSource){this._eventSource.removeListener(this._eventListener);
+this._eventListener=null;
+this._eventSource=null;
+}this._timeline=null;
+this._bandInfo=null;
+this._labeller=null;
+this._ether=null;
+this._etherPainter=null;
+this._eventPainter=null;
+this._decorators=null;
+this._onScrollListeners=null;
+this._syncWithBandHandler=null;
+this._selectorListener=null;
+this._div=null;
+this._innerDiv=null;
+this._keyboardInput=null;
+};
+Timeline._Band.prototype.addOnScrollListener=function(A){this._onScrollListeners.push(A);
+};
+Timeline._Band.prototype.removeOnScrollListener=function(B){for(var A=0;
+A<this._onScrollListeners.length;
+A++){if(this._onScrollListeners[A]==B){this._onScrollListeners.splice(A,1);
+break;
+}}};
+Timeline._Band.prototype.setSyncWithBand=function(B,A){if(this._syncWithBand){this._syncWithBand.removeOnScrollListener(this._syncWithBandHandler);
+}this._syncWithBand=B;
+this._syncWithBand.addOnScrollListener(this._syncWithBandHandler);
+this._highlight=A;
+this._positionHighlight();
+};
+Timeline._Band.prototype.getLocale=function(){return this._locale;
+};
+Timeline._Band.prototype.getTimeZone=function(){return this._timeZone;
+};
+Timeline._Band.prototype.getLabeller=function(){return this._labeller;
+};
+Timeline._Band.prototype.getIndex=function(){return this._index;
+};
+Timeline._Band.prototype.getEther=function(){return this._ether;
+};
+Timeline._Band.prototype.getEtherPainter=function(){return this._etherPainter;
+};
+Timeline._Band.prototype.getEventSource=function(){return this._eventSource;
+};
+Timeline._Band.prototype.getEventPainter=function(){return this._eventPainter;
+};
+Timeline._Band.prototype.getTimeline=function(){return this._timeline;
+};
+Timeline._Band.prototype.updateEventTrackInfo=function(A,B){this._eventTrackIncrement=B;
+if(A>this._eventTracksNeeded){this._eventTracksNeeded=A;
+}};
+Timeline._Band.prototype.checkAutoWidth=function(){if(!this._timeline.autoWidth){return ;
+}var C=this._eventPainter.getType()=="overview";
+var A=C?this._theme.event.overviewTrack.autoWidthMargin:this._theme.event.track.autoWidthMargin;
+var B=Math.ceil((this._eventTracksNeeded+A)*this._eventTrackIncrement);
+B+=C?this._theme.event.overviewTrack.offset:this._theme.event.track.offset;
+var D=this._bandInfo;
+if(B!=D.width){D.width=B;
+}};
+Timeline._Band.prototype.layout=function(){this.paint();
+};
+Timeline._Band.prototype.paint=function(){this._etherPainter.paint();
+this._paintDecorators();
+this._paintEvents();
+};
+Timeline._Band.prototype.softLayout=function(){this.softPaint();
+};
+Timeline._Band.prototype.softPaint=function(){this._etherPainter.softPaint();
+this._softPaintDecorators();
+this._softPaintEvents();
+};
+Timeline._Band.prototype.setBandShiftAndWidth=function(A,D){var C=this._keyboardInput.parentNode;
+var B=A+Math.floor(D/2);
+if(this._timeline.isHorizontal()){this._div.style.top=A+"px";
+this._div.style.height=D+"px";
+C.style.top=B+"px";
+C.style.left="-1em";
+}else{this._div.style.left=A+"px";
+this._div.style.width=D+"px";
+C.style.left=B+"px";
+C.style.top="-1em";
+}};
+Timeline._Band.prototype.getViewWidth=function(){if(this._timeline.isHorizontal()){return this._div.offsetHeight;
+}else{return this._div.offsetWidth;
+}};
+Timeline._Band.prototype.setViewLength=function(A){this._viewLength=A;
+this._recenterDiv();
+this._onChanging();
+};
+Timeline._Band.prototype.getViewLength=function(){return this._viewLength;
+};
+Timeline._Band.prototype.getTotalViewLength=function(){return Timeline._Band.SCROLL_MULTIPLES*this._viewLength;
+};
+Timeline._Band.prototype.getViewOffset=function(){return this._viewOffset;
+};
+Timeline._Band.prototype.getMinDate=function(){return this._ether.pixelOffsetToDate(this._viewOffset);
+};
+Timeline._Band.prototype.getMaxDate=function(){return this._ether.pixelOffsetToDate(this._viewOffset+Timeline._Band.SCROLL_MULTIPLES*this._viewLength);
+};
+Timeline._Band.prototype.getMinVisibleDate=function(){return this._ether.pixelOffsetToDate(0);
+};
+Timeline._Band.prototype.getMinVisibleDateAfterDelta=function(A){return this._ether.pixelOffsetToDate(A);
+};
+Timeline._Band.prototype.getMaxVisibleDate=function(){return this._ether.pixelOffsetToDate(this._viewLength);
+};
+Timeline._Band.prototype.getMaxVisibleDateAfterDelta=function(A){return this._ether.pixelOffsetToDate(this._viewLength+A);
+};
+Timeline._Band.prototype.getCenterVisibleDate=function(){return this._ether.pixelOffsetToDate(this._viewLength/2);
+};
+Timeline._Band.prototype.setMinVisibleDate=function(A){if(!this._changing){this._moveEther(Math.round(-this._ether.dateToPixelOffset(A)));
+}};
+Timeline._Band.prototype.setMaxVisibleDate=function(A){if(!this._changing){this._moveEther(Math.round(this._viewLength-this._ether.dateToPixelOffset(A)));
+}};
+Timeline._Band.prototype.setCenterVisibleDate=function(A){if(!this._changing){this._moveEther(Math.round(this._viewLength/2-this._ether.dateToPixelOffset(A)));
+}};
+Timeline._Band.prototype.dateToPixelOffset=function(A){return this._ether.dateToPixelOffset(A)-this._viewOffset;
+};
+Timeline._Band.prototype.pixelOffsetToDate=function(A){return this._ether.pixelOffsetToDate(A+this._viewOffset);
+};
+Timeline._Band.prototype.createLayerDiv=function(C,A){var D=this._timeline.getDocument().createElement("div");
+D.className="timeline-band-layer"+(typeof A=="string"?(" "+A):"");
+D.style.zIndex=C;
+this._innerDiv.appendChild(D);
+var B=this._timeline.getDocument().createElement("div");
+B.className="timeline-band-layer-inner";
+if(SimileAjax.Platform.browser.isIE){B.style.cursor="move";
+}else{B.style.cursor="-moz-grab";
+}D.appendChild(B);
+return B;
+};
+Timeline._Band.prototype.removeLayerDiv=function(A){this._innerDiv.removeChild(A.parentNode);
+};
+Timeline._Band.prototype.scrollToCenter=function(A,C){var B=this._ether.dateToPixelOffset(A);
+if(B<-this._viewLength/2){this.setCenterVisibleDate(this.pixelOffsetToDate(B+this._viewLength));
+}else{if(B>3*this._viewLength/2){this.setCenterVisibleDate(this.pixelOffsetToDate(B-this._viewLength));
+}}this._autoScroll(Math.round(this._viewLength/2-this._ether.dateToPixelOffset(A)),C);
+};
+Timeline._Band.prototype.showBubbleForEvent=function(C){var A=this.getEventSource().getEvent(C);
+if(A){var B=this;
+this.scrollToCenter(A.getStart(),function(){B._eventPainter.showBubble(A);
+});
+}};
+Timeline._Band.prototype.zoom=function(C,A,F,E){if(!this._zoomSteps){return ;
+}A+=this._viewOffset;
+var D=this._ether.pixelOffsetToDate(A);
+var B=this._ether.zoom(C);
+this._etherPainter.zoom(B);
+this._moveEther(Math.round(-this._ether.dateToPixelOffset(D)));
+this._moveEther(A);
+};
+Timeline._Band.prototype._onMouseDown=function(B,A,C){this.closeBubble();
+this._dragging=true;
+this._dragX=A.clientX;
+this._dragY=A.clientY;
+};
+Timeline._Band.prototype._onMouseMove=function(D,A,E){if(this._dragging){var C=A.clientX-this._dragX;
+var B=A.clientY-this._dragY;
+this._dragX=A.clientX;
+this._dragY=A.clientY;
+this._moveEther(this._timeline.isHorizontal()?C:B);
+this._positionHighlight();
+}};
+Timeline._Band.prototype._onMouseUp=function(B,A,C){this._dragging=false;
+this._keyboardInput.focus();
+};
+Timeline._Band.prototype._onMouseOut=function(C,B,D){var A=SimileAjax.DOM.getEventRelativeCoordinates(B,C);
+A.x+=this._viewOffset;
+if(A.x<0||A.x>C.offsetWidth||A.y<0||A.y>C.offsetHeight){this._dragging=false;
+}};
+Timeline._Band.prototype._onMouseScroll=function(G,H,B){var A=new Date();
+A=A.getTime();
+if(!this._lastScrollTime||((A-this._lastScrollTime)>50)){this._lastScrollTime=A;
+var I=0;
+if(H.wheelDelta){I=H.wheelDelta/120;
+}else{if(H.detail){I=-H.detail/3;
+}}var F=this._theme.mouseWheel;
+if(this._zoomSteps||F==="zoom"){var E=SimileAjax.DOM.getEventRelativeCoordinates(H,G);
+if(I!=0){var D;
+if(I>0){D=true;
+}if(I<0){D=false;
+}this._timeline.zoom(D,E.x,E.y,G);
+}}else{if(F==="scroll"){var C=50*(I<0?-1:1);
+this._moveEther(C);
+}}}if(H.stopPropagation){H.stopPropagation();
+}H.cancelBubble=true;
+if(H.preventDefault){H.preventDefault();
+}H.returnValue=false;
+};
+Timeline._Band.prototype._onDblClick=function(C,B,E){var A=SimileAjax.DOM.getEventRelativeCoordinates(B,C);
+var D=A.x-(this._viewLength/2-this._viewOffset);
+this._autoScroll(-D);
+};
+Timeline._Band.prototype._onKeyDown=function(B,A,C){if(!this._dragging){switch(A.keyCode){case 27:break;
+case 37:case 38:this._scrollSpeed=Math.min(50,Math.abs(this._scrollSpeed*1.05));
+this._moveEther(this._scrollSpeed);
+break;
+case 39:case 40:this._scrollSpeed=-Math.min(50,Math.abs(this._scrollSpeed*1.05));
+this._moveEther(this._scrollSpeed);
+break;
+default:return true;
+}this.closeBubble();
+SimileAjax.DOM.cancelEvent(A);
+return false;
+}return true;
+};
+Timeline._Band.prototype._onKeyUp=function(B,A,C){if(!this._dragging){this._scrollSpeed=this._originalScrollSpeed;
+switch(A.keyCode){case 35:this.setCenterVisibleDate(this._eventSource.getLatestDate());
+break;
+case 36:this.setCenterVisibleDate(this._eventSource.getEarliestDate());
+break;
+case 33:this._autoScroll(this._timeline.getPixelLength());
+break;
+case 34:this._autoScroll(-this._timeline.getPixelLength());
+break;
+default:return true;
+}this.closeBubble();
+SimileAjax.DOM.cancelEvent(A);
+return false;
+}return true;
+};
+Timeline._Band.prototype._autoScroll=function(D,C){var A=this;
+var B=SimileAjax.Graphics.createAnimation(function(E,F){A._moveEther(F);
+},0,D,1000,C);
+B.run();
+};
+Timeline._Band.prototype._moveEther=function(A){this.closeBubble();
+if(!this._timeline.shiftOK(this._index,A)){return ;
+}this._viewOffset+=A;
+this._ether.shiftPixels(-A);
+if(this._timeline.isHorizontal()){this._div.style.left=this._viewOffset+"px";
+}else{this._div.style.top=this._viewOffset+"px";
+}if(this._viewOffset>-this._viewLength*0.5||this._viewOffset<-this._viewLength*(Timeline._Band.SCROLL_MULTIPLES-1.5)){this._recenterDiv();
+}else{this.softLayout();
+}this._onChanging();
+};
+Timeline._Band.prototype._onChanging=function(){this._changing=true;
+this._fireOnScroll();
+this._setSyncWithBandDate();
+this._changing=false;
+};
+Timeline._Band.prototype.busy=function(){return(this._changing);
+};
+Timeline._Band.prototype._fireOnScroll=function(){for(var A=0;
+A<this._onScrollListeners.length;
+A++){this._onScrollListeners[A](this);
+}};
+Timeline._Band.prototype._setSyncWithBandDate=function(){if(this._syncWithBand){var A=this._ether.pixelOffsetToDate(this.getViewLength()/2);
+this._syncWithBand.setCenterVisibleDate(A);
+}};
+Timeline._Band.prototype._onHighlightBandScroll=function(){if(this._syncWithBand){var A=this._syncWithBand.getCenterVisibleDate();
+var B=this._ether.dateToPixelOffset(A);
+this._moveEther(Math.round(this._viewLength/2-B));
+if(this._highlight){this._etherPainter.setHighlight(this._syncWithBand.getMinVisibleDate(),this._syncWithBand.getMaxVisibleDate());
+}}};
+Timeline._Band.prototype._onAddMany=function(){this._paintEvents();
+};
+Timeline._Band.prototype._onClear=function(){this._paintEvents();
+};
+Timeline._Band.prototype._positionHighlight=function(){if(this._syncWithBand){var A=this._syncWithBand.getMinVisibleDate();
+var B=this._syncWithBand.getMaxVisibleDate();
+if(this._highlight){this._etherPainter.setHighlight(A,B);
+}}};
+Timeline._Band.prototype._recenterDiv=function(){this._viewOffset=-this._viewLength*(Timeline._Band.SCROLL_MULTIPLES-1)/2;
+if(this._timeline.isHorizontal()){this._div.style.left=this._viewOffset+"px";
+this._div.style.width=(Timeline._Band.SCROLL_MULTIPLES*this._viewLength)+"px";
+}else{this._div.style.top=this._viewOffset+"px";
+this._div.style.height=(Timeline._Band.SCROLL_MULTIPLES*this._viewLength)+"px";
+}this.layout();
+};
+Timeline._Band.prototype._paintEvents=function(){this._eventPainter.paint();
+};
+Timeline._Band.prototype._softPaintEvents=function(){this._eventPainter.softPaint();
+};
+Timeline._Band.prototype._paintDecorators=function(){for(var A=0;
+A<this._decorators.length;
+A++){this._decorators[A].paint();
+}};
+Timeline._Band.prototype._softPaintDecorators=function(){for(var A=0;
+A<this._decorators.length;
+A++){this._decorators[A].softPaint();
+}};
+Timeline._Band.prototype.closeBubble=function(){SimileAjax.WindowManager.cancelPopups();
+};
+
+
+/* compact-painter.js */
+Timeline.CompactEventPainter=function(A){this._params=A;
+this._onSelectListeners=[];
+this._filterMatcher=null;
+this._highlightMatcher=null;
+this._frc=null;
+this._eventIdToElmt={};
+};
+Timeline.CompactEventPainter.prototype.initialize=function(B,A){this._band=B;
+this._timeline=A;
+this._backLayer=null;
+this._eventLayer=null;
+this._lineLayer=null;
+this._highlightLayer=null;
+this._eventIdToElmt=null;
+};
+Timeline.CompactEventPainter.prototype.addOnSelectListener=function(A){this._onSelectListeners.push(A);
+};
+Timeline.CompactEventPainter.prototype.removeOnSelectListener=function(B){for(var A=0;
+A<this._onSelectListeners.length;
+A++){if(this._onSelectListeners[A]==B){this._onSelectListeners.splice(A,1);
+break;
+}}};
+Timeline.CompactEventPainter.prototype.getFilterMatcher=function(){return this._filterMatcher;
+};
+Timeline.CompactEventPainter.prototype.setFilterMatcher=function(A){this._filterMatcher=A;
+};
+Timeline.CompactEventPainter.prototype.getHighlightMatcher=function(){return this._highlightMatcher;
+};
+Timeline.CompactEventPainter.prototype.setHighlightMatcher=function(A){this._highlightMatcher=A;
+};
+Timeline.CompactEventPainter.prototype.paint=function(){var N=this._band.getEventSource();
+if(N==null){return ;
+}this._eventIdToElmt={};
+this._prepareForPainting();
+var O=this._params.theme;
+var L=O.event;
+var G={trackOffset:"trackOffset" in this._params?this._params.trackOffset:10,trackHeight:"trackHeight" in this._params?this._params.trackHeight:10,tapeHeight:O.event.tape.height,tapeBottomMargin:"tapeBottomMargin" in this._params?this._params.tapeBottomMargin:2,labelBottomMargin:"labelBottomMargin" in this._params?this._params.labelBottomMargin:5,labelRightMargin:"labelRightMargin" in this._params?this._params.labelRightMargin:5,defaultIcon:L.instant.icon,defaultIconWidth:L.instant.iconWidth,defaultIconHeight:L.instant.iconHeight,customIconWidth:"iconWidth" in this._params?this._params.iconWidth:L.instant.iconWidth,customIconHeight:"iconHeight" in this._params?this._params.iconHeight:L.instant.iconHeight,iconLabelGap:"iconLabelGap" in this._params?this._params.iconLabelGap:2,iconBottomMargin:"iconBottomMargin" in this._params?this._params.iconBottomMargin:2};
+if("compositeIcon" in this._params){G.compositeIcon=this._params.compositeIcon;
+G.compositeIconWidth=this._params.compositeIconWidth||G.customIconWidth;
+G.compositeIconHeight=this._params.compositeIconHeight||G.customIconHeight;
+}else{G.compositeIcon=G.defaultIcon;
+G.compositeIconWidth=G.defaultIconWidth;
+G.compositeIconHeight=G.defaultIconHeight;
+}G.defaultStackIcon="icon" in this._params.stackConcurrentPreciseInstantEvents?this._params.stackConcurrentPreciseInstantEvents.icon:G.defaultIcon;
+G.defaultStackIconWidth="iconWidth" in this._params.stackConcurrentPreciseInstantEvents?this._params.stackConcurrentPreciseInstantEvents.iconWidth:G.defaultIconWidth;
+G.defaultStackIconHeight="iconHeight" in this._params.stackConcurrentPreciseInstantEvents?this._params.stackConcurrentPreciseInstantEvents.iconHeight:G.defaultIconHeight;
+var B=this._band.getMinDate();
+var D=this._band.getMaxDate();
+var R=(this._filterMatcher!=null)?this._filterMatcher:function(S){return true;
+};
+var Q=(this._highlightMatcher!=null)?this._highlightMatcher:function(S){return -1;
+};
+var F=N.getEventIterator(B,D);
+var H="stackConcurrentPreciseInstantEvents" in this._params&&typeof this._params.stackConcurrentPreciseInstantEvents=="object";
+var P="collapseConcurrentPreciseInstantEvents" in this._params&&this._params.collapseConcurrentPreciseInstantEvents;
+if(P||H){var M=[];
+var A=null;
+while(F.hasNext()){var E=F.next();
+if(R(E)){if(!E.isInstant()||E.isImprecise()){this.paintEvent(E,G,this._params.theme,Q(E));
+}else{if(A!=null&&A.getStart().getTime()==E.getStart().getTime()){M[M.length-1].push(E);
+}else{M.push([E]);
+A=E;
+}}}}for(var J=0;
+J<M.length;
+J++){var K=M[J];
+if(K.length==1){this.paintEvent(K[0],G,this._params.theme,Q(E));
+}else{var C=-1;
+for(var I=0;
+C<0&&I<K.length;
+I++){C=Q(K[I]);
+}if(H){this.paintStackedPreciseInstantEvents(K,G,this._params.theme,C);
+}else{this.paintCompositePreciseInstantEvents(K,G,this._params.theme,C);
+}}}}else{while(F.hasNext()){var E=F.next();
+if(R(E)){this.paintEvent(E,G,this._params.theme,Q(E));
+}}}this._highlightLayer.style.display="block";
+this._lineLayer.style.display="block";
+this._eventLayer.style.display="block";
+};
+Timeline.CompactEventPainter.prototype.softPaint=function(){};
+Timeline.CompactEventPainter.prototype._prepareForPainting=function(){var B=this._band;
+if(this._backLayer==null){this._backLayer=this._band.createLayerDiv(0,"timeline-band-events");
+this._backLayer.style.visibility="hidden";
+var A=document.createElement("span");
+A.className="timeline-event-label";
+this._backLayer.appendChild(A);
+this._frc=SimileAjax.Graphics.getFontRenderingContext(A);
+}this._frc.update();
+this._tracks=[];
+if(this._highlightLayer!=null){B.removeLayerDiv(this._highlightLayer);
+}this._highlightLayer=B.createLayerDiv(105,"timeline-band-highlights");
+this._highlightLayer.style.display="none";
+if(this._lineLayer!=null){B.removeLayerDiv(this._lineLayer);
+}this._lineLayer=B.createLayerDiv(110,"timeline-band-lines");
+this._lineLayer.style.display="none";
+if(this._eventLayer!=null){B.removeLayerDiv(this._eventLayer);
+}this._eventLayer=B.createLayerDiv(115,"timeline-band-events");
+this._eventLayer.style.display="none";
+};
+Timeline.CompactEventPainter.prototype.paintEvent=function(B,C,D,A){if(B.isInstant()){this.paintInstantEvent(B,C,D,A);
+}else{this.paintDurationEvent(B,C,D,A);
+}};
+Timeline.CompactEventPainter.prototype.paintInstantEvent=function(B,C,D,A){if(B.isImprecise()){this.paintImpreciseInstantEvent(B,C,D,A);
+}else{this.paintPreciseInstantEvent(B,C,D,A);
+}};
+Timeline.CompactEventPainter.prototype.paintDurationEvent=function(B,C,D,A){if(B.isImprecise()){this.paintImpreciseDurationEvent(B,C,D,A);
+}else{this.paintPreciseDurationEvent(B,C,D,A);
+}};
+Timeline.CompactEventPainter.prototype.paintPreciseInstantEvent=function(H,F,B,A){var C={tooltip:H.getProperty("tooltip")||H.getText()};
+var E={url:H.getIcon()};
+if(E.url==null){E.url=F.defaultIcon;
+E.width=F.defaultIconWidth;
+E.height=F.defaultIconHeight;
+E.className="timeline-event-icon-default";
+}else{E.width=H.getProperty("iconWidth")||F.customIconWidth;
+E.height=H.getProperty("iconHeight")||F.customIconHeight;
+}var J={text:H.getText(),color:H.getTextColor()||H.getColor(),className:H.getClassName()};
+var G=this.paintTapeIconLabel(H.getStart(),C,null,E,J,F,B,A);
+var I=this;
+var D=function(L,K,M){return I._onClickInstantEvent(G.iconElmtData.elmt,K,H);
+};
+SimileAjax.DOM.registerEvent(G.iconElmtData.elmt,"mousedown",D);
+SimileAjax.DOM.registerEvent(G.labelElmtData.elmt,"mousedown",D);
+this._eventIdToElmt[H.getID()]=G.iconElmtData.elmt;
+};
+Timeline.CompactEventPainter.prototype.paintCompositePreciseInstantEvents=function(J,H,D,B){var K=J[0];
+var A=[];
+for(var C=0;
+C<J.length;
+C++){A.push(J[C].getProperty("tooltip")||J[C].getText());
+}var E={tooltip:A.join("; ")};
+var G={url:H.compositeIcon,width:H.compositeIconWidth,height:H.compositeIconHeight,className:"timeline-event-icon-composite"};
+var M={text:String.substitute(this._params.compositeEventLabelTemplate,[J.length])};
+var I=this.paintTapeIconLabel(K.getStart(),E,null,G,M,H,D,B);
+var L=this;
+var F=function(O,N,P){return L._onClickMultiplePreciseInstantEvent(I.iconElmtData.elmt,N,J);
+};
+SimileAjax.DOM.registerEvent(I.iconElmtData.elmt,"mousedown",F);
+SimileAjax.DOM.registerEvent(I.labelElmtData.elmt,"mousedown",F);
+for(var C=0;
+C<J.length;
+C++){this._eventIdToElmt[J[C].getID()]=I.iconElmtData.elmt;
+}};
+Timeline.CompactEventPainter.prototype.paintStackedPreciseInstantEvents=function(T,j,c,E){var S="limit" in this._params.stackConcurrentPreciseInstantEvents?this._params.stackConcurrentPreciseInstantEvents.limit:10;
+var G="moreMessageTemplate" in this._params.stackConcurrentPreciseInstantEvents?this._params.stackConcurrentPreciseInstantEvents.moreMessageTemplate:"%0 More Events";
+var Q=S<=T.length-2;
+var B=this._band;
+var L=function(i){return Math.round(B.dateToPixelOffset(i));
+};
+var O=function(i){var r={url:i.getIcon()};
+if(r.url==null){r.url=j.defaultStackIcon;
+r.width=j.defaultStackIconWidth;
+r.height=j.defaultStackIconHeight;
+r.className="timeline-event-icon-stack timeline-event-icon-default";
+}else{r.width=i.getProperty("iconWidth")||j.customIconWidth;
+r.height=i.getProperty("iconHeight")||j.customIconHeight;
+r.className="timeline-event-icon-stack";
+}return r;
+};
+var C=O(T[0]);
+var V=5;
+var D=0;
+var g=0;
+var p=0;
+var U=0;
+var l=[];
+for(var n=0;
+n<T.length&&(!Q||n<S);
+n++){var b=T[n];
+var a=b.getText();
+var X=O(b);
+var W=this._frc.computeSize(a);
+var K={text:a,iconData:X,labelSize:W,iconLeft:C.width+n*V-X.width};
+K.labelLeft=C.width+n*V+j.iconLabelGap;
+K.top=p;
+l.push(K);
+D=Math.min(D,K.iconLeft);
+p+=W.height;
+g=Math.max(g,K.labelLeft+W.width);
+U=Math.max(U,K.top+X.height);
+}if(Q){var e=String.substitute(G,[T.length-S]);
+var H=this._frc.computeSize(e);
+var J=C.width+(S-1)*V+j.iconLabelGap;
+var m=p;
+p+=H.height;
+g=Math.max(g,J+H.width);
+}g+=j.labelRightMargin;
+p+=j.labelBottomMargin;
+U+=j.iconBottomMargin;
+var F=L(T[0].getStart());
+var Y=[];
+var N=Math.ceil(Math.max(U,p)/j.trackHeight);
+var M=C.width+(T.length-1)*V;
+for(var n=0;
+n<N;
+n++){Y.push({start:D,end:M});
+}var f=Math.ceil(p/j.trackHeight);
+for(var n=0;
+n<f;
+n++){var P=Y[n];
+P.end=Math.max(P.end,g);
+}var k=this._fitTracks(F,Y);
+var Z=k*j.trackHeight+j.trackOffset;
+var q=this._timeline.getDocument().createElement("div");
+q.className="timeline-event-icon-stack";
+q.style.position="absolute";
+q.style.overflow="visible";
+q.style.left=F+"px";
+q.style.top=Z+"px";
+q.style.width=M+"px";
+q.style.height=U+"px";
+q.innerHTML="<div style='position: relative'></div>";
+this._eventLayer.appendChild(q);
+var I=this;
+var R=function(r){try{var w=parseInt(this.getAttribute("index"));
+var u=q.firstChild.childNodes;
+for(var s=0;
+s<u.length;
+s++){var v=u[s];
+if(s==w){v.style.zIndex=u.length;
+}else{v.style.zIndex=u.length-s;
+}}}catch(t){}};
+var d=function(u){var w=l[u];
+var r=T[u];
+var i=r.getProperty("tooltip")||r.getText();
+var v=I._paintEventLabel({tooltip:i},{text:w.text},F+w.labelLeft,Z+w.top,w.labelSize.width,w.labelSize.height,c);
+v.elmt.setAttribute("index",u);
+v.elmt.onmouseover=R;
+var t=SimileAjax.Graphics.createTranslucentImage(w.iconData.url);
+var s=I._timeline.getDocument().createElement("div");
+s.className="timeline-event-icon"+("className" in w.iconData?(" "+w.iconData.className):"");
+s.style.left=w.iconLeft+"px";
+s.style.top=w.top+"px";
+s.style.zIndex=(l.length-u);
+s.appendChild(t);
+s.setAttribute("index",u);
+s.onmouseover=R;
+q.firstChild.appendChild(s);
+var x=function(z,y,AA){return I._onClickInstantEvent(v.elmt,y,r);
+};
+SimileAjax.DOM.registerEvent(s,"mousedown",x);
+SimileAjax.DOM.registerEvent(v.elmt,"mousedown",x);
+I._eventIdToElmt[r.getID()]=s;
+};
+for(var n=0;
+n<l.length;
+n++){d(n);
+}if(Q){var o=T.slice(S);
+var A=this._paintEventLabel({tooltip:e},{text:e},F+J,Z+m,H.width,H.height,c);
+var h=function(r,i,s){return I._onClickMultiplePreciseInstantEvent(A.elmt,i,o);
+};
+SimileAjax.DOM.registerEvent(A.elmt,"mousedown",h);
+for(var n=0;
+n<o.length;
+n++){this._eventIdToElmt[o[n].getID()]=A.elmt;
+}}};
+Timeline.CompactEventPainter.prototype.paintImpreciseInstantEvent=function(I,G,B,A){var C={tooltip:I.getProperty("tooltip")||I.getText()};
+var E={start:I.getStart(),end:I.getEnd(),latestStart:I.getLatestStart(),earliestEnd:I.getEarliestEnd(),isInstant:true};
+var F={url:I.getIcon()};
+if(F.url==null){F=null;
+}else{F.width=I.getProperty("iconWidth")||G.customIconWidth;
+F.height=I.getProperty("iconHeight")||G.customIconHeight;
+}var K={text:I.getText(),color:I.getTextColor()||I.getColor(),className:I.getClassName()};
+var H=this.paintTapeIconLabel(I.getStart(),C,E,F,K,G,B,A);
+var J=this;
+var D=F!=null?function(M,L,N){return J._onClickInstantEvent(H.iconElmtData.elmt,L,I);
+}:function(M,L,N){return J._onClickInstantEvent(H.labelElmtData.elmt,L,I);
+};
+SimileAjax.DOM.registerEvent(H.labelElmtData.elmt,"mousedown",D);
+SimileAjax.DOM.registerEvent(H.impreciseTapeElmtData.elmt,"mousedown",D);
+if(F!=null){SimileAjax.DOM.registerEvent(H.iconElmtData.elmt,"mousedown",D);
+this._eventIdToElmt[I.getID()]=H.iconElmtData.elmt;
+}else{this._eventIdToElmt[I.getID()]=H.labelElmtData.elmt;
+}};
+Timeline.CompactEventPainter.prototype.paintPreciseDurationEvent=function(I,G,B,A){var C={tooltip:I.getProperty("tooltip")||I.getText()};
+var E={start:I.getStart(),end:I.getEnd(),isInstant:false};
+var F={url:I.getIcon()};
+if(F.url==null){F=null;
+}else{F.width=I.getProperty("iconWidth")||G.customIconWidth;
+F.height=I.getProperty("iconHeight")||G.customIconHeight;
+}var K={text:I.getText(),color:I.getTextColor()||I.getColor(),className:I.getClassName()};
+var H=this.paintTapeIconLabel(I.getLatestStart(),C,E,F,K,G,B,A);
+var J=this;
+var D=F!=null?function(M,L,N){return J._onClickInstantEvent(H.iconElmtData.elmt,L,I);
+}:function(M,L,N){return J._onClickInstantEvent(H.labelElmtData.elmt,L,I);
+};
+SimileAjax.DOM.registerEvent(H.labelElmtData.elmt,"mousedown",D);
+SimileAjax.DOM.registerEvent(H.tapeElmtData.elmt,"mousedown",D);
+if(F!=null){SimileAjax.DOM.registerEvent(H.iconElmtData.elmt,"mousedown",D);
+this._eventIdToElmt[I.getID()]=H.iconElmtData.elmt;
+}else{this._eventIdToElmt[I.getID()]=H.labelElmtData.elmt;
+}};
+Timeline.CompactEventPainter.prototype.paintImpreciseDurationEvent=function(I,G,B,A){var C={tooltip:I.getProperty("tooltip")||I.getText()};
+var E={start:I.getStart(),end:I.getEnd(),latestStart:I.getLatestStart(),earliestEnd:I.getEarliestEnd(),isInstant:false};
+var F={url:I.getIcon()};
+if(F.url==null){F=null;
+}else{F.width=I.getProperty("iconWidth")||G.customIconWidth;
+F.height=I.getProperty("iconHeight")||G.customIconHeight;
+}var K={text:I.getText(),color:I.getTextColor()||I.getColor(),className:I.getClassName()};
+var H=this.paintTapeIconLabel(I.getLatestStart(),C,E,F,K,G,B,A);
+var J=this;
+var D=F!=null?function(M,L,N){return J._onClickInstantEvent(H.iconElmtData.elmt,L,I);
+}:function(M,L,N){return J._onClickInstantEvent(H.labelElmtData.elmt,L,I);
+};
+SimileAjax.DOM.registerEvent(H.labelElmtData.elmt,"mousedown",D);
+SimileAjax.DOM.registerEvent(H.tapeElmtData.elmt,"mousedown",D);
+if(F!=null){SimileAjax.DOM.registerEvent(H.iconElmtData.elmt,"mousedown",D);
+this._eventIdToElmt[I.getID()]=H.iconElmtData.elmt;
+}else{this._eventIdToElmt[I.getID()]=H.labelElmtData.elmt;
+}};
+Timeline.CompactEventPainter.prototype.paintTapeIconLabel=function(V,O,S,I,a,X,c,Z){var R=this._band;
+var F=function(e){return Math.round(R.dateToPixelOffset(e));
+};
+var d=F(V);
+var W=[];
+var b=0;
+var B=0;
+var C=0;
+if(S!=null){b=X.tapeHeight+X.tapeBottomMargin;
+B=Math.ceil(X.tapeHeight/X.trackHeight);
+var A=F(S.end)-d;
+var L=F(S.start)-d;
+for(var Q=0;
+Q<B;
+Q++){W.push({start:L,end:A});
+}C=X.trackHeight-(b%X.tapeHeight);
+}var N=0;
+var U=0;
+if(I!=null){if("iconAlign" in I&&I.iconAlign=="center"){N=-Math.floor(I.width/2);
+}U=N+I.width+X.iconLabelGap;
+if(B>0){W[B-1].end=Math.max(W[B-1].end,U);
+}var E=I.height+X.iconBottomMargin+C;
+while(E>0){W.push({start:N,end:U});
+E-=X.trackHeight;
+}}var P=a.text;
+var H=this._frc.computeSize(P);
+var M=H.height+X.labelBottomMargin+C;
+var J=U+H.width+X.labelRightMargin;
+if(B>0){W[B-1].end=Math.max(W[B-1].end,J);
+}for(var Y=0;
+M>0;
+Y++){if(B+Y<W.length){var T=W[B+Y];
+T.end=J;
+}else{W.push({start:0,end:J});
+}M-=X.trackHeight;
+}var G=this._fitTracks(d,W);
+var K=G*X.trackHeight+X.trackOffset;
+var D={};
+D.labelElmtData=this._paintEventLabel(O,a,d+U,K+b,H.width,H.height,c);
+if(S!=null){if("latestStart" in S||"earliestEnd" in S){D.impreciseTapeElmtData=this._paintEventTape(O,S,X.tapeHeight,K,F(S.start),F(S.end),c.event.duration.impreciseColor,c.event.duration.impreciseOpacity,X,c);
+}if(!S.isInstant&&"start" in S&&"end" in S){D.tapeElmtData=this._paintEventTape(O,S,X.tapeHeight,K,d,F("earliestEnd" in S?S.earliestEnd:S.end),S.color,100,X,c);
+}}if(I!=null){D.iconElmtData=this._paintEventIcon(O,I,K+b,d+N,X,c);
+}return D;
+};
+Timeline.CompactEventPainter.prototype._fitTracks=function(F,C){var H;
+for(H=0;
+H<this._tracks.length;
+H++){var E=true;
+for(var B=0;
+B<C.length&&(H+B)<this._tracks.length;
+B++){var G=this._tracks[H+B];
+var A=C[B];
+if(F+A.start<G){E=false;
+break;
+}}if(E){break;
+}}for(var D=0;
+D<C.length;
+D++){this._tracks[H+D]=F+C[D].end;
+}return H;
+};
+Timeline.CompactEventPainter.prototype._paintEventIcon=function(C,D,H,G,E,F){var B=SimileAjax.Graphics.createTranslucentImage(D.url);
+var A=this._timeline.getDocument().createElement("div");
+A.className="timeline-event-icon"+("className" in D?(" "+D.className):"");
+A.style.left=G+"px";
+A.style.top=H+"px";
+A.appendChild(B);
+if("tooltip" in C&&typeof C.tooltip=="string"){A.title=C.tooltip;
+}this._eventLayer.appendChild(A);
+return{left:G,top:H,width:E.iconWidth,height:E.iconHeight,elmt:A};
+};
+Timeline.CompactEventPainter.prototype._paintEventLabel=function(E,I,C,F,A,G,D){var H=this._timeline.getDocument();
+var B=H.createElement("div");
+B.className="timeline-event-label";
+B.style.left=C+"px";
+B.style.width=(A+1)+"px";
+B.style.top=F+"px";
+B.innerHTML=I.text;
+if("tooltip" in E&&typeof E.tooltip=="string"){B.title=E.tooltip;
+}if("color" in I&&typeof I.color=="string"){B.style.color=I.color;
+}if("className" in I&&typeof I.className=="string"){B.className+=" "+I.className;
+}this._eventLayer.appendChild(B);
+return{left:C,top:F,width:A,height:G,elmt:B};
+};
+Timeline.CompactEventPainter.prototype._paintEventTape=function(G,H,K,J,D,A,E,C,I,F){var B=A-D;
+var L=this._timeline.getDocument().createElement("div");
+L.className="timeline-event-tape";
+L.style.left=D+"px";
+L.style.top=J+"px";
+L.style.width=B+"px";
+L.style.height=K+"px";
+if("tooltip" in G&&typeof G.tooltip=="string"){L.title=G.tooltip;
+}if(E!=null&&typeof H.color=="string"){L.style.backgroundColor=E;
+}if("backgroundImage" in H&&typeof H.backgroundImage=="string"){L.style.backgroundImage="url("+backgroundImage+")";
+L.style.backgroundRepeat=("backgroundRepeat" in H&&typeof H.backgroundRepeat=="string")?H.backgroundRepeat:"repeat";
+}SimileAjax.Graphics.setOpacity(L,C);
+if("className" in H&&typeof H.className=="string"){L.className+=" "+H.className;
+}this._eventLayer.appendChild(L);
+return{left:D,top:J,width:B,height:K,elmt:L};
+};
+Timeline.CompactEventPainter.prototype._createHighlightDiv=function(A,C,E){if(A>=0){var D=this._timeline.getDocument();
+var G=E.event;
+var B=G.highlightColors[Math.min(A,G.highlightColors.length-1)];
+var F=D.createElement("div");
+F.style.position="absolute";
+F.style.overflow="hidden";
+F.style.left=(C.left-2)+"px";
+F.style.width=(C.width+4)+"px";
+F.style.top=(C.top-2)+"px";
+F.style.height=(C.height+4)+"px";
+this._highlightLayer.appendChild(F);
+}};
+Timeline.CompactEventPainter.prototype._onClickMultiplePreciseInstantEvent=function(E,A,B){var F=SimileAjax.DOM.getPageCoordinates(E);
+this._showBubble(F.left+Math.ceil(E.offsetWidth/2),F.top+Math.ceil(E.offsetHeight/2),B);
+var D=[];
+for(var C=0;
+C<B.length;
+C++){D.push(B[C].getID());
+}this._fireOnSelect(D);
+A.cancelBubble=true;
+SimileAjax.DOM.cancelEvent(A);
+return false;
+};
+Timeline.CompactEventPainter.prototype._onClickInstantEvent=function(C,A,B){var D=SimileAjax.DOM.getPageCoordinates(C);
+this._showBubble(D.left+Math.ceil(C.offsetWidth/2),D.top+Math.ceil(C.offsetHeight/2),[B]);
+this._fireOnSelect([B.getID()]);
+A.cancelBubble=true;
+SimileAjax.DOM.cancelEvent(A);
+return false;
+};
+Timeline.CompactEventPainter.prototype._onClickDurationEvent=function(F,B,C){if("pageX" in B){var A=B.pageX;
+var E=B.pageY;
+}else{var D=SimileAjax.DOM.getPageCoordinates(F);
+var A=B.offsetX+D.left;
+var E=B.offsetY+D.top;
+}this._showBubble(A,E,[C]);
+this._fireOnSelect([C.getID()]);
+B.cancelBubble=true;
+SimileAjax.DOM.cancelEvent(B);
+return false;
+};
+Timeline.CompactEventPainter.prototype.showBubble=function(A){var B=this._eventIdToElmt[A.getID()];
+if(B){var C=SimileAjax.DOM.getPageCoordinates(B);
+this._showBubble(C.left+B.offsetWidth/2,C.top+B.offsetHeight/2,[A]);
+}};
+Timeline.CompactEventPainter.prototype._showBubble=function(A,F,B){var E=document.createElement("div");
+B=("fillInfoBubble" in B)?[B]:B;
+for(var D=0;
+D<B.length;
+D++){var C=document.createElement("div");
+E.appendChild(C);
+B[D].fillInfoBubble(C,this._params.theme,this._band.getLabeller());
+}SimileAjax.WindowManager.cancelPopups();
+SimileAjax.Graphics.createBubbleForContentAndPoint(E,A,F,this._params.theme.event.bubble.width);
+};
+Timeline.CompactEventPainter.prototype._fireOnSelect=function(B){for(var A=0;
+A<this._onSelectListeners.length;
+A++){this._onSelectListeners[A](B);
+}};
+
+
+/* decorators.js */
+Timeline.SpanHighlightDecorator=function(A){this._unit=A.unit!=null?A.unit:SimileAjax.NativeDateUnit;
+this._startDate=(typeof A.startDate=="string")?this._unit.parseFromObject(A.startDate):A.startDate;
+this._endDate=(typeof A.endDate=="string")?this._unit.parseFromObject(A.endDate):A.endDate;
+this._startLabel=A.startLabel!=null?A.startLabel:"";
+this._endLabel=A.endLabel!=null?A.endLabel:"";
+this._color=A.color;
+this._cssClass=A.cssClass!=null?A.cssClass:null;
+this._opacity=A.opacity!=null?A.opacity:100;
+this._zIndex=(A.inFront!=null&&A.inFront)?113:10;
+};
+Timeline.SpanHighlightDecorator.prototype.initialize=function(B,A){this._band=B;
+this._timeline=A;
+this._layerDiv=null;
+};
+Timeline.SpanHighlightDecorator.prototype.paint=function(){if(this._layerDiv!=null){this._band.removeLayerDiv(this._layerDiv);
+}this._layerDiv=this._band.createLayerDiv(this._zIndex);
+this._layerDiv.setAttribute("name","span-highlight-decorator");
+this._layerDiv.style.display="none";
+var E=this._band.getMinDate();
+var A=this._band.getMaxDate();
+if(this._unit.compare(this._startDate,A)<0&&this._unit.compare(this._endDate,E)>0){E=this._unit.later(E,this._startDate);
+A=this._unit.earlier(A,this._endDate);
+var F=this._band.dateToPixelOffset(E);
+var I=this._band.dateToPixelOffset(A);
+var H=this._timeline.getDocument();
+var K=function(){var L=H.createElement("table");
+L.insertRow(0).insertCell(0);
+return L;
+};
+var B=H.createElement("div");
+B.className="timeline-highlight-decorator";
+if(this._cssClass){B.className+=" "+this._cssClass;
+}if(this._color!=null){B.style.backgroundColor=this._color;
+}if(this._opacity<100){SimileAjax.Graphics.setOpacity(B,this._opacity);
+}this._layerDiv.appendChild(B);
+var J=K();
+J.className="timeline-highlight-label timeline-highlight-label-start";
+var C=J.rows[0].cells[0];
+C.innerHTML=this._startLabel;
+if(this._cssClass){C.className="label_"+this._cssClass;
+}this._layerDiv.appendChild(J);
+var G=K();
+G.className="timeline-highlight-label timeline-highlight-label-end";
+var D=G.rows[0].cells[0];
+D.innerHTML=this._endLabel;
+if(this._cssClass){D.className="label_"+this._cssClass;
+}this._layerDiv.appendChild(G);
+if(this._timeline.isHorizontal()){B.style.left=F+"px";
+B.style.width=(I-F)+"px";
+J.style.right=(this._band.getTotalViewLength()-F)+"px";
+J.style.width=(this._startLabel.length)+"em";
+G.style.left=I+"px";
+G.style.width=(this._endLabel.length)+"em";
+}else{B.style.top=F+"px";
+B.style.height=(I-F)+"px";
+J.style.bottom=F+"px";
+J.style.height="1.5px";
+G.style.top=I+"px";
+G.style.height="1.5px";
+}}this._layerDiv.style.display="block";
+};
+Timeline.SpanHighlightDecorator.prototype.softPaint=function(){};
+Timeline.PointHighlightDecorator=function(A){this._unit=A.unit!=null?A.unit:SimileAjax.NativeDateUnit;
+this._date=(typeof A.date=="string")?this._unit.parseFromObject(A.date):A.date;
+this._width=A.width!=null?A.width:10;
+this._color=A.color;
+this._cssClass=A.cssClass!=null?A.cssClass:"";
+this._opacity=A.opacity!=null?A.opacity:100;
+};
+Timeline.PointHighlightDecorator.prototype.initialize=function(B,A){this._band=B;
+this._timeline=A;
+this._layerDiv=null;
+};
+Timeline.PointHighlightDecorator.prototype.paint=function(){if(this._layerDiv!=null){this._band.removeLayerDiv(this._layerDiv);
+}this._layerDiv=this._band.createLayerDiv(10);
+this._layerDiv.setAttribute("name","span-highlight-decorator");
+this._layerDiv.style.display="none";
+var C=this._band.getMinDate();
+var E=this._band.getMaxDate();
+if(this._unit.compare(this._date,E)<0&&this._unit.compare(this._date,C)>0){var A=this._band.dateToPixelOffset(this._date);
+var B=A-Math.round(this._width/2);
+var D=this._timeline.getDocument();
+var F=D.createElement("div");
+F.className="timeline-highlight-point-decorator";
+F.className+=" "+this._cssClass;
+if(this._color!=null){F.style.backgroundColor=this._color;
+}if(this._opacity<100){SimileAjax.Graphics.setOpacity(F,this._opacity);
+}this._layerDiv.appendChild(F);
+if(this._timeline.isHorizontal()){F.style.left=B+"px";
+F.style.width=this._width;
+}else{F.style.top=B+"px";
+F.style.height=this._width;
+}}this._layerDiv.style.display="block";
+};
+Timeline.PointHighlightDecorator.prototype.softPaint=function(){};
+
+
+/* detailed-painter.js */
+Timeline.DetailedEventPainter=function(A){this._params=A;
+this._onSelectListeners=[];
+this._filterMatcher=null;
+this._highlightMatcher=null;
+this._frc=null;
+this._eventIdToElmt={};
+};
+Timeline.DetailedEventPainter.prototype.initialize=function(B,A){this._band=B;
+this._timeline=A;
+this._backLayer=null;
+this._eventLayer=null;
+this._lineLayer=null;
+this._highlightLayer=null;
+this._eventIdToElmt=null;
+};
+Timeline.DetailedEventPainter.prototype.getType=function(){return"detailed";
+};
+Timeline.DetailedEventPainter.prototype.addOnSelectListener=function(A){this._onSelectListeners.push(A);
+};
+Timeline.DetailedEventPainter.prototype.removeOnSelectListener=function(B){for(var A=0;
+A<this._onSelectListeners.length;
+A++){if(this._onSelectListeners[A]==B){this._onSelectListeners.splice(A,1);
+break;
+}}};
+Timeline.DetailedEventPainter.prototype.getFilterMatcher=function(){return this._filterMatcher;
+};
+Timeline.DetailedEventPainter.prototype.setFilterMatcher=function(A){this._filterMatcher=A;
+};
+Timeline.DetailedEventPainter.prototype.getHighlightMatcher=function(){return this._highlightMatcher;
+};
+Timeline.DetailedEventPainter.prototype.setHighlightMatcher=function(A){this._highlightMatcher=A;
+};
+Timeline.DetailedEventPainter.prototype.paint=function(){var C=this._band.getEventSource();
+if(C==null){return ;
+}this._eventIdToElmt={};
+this._prepareForPainting();
+var I=this._params.theme.event;
+var G=Math.max(I.track.height,this._frc.getLineHeight());
+var F={trackOffset:Math.round(this._band.getViewWidth()/2-G/2),trackHeight:G,trackGap:I.track.gap,trackIncrement:G+I.track.gap,icon:I.instant.icon,iconWidth:I.instant.iconWidth,iconHeight:I.instant.iconHeight,labelWidth:I.label.width};
+var D=this._band.getMinDate();
+var B=this._band.getMaxDate();
+var J=(this._filterMatcher!=null)?this._filterMatcher:function(K){return true;
+};
+var A=(this._highlightMatcher!=null)?this._highlightMatcher:function(K){return -1;
+};
+var E=C.getEventReverseIterator(D,B);
+while(E.hasNext()){var H=E.next();
+if(J(H)){this.paintEvent(H,F,this._params.theme,A(H));
+}}this._highlightLayer.style.display="block";
+this._lineLayer.style.display="block";
+this._eventLayer.style.display="block";
+this._band.updateEventTrackInfo(this._lowerTracks.length+this._upperTracks.length,F.trackIncrement);
+};
+Timeline.DetailedEventPainter.prototype.softPaint=function(){};
+Timeline.DetailedEventPainter.prototype._prepareForPainting=function(){var B=this._band;
+if(this._backLayer==null){this._backLayer=this._band.createLayerDiv(0,"timeline-band-events");
+this._backLayer.style.visibility="hidden";
+var A=document.createElement("span");
+A.className="timeline-event-label";
+this._backLayer.appendChild(A);
+this._frc=SimileAjax.Graphics.getFontRenderingContext(A);
+}this._frc.update();
+this._lowerTracks=[];
+this._upperTracks=[];
+if(this._highlightLayer!=null){B.removeLayerDiv(this._highlightLayer);
+}this._highlightLayer=B.createLayerDiv(105,"timeline-band-highlights");
+this._highlightLayer.style.display="none";
+if(this._lineLayer!=null){B.removeLayerDiv(this._lineLayer);
+}this._lineLayer=B.createLayerDiv(110,"timeline-band-lines");
+this._lineLayer.style.display="none";
+if(this._eventLayer!=null){B.removeLayerDiv(this._eventLayer);
+}this._eventLayer=B.createLayerDiv(110,"timeline-band-events");
+this._eventLayer.style.display="none";
+};
+Timeline.DetailedEventPainter.prototype.paintEvent=function(B,C,D,A){if(B.isInstant()){this.paintInstantEvent(B,C,D,A);
+}else{this.paintDurationEvent(B,C,D,A);
+}};
+Timeline.DetailedEventPainter.prototype.paintInstantEvent=function(B,C,D,A){if(B.isImprecise()){this.paintImpreciseInstantEvent(B,C,D,A);
+}else{this.paintPreciseInstantEvent(B,C,D,A);
+}};
+Timeline.DetailedEventPainter.prototype.paintDurationEvent=function(B,C,D,A){if(B.isImprecise()){this.paintImpreciseDurationEvent(B,C,D,A);
+}else{this.paintPreciseDurationEvent(B,C,D,A);
+}};
+Timeline.DetailedEventPainter.prototype.paintPreciseInstantEvent=function(L,P,S,Q){var T=this._timeline.getDocument();
+var J=L.getText();
+var G=L.getStart();
+var H=Math.round(this._band.dateToPixelOffset(G));
+var A=Math.round(H+P.iconWidth/2);
+var C=Math.round(H-P.iconWidth/2);
+var E=this._frc.computeSize(J);
+var F=this._findFreeTrackForSolid(A,H);
+var B=this._paintEventIcon(L,F,C,P,S);
+var K=A+S.event.label.offsetFromLine;
+var O=F;
+var D=this._getTrackData(F);
+if(Math.min(D.solid,D.text)>=K+E.width){D.solid=C;
+D.text=K;
+}else{D.solid=C;
+K=H+S.event.label.offsetFromLine;
+O=this._findFreeTrackForText(F,K+E.width,function(U){U.line=H-2;
+});
+this._getTrackData(O).text=C;
+this._paintEventLine(L,H,F,O,P,S);
+}var N=Math.round(P.trackOffset+O*P.trackIncrement+P.trackHeight/2-E.height/2);
+var R=this._paintEventLabel(L,J,K,N,E.width,E.height,S);
+var M=this;
+var I=function(V,U,W){return M._onClickInstantEvent(B.elmt,U,L);
+};
+SimileAjax.DOM.registerEvent(B.elmt,"mousedown",I);
+SimileAjax.DOM.registerEvent(R.elmt,"mousedown",I);
+this._createHighlightDiv(Q,B,S);
+this._eventIdToElmt[L.getID()]=B.elmt;
+};
+Timeline.DetailedEventPainter.prototype.paintImpreciseInstantEvent=function(O,S,W,T){var X=this._timeline.getDocument();
+var M=O.getText();
+var I=O.getStart();
+var U=O.getEnd();
+var K=Math.round(this._band.dateToPixelOffset(I));
+var B=Math.round(this._band.dateToPixelOffset(U));
+var A=Math.round(K+S.iconWidth/2);
+var D=Math.round(K-S.iconWidth/2);
+var G=this._frc.computeSize(M);
+var H=this._findFreeTrackForSolid(B,K);
+var E=this._paintEventTape(O,H,K,B,W.event.instant.impreciseColor,W.event.instant.impreciseOpacity,S,W);
+var C=this._paintEventIcon(O,H,D,S,W);
+var F=this._getTrackData(H);
+F.solid=D;
+var N=A+W.event.label.offsetFromLine;
+var J=N+G.width;
+var R;
+if(J<B){R=H;
+}else{N=K+W.event.label.offsetFromLine;
+J=N+G.width;
+R=this._findFreeTrackForText(H,J,function(Y){Y.line=K-2;
+});
+this._getTrackData(R).text=D;
+this._paintEventLine(O,K,H,R,S,W);
+}var Q=Math.round(S.trackOffset+R*S.trackIncrement+S.trackHeight/2-G.height/2);
+var V=this._paintEventLabel(O,M,N,Q,G.width,G.height,W);
+var P=this;
+var L=function(Z,Y,a){return P._onClickInstantEvent(C.elmt,Y,O);
+};
+SimileAjax.DOM.registerEvent(C.elmt,"mousedown",L);
+SimileAjax.DOM.registerEvent(E.elmt,"mousedown",L);
+SimileAjax.DOM.registerEvent(V.elmt,"mousedown",L);
+this._createHighlightDiv(T,C,W);
+this._eventIdToElmt[O.getID()]=C.elmt;
+};
+Timeline.DetailedEventPainter.prototype.paintPreciseDurationEvent=function(K,O,T,Q){var U=this._timeline.getDocument();
+var I=K.getText();
+var E=K.getStart();
+var R=K.getEnd();
+var F=Math.round(this._band.dateToPixelOffset(E));
+var A=Math.round(this._band.dateToPixelOffset(R));
+var C=this._frc.computeSize(I);
+var D=this._findFreeTrackForSolid(A);
+var P=K.getColor();
+P=P!=null?P:T.event.duration.color;
+var B=this._paintEventTape(K,D,F,A,P,100,O,T);
+var H=this._getTrackData(D);
+H.solid=F;
+var J=F+T.event.label.offsetFromLine;
+var N=this._findFreeTrackForText(D,J+C.width,function(V){V.line=F-2;
+});
+this._getTrackData(N).text=F-2;
+this._paintEventLine(K,F,D,N,O,T);
+var M=Math.round(O.trackOffset+N*O.trackIncrement+O.trackHeight/2-C.height/2);
+var S=this._paintEventLabel(K,I,J,M,C.width,C.height,T);
+var L=this;
+var G=function(W,V,X){return L._onClickDurationEvent(B.elmt,V,K);
+};
+SimileAjax.DOM.registerEvent(B.elmt,"mousedown",G);
+SimileAjax.DOM.registerEvent(S.elmt,"mousedown",G);
+this._createHighlightDiv(Q,B,T);
+this._eventIdToElmt[K.getID()]=B.elmt;
+};
+Timeline.DetailedEventPainter.prototype.paintImpreciseDurationEvent=function(M,T,Y,V){var Z=this._timeline.getDocument();
+var K=M.getText();
+var G=M.getStart();
+var S=M.getLatestStart();
+var W=M.getEnd();
+var O=M.getEarliestEnd();
+var H=Math.round(this._band.dateToPixelOffset(G));
+var E=Math.round(this._band.dateToPixelOffset(S));
+var A=Math.round(this._band.dateToPixelOffset(W));
+var F=Math.round(this._band.dateToPixelOffset(O));
+var C=this._frc.computeSize(K);
+var D=this._findFreeTrackForSolid(A);
+var U=M.getColor();
+U=U!=null?U:Y.event.duration.color;
+var R=this._paintEventTape(M,D,H,A,Y.event.duration.impreciseColor,Y.event.duration.impreciseOpacity,T,Y);
+var B=this._paintEventTape(M,D,E,F,U,100,T,Y);
+var J=this._getTrackData(D);
+J.solid=H;
+var L=E+Y.event.label.offsetFromLine;
+var Q=this._findFreeTrackForText(D,L+C.width,function(a){a.line=E-2;
+});
+this._getTrackData(Q).text=E-2;
+this._paintEventLine(M,E,D,Q,T,Y);
+var P=Math.round(T.trackOffset+Q*T.trackIncrement+T.trackHeight/2-C.height/2);
+var X=this._paintEventLabel(M,K,L,P,C.width,C.height,Y);
+var N=this;
+var I=function(b,a,c){return N._onClickDurationEvent(B.elmt,a,M);
+};
+SimileAjax.DOM.registerEvent(B.elmt,"mousedown",I);
+SimileAjax.DOM.registerEvent(X.elmt,"mousedown",I);
+this._createHighlightDiv(V,B,Y);
+this._eventIdToElmt[M.getID()]=B.elmt;
+};
+Timeline.DetailedEventPainter.prototype._findFreeTrackForSolid=function(D,A){for(var C=0;
+true;
+C++){if(C<this._lowerTracks.length){var B=this._lowerTracks[C];
+if(Math.min(B.solid,B.text)>D&&(!(A)||B.line>A)){return C;
+}}else{this._lowerTracks.push({solid:Number.POSITIVE_INFINITY,text:Number.POSITIVE_INFINITY,line:Number.POSITIVE_INFINITY});
+return C;
+}if(C<this._upperTracks.length){var B=this._upperTracks[C];
+if(Math.min(B.solid,B.text)>D&&(!(A)||B.line>A)){return -1-C;
+}}else{this._upperTracks.push({solid:Number.POSITIVE_INFINITY,text:Number.POSITIVE_INFINITY,line:Number.POSITIVE_INFINITY});
+return -1-C;
+}}};
+Timeline.DetailedEventPainter.prototype._findFreeTrackForText=function(C,A,I){var B;
+var E;
+var F;
+var H;
+if(C<0){B=true;
+F=-C;
+E=this._findFreeUpperTrackForText(F,A);
+H=-1-E;
+}else{if(C>0){B=false;
+F=C+1;
+E=this._findFreeLowerTrackForText(F,A);
+H=E;
+}else{var G=this._findFreeUpperTrackForText(0,A);
+var J=this._findFreeLowerTrackForText(1,A);
+if(J-1<=G){B=false;
+F=1;
+E=J;
+H=E;
+}else{B=true;
+F=0;
+E=G;
+H=-1-E;
+}}}if(B){if(E==this._upperTracks.length){this._upperTracks.push({solid:Number.POSITIVE_INFINITY,text:Number.POSITIVE_INFINITY,line:Number.POSITIVE_INFINITY});
+}for(var D=F;
+D<E;
+D++){I(this._upperTracks[D]);
+}}else{if(E==this._lowerTracks.length){this._lowerTracks.push({solid:Number.POSITIVE_INFINITY,text:Number.POSITIVE_INFINITY,line:Number.POSITIVE_INFINITY});
+}for(var D=F;
+D<E;
+D++){I(this._lowerTracks[D]);
+}}return H;
+};
+Timeline.DetailedEventPainter.prototype._findFreeLowerTrackForText=function(A,C){for(;
+A<this._lowerTracks.length;
+A++){var B=this._lowerTracks[A];
+if(Math.min(B.solid,B.text)>=C){break;
+}}return A;
+};
+Timeline.DetailedEventPainter.prototype._findFreeUpperTrackForText=function(A,C){for(;
+A<this._upperTracks.length;
+A++){var B=this._upperTracks[A];
+if(Math.min(B.solid,B.text)>=C){break;
+}}return A;
+};
+Timeline.DetailedEventPainter.prototype._getTrackData=function(A){return(A<0)?this._upperTracks[-A-1]:this._lowerTracks[A];
+};
+Timeline.DetailedEventPainter.prototype._paintEventLine=function(J,E,D,A,G,F){var H=Math.round(G.trackOffset+D*G.trackIncrement+G.trackHeight/2);
+var I=Math.round(Math.abs(A-D)*G.trackIncrement);
+var C="1px solid "+F.event.label.lineColor;
+var B=this._timeline.getDocument().createElement("div");
+B.style.position="absolute";
+B.style.left=E+"px";
+B.style.width=F.event.label.offsetFromLine+"px";
+B.style.height=I+"px";
+if(D>A){B.style.top=(H-I)+"px";
+B.style.borderTop=C;
+}else{B.style.top=H+"px";
+B.style.borderBottom=C;
+}B.style.borderLeft=C;
+this._lineLayer.appendChild(B);
+};
+Timeline.DetailedEventPainter.prototype._paintEventIcon=function(J,B,C,F,E){var H=J.getIcon();
+H=H!=null?H:F.icon;
+var G=F.trackOffset+B*F.trackIncrement+F.trackHeight/2;
+var I=Math.round(G-F.iconHeight/2);
+var D=SimileAjax.Graphics.createTranslucentImage(H);
+var A=this._timeline.getDocument().createElement("div");
+A.style.position="absolute";
+A.style.left=C+"px";
+A.style.top=I+"px";
+A.appendChild(D);
+A.style.cursor="pointer";
+if(J._title!=null){A.title=J._title;
+}this._eventLayer.appendChild(A);
+return{left:C,top:I,width:F.iconWidth,height:F.iconHeight,elmt:A};
+};
+Timeline.DetailedEventPainter.prototype._paintEventLabel=function(I,J,C,F,A,G,E){var H=this._timeline.getDocument();
+var K=H.createElement("div");
+K.style.position="absolute";
+K.style.left=C+"px";
+K.style.width=A+"px";
+K.style.top=F+"px";
+K.style.height=G+"px";
+K.style.backgroundColor=E.event.label.backgroundColor;
+SimileAjax.Graphics.setOpacity(K,E.event.label.backgroundOpacity);
+this._eventLayer.appendChild(K);
+var B=H.createElement("div");
+B.style.position="absolute";
+B.style.left=C+"px";
+B.style.width=A+"px";
+B.style.top=F+"px";
+B.innerHTML=J;
+B.style.cursor="pointer";
+if(I._title!=null){B.title=I._title;
+}var D=I.getTextColor();
+if(D==null){D=I.getColor();
+}if(D!=null){B.style.color=D;
+}this._eventLayer.appendChild(B);
+return{left:C,top:F,width:A,height:G,elmt:B};
+};
+Timeline.DetailedEventPainter.prototype._paintEventTape=function(L,B,D,A,G,C,I,H){var F=A-D;
+var E=H.event.tape.height;
+var K=I.trackOffset+B*I.trackIncrement+I.trackHeight/2;
+var J=Math.round(K-E/2);
+var M=this._timeline.getDocument().createElement("div");
+M.style.position="absolute";
+M.style.left=D+"px";
+M.style.width=F+"px";
+M.style.top=J+"px";
+M.style.height=E+"px";
+M.style.backgroundColor=G;
+M.style.overflow="hidden";
+M.style.cursor="pointer";
+if(L._title!=null){M.title=L._title;
+}SimileAjax.Graphics.setOpacity(M,C);
+this._eventLayer.appendChild(M);
+return{left:D,top:J,width:F,height:E,elmt:M};
+};
+Timeline.DetailedEventPainter.prototype._createHighlightDiv=function(A,C,E){if(A>=0){var D=this._timeline.getDocument();
+var G=E.event;
+var B=G.highlightColors[Math.min(A,G.highlightColors.length-1)];
+var F=D.createElement("div");
+F.style.position="absolute";
+F.style.overflow="hidden";
+F.style.left=(C.left-2)+"px";
+F.style.width=(C.width+4)+"px";
+F.style.top=(C.top-2)+"px";
+F.style.height=(C.height+4)+"px";
+F.style.background=B;
+this._highlightLayer.appendChild(F);
+}};
+Timeline.DetailedEventPainter.prototype._onClickInstantEvent=function(C,A,B){var D=SimileAjax.DOM.getPageCoordinates(C);
+this._showBubble(D.left+Math.ceil(C.offsetWidth/2),D.top+Math.ceil(C.offsetHeight/2),B);
+this._fireOnSelect(B.getID());
+A.cancelBubble=true;
+SimileAjax.DOM.cancelEvent(A);
+return false;
+};
+Timeline.DetailedEventPainter.prototype._onClickDurationEvent=function(F,B,C){if("pageX" in B){var A=B.pageX;
+var E=B.pageY;
+}else{var D=SimileAjax.DOM.getPageCoordinates(F);
+var A=B.offsetX+D.left;
+var E=B.offsetY+D.top;
+}this._showBubble(A,E,C);
+this._fireOnSelect(C.getID());
+B.cancelBubble=true;
+SimileAjax.DOM.cancelEvent(B);
+return false;
+};
+Timeline.DetailedEventPainter.prototype.showBubble=function(A){var B=this._eventIdToElmt[A.getID()];
+if(B){var C=SimileAjax.DOM.getPageCoordinates(B);
+this._showBubble(C.left+B.offsetWidth/2,C.top+B.offsetHeight/2,A);
+}};
+Timeline.DetailedEventPainter.prototype._showBubble=function(B,E,C){var D=document.createElement("div");
+var A=this._params.theme.event.bubble;
+C.fillInfoBubble(D,this._params.theme,this._band.getLabeller());
+SimileAjax.WindowManager.cancelPopups();
+SimileAjax.Graphics.createBubbleForContentAndPoint(D,B,E,A.width,null,A.maxHeight);
+};
+Timeline.DetailedEventPainter.prototype._fireOnSelect=function(A){for(var B=0;
+B<this._onSelectListeners.length;
+B++){this._onSelectListeners[B](A);
+}};
+
+
+/* ether-painters.js */
+Timeline.GregorianEtherPainter=function(A){this._params=A;
+this._theme=A.theme;
+this._unit=A.unit;
+this._multiple=("multiple" in A)?A.multiple:1;
+};
+Timeline.GregorianEtherPainter.prototype.initialize=function(C,B){this._band=C;
+this._timeline=B;
+this._backgroundLayer=C.createLayerDiv(0);
+this._backgroundLayer.setAttribute("name","ether-background");
+this._backgroundLayer.className="timeline-ether-bg";
+this._markerLayer=null;
+this._lineLayer=null;
+var D=("align" in this._params&&this._params.align!=undefined)?this._params.align:this._theme.ether.interval.marker[B.isHorizontal()?"hAlign":"vAlign"];
+var A=("showLine" in this._params)?this._params.showLine:this._theme.ether.interval.line.show;
+this._intervalMarkerLayout=new Timeline.EtherIntervalMarkerLayout(this._timeline,this._band,this._theme,D,A);
+this._highlight=new Timeline.EtherHighlight(this._timeline,this._band,this._theme,this._backgroundLayer);
+};
+Timeline.GregorianEtherPainter.prototype.setHighlight=function(A,B){this._highlight.position(A,B);
+};
+Timeline.GregorianEtherPainter.prototype.paint=function(){if(this._markerLayer){this._band.removeLayerDiv(this._markerLayer);
+}this._markerLayer=this._band.createLayerDiv(100);
+this._markerLayer.setAttribute("name","ether-markers");
+this._markerLayer.style.display="none";
+if(this._lineLayer){this._band.removeLayerDiv(this._lineLayer);
+}this._lineLayer=this._band.createLayerDiv(1);
+this._lineLayer.setAttribute("name","ether-lines");
+this._lineLayer.style.display="none";
+var C=this._band.getMinDate();
+var F=this._band.getMaxDate();
+var A=this._band.getTimeZone();
+var E=this._band.getLabeller();
+SimileAjax.DateTime.roundDownToInterval(C,this._unit,A,this._multiple,this._theme.firstDayOfWeek);
+var D=this;
+var B=function(G){for(var H=0;
+H<D._multiple;
+H++){SimileAjax.DateTime.incrementByInterval(G,D._unit);
+}};
+while(C.getTime()<F.getTime()){this._intervalMarkerLayout.createIntervalMarker(C,E,this._unit,this._markerLayer,this._lineLayer);
+B(C);
+}this._markerLayer.style.display="block";
+this._lineLayer.style.display="block";
+};
+Timeline.GregorianEtherPainter.prototype.softPaint=function(){};
+Timeline.GregorianEtherPainter.prototype.zoom=function(A){if(A!=0){this._unit+=A;
+}};
+Timeline.HotZoneGregorianEtherPainter=function(G){this._params=G;
+this._theme=G.theme;
+this._zones=[{startTime:Number.NEGATIVE_INFINITY,endTime:Number.POSITIVE_INFINITY,unit:G.unit,multiple:1}];
+for(var F=0;
+F<G.zones.length;
+F++){var C=G.zones[F];
+var E=SimileAjax.DateTime.parseGregorianDateTime(C.start).getTime();
+var B=SimileAjax.DateTime.parseGregorianDateTime(C.end).getTime();
+for(var D=0;
+D<this._zones.length&&B>E;
+D++){var A=this._zones[D];
+if(E<A.endTime){if(E>A.startTime){this._zones.splice(D,0,{startTime:A.startTime,endTime:E,unit:A.unit,multiple:A.multiple});
+D++;
+A.startTime=E;
+}if(B<A.endTime){this._zones.splice(D,0,{startTime:E,endTime:B,unit:C.unit,multiple:(C.multiple)?C.multiple:1});
+D++;
+A.startTime=B;
+E=B;
+}else{A.multiple=C.multiple;
+A.unit=C.unit;
+E=A.endTime;
+}}}}};
+Timeline.HotZoneGregorianEtherPainter.prototype.initialize=function(C,B){this._band=C;
+this._timeline=B;
+this._backgroundLayer=C.createLayerDiv(0);
+this._backgroundLayer.setAttribute("name","ether-background");
+this._backgroundLayer.className="timeline-ether-bg";
+this._markerLayer=null;
+this._lineLayer=null;
+var D=("align" in this._params&&this._params.align!=undefined)?this._params.align:this._theme.ether.interval.marker[B.isHorizontal()?"hAlign":"vAlign"];
+var A=("showLine" in this._params)?this._params.showLine:this._theme.ether.interval.line.show;
+this._intervalMarkerLayout=new Timeline.EtherIntervalMarkerLayout(this._timeline,this._band,this._theme,D,A);
+this._highlight=new Timeline.EtherHighlight(this._timeline,this._band,this._theme,this._backgroundLayer);
+};
+Timeline.HotZoneGregorianEtherPainter.prototype.setHighlight=function(A,B){this._highlight.position(A,B);
+};
+Timeline.HotZoneGregorianEtherPainter.prototype.paint=function(){if(this._markerLayer){this._band.removeLayerDiv(this._markerLayer);
+}this._markerLayer=this._band.createLayerDiv(100);
+this._markerLayer.setAttribute("name","ether-markers");
+this._markerLayer.style.display="none";
+if(this._lineLayer){this._band.removeLayerDiv(this._lineLayer);
+}this._lineLayer=this._band.createLayerDiv(1);
+this._lineLayer.setAttribute("name","ether-lines");
+this._lineLayer.style.display="none";
+var C=this._band.getMinDate();
+var A=this._band.getMaxDate();
+var I=this._band.getTimeZone();
+var L=this._band.getLabeller();
+var B=this;
+var J=function(N,M){for(var O=0;
+O<M.multiple;
+O++){SimileAjax.DateTime.incrementByInterval(N,M.unit);
+}};
+var D=0;
+while(D<this._zones.length){if(C.getTime()<this._zones[D].endTime){break;
+}D++;
+}var E=this._zones.length-1;
+while(E>=0){if(A.getTime()>this._zones[E].startTime){break;
+}E--;
+}for(var H=D;
+H<=E;
+H++){var G=this._zones[H];
+var K=new Date(Math.max(C.getTime(),G.startTime));
+var F=new Date(Math.min(A.getTime(),G.endTime));
+SimileAjax.DateTime.roundDownToInterval(K,G.unit,I,G.multiple,this._theme.firstDayOfWeek);
+SimileAjax.DateTime.roundUpToInterval(F,G.unit,I,G.multiple,this._theme.firstDayOfWeek);
+while(K.getTime()<F.getTime()){this._intervalMarkerLayout.createIntervalMarker(K,L,G.unit,this._markerLayer,this._lineLayer);
+J(K,G);
+}}this._markerLayer.style.display="block";
+this._lineLayer.style.display="block";
+};
+Timeline.HotZoneGregorianEtherPainter.prototype.softPaint=function(){};
+Timeline.HotZoneGregorianEtherPainter.prototype.zoom=function(A){if(A!=0){for(var B=0;
+B<this._zones.length;
+++B){if(this._zones[B]){this._zones[B].unit+=A;
+}}}};
+Timeline.YearCountEtherPainter=function(A){this._params=A;
+this._theme=A.theme;
+this._startDate=SimileAjax.DateTime.parseGregorianDateTime(A.startDate);
+this._multiple=("multiple" in A)?A.multiple:1;
+};
+Timeline.YearCountEtherPainter.prototype.initialize=function(C,B){this._band=C;
+this._timeline=B;
+this._backgroundLayer=C.createLayerDiv(0);
+this._backgroundLayer.setAttribute("name","ether-background");
+this._backgroundLayer.className="timeline-ether-bg";
+this._markerLayer=null;
+this._lineLayer=null;
+var D=("align" in this._params)?this._params.align:this._theme.ether.interval.marker[B.isHorizontal()?"hAlign":"vAlign"];
+var A=("showLine" in this._params)?this._params.showLine:this._theme.ether.interval.line.show;
+this._intervalMarkerLayout=new Timeline.EtherIntervalMarkerLayout(this._timeline,this._band,this._theme,D,A);
+this._highlight=new Timeline.EtherHighlight(this._timeline,this._band,this._theme,this._backgroundLayer);
+};
+Timeline.YearCountEtherPainter.prototype.setHighlight=function(A,B){this._highlight.position(A,B);
+};
+Timeline.YearCountEtherPainter.prototype.paint=function(){if(this._markerLayer){this._band.removeLayerDiv(this._markerLayer);
+}this._markerLayer=this._band.createLayerDiv(100);
+this._markerLayer.setAttribute("name","ether-markers");
+this._markerLayer.style.display="none";
+if(this._lineLayer){this._band.removeLayerDiv(this._lineLayer);
+}this._lineLayer=this._band.createLayerDiv(1);
+this._lineLayer.setAttribute("name","ether-lines");
+this._lineLayer.style.display="none";
+var B=new Date(this._startDate.getTime());
+var F=this._band.getMaxDate();
+var E=this._band.getMinDate().getUTCFullYear()-this._startDate.getUTCFullYear();
+B.setUTCFullYear(this._band.getMinDate().getUTCFullYear()-E%this._multiple);
+var C=this;
+var A=function(G){for(var H=0;
+H<C._multiple;
+H++){SimileAjax.DateTime.incrementByInterval(G,SimileAjax.DateTime.YEAR);
+}};
+var D={labelInterval:function(G,I){var H=G.getUTCFullYear()-C._startDate.getUTCFullYear();
+return{text:H,emphasized:H==0};
+}};
+while(B.getTime()<F.getTime()){this._intervalMarkerLayout.createIntervalMarker(B,D,SimileAjax.DateTime.YEAR,this._markerLayer,this._lineLayer);
+A(B);
+}this._markerLayer.style.display="block";
+this._lineLayer.style.display="block";
+};
+Timeline.YearCountEtherPainter.prototype.softPaint=function(){};
+Timeline.QuarterlyEtherPainter=function(A){this._params=A;
+this._theme=A.theme;
+this._startDate=SimileAjax.DateTime.parseGregorianDateTime(A.startDate);
+};
+Timeline.QuarterlyEtherPainter.prototype.initialize=function(C,B){this._band=C;
+this._timeline=B;
+this._backgroundLayer=C.createLayerDiv(0);
+this._backgroundLayer.setAttribute("name","ether-background");
+this._backgroundLayer.className="timeline-ether-bg";
+this._markerLayer=null;
+this._lineLayer=null;
+var D=("align" in this._params)?this._params.align:this._theme.ether.interval.marker[B.isHorizontal()?"hAlign":"vAlign"];
+var A=("showLine" in this._params)?this._params.showLine:this._theme.ether.interval.line.show;
+this._intervalMarkerLayout=new Timeline.EtherIntervalMarkerLayout(this._timeline,this._band,this._theme,D,A);
+this._highlight=new Timeline.EtherHighlight(this._timeline,this._band,this._theme,this._backgroundLayer);
+};
+Timeline.QuarterlyEtherPainter.prototype.setHighlight=function(A,B){this._highlight.position(A,B);
+};
+Timeline.QuarterlyEtherPainter.prototype.paint=function(){if(this._markerLayer){this._band.removeLayerDiv(this._markerLayer);
+}this._markerLayer=this._band.createLayerDiv(100);
+this._markerLayer.setAttribute("name","ether-markers");
+this._markerLayer.style.display="none";
+if(this._lineLayer){this._band.removeLayerDiv(this._lineLayer);
+}this._lineLayer=this._band.createLayerDiv(1);
+this._lineLayer.setAttribute("name","ether-lines");
+this._lineLayer.style.display="none";
+var B=new Date(0);
+var E=this._band.getMaxDate();
+B.setUTCFullYear(Math.max(this._startDate.getUTCFullYear(),this._band.getMinDate().getUTCFullYear()));
+B.setUTCMonth(this._startDate.getUTCMonth());
+var C=this;
+var A=function(F){F.setUTCMonth(F.getUTCMonth()+3);
+};
+var D={labelInterval:function(G,H){var F=(4+(G.getUTCMonth()-C._startDate.getUTCMonth())/3)%4;
+if(F!=0){return{text:"Q"+(F+1),emphasized:false};
+}else{return{text:"Y"+(G.getUTCFullYear()-C._startDate.getUTCFullYear()+1),emphasized:true};
+}}};
+while(B.getTime()<E.getTime()){this._intervalMarkerLayout.createIntervalMarker(B,D,SimileAjax.DateTime.YEAR,this._markerLayer,this._lineLayer);
+A(B);
+}this._markerLayer.style.display="block";
+this._lineLayer.style.display="block";
+};
+Timeline.QuarterlyEtherPainter.prototype.softPaint=function(){};
+Timeline.EtherIntervalMarkerLayout=function(I,L,C,E,M){var A=I.isHorizontal();
+if(A){if(E=="Top"){this.positionDiv=function(O,N){O.style.left=N+"px";
+O.style.top="0px";
+};
+}else{this.positionDiv=function(O,N){O.style.left=N+"px";
+O.style.bottom="0px";
+};
+}}else{if(E=="Left"){this.positionDiv=function(O,N){O.style.top=N+"px";
+O.style.left="0px";
+};
+}else{this.positionDiv=function(O,N){O.style.top=N+"px";
+O.style.right="0px";
+};
+}}var D=C.ether.interval.marker;
+var K=C.ether.interval.line;
+var B=C.ether.interval.weekend;
+var H=(A?"h":"v")+E;
+var G=D[H+"Styler"];
+var J=D[H+"EmphasizedStyler"];
+var F=SimileAjax.DateTime.gregorianUnitLengths[SimileAjax.DateTime.DAY];
+this.createIntervalMarker=function(T,c,a,Y,P){var U=Math.round(L.dateToPixelOffset(T));
+if(M&&a!=SimileAjax.DateTime.WEEK){var V=I.getDocument().createElement("div");
+V.className="timeline-ether-lines";
+if(K.opacity<100){SimileAjax.Graphics.setOpacity(V,K.opacity);
+}if(A){V.style.left=U+"px";
+}else{V.style.top=U+"px";
+}P.appendChild(V);
+}if(a==SimileAjax.DateTime.WEEK){var N=C.firstDayOfWeek;
+var R=new Date(T.getTime()+(6-N-7)*F);
+var b=new Date(R.getTime()+2*F);
+var Q=Math.round(L.dateToPixelOffset(R));
+var S=Math.round(L.dateToPixelOffset(b));
+var W=Math.max(1,S-Q);
+var X=I.getDocument().createElement("div");
+X.className="timeline-ether-weekends";
+if(B.opacity<100){SimileAjax.Graphics.setOpacity(X,B.opacity);
+}if(A){X.style.left=Q+"px";
+X.style.width=W+"px";
+}else{X.style.top=Q+"px";
+X.style.height=W+"px";
+}P.appendChild(X);
+}var Z=c.labelInterval(T,a);
+var O=I.getDocument().createElement("div");
+O.innerHTML=Z.text;
+O.className="timeline-date-label";
+if(Z.emphasized){O.className+=" timeline-date-label-em";
+}this.positionDiv(O,U);
+Y.appendChild(O);
+return O;
+};
+};
+Timeline.EtherHighlight=function(B,E,D,C){var A=B.isHorizontal();
+this._highlightDiv=null;
+this._createHighlightDiv=function(){if(this._highlightDiv==null){this._highlightDiv=B.getDocument().createElement("div");
+this._highlightDiv.setAttribute("name","ether-highlight");
+this._highlightDiv.className="timeline-ether-highlight";
+var F=D.ether.highlightOpacity;
+if(F<100){SimileAjax.Graphics.setOpacity(this._highlightDiv,F);
+}C.appendChild(this._highlightDiv);
+}};
+this.position=function(H,J){this._createHighlightDiv();
+var I=Math.round(E.dateToPixelOffset(H));
+var G=Math.round(E.dateToPixelOffset(J));
+var F=Math.max(G-I,3);
+if(A){this._highlightDiv.style.left=I+"px";
+this._highlightDiv.style.width=F+"px";
+this._highlightDiv.style.height=(E.getViewWidth()-4)+"px";
+}else{this._highlightDiv.style.top=I+"px";
+this._highlightDiv.style.height=F+"px";
+this._highlightDiv.style.width=(E.getViewWidth()-4)+"px";
+}};
+};
+
+
+/* ethers.js */
+Timeline.LinearEther=function(A){this._params=A;
+this._interval=A.interval;
+this._pixelsPerInterval=A.pixelsPerInterval;
+};
+Timeline.LinearEther.prototype.initialize=function(B,A){this._band=B;
+this._timeline=A;
+this._unit=A.getUnit();
+if("startsOn" in this._params){this._start=this._unit.parseFromObject(this._params.startsOn);
+}else{if("endsOn" in this._params){this._start=this._unit.parseFromObject(this._params.endsOn);
+this.shiftPixels(-this._timeline.getPixelLength());
+}else{if("centersOn" in this._params){this._start=this._unit.parseFromObject(this._params.centersOn);
+this.shiftPixels(-this._timeline.getPixelLength()/2);
+}else{this._start=this._unit.makeDefaultValue();
+this.shiftPixels(-this._timeline.getPixelLength()/2);
+}}}};
+Timeline.LinearEther.prototype.setDate=function(A){this._start=this._unit.cloneValue(A);
+};
+Timeline.LinearEther.prototype.shiftPixels=function(B){var A=this._interval*B/this._pixelsPerInterval;
+this._start=this._unit.change(this._start,A);
+};
+Timeline.LinearEther.prototype.dateToPixelOffset=function(B){var A=this._unit.compare(B,this._start);
+return this._pixelsPerInterval*A/this._interval;
+};
+Timeline.LinearEther.prototype.pixelOffsetToDate=function(B){var A=B*this._interval/this._pixelsPerInterval;
+return this._unit.change(this._start,A);
+};
+Timeline.LinearEther.prototype.zoom=function(D){var A=0;
+var B=this._band._zoomIndex;
+var C=B;
+if(D&&(B>0)){C=B-1;
+}if(!D&&(B<(this._band._zoomSteps.length-1))){C=B+1;
+}this._band._zoomIndex=C;
+this._interval=SimileAjax.DateTime.gregorianUnitLengths[this._band._zoomSteps[C].unit];
+this._pixelsPerInterval=this._band._zoomSteps[C].pixelsPerInterval;
+A=this._band._zoomSteps[C].unit-this._band._zoomSteps[B].unit;
+return A;
+};
+Timeline.HotZoneEther=function(A){this._params=A;
+this._interval=A.interval;
+this._pixelsPerInterval=A.pixelsPerInterval;
+this._theme=A.theme;
+};
+Timeline.HotZoneEther.prototype.initialize=function(I,H){this._band=I;
+this._timeline=H;
+this._unit=H.getUnit();
+this._zones=[{startTime:Number.NEGATIVE_INFINITY,endTime:Number.POSITIVE_INFINITY,magnify:1}];
+var D=this._params;
+for(var E=0;
+E<D.zones.length;
+E++){var G=D.zones[E];
+var F=this._unit.parseFromObject(G.start);
+var B=this._unit.parseFromObject(G.end);
+for(var C=0;
+C<this._zones.length&&this._unit.compare(B,F)>0;
+C++){var A=this._zones[C];
+if(this._unit.compare(F,A.endTime)<0){if(this._unit.compare(F,A.startTime)>0){this._zones.splice(C,0,{startTime:A.startTime,endTime:F,magnify:A.magnify});
+C++;
+A.startTime=F;
+}if(this._unit.compare(B,A.endTime)<0){this._zones.splice(C,0,{startTime:F,endTime:B,magnify:G.magnify*A.magnify});
+C++;
+A.startTime=B;
+F=B;
+}else{A.magnify*=G.magnify;
+F=A.endTime;
+}}}}if("startsOn" in this._params){this._start=this._unit.parseFromObject(this._params.startsOn);
+}else{if("endsOn" in this._params){this._start=this._unit.parseFromObject(this._params.endsOn);
+this.shiftPixels(-this._timeline.getPixelLength());
+}else{if("centersOn" in this._params){this._start=this._unit.parseFromObject(this._params.centersOn);
+this.shiftPixels(-this._timeline.getPixelLength()/2);
+}else{this._start=this._unit.makeDefaultValue();
+this.shiftPixels(-this._timeline.getPixelLength()/2);
+}}}};
+Timeline.HotZoneEther.prototype.setDate=function(A){this._start=this._unit.cloneValue(A);
+};
+Timeline.HotZoneEther.prototype.shiftPixels=function(A){this._start=this.pixelOffsetToDate(A);
+};
+Timeline.HotZoneEther.prototype.dateToPixelOffset=function(A){return this._dateDiffToPixelOffset(this._start,A);
+};
+Timeline.HotZoneEther.prototype.pixelOffsetToDate=function(A){return this._pixelOffsetToDate(A,this._start);
+};
+Timeline.HotZoneEther.prototype.zoom=function(D){var A=0;
+var B=this._band._zoomIndex;
+var C=B;
+if(D&&(B>0)){C=B-1;
+}if(!D&&(B<(this._band._zoomSteps.length-1))){C=B+1;
+}this._band._zoomIndex=C;
+this._interval=SimileAjax.DateTime.gregorianUnitLengths[this._band._zoomSteps[C].unit];
+this._pixelsPerInterval=this._band._zoomSteps[C].pixelsPerInterval;
+A=this._band._zoomSteps[C].unit-this._band._zoomSteps[B].unit;
+return A;
+};
+Timeline.HotZoneEther.prototype._dateDiffToPixelOffset=function(H,C){var D=this._getScale();
+var I=H;
+var B=C;
+var E=0;
+if(this._unit.compare(I,B)<0){var G=0;
+while(G<this._zones.length){if(this._unit.compare(I,this._zones[G].endTime)<0){break;
+}G++;
+}while(this._unit.compare(I,B)<0){var F=this._zones[G];
+var A=this._unit.earlier(B,F.endTime);
+E+=(this._unit.compare(A,I)/(D/F.magnify));
+I=A;
+G++;
+}}else{var G=this._zones.length-1;
+while(G>=0){if(this._unit.compare(I,this._zones[G].startTime)>0){break;
+}G--;
+}while(this._unit.compare(I,B)>0){var F=this._zones[G];
+var A=this._unit.later(B,F.startTime);
+E+=(this._unit.compare(A,I)/(D/F.magnify));
+I=A;
+G--;
+}}return E;
+};
+Timeline.HotZoneEther.prototype._pixelOffsetToDate=function(E,B){var G=this._getScale();
+var D=B;
+if(E>0){var F=0;
+while(F<this._zones.length){if(this._unit.compare(D,this._zones[F].endTime)<0){break;
+}F++;
+}while(E>0){var A=this._zones[F];
+var H=G/A.magnify;
+if(A.endTime==Number.POSITIVE_INFINITY){D=this._unit.change(D,E*H);
+E=0;
+}else{var C=this._unit.compare(A.endTime,D)/H;
+if(C>E){D=this._unit.change(D,E*H);
+E=0;
+}else{D=A.endTime;
+E-=C;
+}}F++;
+}}else{var F=this._zones.length-1;
+while(F>=0){if(this._unit.compare(D,this._zones[F].startTime)>0){break;
+}F--;
+}E=-E;
+while(E>0){var A=this._zones[F];
+var H=G/A.magnify;
+if(A.startTime==Number.NEGATIVE_INFINITY){D=this._unit.change(D,-E*H);
+E=0;
+}else{var C=this._unit.compare(D,A.startTime)/H;
+if(C>E){D=this._unit.change(D,-E*H);
+E=0;
+}else{D=A.startTime;
+E-=C;
+}}F--;
+}}return D;
+};
+Timeline.HotZoneEther.prototype._getScale=function(){return this._interval/this._pixelsPerInterval;
+};
+
+
+/* event-utils.js */
+Timeline.EventUtils={};
+Timeline.EventUtils.getNewEventID=function(){if(this._lastEventID==null){this._lastEventID=0;
+}this._lastEventID+=1;
+return"e"+this._lastEventID;
+};
+Timeline.EventUtils.decodeEventElID=function(C){var D=C.split("-");
+if(D[1]!="tl"){alert("Internal Timeline problem 101, please consult support");
+return{band:null,evt:null};
+}var B=Timeline.getTimelineFromID(D[2]);
+var E=B.getBand(D[3]);
+var A=E.getEventSource.getEvent(D[4]);
+return{band:E,evt:A};
+};
+Timeline.EventUtils.encodeEventElID=function(B,D,C,A){return C+"-tl-"+B.timelineID+"-"+D.getIndex()+"-"+A.getID();
+};
+
+
+/* labellers.js */
+Timeline.GregorianDateLabeller=function(B,A){this._locale=B;
+this._timeZone=A;
+};
+Timeline.GregorianDateLabeller.monthNames=[];
+Timeline.GregorianDateLabeller.dayNames=[];
+Timeline.GregorianDateLabeller.labelIntervalFunctions=[];
+Timeline.GregorianDateLabeller.getMonthName=function(B,A){return Timeline.GregorianDateLabeller.monthNames[A][B];
+};
+Timeline.GregorianDateLabeller.prototype.labelInterval=function(A,C){var B=Timeline.GregorianDateLabeller.labelIntervalFunctions[this._locale];
+if(B==null){B=Timeline.GregorianDateLabeller.prototype.defaultLabelInterval;
+}return B.call(this,A,C);
+};
+Timeline.GregorianDateLabeller.prototype.labelPrecise=function(A){return SimileAjax.DateTime.removeTimeZoneOffset(A,this._timeZone).toUTCString();
+};
+Timeline.GregorianDateLabeller.prototype.defaultLabelInterval=function(B,C){var D;
+var F=false;
+B=SimileAjax.DateTime.removeTimeZoneOffset(B,this._timeZone);
+switch(C){case SimileAjax.DateTime.MILLISECOND:D=B.getUTCMilliseconds();
+break;
+case SimileAjax.DateTime.SECOND:D=B.getUTCSeconds();
+break;
+case SimileAjax.DateTime.MINUTE:var A=B.getUTCMinutes();
+if(A==0){D=B.getUTCHours()+":00";
+F=true;
+}else{D=A;
+}break;
+case SimileAjax.DateTime.HOUR:D=B.getUTCHours()+"hr";
+break;
+case SimileAjax.DateTime.DAY:D=Timeline.GregorianDateLabeller.getMonthName(B.getUTCMonth(),this._locale)+" "+B.getUTCDate();
+break;
+case SimileAjax.DateTime.WEEK:D=Timeline.GregorianDateLabeller.getMonthName(B.getUTCMonth(),this._locale)+" "+B.getUTCDate();
+break;
+case SimileAjax.DateTime.MONTH:var A=B.getUTCMonth();
+if(A!=0){D=Timeline.GregorianDateLabeller.getMonthName(A,this._locale);
+break;
+}case SimileAjax.DateTime.YEAR:case SimileAjax.DateTime.DECADE:case SimileAjax.DateTime.CENTURY:case SimileAjax.DateTime.MILLENNIUM:var E=B.getUTCFullYear();
+if(E>0){D=B.getUTCFullYear();
+}else{D=(1-E)+"BC";
+}F=(C==SimileAjax.DateTime.MONTH)||(C==SimileAjax.DateTime.DECADE&&E%100==0)||(C==SimileAjax.DateTime.CENTURY&&E%1000==0);
+break;
+default:D=B.toUTCString();
+}return{text:D,emphasized:F};
+};
+
+
+/* original-painter.js */
+Timeline.OriginalEventPainter=function(A){this._params=A;
+this._onSelectListeners=[];
+this._eventPaintListeners=[];
+this._filterMatcher=null;
+this._highlightMatcher=null;
+this._frc=null;
+this._eventIdToElmt={};
+};
+Timeline.OriginalEventPainter.prototype.initialize=function(B,A){this._band=B;
+this._timeline=A;
+this._backLayer=null;
+this._eventLayer=null;
+this._lineLayer=null;
+this._highlightLayer=null;
+this._eventIdToElmt=null;
+};
+Timeline.OriginalEventPainter.prototype.getType=function(){return"original";
+};
+Timeline.OriginalEventPainter.prototype.addOnSelectListener=function(A){this._onSelectListeners.push(A);
+};
+Timeline.OriginalEventPainter.prototype.removeOnSelectListener=function(B){for(var A=0;
+A<this._onSelectListeners.length;
+A++){if(this._onSelectListeners[A]==B){this._onSelectListeners.splice(A,1);
+break;
+}}};
+Timeline.OriginalEventPainter.prototype.addEventPaintListener=function(A){this._eventPaintListeners.push(A);
+};
+Timeline.OriginalEventPainter.prototype.removeEventPaintListener=function(B){for(var A=0;
+A<this._eventPaintListeners.length;
+A++){if(this._eventPaintListeners[A]==B){this._eventPaintListeners.splice(A,1);
+break;
+}}};
+Timeline.OriginalEventPainter.prototype.getFilterMatcher=function(){return this._filterMatcher;
+};
+Timeline.OriginalEventPainter.prototype.setFilterMatcher=function(A){this._filterMatcher=A;
+};
+Timeline.OriginalEventPainter.prototype.getHighlightMatcher=function(){return this._highlightMatcher;
+};
+Timeline.OriginalEventPainter.prototype.setHighlightMatcher=function(A){this._highlightMatcher=A;
+};
+Timeline.OriginalEventPainter.prototype.paint=function(){var C=this._band.getEventSource();
+if(C==null){return ;
+}this._eventIdToElmt={};
+this._fireEventPaintListeners("paintStarting",null,null);
+this._prepareForPainting();
+var I=this._params.theme.event;
+var G=Math.max(I.track.height,I.tape.height+this._frc.getLineHeight());
+var F={trackOffset:I.track.offset,trackHeight:G,trackGap:I.track.gap,trackIncrement:G+I.track.gap,icon:I.instant.icon,iconWidth:I.instant.iconWidth,iconHeight:I.instant.iconHeight,labelWidth:I.label.width,maxLabelChar:I.label.maxLabelChar,impreciseIconMargin:I.instant.impreciseIconMargin};
+var D=this._band.getMinDate();
+var B=this._band.getMaxDate();
+var J=(this._filterMatcher!=null)?this._filterMatcher:function(K){return true;
+};
+var A=(this._highlightMatcher!=null)?this._highlightMatcher:function(K){return -1;
+};
+var E=C.getEventReverseIterator(D,B);
+while(E.hasNext()){var H=E.next();
+if(J(H)){this.paintEvent(H,F,this._params.theme,A(H));
+}}this._highlightLayer.style.display="block";
+this._lineLayer.style.display="block";
+this._eventLayer.style.display="block";
+this._band.updateEventTrackInfo(this._tracks.length,F.trackIncrement);
+this._fireEventPaintListeners("paintEnded",null,null);
+};
+Timeline.OriginalEventPainter.prototype.softPaint=function(){};
+Timeline.OriginalEventPainter.prototype._prepareForPainting=function(){var B=this._band;
+if(this._backLayer==null){this._backLayer=this._band.createLayerDiv(0,"timeline-band-events");
+this._backLayer.style.visibility="hidden";
+var A=document.createElement("span");
+A.className="timeline-event-label";
+this._backLayer.appendChild(A);
+this._frc=SimileAjax.Graphics.getFontRenderingContext(A);
+}this._frc.update();
+this._tracks=[];
+if(this._highlightLayer!=null){B.removeLayerDiv(this._highlightLayer);
+}this._highlightLayer=B.createLayerDiv(105,"timeline-band-highlights");
+this._highlightLayer.style.display="none";
+if(this._lineLayer!=null){B.removeLayerDiv(this._lineLayer);
+}this._lineLayer=B.createLayerDiv(110,"timeline-band-lines");
+this._lineLayer.style.display="none";
+if(this._eventLayer!=null){B.removeLayerDiv(this._eventLayer);
+}this._eventLayer=B.createLayerDiv(115,"timeline-band-events");
+this._eventLayer.style.display="none";
+};
+Timeline.OriginalEventPainter.prototype.paintEvent=function(B,C,D,A){if(B.isInstant()){this.paintInstantEvent(B,C,D,A);
+}else{this.paintDurationEvent(B,C,D,A);
+}};
+Timeline.OriginalEventPainter.prototype.paintInstantEvent=function(B,C,D,A){if(B.isImprecise()){this.paintImpreciseInstantEvent(B,C,D,A);
+}else{this.paintPreciseInstantEvent(B,C,D,A);
+}};
+Timeline.OriginalEventPainter.prototype.paintDurationEvent=function(B,C,D,A){if(B.isImprecise()){this.paintImpreciseDurationEvent(B,C,D,A);
+}else{this.paintPreciseDurationEvent(B,C,D,A);
+}};
+Timeline.OriginalEventPainter.prototype.paintPreciseInstantEvent=function(N,S,V,T){var W=this._timeline.getDocument();
+var L=N.getText();
+var H=N.getStart();
+var I=Math.round(this._band.dateToPixelOffset(H));
+var A=Math.round(I+S.iconWidth/2);
+var C=Math.round(I-S.iconWidth/2);
+var F=this._getLabelDivClassName(N);
+var D=this._frc.computeSize(L,F);
+var M=A+V.event.label.offsetFromLine;
+var J=M+D.width;
+var Q=J;
+var P=this._findFreeTrack(N,Q);
+var R=Math.round(S.trackOffset+P*S.trackIncrement+S.trackHeight/2-D.height/2);
+var B=this._paintEventIcon(N,P,C,S,V,0);
+var U=this._paintEventLabel(N,L,M,R,D.width,D.height,V,F,T);
+var E=[B.elmt,U.elmt];
+var O=this;
+var K=function(Y,X,Z){return O._onClickInstantEvent(B.elmt,X,N);
+};
+SimileAjax.DOM.registerEvent(B.elmt,"mousedown",K);
+SimileAjax.DOM.registerEvent(U.elmt,"mousedown",K);
+var G=this._createHighlightDiv(T,B,V,N);
+if(G!=null){E.push(G);
+}this._fireEventPaintListeners("paintedEvent",N,E);
+this._eventIdToElmt[N.getID()]=B.elmt;
+this._tracks[P]=C;
+};
+Timeline.OriginalEventPainter.prototype.paintImpreciseInstantEvent=function(P,U,Z,W){var b=this._timeline.getDocument();
+var N=P.getText();
+var J=P.getStart();
+var X=P.getEnd();
+var K=Math.round(this._band.dateToPixelOffset(J));
+var B=Math.round(this._band.dateToPixelOffset(X));
+var A=Math.round(K+U.iconWidth/2);
+var D=Math.round(K-U.iconWidth/2);
+var H=this._getLabelDivClassName(P);
+var F=this._frc.computeSize(N,H);
+var O=A+Z.event.label.offsetFromLine;
+var L=O+F.width;
+var S=Math.max(L,B);
+var R=this._findFreeTrack(P,S);
+var a=Z.event.tape.height;
+var T=Math.round(U.trackOffset+R*U.trackIncrement+a);
+var C=this._paintEventIcon(P,R,D,U,Z,a);
+var Y=this._paintEventLabel(P,N,O,T,F.width,F.height,Z,H,W);
+var V=P.getColor();
+V=V!=null?V:Z.event.instant.impreciseColor;
+var E=this._paintEventTape(P,R,K,B,V,Z.event.instant.impreciseOpacity,U,Z,0);
+var G=[C.elmt,Y.elmt,E.elmt];
+var Q=this;
+var M=function(d,c,e){return Q._onClickInstantEvent(C.elmt,c,P);
+};
+SimileAjax.DOM.registerEvent(C.elmt,"mousedown",M);
+SimileAjax.DOM.registerEvent(E.elmt,"mousedown",M);
+SimileAjax.DOM.registerEvent(Y.elmt,"mousedown",M);
+var I=this._createHighlightDiv(W,C,Z,P);
+if(I!=null){G.push(I);
+}this._fireEventPaintListeners("paintedEvent",P,G);
+this._eventIdToElmt[P.getID()]=C.elmt;
+this._tracks[R]=D;
+};
+Timeline.OriginalEventPainter.prototype.paintPreciseDurationEvent=function(M,R,W,T){var X=this._timeline.getDocument();
+var K=M.getText();
+var G=M.getStart();
+var U=M.getEnd();
+var H=Math.round(this._band.dateToPixelOffset(G));
+var A=Math.round(this._band.dateToPixelOffset(U));
+var E=this._getLabelDivClassName(M);
+var C=this._frc.computeSize(K,E);
+var L=H;
+var I=L+C.width;
+var P=Math.max(I,A);
+var O=this._findFreeTrack(M,P);
+var Q=Math.round(R.trackOffset+O*R.trackIncrement+W.event.tape.height);
+var S=M.getColor();
+S=S!=null?S:W.event.duration.color;
+var B=this._paintEventTape(M,O,H,A,S,100,R,W,0);
+var V=this._paintEventLabel(M,K,L,Q,C.width,C.height,W,E,T);
+var D=[B.elmt,V.elmt];
+var N=this;
+var J=function(Z,Y,a){return N._onClickDurationEvent(B.elmt,Y,M);
+};
+SimileAjax.DOM.registerEvent(B.elmt,"mousedown",J);
+SimileAjax.DOM.registerEvent(V.elmt,"mousedown",J);
+var F=this._createHighlightDiv(T,B,W,M);
+if(F!=null){D.push(F);
+}this._fireEventPaintListeners("paintedEvent",M,D);
+this._eventIdToElmt[M.getID()]=B.elmt;
+this._tracks[O]=H;
+};
+Timeline.OriginalEventPainter.prototype.paintImpreciseDurationEvent=function(O,W,b,Y){var c=this._timeline.getDocument();
+var M=O.getText();
+var I=O.getStart();
+var V=O.getLatestStart();
+var Z=O.getEnd();
+var Q=O.getEarliestEnd();
+var K=Math.round(this._band.dateToPixelOffset(I));
+var F=Math.round(this._band.dateToPixelOffset(V));
+var A=Math.round(this._band.dateToPixelOffset(Z));
+var G=Math.round(this._band.dateToPixelOffset(Q));
+var E=this._getLabelDivClassName(O);
+var C=this._frc.computeSize(M,E);
+var N=F;
+var J=N+C.width;
+var S=Math.max(J,A);
+var R=this._findFreeTrack(O,S);
+var T=Math.round(W.trackOffset+R*W.trackIncrement+b.event.tape.height);
+var X=O.getColor();
+X=X!=null?X:b.event.duration.color;
+var U=this._paintEventTape(O,R,K,A,b.event.duration.impreciseColor,b.event.duration.impreciseOpacity,W,b,0);
+var B=this._paintEventTape(O,R,F,G,X,100,W,b,1);
+var a=this._paintEventLabel(O,M,N,T,C.width,C.height,b,E,Y);
+var D=[U.elmt,B.elmt,a.elmt];
+var P=this;
+var L=function(e,d,f){return P._onClickDurationEvent(B.elmt,d,O);
+};
+SimileAjax.DOM.registerEvent(B.elmt,"mousedown",L);
+SimileAjax.DOM.registerEvent(a.elmt,"mousedown",L);
+var H=this._createHighlightDiv(Y,B,b,O);
+if(H!=null){D.push(H);
+}this._fireEventPaintListeners("paintedEvent",O,D);
+this._eventIdToElmt[O.getID()]=B.elmt;
+this._tracks[R]=K;
+};
+Timeline.OriginalEventPainter.prototype._encodeEventElID=function(B,A){return Timeline.EventUtils.encodeEventElID(this._timeline,this._band,B,A);
+};
+Timeline.OriginalEventPainter.prototype._findFreeTrack=function(E,D){var A=E.getTrackNum();
+if(A!=null){return A;
+}for(var C=0;
+C<this._tracks.length;
+C++){var B=this._tracks[C];
+if(B>D){break;
+}}return C;
+};
+Timeline.OriginalEventPainter.prototype._paintEventIcon=function(K,B,C,G,F,D){var I=K.getIcon();
+I=I!=null?I:G.icon;
+var J;
+if(D>0){J=G.trackOffset+B*G.trackIncrement+D+G.impreciseIconMargin;
+}else{var H=G.trackOffset+B*G.trackIncrement+G.trackHeight/2;
+J=Math.round(H-G.iconHeight/2);
+}var E=SimileAjax.Graphics.createTranslucentImage(I);
+var A=this._timeline.getDocument().createElement("div");
+A.className=this._getElClassName("timeline-event-icon",K,"icon");
+A.id=this._encodeEventElID("icon",K);
+A.style.left=C+"px";
+A.style.top=J+"px";
+A.appendChild(E);
+if(K._title!=null){A.title=K._title;
+}this._eventLayer.appendChild(A);
+return{left:C,top:J,width:G.iconWidth,height:G.iconHeight,elmt:A};
+};
+Timeline.OriginalEventPainter.prototype._paintEventLabel=function(K,L,D,H,A,J,G,E,C){var I=this._timeline.getDocument();
+var B=I.createElement("div");
+B.className=E;
+B.id=this._encodeEventElID("label",K);
+B.style.left=D+"px";
+B.style.width=A+"px";
+B.style.top=H+"px";
+B.innerHTML=L;
+if(K._title!=null){B.title=K._title;
+}var F=K.getTextColor();
+if(F==null){F=K.getColor();
+}if(F!=null){B.style.color=F;
+}if(G.event.highlightLabelBackground&&C>=0){B.style.background=this._getHighlightColor(C,G);
+}this._eventLayer.appendChild(B);
+return{left:D,top:H,width:A,height:J,elmt:B};
+};
+Timeline.OriginalEventPainter.prototype._paintEventTape=function(N,B,D,A,G,C,J,I,M){var F=A-D;
+var E=I.event.tape.height;
+var K=J.trackOffset+B*J.trackIncrement;
+var O=this._timeline.getDocument().createElement("div");
+O.className=this._getElClassName("timeline-event-tape",N,"tape");
+O.id=this._encodeEventElID("tape"+M,N);
+O.style.left=D+"px";
+O.style.width=F+"px";
+O.style.height=E+"px";
+O.style.top=K+"px";
+if(N._title!=null){O.title=N._title;
+}if(G!=null){O.style.backgroundColor=G;
+}var L=N.getTapeImage();
+var H=N.getTapeRepeat();
+H=H!=null?H:"repeat";
+if(L!=null){O.style.backgroundImage="url("+L+")";
+O.style.backgroundRepeat=H;
+}SimileAjax.Graphics.setOpacity(O,C);
+this._eventLayer.appendChild(O);
+return{left:D,top:K,width:F,height:E,elmt:O};
+};
+Timeline.OriginalEventPainter.prototype._getLabelDivClassName=function(A){return this._getElClassName("timeline-event-label",A,"label");
+};
+Timeline.OriginalEventPainter.prototype._getElClassName=function(D,C,A){var E=C.getClassName(),B=[];
+if(E){if(A){B.push(A+"-"+E+" ");
+}B.push(E+" ");
+}B.push(D);
+return(B.join(""));
+};
+Timeline.OriginalEventPainter.prototype._getHighlightColor=function(A,B){var C=B.event.highlightColors;
+return C[Math.min(A,C.length-1)];
+};
+Timeline.OriginalEventPainter.prototype._createHighlightDiv=function(A,D,F,B){var G=null;
+if(A>=0){var E=this._timeline.getDocument();
+var C=this._getHighlightColor(A,F);
+G=E.createElement("div");
+G.className=this._getElClassName("timeline-event-highlight",B,"highlight");
+G.id=this._encodeEventElID("highlight0",B);
+G.style.position="absolute";
+G.style.overflow="hidden";
+G.style.left=(D.left-2)+"px";
+G.style.width=(D.width+4)+"px";
+G.style.top=(D.top-2)+"px";
+G.style.height=(D.height+4)+"px";
+G.style.background=C;
+this._highlightLayer.appendChild(G);
+}return G;
+};
+Timeline.OriginalEventPainter.prototype._onClickInstantEvent=function(C,A,B){var D=SimileAjax.DOM.getPageCoordinates(C);
+this._showBubble(D.left+Math.ceil(C.offsetWidth/2),D.top+Math.ceil(C.offsetHeight/2),B);
+this._fireOnSelect(B.getID());
+A.cancelBubble=true;
+SimileAjax.DOM.cancelEvent(A);
+return false;
+};
+Timeline.OriginalEventPainter.prototype._onClickDurationEvent=function(F,B,C){if("pageX" in B){var A=B.pageX;
+var E=B.pageY;
+}else{var D=SimileAjax.DOM.getPageCoordinates(F);
+var A=B.offsetX+D.left;
+var E=B.offsetY+D.top;
+}this._showBubble(A,E,C);
+this._fireOnSelect(C.getID());
+B.cancelBubble=true;
+SimileAjax.DOM.cancelEvent(B);
+return false;
+};
+Timeline.OriginalEventPainter.prototype.showBubble=function(A){var B=this._eventIdToElmt[A.getID()];
+if(B){var C=SimileAjax.DOM.getPageCoordinates(B);
+this._showBubble(C.left+B.offsetWidth/2,C.top+B.offsetHeight/2,A);
+}};
+Timeline.OriginalEventPainter.prototype._showBubble=function(B,E,C){var D=document.createElement("div");
+var A=this._params.theme.event.bubble;
+C.fillInfoBubble(D,this._params.theme,this._band.getLabeller());
+SimileAjax.WindowManager.cancelPopups();
+SimileAjax.Graphics.createBubbleForContentAndPoint(D,B,E,A.width,null,A.maxHeight);
+};
+Timeline.OriginalEventPainter.prototype._fireOnSelect=function(A){for(var B=0;
+B<this._onSelectListeners.length;
+B++){this._onSelectListeners[B](A);
+}};
+Timeline.OriginalEventPainter.prototype._fireEventPaintListeners=function(D,A,C){for(var B=0;
+B<this._eventPaintListeners.length;
+B++){this._eventPaintListeners[B](this._band,D,A,C);
+}};
+
+
+/* overview-painter.js */
+Timeline.OverviewEventPainter=function(A){this._params=A;
+this._onSelectListeners=[];
+this._filterMatcher=null;
+this._highlightMatcher=null;
+};
+Timeline.OverviewEventPainter.prototype.initialize=function(B,A){this._band=B;
+this._timeline=A;
+this._eventLayer=null;
+this._highlightLayer=null;
+};
+Timeline.OverviewEventPainter.prototype.getType=function(){return"overview";
+};
+Timeline.OverviewEventPainter.prototype.addOnSelectListener=function(A){this._onSelectListeners.push(A);
+};
+Timeline.OverviewEventPainter.prototype.removeOnSelectListener=function(B){for(var A=0;
+A<this._onSelectListeners.length;
+A++){if(this._onSelectListeners[A]==B){this._onSelectListeners.splice(A,1);
+break;
+}}};
+Timeline.OverviewEventPainter.prototype.getFilterMatcher=function(){return this._filterMatcher;
+};
+Timeline.OverviewEventPainter.prototype.setFilterMatcher=function(A){this._filterMatcher=A;
+};
+Timeline.OverviewEventPainter.prototype.getHighlightMatcher=function(){return this._highlightMatcher;
+};
+Timeline.OverviewEventPainter.prototype.setHighlightMatcher=function(A){this._highlightMatcher=A;
+};
+Timeline.OverviewEventPainter.prototype.paint=function(){var C=this._band.getEventSource();
+if(C==null){return ;
+}this._prepareForPainting();
+var H=this._params.theme.event;
+var F={trackOffset:H.overviewTrack.offset,trackHeight:H.overviewTrack.height,trackGap:H.overviewTrack.gap,trackIncrement:H.overviewTrack.height+H.overviewTrack.gap};
+var D=this._band.getMinDate();
+var B=this._band.getMaxDate();
+var I=(this._filterMatcher!=null)?this._filterMatcher:function(J){return true;
+};
+var A=(this._highlightMatcher!=null)?this._highlightMatcher:function(J){return -1;
+};
+var E=C.getEventReverseIterator(D,B);
+while(E.hasNext()){var G=E.next();
+if(I(G)){this.paintEvent(G,F,this._params.theme,A(G));
+}}this._highlightLayer.style.display="block";
+this._eventLayer.style.display="block";
+this._band.updateEventTrackInfo(this._tracks.length,F.trackIncrement);
+};
+Timeline.OverviewEventPainter.prototype.softPaint=function(){};
+Timeline.OverviewEventPainter.prototype._prepareForPainting=function(){var A=this._band;
+this._tracks=[];
+if(this._highlightLayer!=null){A.removeLayerDiv(this._highlightLayer);
+}this._highlightLayer=A.createLayerDiv(105,"timeline-band-highlights");
+this._highlightLayer.style.display="none";
+if(this._eventLayer!=null){A.removeLayerDiv(this._eventLayer);
+}this._eventLayer=A.createLayerDiv(110,"timeline-band-events");
+this._eventLayer.style.display="none";
+};
+Timeline.OverviewEventPainter.prototype.paintEvent=function(B,C,D,A){if(B.isInstant()){this.paintInstantEvent(B,C,D,A);
+}else{this.paintDurationEvent(B,C,D,A);
+}};
+Timeline.OverviewEventPainter.prototype.paintInstantEvent=function(I,H,E,A){var F=I.getStart();
+var B=Math.round(this._band.dateToPixelOffset(F));
+var C=I.getColor(),D=I.getClassName();
+if(D){C=null;
+}else{C=C!=null?C:E.event.duration.color;
+}var G=this._paintEventTick(I,B,C,100,H,E);
+this._createHighlightDiv(A,G,E);
+};
+Timeline.OverviewEventPainter.prototype.paintDurationEvent=function(L,K,H,B){var A=L.getLatestStart();
+var I=L.getEarliestEnd();
+var J=Math.round(this._band.dateToPixelOffset(A));
+var C=Math.round(this._band.dateToPixelOffset(I));
+var F=0;
+for(;
+F<this._tracks.length;
+F++){if(C<this._tracks[F]){break;
+}}this._tracks[F]=C;
+var E=L.getColor(),G=L.getClassName();
+if(G){E=null;
+}else{E=E!=null?E:H.event.duration.color;
+}var D=this._paintEventTape(L,F,J,C,E,100,K,H,G);
+this._createHighlightDiv(B,D,H);
+};
+Timeline.OverviewEventPainter.prototype._paintEventTape=function(K,B,D,L,E,C,H,G,F){var I=H.trackOffset+B*H.trackIncrement;
+var A=L-D;
+var J=H.trackHeight;
+var M=this._timeline.getDocument().createElement("div");
+M.className="timeline-small-event-tape";
+if(F){M.className+=" small-"+F;
+}M.style.left=D+"px";
+M.style.width=A+"px";
+M.style.top=I+"px";
+M.style.height=J+"px";
+if(E){M.style.backgroundColor=E;
+}if(C<100){SimileAjax.Graphics.setOpacity(M,C);
+}this._eventLayer.appendChild(M);
+return{left:D,top:I,width:A,height:J,elmt:M};
+};
+Timeline.OverviewEventPainter.prototype._paintEventTick=function(J,C,D,B,G,F){var I=F.event.overviewTrack.tickHeight;
+var H=G.trackOffset-I;
+var A=1;
+var K=this._timeline.getDocument().createElement("div");
+K.className="timeline-small-event-icon";
+K.style.left=C+"px";
+K.style.top=H+"px";
+var E=J.getClassName();
+if(E){K.className+=" small-"+E;
+}if(B<100){SimileAjax.Graphics.setOpacity(K,B);
+}this._eventLayer.appendChild(K);
+return{left:C,top:H,width:A,height:I,elmt:K};
+};
+Timeline.OverviewEventPainter.prototype._createHighlightDiv=function(A,C,E){if(A>=0){var D=this._timeline.getDocument();
+var G=E.event;
+var B=G.highlightColors[Math.min(A,G.highlightColors.length-1)];
+var F=D.createElement("div");
+F.style.position="absolute";
+F.style.overflow="hidden";
+F.style.left=(C.left-1)+"px";
+F.style.width=(C.width+2)+"px";
+F.style.top=(C.top-1)+"px";
+F.style.height=(C.height+2)+"px";
+F.style.background=B;
+this._highlightLayer.appendChild(F);
+}};
+Timeline.OverviewEventPainter.prototype.showBubble=function(A){};
+
+
+/* sources.js */
+Timeline.DefaultEventSource=function(A){this._events=(A instanceof Object)?A:new SimileAjax.EventIndex();
+this._listeners=[];
+};
+Timeline.DefaultEventSource.prototype.addListener=function(A){this._listeners.push(A);
+};
+Timeline.DefaultEventSource.prototype.removeListener=function(B){for(var A=0;
+A<this._listeners.length;
+A++){if(this._listeners[A]==B){this._listeners.splice(A,1);
+break;
+}}};
+Timeline.DefaultEventSource.prototype.loadXML=function(G,A){var C=this._getBaseURL(A);
+var H=G.documentElement.getAttribute("wiki-url");
+var J=G.documentElement.getAttribute("wiki-section");
+var F=G.documentElement.getAttribute("date-time-format");
+var E=this._events.getUnit().getParser(F);
+var D=G.documentElement.firstChild;
+var I=false;
+while(D!=null){if(D.nodeType==1){var L="";
+if(D.firstChild!=null&&D.firstChild.nodeType==3){L=D.firstChild.nodeValue;
+}var B=(D.getAttribute("isDuration")===null&&D.getAttribute("durationEvent")===null)||D.getAttribute("isDuration")=="false"||D.getAttribute("durationEvent")=="false";
+var K=new Timeline.DefaultEventSource.Event({id:D.getAttribute("id"),start:E(D.getAttribute("start")),end:E(D.getAttribute("end")),latestStart:E(D.getAttribute("latestStart")),earliestEnd:E(D.getAttribute("earliestEnd")),instant:B,text:D.getAttribute("title"),description:L,image:this._resolveRelativeURL(D.getAttribute("image"),C),link:this._resolveRelativeURL(D.getAttribute("link"),C),icon:this._resolveRelativeURL(D.getAttribute("icon"),C),color:D.getAttribute("color"),textColor:D.getAttribute("textColor"),hoverText:D.getAttribute("hoverText"),classname:D.getAttribute("classname"),tapeImage:D.getAttribute("tapeImage"),tapeRepeat:D.getAttribute("tapeRepeat"),caption:D.getAttribute("caption"),eventID:D.getAttribute("eventID"),trackNum:D.getAttribute("trackNum")});
+K._node=D;
+K.getProperty=function(M){return this._node.getAttribute(M);
+};
+K.setWikiInfo(H,J);
+this._events.add(K);
+I=true;
+}D=D.nextSibling;
+}if(I){this._fire("onAddMany",[]);
+}};
+Timeline.DefaultEventSource.prototype.loadJSON=function(H,B){var D=this._getBaseURL(B);
+var J=false;
+if(H&&H.events){var I=("wikiURL" in H)?H.wikiURL:null;
+var K=("wikiSection" in H)?H.wikiSection:null;
+var F=("dateTimeFormat" in H)?H.dateTimeFormat:null;
+var E=this._events.getUnit().getParser(F);
+for(var G=0;
+G<H.events.length;
+G++){var A=H.events[G];
+var C=A.isDuration||(A.durationEvent!=null&&!A.durationEvent);
+var L=new Timeline.DefaultEventSource.Event({id:("id" in A)?A.id:undefined,start:E(A.start),end:E(A.end),latestStart:E(A.latestStart),earliestEnd:E(A.earliestEnd),instant:C,text:A.title,description:A.description,image:this._resolveRelativeURL(A.image,D),link:this._resolveRelativeURL(A.link,D),icon:this._resolveRelativeURL(A.icon,D),color:A.color,textColor:A.textColor,hoverText:A.hoverText,classname:A.classname,tapeImage:A.tapeImage,tapeRepeat:A.tapeRepeat,caption:A.caption,eventID:A.eventID,trackNum:A.trackNum});
+L._obj=A;
+L.getProperty=function(M){return this._obj[M];
+};
+L.setWikiInfo(I,K);
+this._events.add(L);
+J=true;
+}}if(J){this._fire("onAddMany",[]);
+}};
+Timeline.DefaultEventSource.prototype.loadSPARQL=function(I,B){var E=this._getBaseURL(B);
+var H="iso8601";
+var G=this._events.getUnit().getParser(H);
+if(I==null){return ;
+}var F=I.documentElement.firstChild;
+while(F!=null&&(F.nodeType!=1||F.nodeName!="results")){F=F.nextSibling;
+}var J=null;
+var L=null;
+if(F!=null){J=F.getAttribute("wiki-url");
+L=F.getAttribute("wiki-section");
+F=F.firstChild;
+}var K=false;
+while(F!=null){if(F.nodeType==1){var D={};
+var A=F.firstChild;
+while(A!=null){if(A.nodeType==1&&A.firstChild!=null&&A.firstChild.nodeType==1&&A.firstChild.firstChild!=null&&A.firstChild.firstChild.nodeType==3){D[A.getAttribute("name")]=A.firstChild.firstChild.nodeValue;
+}A=A.nextSibling;
+}if(D["start"]==null&&D["date"]!=null){D["start"]=D["date"];
+}var C=(D["isDuration"]===null&&D["durationEvent"]===null)||D["isDuration"]=="false"||D["durationEvent"]=="false";
+var M=new Timeline.DefaultEventSource.Event({id:D["id"],start:G(D["start"]),end:G(D["end"]),latestStart:G(D["latestStart"]),earliestEnd:G(D["earliestEnd"]),instant:C,text:D["title"],description:D["description"],image:this._resolveRelativeURL(D["image"],E),link:this._resolveRelativeURL(D["link"],E),icon:this._resolveRelativeURL(D["icon"],E),color:D["color"],textColor:D["textColor"],hoverText:D["hoverText"],caption:D["caption"],classname:D["classname"],tapeImage:D["tapeImage"],tapeRepeat:D["tapeRepeat"],eventID:D["eventID"],trackNum:D["trackNum"]});
+M._bindings=D;
+M.getProperty=function(N){return this._bindings[N];
+};
+M.setWikiInfo(J,L);
+this._events.add(M);
+K=true;
+}F=F.nextSibling;
+}if(K){this._fire("onAddMany",[]);
+}};
+Timeline.DefaultEventSource.prototype.add=function(A){this._events.add(A);
+this._fire("onAddOne",[A]);
+};
+Timeline.DefaultEventSource.prototype.addMany=function(A){for(var B=0;
+B<A.length;
+B++){this._events.add(A[B]);
+}this._fire("onAddMany",[]);
+};
+Timeline.DefaultEventSource.prototype.clear=function(){this._events.removeAll();
+this._fire("onClear",[]);
+};
+Timeline.DefaultEventSource.prototype.getEvent=function(A){return this._events.getEvent(A);
+};
+Timeline.DefaultEventSource.prototype.getEventIterator=function(A,B){return this._events.getIterator(A,B);
+};
+Timeline.DefaultEventSource.prototype.getEventReverseIterator=function(A,B){return this._events.getReverseIterator(A,B);
+};
+Timeline.DefaultEventSource.prototype.getAllEventIterator=function(){return this._events.getAllIterator();
+};
+Timeline.DefaultEventSource.prototype.getCount=function(){return this._events.getCount();
+};
+Timeline.DefaultEventSource.prototype.getEarliestDate=function(){return this._events.getEarliestDate();
+};
+Timeline.DefaultEventSource.prototype.getLatestDate=function(){return this._events.getLatestDate();
+};
+Timeline.DefaultEventSource.prototype._fire=function(B,A){for(var C=0;
+C<this._listeners.length;
+C++){var D=this._listeners[C];
+if(B in D){try{D[B].apply(D,A);
+}catch(E){SimileAjax.Debug.exception(E);
+}}}};
+Timeline.DefaultEventSource.prototype._getBaseURL=function(A){if(A.indexOf("://")<0){var C=this._getBaseURL(document.location.href);
+if(A.substr(0,1)=="/"){A=C.substr(0,C.indexOf("/",C.indexOf("://")+3))+A;
+}else{A=C+A;
+}}var B=A.lastIndexOf("/");
+if(B<0){return"";
+}else{return A.substr(0,B+1);
+}};
+Timeline.DefaultEventSource.prototype._resolveRelativeURL=function(A,B){if(A==null||A==""){return A;
+}else{if(A.indexOf("://")>0){return A;
+}else{if(A.substr(0,1)=="/"){return B.substr(0,B.indexOf("/",B.indexOf("://")+3))+A;
+}else{return B+A;
+}}}};
+Timeline.DefaultEventSource.Event=function(A){function D(E){return(A[E]!=null&&A[E]!="")?A[E]:null;
+}var C=A.id?A.id.trim():"";
+this._id=C.length>0?C:Timeline.EventUtils.getNewEventID();
+this._instant=A.instant||(A.end==null);
+this._start=A.start;
+this._end=(A.end!=null)?A.end:A.start;
+this._latestStart=(A.latestStart!=null)?A.latestStart:(A.instant?this._end:this._start);
+this._earliestEnd=(A.earliestEnd!=null)?A.earliestEnd:this._end;
+var B=[];
+if(this._start>this._latestStart){this._latestStart=this._start;
+B.push("start is > latestStart");
+}if(this._start>this._earliestEnd){this._earliestEnd=this._latestStart;
+B.push("start is > earliestEnd");
+}if(this._start>this._end){this._end=this._earliestEnd;
+B.push("start is > end");
+}if(this._latestStart>this._earliestEnd){this._earliestEnd=this._latestStart;
+B.push("latestStart is > earliestEnd");
+}if(this._latestStart>this._end){this._end=this._earliestEnd;
+B.push("latestStart is > end");
+}if(this._earliestEnd>this._end){this._end=this._earliestEnd;
+B.push("earliestEnd is > end");
+}this._eventID=D("eventID");
+this._text=(A.text!=null)?SimileAjax.HTML.deEntify(A.text):"";
+if(B.length>0){this._text+=" PROBLEM: "+B.join(", ");
+}this._description=SimileAjax.HTML.deEntify(A.description);
+this._image=D("image");
+this._link=D("link");
+this._title=D("hoverText");
+this._title=D("caption");
+this._icon=D("icon");
+this._color=D("color");
+this._textColor=D("textColor");
+this._classname=D("classname");
+this._tapeImage=D("tapeImage");
+this._tapeRepeat=D("tapeRepeat");
+this._trackNum=D("trackNum");
+if(this._trackNum!=null){this._trackNum=parseInt(this._trackNum);
+}this._wikiURL=null;
+this._wikiSection=null;
+};
+Timeline.DefaultEventSource.Event.prototype={getID:function(){return this._id;
+},isInstant:function(){return this._instant;
+},isImprecise:function(){return this._start!=this._latestStart||this._end!=this._earliestEnd;
+},getStart:function(){return this._start;
+},getEnd:function(){return this._end;
+},getLatestStart:function(){return this._latestStart;
+},getEarliestEnd:function(){return this._earliestEnd;
+},getEventID:function(){return this._eventID;
+},getText:function(){return this._text;
+},getDescription:function(){return this._description;
+},getImage:function(){return this._image;
+},getLink:function(){return this._link;
+},getIcon:function(){return this._icon;
+},getColor:function(){return this._color;
+},getTextColor:function(){return this._textColor;
+},getClassName:function(){return this._classname;
+},getTapeImage:function(){return this._tapeImage;
+},getTapeRepeat:function(){return this._tapeRepeat;
+},getTrackNum:function(){return this._trackNum;
+},getProperty:function(A){return null;
+},getWikiURL:function(){return this._wikiURL;
+},getWikiSection:function(){return this._wikiSection;
+},setWikiInfo:function(B,A){this._wikiURL=B;
+this._wikiSection=A;
+},fillDescription:function(A){A.innerHTML=this._description;
+},fillWikiInfo:function(D){D.style.display="none";
+if(this._wikiURL==null||this._wikiSection==null){return ;
+}var C=this.getProperty("wikiID");
+if(C==null||C.length==0){C=this.getText();
+}if(C==null||C.length==0){return ;
+}D.style.display="inline";
+C=C.replace(/\s/g,"_");
+var B=this._wikiURL+this._wikiSection.replace(/\s/g,"_")+"/"+C;
+var A=document.createElement("a");
+A.href=B;
+A.target="new";
+A.innerHTML=Timeline.strings[Timeline.clientLocale].wikiLinkLabel;
+D.appendChild(document.createTextNode("["));
+D.appendChild(A);
+D.appendChild(document.createTextNode("]"));
+},fillTime:function(A,B){if(this._instant){if(this.isImprecise()){A.appendChild(A.ownerDocument.createTextNode(B.labelPrecise(this._start)));
+A.appendChild(A.ownerDocument.createElement("br"));
+A.appendChild(A.ownerDocument.createTextNode(B.labelPrecise(this._end)));
+}else{A.appendChild(A.ownerDocument.createTextNode(B.labelPrecise(this._start)));
+}}else{if(this.isImprecise()){A.appendChild(A.ownerDocument.createTextNode(B.labelPrecise(this._start)+" ~ "+B.labelPrecise(this._latestStart)));
+A.appendChild(A.ownerDocument.createElement("br"));
+A.appendChild(A.ownerDocument.createTextNode(B.labelPrecise(this._earliestEnd)+" ~ "+B.labelPrecise(this._end)));
+}else{A.appendChild(A.ownerDocument.createTextNode(B.labelPrecise(this._start)));
+A.appendChild(A.ownerDocument.createElement("br"));
+A.appendChild(A.ownerDocument.createTextNode(B.labelPrecise(this._end)));
+}}},fillInfoBubble:function(A,E,M){var K=A.ownerDocument;
+var J=this.getText();
+var H=this.getLink();
+var B=this.getImage();
+if(B!=null){var D=K.createElement("img");
+D.src=B;
+E.event.bubble.imageStyler(D);
+A.appendChild(D);
+}var L=K.createElement("div");
+var C=K.createTextNode(J);
+if(H!=null){var I=K.createElement("a");
+I.href=H;
+I.appendChild(C);
+L.appendChild(I);
+}else{L.appendChild(C);
+}E.event.bubble.titleStyler(L);
+A.appendChild(L);
+var N=K.createElement("div");
+this.fillDescription(N);
+E.event.bubble.bodyStyler(N);
+A.appendChild(N);
+var G=K.createElement("div");
+this.fillTime(G,M);
+E.event.bubble.timeStyler(G);
+A.appendChild(G);
+var F=K.createElement("div");
+this.fillWikiInfo(F);
+E.event.bubble.wikiStyler(F);
+A.appendChild(F);
+}};
+
+
+/* themes.js */
+Timeline.ClassicTheme=new Object();
+Timeline.ClassicTheme.implementations=[];
+Timeline.ClassicTheme.create=function(B){if(B==null){B=Timeline.getDefaultLocale();
+}var A=Timeline.ClassicTheme.implementations[B];
+if(A==null){A=Timeline.ClassicTheme._Impl;
+}return new A();
+};
+Timeline.ClassicTheme._Impl=function(){this.firstDayOfWeek=0;
+this.autoWidth=false;
+this.autoWidthAnimationTime=500;
+this.timeline_start=null;
+this.timeline_stop=null;
+this.ether={backgroundColors:[],highlightOpacity:50,interval:{line:{show:true,opacity:25},weekend:{opacity:30},marker:{hAlign:"Bottom",vAlign:"Right"}}};
+this.event={track:{height:10,gap:2,offset:2,autoWidthMargin:1.5},overviewTrack:{offset:20,tickHeight:6,height:2,gap:1,autoWidthMargin:5},tape:{height:4},instant:{icon:Timeline.urlPrefix+"images/dull-blue-circle.png",iconWidth:10,iconHeight:10,impreciseOpacity:20,impreciseIconMargin:3},duration:{impreciseOpacity:20},label:{backgroundOpacity:50,offsetFromLine:3},highlightColors:["#FFFF00","#FFC000","#FF0000","#0000FF"],highlightLabelBackground:false,bubble:{width:250,maxHeight:0,titleStyler:function(A){A.className="timeline-event-bubble-title";
+},bodyStyler:function(A){A.className="timeline-event-bubble-body";
+},imageStyler:function(A){A.className="timeline-event-bubble-image";
+},wikiStyler:function(A){A.className="timeline-event-bubble-wiki";
+},timeStyler:function(A){A.className="timeline-event-bubble-time";
+}}};
+this.mouseWheel="scroll";
+};
+
+
+/* timeline.js */
+Timeline.version="2.3.0";
+Timeline.ajax_lib_version=SimileAjax.version;
+Timeline.display_version=Timeline.version+" (with Ajax lib "+Timeline.ajax_lib_version+")";
+Timeline.strings={};
+Timeline.HORIZONTAL=0;
+Timeline.VERTICAL=1;
+Timeline._defaultTheme=null;
+Timeline.getDefaultLocale=function(){return Timeline.clientLocale;
+};
+Timeline.create=function(D,C,E,F){if(Timeline.timelines==null){Timeline.timelines=[];
+}var B=Timeline.timelines.length;
+Timeline.timelines[B]=null;
+var A=new Timeline._Impl(D,C,E,F,B);
+Timeline.timelines[B]=A;
+return A;
+};
+Timeline.createBandInfo=function(F){var G=("theme" in F)?F.theme:Timeline.getDefaultTheme();
+var D=("eventSource" in F)?F.eventSource:null;
+var H=new Timeline.LinearEther({centersOn:("date" in F)?F.date:new Date(),interval:SimileAjax.DateTime.gregorianUnitLengths[F.intervalUnit],pixelsPerInterval:F.intervalPixels,theme:G});
+var C=new Timeline.GregorianEtherPainter({unit:F.intervalUnit,multiple:("multiple" in F)?F.multiple:1,theme:G,align:("align" in F)?F.align:undefined});
+var I={showText:("showEventText" in F)?F.showEventText:true,theme:G};
+if("eventPainterParams" in F){for(var A in F.eventPainterParams){I[A]=F.eventPainterParams[A];
+}}if("trackHeight" in F){I.trackHeight=F.trackHeight;
+}if("trackGap" in F){I.trackGap=F.trackGap;
+}var B=("overview" in F&&F.overview)?"overview":("layout" in F?F.layout:"original");
+var E;
+if("eventPainter" in F){E=new F.eventPainter(I);
+}else{switch(B){case"overview":E=new Timeline.OverviewEventPainter(I);
+break;
+case"detailed":E=new Timeline.DetailedEventPainter(I);
+break;
+default:E=new Timeline.OriginalEventPainter(I);
+}}return{width:F.width,eventSource:D,timeZone:("timeZone" in F)?F.timeZone:0,ether:H,etherPainter:C,eventPainter:E,theme:G,zoomIndex:("zoomIndex" in F)?F.zoomIndex:0,zoomSteps:("zoomSteps" in F)?F.zoomSteps:null};
+};
+Timeline.createHotZoneBandInfo=function(F){var G=("theme" in F)?F.theme:Timeline.getDefaultTheme();
+var D=("eventSource" in F)?F.eventSource:null;
+var H=new Timeline.HotZoneEther({centersOn:("date" in F)?F.date:new Date(),interval:SimileAjax.DateTime.gregorianUnitLengths[F.intervalUnit],pixelsPerInterval:F.intervalPixels,zones:F.zones,theme:G});
+var C=new Timeline.HotZoneGregorianEtherPainter({unit:F.intervalUnit,zones:F.zones,theme:G,align:("align" in F)?F.align:undefined});
+var I={showText:("showEventText" in F)?F.showEventText:true,theme:G};
+if("eventPainterParams" in F){for(var A in F.eventPainterParams){I[A]=F.eventPainterParams[A];
+}}if("trackHeight" in F){I.trackHeight=F.trackHeight;
+}if("trackGap" in F){I.trackGap=F.trackGap;
+}var B=("overview" in F&&F.overview)?"overview":("layout" in F?F.layout:"original");
+var E;
+if("eventPainter" in F){E=new F.eventPainter(I);
+}else{switch(B){case"overview":E=new Timeline.OverviewEventPainter(I);
+break;
+case"detailed":E=new Timeline.DetailedEventPainter(I);
+break;
+default:E=new Timeline.OriginalEventPainter(I);
+}}return{width:F.width,eventSource:D,timeZone:("timeZone" in F)?F.timeZone:0,ether:H,etherPainter:C,eventPainter:E,theme:G,zoomIndex:("zoomIndex" in F)?F.zoomIndex:0,zoomSteps:("zoomSteps" in F)?F.zoomSteps:null};
+};
+Timeline.getDefaultTheme=function(){if(Timeline._defaultTheme==null){Timeline._defaultTheme=Timeline.ClassicTheme.create(Timeline.getDefaultLocale());
+}return Timeline._defaultTheme;
+};
+Timeline.setDefaultTheme=function(A){Timeline._defaultTheme=A;
+};
+Timeline.loadXML=function(A,C){var D=function(G,F,E){alert("Failed to load data xml from "+A+"\n"+G);
+};
+var B=function(F){var E=F.responseXML;
+if(!E.documentElement&&F.responseStream){E.load(F.responseStream);
+}C(E,A);
+};
+SimileAjax.XmlHttp.get(A,D,B);
+};
+Timeline.loadJSON=function(url,f){var fError=function(statusText,status,xmlhttp){alert("Failed to load json data from "+url+"\n"+statusText);
+};
+var fDone=function(xmlhttp){f(eval("("+xmlhttp.responseText+")"),url);
+};
+SimileAjax.XmlHttp.get(url,fError,fDone);
+};
+Timeline.getTimelineFromID=function(A){return Timeline.timelines[A];
+};
+Timeline.writeVersion=function(A){document.getElementById(A).innerHTML=this.display_version;
+};
+Timeline._Impl=function(C,B,D,E,A){SimileAjax.WindowManager.initialize();
+this._containerDiv=C;
+this._bandInfos=B;
+this._orientation=D==null?Timeline.HORIZONTAL:D;
+this._unit=(E!=null)?E:SimileAjax.NativeDateUnit;
+this._starting=true;
+this._autoResizing=false;
+this.autoWidth=B&&B[0]&&B[0].theme&&B[0].theme.autoWidth;
+this.autoWidthAnimationTime=B&&B[0]&&B[0].theme&&B[0].theme.autoWidthAnimationTime;
+this.timelineID=A;
+this.timeline_start=B&&B[0]&&B[0].theme&&B[0].theme.timeline_start;
+this.timeline_stop=B&&B[0]&&B[0].theme&&B[0].theme.timeline_stop;
+this.timeline_at_start=false;
+this.timeline_at_stop=false;
+this._initialize();
+};
+Timeline._Impl.prototype.dispose=function(){for(var A=0;
+A<this._bands.length;
+A++){this._bands[A].dispose();
+}this._bands=null;
+this._bandInfos=null;
+this._containerDiv.innerHTML="";
+Timeline.timelines[this.timelineID]=null;
+};
+Timeline._Impl.prototype.getBandCount=function(){return this._bands.length;
+};
+Timeline._Impl.prototype.getBand=function(A){return this._bands[A];
+};
+Timeline._Impl.prototype.finishedEventLoading=function(){this._autoWidthCheck(true);
+this._starting=false;
+};
+Timeline._Impl.prototype.layout=function(){this._autoWidthCheck(true);
+this._distributeWidths();
+};
+Timeline._Impl.prototype.paint=function(){for(var A=0;
+A<this._bands.length;
+A++){this._bands[A].paint();
+}};
+Timeline._Impl.prototype.getDocument=function(){return this._containerDiv.ownerDocument;
+};
+Timeline._Impl.prototype.addDiv=function(A){this._containerDiv.appendChild(A);
+};
+Timeline._Impl.prototype.removeDiv=function(A){this._containerDiv.removeChild(A);
+};
+Timeline._Impl.prototype.isHorizontal=function(){return this._orientation==Timeline.HORIZONTAL;
+};
+Timeline._Impl.prototype.isVertical=function(){return this._orientation==Timeline.VERTICAL;
+};
+Timeline._Impl.prototype.getPixelLength=function(){return this._orientation==Timeline.HORIZONTAL?this._containerDiv.offsetWidth:this._containerDiv.offsetHeight;
+};
+Timeline._Impl.prototype.getPixelWidth=function(){return this._orientation==Timeline.VERTICAL?this._containerDiv.offsetWidth:this._containerDiv.offsetHeight;
+};
+Timeline._Impl.prototype.getUnit=function(){return this._unit;
+};
+Timeline._Impl.prototype.getWidthStyle=function(){return this._orientation==Timeline.HORIZONTAL?"height":"width";
+};
+Timeline._Impl.prototype.loadXML=function(B,D){var A=this;
+var E=function(H,G,F){alert("Failed to load data xml from "+B+"\n"+H);
+A.hideLoadingMessage();
+};
+var C=function(G){try{var F=G.responseXML;
+if(!F.documentElement&&G.responseStream){F.load(G.responseStream);
+}D(F,B);
+}finally{A.hideLoadingMessage();
+}};
+this.showLoadingMessage();
+window.setTimeout(function(){SimileAjax.XmlHttp.get(B,E,C);
+},0);
+};
+Timeline._Impl.prototype.loadJSON=function(url,f){var tl=this;
+var fError=function(statusText,status,xmlhttp){alert("Failed to load json data from "+url+"\n"+statusText);
+tl.hideLoadingMessage();
+};
+var fDone=function(xmlhttp){try{f(eval("("+xmlhttp.responseText+")"),url);
+}finally{tl.hideLoadingMessage();
+}};
+this.showLoadingMessage();
+window.setTimeout(function(){SimileAjax.XmlHttp.get(url,fError,fDone);
+},0);
+};
+Timeline._Impl.prototype._autoWidthScrollListener=function(A){A.getTimeline()._autoWidthCheck(false);
+};
+Timeline._Impl.prototype._autoWidthCheck=function(C){var A=this;
+var B=A._starting;
+var D=0;
+function E(){var G=A.getWidthStyle();
+if(B){A._containerDiv.style[G]=D+"px";
+}else{A._autoResizing=true;
+var H={};
+H[G]=D+"px";
+SimileAjax.jQuery(A._containerDiv).animate(H,A.autoWidthAnimationTime,"linear",function(){A._autoResizing=false;
+});
+}}function F(){var H=0;
+var G=A.getPixelWidth();
+if(A._autoResizing){return ;
+}for(var I=0;
+I<A._bands.length;
+I++){A._bands[I].checkAutoWidth();
+H+=A._bandInfos[I].width;
+}if(H>G||C){D=H;
+E();
+A._distributeWidths();
+}}if(!A.autoWidth){return ;
+}F();
+};
+Timeline._Impl.prototype._initialize=function(){var H=this._containerDiv;
+var E=H.ownerDocument;
+H.className=H.className.split(" ").concat("timeline-container").join(" ");
+var C=(this.isHorizontal())?"horizontal":"vertical";
+H.className+=" timeline-"+C;
+while(H.firstChild){H.removeChild(H.firstChild);
+}var A=SimileAjax.Graphics.createTranslucentImage(Timeline.urlPrefix+(this.isHorizontal()?"images/copyright-vertical.png":"images/copyright.png"));
+A.className="timeline-copyright";
+A.title="Timeline copyright SIMILE - www.code.google.com/p/simile-widgets/";
+SimileAjax.DOM.registerEvent(A,"click",function(){window.location="http://code.google.com/p/simile-widgets/";
+});
+H.appendChild(A);
+this._bands=[];
+for(var B=0;
+B<this._bandInfos.length;
+B++){var G=new Timeline._Band(this,this._bandInfos[B],B);
+this._bands.push(G);
+}this._distributeWidths();
+for(var B=0;
+B<this._bandInfos.length;
+B++){var F=this._bandInfos[B];
+if("syncWith" in F){this._bands[B].setSyncWithBand(this._bands[F.syncWith],("highlight" in F)?F.highlight:false);
+}}if(this.autoWidth){for(var B=0;
+B<this._bands.length;
+B++){this._bands[B].addOnScrollListener(this._autoWidthScrollListener);
+}}var D=SimileAjax.Graphics.createMessageBubble(E);
+D.containerDiv.className="timeline-message-container";
+H.appendChild(D.containerDiv);
+D.contentDiv.className="timeline-message";
+D.contentDiv.innerHTML="<img src='"+Timeline.urlPrefix+"images/progress-running.gif' /> Loading...";
+this.showLoadingMessage=function(){D.containerDiv.style.display="block";
+};
+this.hideLoadingMessage=function(){D.containerDiv.style.display="none";
+};
+};
+Timeline._Impl.prototype._distributeWidths=function(){var G=this.getPixelLength();
+var B=this.getPixelWidth();
+var C=0;
+for(var F=0;
+F<this._bands.length;
+F++){var J=this._bands[F];
+var I=this._bandInfos[F];
+var E=I.width;
+var D;
+if(typeof E=="string"){var H=E.indexOf("%");
+if(H>0){var A=parseInt(E.substr(0,H));
+D=Math.round(A*B/100);
+}else{D=parseInt(E);
+}}else{D=E;
+}J.setBandShiftAndWidth(C,D);
+J.setViewLength(G);
+C+=D;
+}};
+Timeline._Impl.prototype.shiftOK=function(C,B){var F=B>0,A=B<0;
+if((F&&this.timeline_start==null)||(A&&this.timeline_stop==null)||(B==0)){return(true);
+}var H=false;
+for(var E=0;
+E<this._bands.length&&!H;
+E++){H=this._bands[E].busy();
+}if(H){return(true);
+}if((F&&this.timeline_at_start)||(A&&this.timeline_at_stop)){return(false);
+}var D=false;
+for(var E=0;
+E<this._bands.length&&!D;
+E++){var G=this._bands[E];
+if(F){D=(E==C?G.getMinVisibleDateAfterDelta(B):G.getMinVisibleDate())>=this.timeline_start;
+}else{D=(E==C?G.getMaxVisibleDateAfterDelta(B):G.getMaxVisibleDate())<=this.timeline_stop;
+}}if(F){this.timeline_at_start=!D;
+this.timeline_at_stop=false;
+}else{this.timeline_at_stop=!D;
+this.timeline_at_start=false;
+}return(D);
+};
+Timeline._Impl.prototype.zoom=function(D,A,G,F){var C=new RegExp("^timeline-band-([0-9]+)$");
+var E=null;
+var B=C.exec(F.id);
+if(B){E=parseInt(B[1]);
+}if(E!=null){this._bands[E].zoom(D,A,G,F);
+}this.paint();
+};
+
+
+/* units.js */
+Timeline.NativeDateUnit=new Object();
+Timeline.NativeDateUnit.createLabeller=function(B,A){return new Timeline.GregorianDateLabeller(B,A);
+};
+Timeline.NativeDateUnit.makeDefaultValue=function(){return new Date();
+};
+Timeline.NativeDateUnit.cloneValue=function(A){return new Date(A.getTime());
+};
+Timeline.NativeDateUnit.getParser=function(A){if(typeof A=="string"){A=A.toLowerCase();
+}return(A=="iso8601"||A=="iso 8601")?Timeline.DateTime.parseIso8601DateTime:Timeline.DateTime.parseGregorianDateTime;
+};
+Timeline.NativeDateUnit.parseFromObject=function(A){return Timeline.DateTime.parseGregorianDateTime(A);
+};
+Timeline.NativeDateUnit.toNumber=function(A){return A.getTime();
+};
+Timeline.NativeDateUnit.fromNumber=function(A){return new Date(A);
+};
+Timeline.NativeDateUnit.compare=function(D,C){var B,A;
+if(typeof D=="object"){B=D.getTime();
+}else{B=Number(D);
+}if(typeof C=="object"){A=C.getTime();
+}else{A=Number(C);
+}return B-A;
+};
+Timeline.NativeDateUnit.earlier=function(B,A){return Timeline.NativeDateUnit.compare(B,A)<0?B:A;
+};
+Timeline.NativeDateUnit.later=function(B,A){return Timeline.NativeDateUnit.compare(B,A)>0?B:A;
+};
+Timeline.NativeDateUnit.change=function(A,B){return new Date(A.getTime()+B);
+};

Added: trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/controllers/BibleControllerTest.java
===================================================================
--- trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/controllers/BibleControllerTest.java	                        (rev 0)
+++ trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/controllers/BibleControllerTest.java	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,127 @@
+package com.tyndalehouse.step.rest.controllers;
+
+import static org.apache.commons.collections.CollectionUtils.isEqualCollection;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import com.tyndalehouse.step.core.models.LookupOption;
+import com.tyndalehouse.step.core.service.BibleInformationService;
+
+/**
+ * tests the bible controller
+ * 
+ * @author Chris
+ * 
+ */
+public class BibleControllerTest {
+    private final BibleInformationService bibleInformation = mock(BibleInformationService.class);
+    private final BibleController testController = new BibleController(this.bibleInformation);
+
+    /**
+     * tests that we call correct method
+     */
+    @Test
+    public void testGetBibleVersions() {
+        // do test
+        this.testController.getBibleVersions();
+        verify(this.bibleInformation).getAvailableBibleVersions();
+    }
+
+    /**
+     * check that exception is thrown if no version provided
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetBibleTextNoVersion() {
+        this.testController.getBibleText(null, "Ref");
+    }
+
+    /**
+     * check that exception is thrown if no version provided
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetBibleTextNoVersionWithOptions() {
+        this.testController.getBibleText(null, "Ref", "options");
+    }
+
+    /**
+     * check that exception is thrown if no version provided
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetBibleTextNoVersionWithOptionsAndInterlinear() {
+        this.testController.getBibleText(null, "Ref", "options", "interlinear");
+    }
+
+    /**
+     * check that exception is thrown if no reference is provided
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetBibleTextNoReference() {
+        this.testController.getBibleText("KJV", null);
+    }
+
+    /**
+     * check that exception is thrown if no reference is provided
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetBibleTextNoReferenceWithOptions() {
+        this.testController.getBibleText("KJV", null, "options");
+    }
+
+    /**
+     * check that exception is thrown if no reference is provided
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetBibleTextNoReferenceWithOptionsAndInterlinear() {
+        this.testController.getBibleText("KJV", null, "options", "interlinear");
+    }
+
+    /**
+     * tests that options are parsed correctly and all arguments are passed
+     */
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Test
+    public void testGetBibleText() {
+        final List<LookupOption> options = new ArrayList<LookupOption>();
+        options.add(LookupOption.HEADINGS);
+        options.add(LookupOption.VERSE_NUMBERS);
+
+        // do test
+        this.testController.getBibleText("version", "reference", "HEADINGS,VERSE_NUMBERS", "kjv,esv");
+
+        // verify
+        final ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
+
+        verify(this.bibleInformation).getPassageText(eq("version"), eq("reference"), captor.capture(),
+                eq("kjv,esv"));
+
+        // check the list that was captured
+        final List value = captor.getValue();
+        isEqualCollection(value, options);
+    }
+
+    /**
+     * Test the method delegates
+     */
+    @Test
+    public void testGetFeatures() {
+        final String version = "abp";
+        this.testController.getFeatures(version);
+        verify(this.bibleInformation).getFeaturesForVersion(version);
+    }
+
+    /**
+     * tests that method delegaes
+     **/
+    @Test
+    public void testGetAllFeatures() {
+        this.testController.getAllFeatures();
+        verify(this.bibleInformation).getAllFeatures();
+    }
+}

Modified: trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/controllers/FrontControllerTest.java
===================================================================
--- trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/controllers/FrontControllerTest.java	2011-01-07 21:08:34 UTC (rev 201)
+++ trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/controllers/FrontControllerTest.java	2011-01-07 22:52:32 UTC (rev 202)
@@ -2,18 +2,35 @@
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
 import org.junit.Test;
 
 import com.google.inject.Injector;
+import com.tyndalehouse.step.core.exceptions.StepInternalException;
 import com.tyndalehouse.step.core.service.BibleInformationService;
+import com.tyndalehouse.step.rest.framework.StepRequest;
 
 /**
  * tests the front controller parsing process
@@ -24,6 +41,52 @@
 public class FrontControllerTest {
 
     /**
+     * Tests normal operation of a GET method
+     * 
+     * @throws IOException
+     */
+    @Test
+    public void testDoGet() throws IOException {
+        final HttpServletRequest request = mock(HttpServletRequest.class);
+        final HttpServletResponse response = mock(HttpServletResponse.class);
+
+        final FrontController fc = spy(new FrontController(null, false));
+        final StepRequest parsedRequest = new StepRequest("SomeController", "someMethod", new String[] {
+                "arg1", "arg2" });
+        final ServletOutputStream mockOutputStream = mock(ServletOutputStream.class);
+
+        doReturn(parsedRequest).when(fc).parseRequest(request);
+        doReturn(mockOutputStream).when(response).getOutputStream();
+        final byte[] sampleResponse = new byte[] { 1, 2, 3 };
+        doReturn(sampleResponse).when(fc).invokeMethod(parsedRequest);
+
+        // do the test
+        fc.doGet(request, response);
+        verify(mockOutputStream).write(sampleResponse);
+    }
+
+    /**
+     * tests what happens when doGet catches an exception
+     */
+    @Test
+    public void testDoGetHasException() {
+        final HttpServletRequest request = mock(HttpServletRequest.class);
+        final HttpServletResponse response = mock(HttpServletResponse.class);
+        final StepInternalException testException = new StepInternalException("A test exception");
+
+        final FrontController fc = spy(new FrontController(null, false));
+        final StepRequest parsedRequest = new StepRequest("SomeController", "someMethod", new String[] {
+                "arg1", "arg2" });
+
+        doThrow(testException).when(fc).parseRequest(request);
+        doNothing().when(fc).doError(response, testException, parsedRequest);
+
+        // do the test
+        fc.doGet(request, response);
+
+    }
+
+    /**
      * tests that arguments are parsed correctly given the correct start
      */
     @Test
@@ -31,7 +94,7 @@
         // index starts at ...........0123456789-123456789-123456
         final String sampleRequest = "step-web/rest/bible/get/1K2/2K2";
 
-        final FrontController fc = new FrontController(mock(Injector.class));
+        final FrontController fc = new FrontController(mock(Injector.class), Boolean.FALSE);
 
         // when
         final Object[] args = fc.getArgs(sampleRequest, 24);
@@ -50,7 +113,7 @@
         // index starts at ...........0123456789-123456789-123456
         final String sampleRequest = "step-web/rest/bible/get/1K2/2K2/";
 
-        final FrontController fc = new FrontController(mock(Injector.class));
+        final FrontController fc = new FrontController(mock(Injector.class), Boolean.FALSE);
 
         // when
         final Object[] args = fc.getArgs(sampleRequest, 24);
@@ -62,15 +125,49 @@
     }
 
     /**
-     * tests generation of cache key
+     * we check that the path is concatenated with the servlet path
+     * 
+     * @throws ServletException an uncaught exception
      */
     @Test
-    public void testCacheKey() {
-        assertEquals("controllergetName7",
-                new FrontController(mock(Injector.class)).getCacheKey("controller", "getName", 7));
+    public void testGetPath() throws ServletException {
+        final FrontController fc = new FrontController(null, null);
+        final FrontController spy = spy(fc);
+
+        final ServletContext mockServletContext = mock(ServletContext.class);
+        final HttpServletRequest mockRequest = mock(HttpServletRequest.class);
+
+        spy.init(mock(ServletConfig.class));
+
+        when(spy.getServletContext()).thenReturn(mockServletContext);
+        when(mockServletContext.getContextPath()).thenReturn("context/");
+        when(mockRequest.getServletPath()).thenReturn("servletPath");
+
+        // when
+        final String path = spy.getPath(mockRequest);
+
+        // then
+        assertEquals(path, "context/servletPath");
     }
 
     /**
+     * tests that the headers are setup correctly
+     */
+    @Test
+    public void testHeadersSetupCorrectly() {
+        final HttpServletResponse response = mock(HttpServletResponse.class);
+
+        final int sampleRequestLength = 10;
+        new FrontController(null, null).setupHeaders(response, sampleRequestLength);
+
+        verify(response).addDateHeader(eq("Date"), anyLong());
+        verify(response).setCharacterEncoding("UTF-8");
+        verify(response).setContentType("application/json");
+        verify(response).setContentLength(sampleRequestLength);
+
+    }
+
+    /**
      * tests that resolving method works
      * 
      * @throws IllegalAccessException uncaught exception
@@ -78,13 +175,13 @@
      */
     @Test
     public void testGetControllerMethod() throws IllegalAccessException, InvocationTargetException {
-        final FrontController frontController = new FrontController(mock(Injector.class));
+        final FrontController frontController = new FrontController(mock(Injector.class), Boolean.FALSE);
         final BibleInformationService bibleInfo = mock(BibleInformationService.class);
         final BibleController controllerInstance = new BibleController(bibleInfo);
 
         // when
         final Method controllerMethod = frontController.getControllerMethod("getBibleVersions",
-                controllerInstance, null);
+                controllerInstance, null, null);
 
         // then
         controllerMethod.invoke(controllerInstance);
@@ -98,7 +195,7 @@
     public void testGetController() {
         final String controllerName = "Bible";
         final Injector mockInjector = mock(Injector.class);
-        final FrontController frontController = new FrontController(mockInjector);
+        final FrontController frontController = new FrontController(mockInjector, Boolean.FALSE);
 
         final BibleController mockController = mock(BibleController.class);
         when(mockInjector.getInstance(BibleController.class)).thenReturn(mockController);
@@ -115,7 +212,7 @@
      */
     @Test
     public void testGetClasses() {
-        final FrontController fc = new FrontController(null);
+        final FrontController fc = new FrontController(null, Boolean.FALSE);
 
         assertEquals(0, fc.getClasses(null).length);
         assertEquals(0, fc.getClasses(new Object[0]).length);
@@ -123,4 +220,95 @@
                 fc.getClasses(new Object[] { "hello", new ArrayList<String>() }));
 
     }
+
+    /**
+     * tests that we encode using json mapper and set to UTF 8
+     */
+    @Test
+    public void testJsonEncoding() {
+        final byte[] encodedJsonResponse = new FrontController(null, null).getEncodedJsonResponse("abc");
+
+        // this reprensents the string "{abc}"
+        final byte[] expectedValues = new byte[] { 34, 97, 98, 99, 34 };
+
+        assertArrayEquals(expectedValues, encodedJsonResponse);
+    }
+
+    /**
+     * If an error was thrown, we should map it and output
+     * 
+     * @throws IOException uncaught exception
+     */
+    @Test
+    public void testDoErrorHandlesCorrectly() throws IOException {
+        final FrontController fc = new FrontController(null, null);
+        final HttpServletResponse response = mock(HttpServletResponse.class);
+        final StepRequest stepRequest = new StepRequest("controller", "method", null);
+        final ServletOutputStream outputStream = mock(ServletOutputStream.class);
+        final Throwable exception = mock(Throwable.class);
+        when(response.getOutputStream()).thenReturn(outputStream);
+
+        // do test
+        fc.doError(response, exception, stepRequest);
+
+        // check
+        verify(outputStream).write(any(byte[].class));
+        verify(exception).getMessage();
+    }
+
+    /**
+     * checks that parsing is working correctly
+     * 
+     * @throws ServletException uncaught exception
+     */
+    @Test
+    public void testParseRequest() throws ServletException {
+        final HttpServletRequest request = mock(HttpServletRequest.class);
+        final String requestSeparator = "/";
+        final String contextName = "step-web";
+        final String servletName = "servletName";
+        final String controllerName = "controllerName";
+        final String methodName = "methodName";
+        final String arg1 = "argument1";
+        final String arg2 = "argument2";
+
+        when(request.getServletPath()).thenReturn(servletName);
+        when(request.getRequestURI()).thenReturn(
+                contextName + requestSeparator + servletName + requestSeparator + controllerName
+                        + requestSeparator + methodName + requestSeparator + arg1 + requestSeparator + arg2);
+
+        final FrontController frontController = new FrontController(null, null);
+        frontController.init(mock(ServletConfig.class));
+
+        final FrontController spy = spy(frontController);
+
+        final ServletContext mockServletContext = mock(ServletContext.class);
+        when(spy.getServletContext()).thenReturn(mockServletContext);
+        when(mockServletContext.getContextPath()).thenReturn(contextName + "/");
+
+        // do test
+        final StepRequest parseRequest = frontController.parseRequest(request);
+
+        // check controller name, method name and arguments
+        assertEquals(controllerName, parseRequest.getControllerName());
+        assertEquals(methodName, parseRequest.getMethodName());
+    }
+
+    /**
+     * We check that invoke method calls the correct controller and method with the right arguments
+     */
+    @Test
+    public void testInvokeMethod() {
+        final StepRequest sr = new StepRequest("bible", "getAllFeatures", new String[] {});
+        final BibleController testController = mock(BibleController.class);
+
+        final FrontController fc = spy(new FrontController(null, null));
+        doReturn(testController).when(fc).getController("bible");
+
+        // do test
+        fc.invokeMethod(sr);
+
+        // verify
+        verify(testController).getAllFeatures();
+    }
 }

Added: trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/framework/StepRequestTest.java
===================================================================
--- trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/framework/StepRequestTest.java	                        (rev 0)
+++ trunk/step/step-web/src/test/java/com/tyndalehouse/step/rest/framework/StepRequestTest.java	2011-01-07 22:52:32 UTC (rev 202)
@@ -0,0 +1,56 @@
+package com.tyndalehouse.step.rest.framework;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * Tests that cache keys are constructed correctly
+ * 
+ * @author Chris
+ * 
+ */
+public class StepRequestTest {
+    final String[] args = new String[] { "arg1", "arg2", "arg3" };
+    String testControllerName = "Controller";
+    String testMethodName = "method";
+
+    /**
+     * a method key should not contain arguments, but contain controller name and method name
+     */
+    @Test
+    public void testMethodKey() {
+        final StepRequest stepRequest = getTestStepRequest();
+        final String methodKey = stepRequest.getCacheKey().getMethodKey();
+        assertTrue(methodKey.contains(this.testControllerName));
+        assertTrue(methodKey.contains(this.testMethodName));
+        for (final String s : this.args) {
+            assertFalse(methodKey.contains(s));
+        }
+    }
+
+    /**
+     * A result key should contain controller, method and arguments
+     */
+    @Test
+    public void testResultKey() {
+        final StepRequest stepRequest = getTestStepRequest();
+        final String resultsKey = stepRequest.getCacheKey().getResultsKey();
+        assertTrue(resultsKey.contains(this.testControllerName));
+        assertTrue(resultsKey.contains(this.testMethodName));
+        for (final String s : this.args) {
+            assertTrue(resultsKey.contains(s));
+        }
+
+    }
+
+    /**
+     * helper factory method
+     * 
+     * @return a step request
+     */
+    private StepRequest getTestStepRequest() {
+        return new StepRequest(this.testControllerName, this.testMethodName, this.args);
+    }
+}




More information about the Tynstep-svn mailing list