Merge with 67c2b0fb9b19bdca75a3e83e94eed7f4e9158b18
authorymh <ymh.work@gmail.com>
Wed, 15 Jan 2014 18:36:27 +0100
changeset 240 18a43ba77ad0
parent 213 2e738512336a (current diff)
parent 239 67c2b0fb9b19 (diff)
child 242 570e18094e87
Merge with 67c2b0fb9b19bdca75a3e83e94eed7f4e9158b18
.hgignore
server/pom.xml
server/src/main/java/org/iri_research/renkan/Constants.java
server/src/main/java/org/iri_research/renkan/controller/AdminController.java
server/src/main/webapp/WEB-INF/templates/renkanProjectEdit.html
server/src/main/webapp/static/lib/jquery-ui.min.js
--- a/.classpath	Fri Oct 25 16:42:11 2013 +0200
+++ b/.classpath	Wed Jan 15 18:36:27 2014 +0100
@@ -4,76 +4,31 @@
 	<classpathentry kind="src" path="server/src/test/java"/>
 	<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
 	<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>
-	<classpathentry kind="var" path="M2_REPO/org/opencoweb/coweb-bots/1.0/coweb-bots-1.0.jar" sourcepath="M2_REPO/org/opencoweb/coweb-bots/1.0/coweb-bots-1.0-sources.jar">
-		<attributes>
-			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/opencoweb/coweb-bots/1.0/coweb-bots-1.0-javadoc.jar!/"/>
-			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/opencoweb/coweb-server/1.0/coweb-server-1.0.jar" sourcepath="M2_REPO/org/opencoweb/coweb-server/1.0/coweb-server-1.0-sources.jar">
-		<attributes>
-			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/opencoweb/coweb-server/1.0/coweb-server-1.0-javadoc.jar!/"/>
-			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/opencoweb/coweb-operationengine/1.0/coweb-operationengine-1.0.jar" sourcepath="M2_REPO/org/opencoweb/coweb-operationengine/1.0/coweb-operationengine-1.0-sources.jar">
-		<attributes>
-			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/opencoweb/coweb-operationengine/1.0/coweb-operationengine-1.0-javadoc.jar!/"/>
-			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/cometd/java/bayeux-api/2.5.0/bayeux-api-2.5.0.jar" sourcepath="M2_REPO/org/cometd/java/bayeux-api/2.5.0/bayeux-api-2.5.0-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/org/cometd/java/bayeux-api/2.7.0/bayeux-api-2.7.0.jar" sourcepath="M2_REPO/org/cometd/java/bayeux-api/2.5.0/bayeux-api-2.5.0-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/cometd/java/bayeux-api/2.5.0/bayeux-api-2.5.0-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/cometd/java/cometd-java-common/2.5.0/cometd-java-common-2.5.0.jar" sourcepath="M2_REPO/org/cometd/java/cometd-java-common/2.5.0/cometd-java-common-2.5.0-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/org/cometd/java/cometd-java-common/2.7.0/cometd-java-common-2.7.0.jar" sourcepath="M2_REPO/org/cometd/java/cometd-java-common/2.5.0/cometd-java-common-2.5.0-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/cometd/java/cometd-java-common/2.5.0/cometd-java-common-2.5.0-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-util/8.1.9.v20130131/jetty-util-8.1.9.v20130131.jar">
-		<attributes>
-			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-api/1.6.6/slf4j-api-1.6.6.jar" sourcepath="M2_REPO/org/slf4j/slf4j-api/1.6.6/slf4j-api-1.6.6-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-api/1.7.5/slf4j-api-1.7.5.jar" sourcepath="M2_REPO/org/slf4j/slf4j-api/1.6.6/slf4j-api-1.6.6-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/slf4j/slf4j-api/1.6.6/slf4j-api-1.6.6-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-continuation/8.1.9.v20130131/jetty-continuation-8.1.9.v20130131.jar">
-		<attributes>
-			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-jmx/8.1.9.v20130131/jetty-jmx-8.1.9.v20130131.jar">
-		<attributes>
-			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/com/sun/jersey/jersey-server/1.17.1/jersey-server-1.17.1.jar" sourcepath="M2_REPO/com/sun/jersey/jersey-server/1.17/jersey-server-1.17-sources.jar">
-		<attributes>
-			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/com/sun/jersey/jersey-server/1.17/jersey-server-1.17-javadoc.jar!/"/>
-			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/com/sun/jersey/jersey-core/1.17.1/jersey-core-1.17.1.jar" sourcepath="M2_REPO/com/sun/jersey/jersey-core/1.17/jersey-core-1.17-sources.jar">
-		<attributes>
-			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/com/sun/jersey/jersey-core/1.17/jersey-core-1.17-javadoc.jar!/"/>
-			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/mongodb/mongo-java-driver/2.10.1/mongo-java-driver-2.10.1.jar" sourcepath="M2_REPO/org/mongodb/mongo-java-driver/2.10.1/mongo-java-driver-2.10.1-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/org/mongodb/mongo-java-driver/2.11.3/mongo-java-driver-2.11.3.jar" sourcepath="M2_REPO/org/mongodb/mongo-java-driver/2.10.1/mongo-java-driver-2.10.1-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/mongodb/mongo-java-driver/2.10.1/mongo-java-driver-2.10.1-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/springframework/spring-context/3.2.1.RELEASE/spring-context-3.2.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-context/3.2.1.RELEASE/spring-context-3.2.1.RELEASE-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/org/springframework/spring-context/3.2.4.RELEASE/spring-context-3.2.4.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-context/3.2.1.RELEASE/spring-context-3.2.1.RELEASE-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/springframework/spring-context/3.2.1.RELEASE/spring-context-3.2.1.RELEASE-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
@@ -84,7 +39,7 @@
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/springframework/spring-beans/3.2.1.RELEASE/spring-beans-3.2.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-beans/3.2.1.RELEASE/spring-beans-3.2.1.RELEASE-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/org/springframework/spring-beans/3.2.3.RELEASE/spring-beans-3.2.3.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-beans/3.2.1.RELEASE/spring-beans-3.2.1.RELEASE-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/springframework/spring-beans/3.2.1.RELEASE/spring-beans-3.2.1.RELEASE-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
@@ -95,19 +50,19 @@
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/springframework/data/spring-data-mongodb/1.2.0.RELEASE/spring-data-mongodb-1.2.0.RELEASE.jar" sourcepath="M2_REPO/org/springframework/data/spring-data-mongodb/1.2.0.RELEASE/spring-data-mongodb-1.2.0.RELEASE-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/org/springframework/data/spring-data-mongodb/1.3.1.RELEASE/spring-data-mongodb-1.3.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/data/spring-data-mongodb/1.2.0.RELEASE/spring-data-mongodb-1.2.0.RELEASE-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/springframework/data/spring-data-mongodb/1.2.0.RELEASE/spring-data-mongodb-1.2.0.RELEASE-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/springframework/data/spring-data-commons/1.5.0.RELEASE/spring-data-commons-1.5.0.RELEASE.jar" sourcepath="M2_REPO/org/springframework/data/spring-data-commons/1.5.0.RELEASE/spring-data-commons-1.5.0.RELEASE-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/org/springframework/data/spring-data-commons/1.6.1.RELEASE/spring-data-commons-1.6.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/data/spring-data-commons/1.5.0.RELEASE/spring-data-commons-1.5.0.RELEASE-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/springframework/data/spring-data-commons/1.5.0.RELEASE/spring-data-commons-1.5.0.RELEASE-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/springframework/data/spring-data-jpa/1.3.0.RELEASE/spring-data-jpa-1.3.0.RELEASE.jar" sourcepath="M2_REPO/org/springframework/data/spring-data-jpa/1.3.0.RELEASE/spring-data-jpa-1.3.0.RELEASE-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/org/springframework/data/spring-data-jpa/1.4.1.RELEASE/spring-data-jpa-1.4.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/data/spring-data-jpa/1.3.0.RELEASE/spring-data-jpa-1.3.0.RELEASE-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/springframework/data/spring-data-jpa/1.3.0.RELEASE/spring-data-jpa-1.3.0.RELEASE-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
@@ -119,48 +74,48 @@
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/cometd/java/cometd-java-annotations/2.5.0/cometd-java-annotations-2.5.0.jar" sourcepath="M2_REPO/org/cometd/java/cometd-java-annotations/2.5.0/cometd-java-annotations-2.5.0-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/org/cometd/java/cometd-java-annotations/2.7.0/cometd-java-annotations-2.7.0.jar" sourcepath="M2_REPO/org/cometd/java/cometd-java-annotations/2.5.0/cometd-java-annotations-2.5.0-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/cometd/java/cometd-java-annotations/2.5.0/cometd-java-annotations-2.5.0-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/cometd/java/cometd-java-server/2.5.0/cometd-java-server-2.5.0.jar" sourcepath="M2_REPO/org/cometd/java/cometd-java-server/2.5.0/cometd-java-server-2.5.0-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/org/cometd/java/cometd-java-server/2.7.0/cometd-java-server-2.7.0.jar" sourcepath="M2_REPO/org/cometd/java/cometd-java-server/2.5.0/cometd-java-server-2.5.0-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/cometd/java/cometd-java-server/2.5.0/cometd-java-server-2.5.0-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/javax/servlet/servlet-api/2.5/servlet-api-2.5.jar" sourcepath="M2_REPO/javax/servlet/servlet-api/2.5/servlet-api-2.5-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/javax/servlet/javax.servlet-api/3.0.1/javax.servlet-api-3.0.1.jar" sourcepath="M2_REPO/javax/servlet/servlet-api/2.5/servlet-api-2.5-sources.jar">
 		<attributes>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/springframework/spring-core/3.2.1.RELEASE/spring-core-3.2.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-core/3.2.1.RELEASE/spring-core-3.2.1.RELEASE-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/org/springframework/spring-core/3.2.4.RELEASE/spring-core-3.2.4.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-core/3.2.1.RELEASE/spring-core-3.2.1.RELEASE-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/springframework/spring-core/3.2.1.RELEASE/spring-core-3.2.1.RELEASE-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/springframework/spring-web/3.2.1.RELEASE/spring-web-3.2.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-web/3.2.1.RELEASE/spring-web-3.2.1.RELEASE-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/org/springframework/spring-web/3.2.4.RELEASE/spring-web-3.2.4.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-web/3.2.1.RELEASE/spring-web-3.2.1.RELEASE-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/springframework/spring-web/3.2.1.RELEASE/spring-web-3.2.1.RELEASE-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/springframework/spring-webmvc/3.2.1.RELEASE/spring-webmvc-3.2.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-webmvc/3.2.1.RELEASE/spring-webmvc-3.2.1.RELEASE-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/org/springframework/spring-webmvc/3.2.4.RELEASE/spring-webmvc-3.2.4.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-webmvc/3.2.1.RELEASE/spring-webmvc-3.2.1.RELEASE-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/springframework/spring-webmvc/3.2.1.RELEASE/spring-webmvc-3.2.1.RELEASE-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/junit/junit/4.10/junit-4.10.jar" sourcepath="M2_REPO/junit/junit/4.10/junit-4.10-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/junit/junit/4.11/junit-4.11.jar" sourcepath="M2_REPO/junit/junit/4.10/junit-4.10-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/junit/junit/4.10/junit-4.10-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/springframework/spring-test/3.2.1.RELEASE/spring-test-3.2.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-test/3.2.1.RELEASE/spring-test-3.2.1.RELEASE-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/org/springframework/spring-test/3.2.4.RELEASE/spring-test-3.2.4.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-test/3.2.1.RELEASE/spring-test-3.2.1.RELEASE-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/springframework/spring-test/3.2.1.RELEASE/spring-test-3.2.1.RELEASE-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
@@ -171,95 +126,59 @@
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/commons-codec/commons-codec/1.7/commons-codec-1.7.jar" sourcepath="M2_REPO/commons-codec/commons-codec/1.7/commons-codec-1.7-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/commons-codec/commons-codec/1.8/commons-codec-1.8.jar" sourcepath="M2_REPO/commons-codec/commons-codec/1.7/commons-codec-1.7-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/commons-codec/commons-codec/1.7/commons-codec-1.7-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/springframework/security/spring-security-core/3.1.3.RELEASE/spring-security-core-3.1.3.RELEASE.jar" sourcepath="M2_REPO/org/springframework/security/spring-security-core/3.1.3.RELEASE/spring-security-core-3.1.3.RELEASE-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/org/springframework/security/spring-security-core/3.1.4.RELEASE/spring-security-core-3.1.4.RELEASE.jar" sourcepath="M2_REPO/org/springframework/security/spring-security-core/3.1.3.RELEASE/spring-security-core-3.1.3.RELEASE-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/springframework/security/spring-security-core/3.1.3.RELEASE/spring-security-core-3.1.3.RELEASE-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/springframework/security/spring-security-config/3.1.3.RELEASE/spring-security-config-3.1.3.RELEASE.jar" sourcepath="M2_REPO/org/springframework/security/spring-security-config/3.1.3.RELEASE/spring-security-config-3.1.3.RELEASE-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/org/springframework/security/spring-security-config/3.1.4.RELEASE/spring-security-config-3.1.4.RELEASE.jar" sourcepath="M2_REPO/org/springframework/security/spring-security-config/3.1.3.RELEASE/spring-security-config-3.1.3.RELEASE-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/springframework/security/spring-security-config/3.1.3.RELEASE/spring-security-config-3.1.3.RELEASE-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/springframework/security/spring-security-web/3.1.3.RELEASE/spring-security-web-3.1.3.RELEASE.jar" sourcepath="M2_REPO/org/springframework/security/spring-security-web/3.1.3.RELEASE/spring-security-web-3.1.3.RELEASE-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/org/springframework/security/spring-security-web/3.1.4.RELEASE/spring-security-web-3.1.4.RELEASE.jar" sourcepath="M2_REPO/org/springframework/security/spring-security-web/3.1.3.RELEASE/spring-security-web-3.1.3.RELEASE-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/springframework/security/spring-security-web/3.1.3.RELEASE/spring-security-web-3.1.3.RELEASE-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
 		<attributes>
 			<attribute name="owner.project.facets" value="java"/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/com/fasterxml/jackson/core/jackson-core/2.1.4/jackson-core-2.1.4.jar" sourcepath="M2_REPO/com/fasterxml/jackson/core/jackson-core/2.1.4/jackson-core-2.1.4-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/com/fasterxml/jackson/core/jackson-core/2.2.3/jackson-core-2.2.3.jar" sourcepath="M2_REPO/com/fasterxml/jackson/core/jackson-core/2.1.4/jackson-core-2.1.4-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.1.4/jackson-core-2.1.4-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/com/fasterxml/jackson/core/jackson-databind/2.1.4/jackson-databind-2.1.4.jar" sourcepath="M2_REPO/com/fasterxml/jackson/core/jackson-databind/2.1.4/jackson-databind-2.1.4-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/com/fasterxml/jackson/core/jackson-databind/2.2.3/jackson-databind-2.2.3.jar" sourcepath="M2_REPO/com/fasterxml/jackson/core/jackson-databind/2.1.4/jackson-databind-2.1.4-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.1.4/jackson-databind-2.1.4-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/cometd/java/cometd-websocket-jetty/2.5.1/cometd-websocket-jetty-2.5.1.jar" sourcepath="M2_REPO/org/cometd/java/cometd-websocket-jetty/2.5.1/cometd-websocket-jetty-2.5.1-sources.jar">
-		<attributes>
-			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/org/cometd/java/cometd-websocket-jetty/2.5.1/cometd-websocket-jetty-2.5.1-javadoc.jar!/"/>
-			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-websocket/8.1.9.v20130131/jetty-websocket-8.1.9.v20130131.jar">
+	<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/aggregate/jetty-all/8.1.13.v20130916/jetty-all-8.1.13.v20130916.jar" sourcepath="/M2_REPO/org/eclipse/jetty/aggregate/jetty-all/9.0.5.v20130815/jetty-all-9.0.5.v20130815-sources.jar">
 		<attributes>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/com/fasterxml/jackson/core/jackson-annotations/2.1.4/jackson-annotations-2.1.4.jar" sourcepath="M2_REPO/com/fasterxml/jackson/core/jackson-annotations/2.1.4/jackson-annotations-2.1.4-sources.jar">
-		<attributes>
-			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.1.4/jackson-annotations-2.1.4-javadoc.jar!/"/>
-			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/com/sun/jersey/jersey-test-framework/jersey-test-framework-core/1.17.1/jersey-test-framework-core-1.17.1.jar" sourcepath="M2_REPO/com/sun/jersey/jersey-test-framework/jersey-test-framework-core/1.17/jersey-test-framework-core-1.17-sources.jar">
-		<attributes>
-			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/com/sun/jersey/jersey-test-framework/jersey-test-framework-core/1.17/jersey-test-framework-core-1.17-javadoc.jar!/"/>
-			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/com/sun/jersey/jersey-servlet/1.17.1/jersey-servlet-1.17.1.jar" sourcepath="M2_REPO/com/sun/jersey/jersey-servlet/1.17/jersey-servlet-1.17-sources.jar">
-		<attributes>
-			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/com/sun/jersey/jersey-servlet/1.17/jersey-servlet-1.17-javadoc.jar!/"/>
-			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/com/sun/jersey/contribs/jersey-spring/1.17.1/jersey-spring-1.17.1.jar" sourcepath="M2_REPO/com/sun/jersey/contribs/jersey-spring/1.17/jersey-spring-1.17-sources.jar">
-		<attributes>
-			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/com/sun/jersey/contribs/jersey-spring/1.17/jersey-spring-1.17-javadoc.jar!/"/>
-			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/com/sun/jersey/jersey-client/1.17.1/jersey-client-1.17.1.jar" sourcepath="M2_REPO/com/sun/jersey/jersey-client/1.17/jersey-client-1.17-sources.jar">
-		<attributes>
-			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/com/sun/jersey/jersey-client/1.17/jersey-client-1.17-javadoc.jar!/"/>
-			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/joda-time/joda-time/2.1/joda-time-2.1.jar" sourcepath="M2_REPO/joda-time/joda-time/2.1/joda-time-2.1-sources.jar">
+	<classpathentry kind="var" path="M2_REPO/joda-time/joda-time/2.3/joda-time-2.3.jar" sourcepath="M2_REPO/joda-time/joda-time/2.1/joda-time-2.1-sources.jar">
 		<attributes>
 			<attribute name="javadoc_location" value="jar:file:/Users/ymh/.m2/repository/joda-time/joda-time/2.1/joda-time-2.1-javadoc.jar!/"/>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/javax/validation/validation-api/1.1.0.CR2/validation-api-1.1.0.CR2.jar">
+	<classpathentry kind="var" path="M2_REPO/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final.jar">
 		<attributes>
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
@@ -269,10 +188,21 @@
 			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
 		</attributes>
 	</classpathentry>
-	<classpathentry kind="var" path="M2_REPO/com/sun/jersey/jersey-json/1.17.1/jersey-json-1.17.1.jar">
-		<attributes>
-			<attribute name="org.eclipse.jst.component.nondependency" value=""/>
-		</attributes>
-	</classpathentry>
+	<classpathentry kind="lib" path="server/lib/org/opencoweb/coweb-bots/1.0.1-SNAPSHOT/coweb-bots-1.0.1-SNAPSHOT.jar"/>
+	<classpathentry kind="lib" path="server/lib/org/opencoweb/coweb-operationengine/1.0.1-SNAPSHOT/coweb-operationengine-1.0.1-SNAPSHOT.jar"/>
+	<classpathentry kind="lib" path="server/lib/org/opencoweb/coweb-server/1.0.1-SNAPSHOT/coweb-server-1.0.1-SNAPSHOT.jar"/>
+	<classpathentry kind="var" path="M2_REPO/com/fasterxml/jackson/core/jackson-annotations/2.2.3/jackson-annotations-2.2.3.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/glassfish/jersey/core/jersey-client/2.3.1/jersey-client-2.3.1.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/glassfish/jersey/core/jersey-common/2.3.1/jersey-common-2.3.1.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/glassfish/jersey/core/jersey-server/2.3.1/jersey-server-2.3.1.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/glassfish/jersey/containers/jersey-container-servlet-core/2.3.1/jersey-container-servlet-core-2.3.1.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/glassfish/jersey/test-framework/jersey-test-framework-core/2.3.1/jersey-test-framework-core-2.3.1.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/glassfish/jersey/ext/jersey-spring3/2.3.1/jersey-spring3-2.3.1.jar"/>
+	<classpathentry kind="var" path="M2_REPO/javax/ws/rs/javax.ws.rs-api/2.0/javax.ws.rs-api-2.0.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar"/>
+	<classpathentry kind="var" path="M2_REPO/com/fasterxml/jackson/datatype/jackson-datatype-joda/2.2.3/jackson-datatype-joda-2.2.3.jar"/>
+	<classpathentry kind="var" path="M2_REPO/com/fasterxml/jackson/jaxrs/jackson-jaxrs-json-provider/2.2.3/jackson-jaxrs-json-provider-2.2.3.jar"/>
+	<classpathentry kind="var" path="M2_REPO/com/fasterxml/jackson/jaxrs/jackson-jaxrs-base/2.2.3/jackson-jaxrs-base-2.2.3.jar"/>
+	<classpathentry kind="var" path="M2_REPO/org/apache/commons/commons-collections4/4.0/commons-collections4-4.0.jar"/>
 	<classpathentry kind="output" path="server/target/classes"/>
 </classpath>
--- a/.settings/org.eclipse.jdt.core.prefs	Fri Oct 25 16:42:11 2013 +0200
+++ b/.settings/org.eclipse.jdt.core.prefs	Wed Jan 15 18:36:27 2014 +0100
@@ -1,4 +1,10 @@
 eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
@@ -6,6 +12,88 @@
 org.eclipse.jdt.core.compiler.debug.lineNumber=generate
 org.eclipse.jdt.core.compiler.debug.localVariable=generate
 org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=error
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=enabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=enabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=error
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
 org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
 org.eclipse.jdt.core.compiler.source=1.7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/README.md	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,9 @@
+Dependencies
+
+- Icon user from echo-icon-theme (echo) (Open Icon Library - http://openiconlibrary.sourceforge.net/)  
+licence CC BY-SA - Creative Commons
+
+- cf pom.xml for dependencies
+
+Commandes maven:
+mvn -DskipTests -Djava.awt.headless=true -Duser.timezone="UTC" clean jetty:run-war
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/admin-archetype/1.0.1-SNAPSHOT/_remote.repositories	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Mon Oct 14 16:54:20 CEST 2013
+admin-archetype-1.0.1-SNAPSHOT.jar>=
+admin-archetype-1.0.1-SNAPSHOT.pom>=
Binary file server/lib/org/opencoweb/admin-archetype/1.0.1-SNAPSHOT/admin-archetype-1.0.1-SNAPSHOT.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/admin-archetype/1.0.1-SNAPSHOT/admin-archetype-1.0.1-SNAPSHOT.pom	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <parent>
+        <groupId>org.opencoweb</groupId>
+        <artifactId>coweb-admin</artifactId>
+        <version>1.0.1-SNAPSHOT</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.opencoweb</groupId>
+    <artifactId>admin-archetype</artifactId>
+    <packaging>maven-archetype</packaging>
+    <name>OpenCoweb :: Java :: Admin :: Archetype</name>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>org.apache.maven.archetype</groupId>
+                <artifactId>archetype-packaging</artifactId>
+                <version>2.0-alpha-5</version>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <artifactId>maven-archetype-plugin</artifactId>
+                <version>2.0-alpha-4</version>
+                <extensions>true</extensions>
+            </plugin>
+        </plugins>
+        <resources>
+            <resource>
+                <directory>${basedir}/src/main/resources</directory>
+                <filtering>false</filtering>
+            </resource>
+            <resource>
+                <directory>${basedir}/src/main/resources</directory>
+                <includes>
+                    <include>**/archetype-metadata.xml</include>
+                </includes>
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+    </build>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/admin-archetype/1.0.1-SNAPSHOT/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata modelVersion="1.1.0">
+  <groupId>org.opencoweb</groupId>
+  <artifactId>admin-archetype</artifactId>
+  <version>1.0.1-SNAPSHOT</version>
+  <versioning>
+    <snapshot>
+      <localCopy>true</localCopy>
+    </snapshot>
+    <lastUpdated>20131014145420</lastUpdated>
+    <snapshotVersions>
+      <snapshotVersion>
+        <extension>jar</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145420</updated>
+      </snapshotVersion>
+      <snapshotVersion>
+        <extension>pom</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145420</updated>
+      </snapshotVersion>
+    </snapshotVersions>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/admin-archetype/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+  <groupId>org.opencoweb</groupId>
+  <artifactId>admin-archetype</artifactId>
+  <versioning>
+    <versions>
+      <version>1.0.1-SNAPSHOT</version>
+    </versions>
+    <lastUpdated>20131014145420</lastUpdated>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/admin-jar/1.0.1-SNAPSHOT/_remote.repositories	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Mon Oct 14 16:54:21 CEST 2013
+admin-jar-1.0.1-SNAPSHOT.jar>=
+admin-jar-1.0.1-SNAPSHOT.pom>=
Binary file server/lib/org/opencoweb/admin-jar/1.0.1-SNAPSHOT/admin-jar-1.0.1-SNAPSHOT.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/admin-jar/1.0.1-SNAPSHOT/admin-jar-1.0.1-SNAPSHOT.pom	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <parent>
+        <groupId>org.opencoweb</groupId>
+        <artifactId>coweb-admin</artifactId>
+        <version>1.0.1-SNAPSHOT</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>admin-jar</artifactId>
+    <packaging>jar</packaging>
+    <name>OpenCoweb :: Java :: Admin :: Jar</name>
+    
+    <dependencies>
+        <dependency>
+            <groupId>javax</groupId>
+            <artifactId>javaee-api</artifactId>
+            <version>6.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <version>2.5</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+        	<groupId>org.apache.wink</groupId>
+        	<artifactId>wink-json4j</artifactId>
+        	<version>1.1.2-incubating</version>
+        	<type>jar</type>
+        	<scope>compile</scope>
+        </dependency>
+        <dependency>
+        	<groupId>org.opencoweb</groupId>
+        	<artifactId>coweb-server</artifactId>
+        	<version>${project.version}</version>
+        	<type>jar</type>
+        	<scope>provided</scope>
+        </dependency>
+    </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/admin-jar/1.0.1-SNAPSHOT/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata modelVersion="1.1.0">
+  <groupId>org.opencoweb</groupId>
+  <artifactId>admin-jar</artifactId>
+  <version>1.0.1-SNAPSHOT</version>
+  <versioning>
+    <snapshot>
+      <localCopy>true</localCopy>
+    </snapshot>
+    <lastUpdated>20131014145421</lastUpdated>
+    <snapshotVersions>
+      <snapshotVersion>
+        <extension>jar</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145421</updated>
+      </snapshotVersion>
+      <snapshotVersion>
+        <extension>pom</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145421</updated>
+      </snapshotVersion>
+    </snapshotVersions>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/admin-jar/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+  <groupId>org.opencoweb</groupId>
+  <artifactId>admin-jar</artifactId>
+  <versioning>
+    <versions>
+      <version>1.0.1-SNAPSHOT</version>
+    </versions>
+    <lastUpdated>20131014145421</lastUpdated>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-admin/1.0.1-SNAPSHOT/_remote.repositories	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,3 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Mon Oct 14 16:54:20 CEST 2013
+coweb-admin-1.0.1-SNAPSHOT.pom>=
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-admin/1.0.1-SNAPSHOT/coweb-admin-1.0.1-SNAPSHOT.pom	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.opencoweb</groupId>
+        <artifactId>coweb-java</artifactId>
+        <version>1.0.1-SNAPSHOT</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>coweb-admin</artifactId>
+    <packaging>pom</packaging>
+    <name>OpenCoweb :: Java :: Admin</name>
+
+    <modules>
+        <module>admin-archetype</module>
+        <module>admin-jar</module>
+  	</modules>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-admin/1.0.1-SNAPSHOT/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata modelVersion="1.1.0">
+  <groupId>org.opencoweb</groupId>
+  <artifactId>coweb-admin</artifactId>
+  <version>1.0.1-SNAPSHOT</version>
+  <versioning>
+    <snapshot>
+      <localCopy>true</localCopy>
+    </snapshot>
+    <lastUpdated>20131014145420</lastUpdated>
+    <snapshotVersions>
+      <snapshotVersion>
+        <extension>pom</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145420</updated>
+      </snapshotVersion>
+    </snapshotVersions>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-admin/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+  <groupId>org.opencoweb</groupId>
+  <artifactId>coweb-admin</artifactId>
+  <versioning>
+    <versions>
+      <version>1.0.1-SNAPSHOT</version>
+    </versions>
+    <lastUpdated>20131014145420</lastUpdated>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-archetype/1.0.1-SNAPSHOT/_remote.repositories	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Mon Oct 14 16:54:20 CEST 2013
+coweb-archetype-1.0.1-SNAPSHOT.jar>=
+coweb-archetype-1.0.1-SNAPSHOT.pom>=
Binary file server/lib/org/opencoweb/coweb-archetype/1.0.1-SNAPSHOT/coweb-archetype-1.0.1-SNAPSHOT.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-archetype/1.0.1-SNAPSHOT/coweb-archetype-1.0.1-SNAPSHOT.pom	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <parent>
+        <groupId>org.opencoweb</groupId>
+        <artifactId>coweb-java</artifactId>
+        <version>1.0.1-SNAPSHOT</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.opencoweb</groupId>
+    <artifactId>coweb-archetype</artifactId>
+    <packaging>maven-archetype</packaging>
+    <name>OpenCoweb :: Java :: Archetype</name>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>org.apache.maven.archetype</groupId>
+                <artifactId>archetype-packaging</artifactId>
+                <version>2.0-alpha-5</version>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <artifactId>maven-archetype-plugin</artifactId>
+                <version>2.0-alpha-4</version>
+                <extensions>true</extensions>
+            </plugin>
+        </plugins>
+        <resources>
+            <resource>
+                <directory>${basedir}/src/main/resources</directory>
+                <filtering>false</filtering>
+            </resource>
+            <resource>
+                <directory>${basedir}/src/main/resources</directory>
+                <includes>
+                    <include>**/archetype-metadata.xml</include>
+                </includes>
+                <filtering>true</filtering>
+            </resource>
+        </resources>
+    </build>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-archetype/1.0.1-SNAPSHOT/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata modelVersion="1.1.0">
+  <groupId>org.opencoweb</groupId>
+  <artifactId>coweb-archetype</artifactId>
+  <version>1.0.1-SNAPSHOT</version>
+  <versioning>
+    <snapshot>
+      <localCopy>true</localCopy>
+    </snapshot>
+    <lastUpdated>20131014145420</lastUpdated>
+    <snapshotVersions>
+      <snapshotVersion>
+        <extension>jar</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145420</updated>
+      </snapshotVersion>
+      <snapshotVersion>
+        <extension>pom</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145420</updated>
+      </snapshotVersion>
+    </snapshotVersions>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-archetype/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+  <groupId>org.opencoweb</groupId>
+  <artifactId>coweb-archetype</artifactId>
+  <versioning>
+    <versions>
+      <version>1.0.1-SNAPSHOT</version>
+    </versions>
+    <lastUpdated>20131014145420</lastUpdated>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-bots/1.0.1-SNAPSHOT/_remote.repositories	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Mon Oct 14 16:54:09 CEST 2013
+coweb-bots-1.0.1-SNAPSHOT.jar>=
+coweb-bots-1.0.1-SNAPSHOT.pom>=
Binary file server/lib/org/opencoweb/coweb-bots/1.0.1-SNAPSHOT/coweb-bots-1.0.1-SNAPSHOT.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-bots/1.0.1-SNAPSHOT/coweb-bots-1.0.1-SNAPSHOT.pom	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.opencoweb</groupId>
+        <artifactId>coweb-java</artifactId>
+        <version>1.0.1-SNAPSHOT</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>coweb-bots</artifactId>
+    <groupId>org.opencoweb</groupId>
+    <packaging>jar</packaging>
+    <name>OpenCoweb :: Java :: Bots</name>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-bots/1.0.1-SNAPSHOT/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata modelVersion="1.1.0">
+  <groupId>org.opencoweb</groupId>
+  <artifactId>coweb-bots</artifactId>
+  <version>1.0.1-SNAPSHOT</version>
+  <versioning>
+    <snapshot>
+      <localCopy>true</localCopy>
+    </snapshot>
+    <lastUpdated>20131014145409</lastUpdated>
+    <snapshotVersions>
+      <snapshotVersion>
+        <extension>jar</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145409</updated>
+      </snapshotVersion>
+      <snapshotVersion>
+        <extension>pom</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145409</updated>
+      </snapshotVersion>
+    </snapshotVersions>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-bots/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+  <groupId>org.opencoweb</groupId>
+  <artifactId>coweb-bots</artifactId>
+  <versioning>
+    <versions>
+      <version>1.0.1-SNAPSHOT</version>
+    </versions>
+    <lastUpdated>20131014145409</lastUpdated>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-build/1.0.1-SNAPSHOT/_remote.repositories	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Mon Oct 14 16:54:22 CEST 2013
+coweb-build-1.0.1-SNAPSHOT.pom>=
+coweb-build-1.0.1-SNAPSHOT.war>=
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-build/1.0.1-SNAPSHOT/coweb-build-1.0.1-SNAPSHOT.pom	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.opencoweb</groupId>
+        <artifactId>coweb-java</artifactId>
+        <version>1.0.1-SNAPSHOT</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>coweb-build</artifactId>
+    <name>OpenCoweb Build :: Applications</name>
+    <packaging>war</packaging>
+
+    <build>
+        <plugins>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-war-plugin</artifactId>
+                <version>2.1.1</version>
+                <configuration>
+                    <overlays>
+                        <overlay>
+                            <groupId>org.opencoweb</groupId>
+                            <artifactId>coweb-javascript</artifactId>
+                            <type>war</type>
+                            <excludes>
+                                <exclude>META-INF/**</exclude>
+                                <exclude>WEB-INF/**</exclude>
+                            </excludes>
+                            <targetPath>lib</targetPath>
+                        </overlay>
+                    </overlays>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opencoweb</groupId>
+            <artifactId>coweb-bots</artifactId>
+            <version>${coweb-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opencoweb</groupId>
+            <artifactId>coweb-operationengine</artifactId>
+            <version>${coweb-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opencoweb</groupId>
+            <artifactId>coweb-server</artifactId>
+            <version>${coweb-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opencoweb</groupId>
+            <artifactId>coweb-javascript</artifactId>
+            <version>${coweb-version}</version>
+            <type>war</type>
+        </dependency>
+    </dependencies>
+</project>
Binary file server/lib/org/opencoweb/coweb-build/1.0.1-SNAPSHOT/coweb-build-1.0.1-SNAPSHOT.war has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-build/1.0.1-SNAPSHOT/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata modelVersion="1.1.0">
+  <groupId>org.opencoweb</groupId>
+  <artifactId>coweb-build</artifactId>
+  <version>1.0.1-SNAPSHOT</version>
+  <versioning>
+    <snapshot>
+      <localCopy>true</localCopy>
+    </snapshot>
+    <lastUpdated>20131014145422</lastUpdated>
+    <snapshotVersions>
+      <snapshotVersion>
+        <extension>war</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145422</updated>
+      </snapshotVersion>
+      <snapshotVersion>
+        <extension>pom</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145422</updated>
+      </snapshotVersion>
+    </snapshotVersions>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-build/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+  <groupId>org.opencoweb</groupId>
+  <artifactId>coweb-build</artifactId>
+  <versioning>
+    <versions>
+      <version>1.0.1-SNAPSHOT</version>
+    </versions>
+    <lastUpdated>20131014145422</lastUpdated>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-client/1.0.1-SNAPSHOT/_remote.repositories	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Mon Oct 14 16:54:19 CEST 2013
+coweb-client-1.0.1-SNAPSHOT.jar>=
+coweb-client-1.0.1-SNAPSHOT.pom>=
Binary file server/lib/org/opencoweb/coweb-client/1.0.1-SNAPSHOT/coweb-client-1.0.1-SNAPSHOT.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-client/1.0.1-SNAPSHOT/coweb-client-1.0.1-SNAPSHOT.pom	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.opencoweb</groupId>
+        <artifactId>coweb-java</artifactId>
+        <version>1.0.1-SNAPSHOT</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.opencoweb</groupId>
+    <artifactId>coweb-client</artifactId>
+    <name>OpenCoweb :: Java :: Client</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.cometd.java</groupId>
+            <artifactId>cometd-java-client</artifactId>
+            <version>${cometd-version}</version>
+        </dependency>
+    </dependencies>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-client/1.0.1-SNAPSHOT/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata modelVersion="1.1.0">
+  <groupId>org.opencoweb</groupId>
+  <artifactId>coweb-client</artifactId>
+  <version>1.0.1-SNAPSHOT</version>
+  <versioning>
+    <snapshot>
+      <localCopy>true</localCopy>
+    </snapshot>
+    <lastUpdated>20131014145419</lastUpdated>
+    <snapshotVersions>
+      <snapshotVersion>
+        <extension>jar</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145419</updated>
+      </snapshotVersion>
+      <snapshotVersion>
+        <extension>pom</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145419</updated>
+      </snapshotVersion>
+    </snapshotVersions>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-client/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+  <groupId>org.opencoweb</groupId>
+  <artifactId>coweb-client</artifactId>
+  <versioning>
+    <versions>
+      <version>1.0.1-SNAPSHOT</version>
+    </versions>
+    <lastUpdated>20131014145419</lastUpdated>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-java/1.0.1-SNAPSHOT/_remote.repositories	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,3 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Mon Oct 14 16:54:04 CEST 2013
+coweb-java-1.0.1-SNAPSHOT.pom>=
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-java/1.0.1-SNAPSHOT/coweb-java-1.0.1-SNAPSHOT.pom	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.opencoweb</groupId>
+    <artifactId>coweb-java</artifactId>
+    <packaging>pom</packaging>
+    
+    <name>OpenCoweb</name>
+    <description>Open Cooperative Web Framework</description>
+    <version>1.0.1-SNAPSHOT</version>
+    <url>http://opencoweb.org</url>
+    <inceptionYear>2011</inceptionYear>
+    <organization>
+        <name>The Dojo Foundation</name>
+        <url>http://dojofoundation.org</url>
+    </organization>
+    
+    <licenses>
+        <license>
+            <name>The New BSD License</name>
+            <url>http://www.opensource.org/licenses/bsd-license.html</url>
+        </license>
+        <license>
+            <name>The Academic Free License, v. 2.1</name>
+            <url>http://en.wikipedia.org/wiki/Academic_Free_License</url>
+        </license>
+    </licenses>
+    
+    <developers>
+        <developer>
+            <id>parente</id>
+            <name>Peter Parente</name>
+            <email>pparent@us.ibm.com</email>
+            <organization>IBM Corporation</organization>
+        </developer>
+        <developer>
+            <id>bpburns</id>
+            <name>Brian Burns</name>
+            <email>bburns@us.ibm.com</email>
+            <organization>IBM Corporation</organization>
+        </developer>
+        <developer>
+            <id>vinomaster</id>
+            <name>Dan Gisolfi</name>
+            <email>gisolfi@us.ibm.com</email>
+            <organization>IBM Corporation</organization>
+        </developer>
+    </developers>
+
+    <scm>
+        <connection>scm:git:git@github.com:opencoweb/coweb.git</connection>
+        <developerConnection>scm:git:git@github.com:opencoweb/coweb.git</developerConnection>
+        <url>git@github.com:opencoweb/coweb.git</url>
+    </scm>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <cometd-version>2.7.0</cometd-version>
+        <coweb-version>1.0.1-SNAPSHOT</coweb-version>
+    </properties>
+
+    <modules>
+        <module>coweb-operationengine</module>
+        <module>coweb-bots</module>
+        <module>coweb-server</module>
+        <module>coweb-javascript</module>
+        <module>coweb-client</module>
+        <module>coweb-archetype</module>
+        <module>coweb-admin</module>
+        <module>coweb-build</module>
+    </modules>
+
+    <build>
+        <defaultGoal>install</defaultGoal>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <version>2.7</version>
+                <configuration>
+                    <doctitle>${project.name} ${project.version} Java Server API</doctitle>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>aggregate</id>
+                        <goals>
+                            <goal>aggregate</goal>
+                        </goals>
+                        <phase>site</phase>
+                        <configuration></configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>2.3.2</version>
+                    <configuration>
+                        <source>1.6</source>
+                        <target>1.6</target>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+    <profiles>
+        <profile>
+            <id>release-sign-artifacts</id>
+            <activation>
+                <property>
+                    <name>performRelease</name>
+                    <value>true</value>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-gpg-plugin</artifactId>
+                        <version>1.1</version>
+                        <executions>
+                            <execution>
+                                <id>sign-artifacts</id>
+                                <phase>verify</phase>
+                                <goals>
+                                    <goal>sign</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-java/1.0.1-SNAPSHOT/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata modelVersion="1.1.0">
+  <groupId>org.opencoweb</groupId>
+  <artifactId>coweb-java</artifactId>
+  <version>1.0.1-SNAPSHOT</version>
+  <versioning>
+    <snapshot>
+      <localCopy>true</localCopy>
+    </snapshot>
+    <lastUpdated>20131014145404</lastUpdated>
+    <snapshotVersions>
+      <snapshotVersion>
+        <extension>pom</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145404</updated>
+      </snapshotVersion>
+    </snapshotVersions>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-java/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+  <groupId>org.opencoweb</groupId>
+  <artifactId>coweb-java</artifactId>
+  <versioning>
+    <versions>
+      <version>1.0.1-SNAPSHOT</version>
+    </versions>
+    <lastUpdated>20131014145404</lastUpdated>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-javascript/1.0.1-SNAPSHOT/_remote.repositories	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Mon Oct 14 16:54:19 CEST 2013
+coweb-javascript-1.0.1-SNAPSHOT.pom>=
+coweb-javascript-1.0.1-SNAPSHOT.war>=
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-javascript/1.0.1-SNAPSHOT/coweb-javascript-1.0.1-SNAPSHOT.pom	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.opencoweb</groupId>
+        <artifactId>coweb-java</artifactId>
+        <version>1.0.1-SNAPSHOT</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.opencoweb</groupId>
+    <artifactId>coweb-javascript</artifactId>
+    <name>OpenCoweb :: Java :: JavaScript</name>
+    <packaging>war</packaging>
+
+    <properties>
+	    <i18n-plugin-url>http://requirejs.org/docs/release/1.0.0/minified/i18n.js</i18n-plugin-url>
+        <coweb-jsoe>${project.build.directory}/${project.artifactId}-${project.version}/coweb/jsoe</coweb-jsoe>
+        <coweb-jsoe-src>src/main/webapp/coweb/jsoe</coweb-jsoe-src>
+	</properties>
+
+    <build>
+        <plugins>
+			<plugin>
+			    <groupId>org.apache.maven.plugins</groupId>
+			    <artifactId>maven-war-plugin</artifactId>
+			    <version>2.2</version>
+				<configuration>
+                    <warSourceExcludes>coweb/jsoe/</warSourceExcludes>
+				</configuration>
+			</plugin>
+		    <plugin>
+			    <groupId>org.apache.maven.plugins</groupId>
+			    <artifactId>maven-dependency-plugin</artifactId>
+			    <version>2.4</version>
+			    <executions>
+				  <execution>
+					<id>unpack</id>
+					<phase>compile</phase>
+					<goals><goal>unpack</goal></goals>
+			        <configuration>
+			          <artifactItems>
+			            <artifactItem>
+			              <groupId>org.cometd.javascript</groupId>
+			              <artifactId>cometd-javascript-common</artifactId>
+			              <version>${cometd.version}</version>
+			              <type>war</type>
+			              <overWrite>false</overWrite>
+			              <outputDirectory>${project.build.directory}/tmp</outputDirectory>
+						  <includes>**/cometd.js,**/cometd/AckExtension.js</includes>
+			            </artifactItem>
+			          </artifactItems>
+			          <!-- other configurations here -->
+			        </configuration>
+			     </execution>
+		      </executions>
+			  
+			</plugin>
+            <plugin>
+                <artifactId>maven-antrun-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>prepare-package</phase>
+                        <configuration>
+                            <tasks>
+								<property name="workpath" location="${project.build.directory}/tmp" />
+								<echo message="HERE ***************************   ${workpath}" />
+
+                                <!-- Pull in cometd. -->
+                                <delete dir="${project.build.directory}/${project.artifactId}-${project.version}/org/cometd" />
+                                <copy file="${workpath}/org/cometd.js"
+                                    tofile="${project.build.directory}/${project.artifactId}-${project.version}/org/cometd.js" />
+                                <copy file="${workpath}/org/cometd/AckExtension.js"
+                                    tofile="${project.build.directory}/${project.artifactId}-${project.version}/org/cometd/AckExtension.js" />
+
+                                <!-- Pull in requirejs's i18n library. -->
+								<mkdir dir="${project.build.directory}/${project.artifactId}-${project.version}/org/requirejs"/>
+                                <get src="${i18n-plugin-url}"
+                                    dest="${project.build.directory}/${project.artifactId}-${project.version}/org/requirejs/i18n.js"/>
+
+                                <!-- Use only the relevant coweb-jsoe files. -->
+                                <copy todir="${coweb-jsoe}">
+                                    <fileset dir="${coweb-jsoe-src}/src/coweb/jsoe">
+                                        <include name="*.js" />
+                                        <exclude name="OTEngine.js" />
+                                    </fileset>
+                                </copy>
+                                <copy todir="${coweb-jsoe}/nls">
+                                    <fileset dir="${coweb-jsoe-src}/src/coweb/jsoe/nls" />
+                                </copy>
+
+							  </tasks>
+                        </configuration>
+                        <goals>
+                            <goal>run</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+	<dependencies>
+	  <dependency>
+		<groupId>org.cometd.javascript</groupId>
+        <artifactId>cometd-javascript-common</artifactId>
+        <version>${cometd-version}</version>
+		<type>war</type>
+		<scope>provided</scope>
+	</dependency>
+    </dependencies>
+</project>
Binary file server/lib/org/opencoweb/coweb-javascript/1.0.1-SNAPSHOT/coweb-javascript-1.0.1-SNAPSHOT.war has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-javascript/1.0.1-SNAPSHOT/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata modelVersion="1.1.0">
+  <groupId>org.opencoweb</groupId>
+  <artifactId>coweb-javascript</artifactId>
+  <version>1.0.1-SNAPSHOT</version>
+  <versioning>
+    <snapshot>
+      <localCopy>true</localCopy>
+    </snapshot>
+    <lastUpdated>20131014145419</lastUpdated>
+    <snapshotVersions>
+      <snapshotVersion>
+        <extension>war</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145419</updated>
+      </snapshotVersion>
+      <snapshotVersion>
+        <extension>pom</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145419</updated>
+      </snapshotVersion>
+    </snapshotVersions>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-javascript/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+  <groupId>org.opencoweb</groupId>
+  <artifactId>coweb-javascript</artifactId>
+  <versioning>
+    <versions>
+      <version>1.0.1-SNAPSHOT</version>
+    </versions>
+    <lastUpdated>20131014145419</lastUpdated>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-operationengine/1.0.1-SNAPSHOT/_remote.repositories	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Mon Oct 14 16:54:09 CEST 2013
+coweb-operationengine-1.0.1-SNAPSHOT.jar>=
+coweb-operationengine-1.0.1-SNAPSHOT.pom>=
Binary file server/lib/org/opencoweb/coweb-operationengine/1.0.1-SNAPSHOT/coweb-operationengine-1.0.1-SNAPSHOT.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-operationengine/1.0.1-SNAPSHOT/coweb-operationengine-1.0.1-SNAPSHOT.pom	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.opencoweb</groupId>
+        <artifactId>coweb-java</artifactId>
+        <version>1.0.1-SNAPSHOT</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.opencoweb</groupId>
+    <artifactId>coweb-operationengine</artifactId>
+    <name>OpenCoweb :: Java :: OperationEngine</name>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-operationengine/1.0.1-SNAPSHOT/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata modelVersion="1.1.0">
+  <groupId>org.opencoweb</groupId>
+  <artifactId>coweb-operationengine</artifactId>
+  <version>1.0.1-SNAPSHOT</version>
+  <versioning>
+    <snapshot>
+      <localCopy>true</localCopy>
+    </snapshot>
+    <lastUpdated>20131014145409</lastUpdated>
+    <snapshotVersions>
+      <snapshotVersion>
+        <extension>jar</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145409</updated>
+      </snapshotVersion>
+      <snapshotVersion>
+        <extension>pom</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145409</updated>
+      </snapshotVersion>
+    </snapshotVersions>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-operationengine/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+  <groupId>org.opencoweb</groupId>
+  <artifactId>coweb-operationengine</artifactId>
+  <versioning>
+    <versions>
+      <version>1.0.1-SNAPSHOT</version>
+    </versions>
+    <lastUpdated>20131014145409</lastUpdated>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-server/1.0.1-SNAPSHOT/_remote.repositories	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Mon Oct 14 16:54:10 CEST 2013
+coweb-server-1.0.1-SNAPSHOT.pom>=
+coweb-server-1.0.1-SNAPSHOT.jar>=
Binary file server/lib/org/opencoweb/coweb-server/1.0.1-SNAPSHOT/coweb-server-1.0.1-SNAPSHOT.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-server/1.0.1-SNAPSHOT/coweb-server-1.0.1-SNAPSHOT.pom	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.opencoweb</groupId>
+        <artifactId>coweb-java</artifactId>
+        <version>1.0.1-SNAPSHOT</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.opencoweb</groupId>
+    <artifactId>coweb-server</artifactId>
+    <name>OpenCoweb :: Java :: Server</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opencoweb</groupId>
+            <artifactId>coweb-bots</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opencoweb</groupId>
+            <artifactId>coweb-operationengine</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.cometd.java</groupId>
+            <artifactId>cometd-java-server</artifactId>
+            <version>${cometd-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.cometd.java</groupId>
+            <artifactId>bayeux-api</artifactId>
+            <version>${cometd-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.cometd.java</groupId>
+            <artifactId>cometd-java-common</artifactId>
+            <version>${cometd-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.cometd.java</groupId>
+            <artifactId>cometd-websocket-jetty</artifactId>
+            <version>${cometd-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <version>2.5</version>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-server/1.0.1-SNAPSHOT/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata modelVersion="1.1.0">
+  <groupId>org.opencoweb</groupId>
+  <artifactId>coweb-server</artifactId>
+  <version>1.0.1-SNAPSHOT</version>
+  <versioning>
+    <snapshot>
+      <localCopy>true</localCopy>
+    </snapshot>
+    <lastUpdated>20131014145410</lastUpdated>
+    <snapshotVersions>
+      <snapshotVersion>
+        <extension>jar</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145410</updated>
+      </snapshotVersion>
+      <snapshotVersion>
+        <extension>pom</extension>
+        <value>1.0.1-SNAPSHOT</value>
+        <updated>20131014145410</updated>
+      </snapshotVersion>
+    </snapshotVersions>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/coweb-server/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+  <groupId>org.opencoweb</groupId>
+  <artifactId>coweb-server</artifactId>
+  <versioning>
+    <versions>
+      <version>1.0.1-SNAPSHOT</version>
+    </versions>
+    <lastUpdated>20131014145410</lastUpdated>
+  </versioning>
+</metadata>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/opencoweb/maven-metadata-local.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+  <plugins>
+    <plugin>
+      <name>OpenCoweb :: Java :: Archetype</name>
+      <prefix>coweb-archetype</prefix>
+      <artifactId>coweb-archetype</artifactId>
+    </plugin>
+    <plugin>
+      <name>OpenCoweb :: Java :: Admin :: Archetype</name>
+      <prefix>admin-archetype</prefix>
+      <artifactId>admin-archetype</artifactId>
+    </plugin>
+  </plugins>
+</metadata>
Binary file server/lib/org/thymeleaf/extras/thymeleaf-joda-dialect/0.0.3/thymeleaf-joda-dialect-0.0.3.jar has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/lib/org/thymeleaf/extras/thymeleaf-joda-dialect/0.0.3/thymeleaf-joda-dialect-0.0.3.pom	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,145 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>org.thymeleaf.extras</groupId>
+	<artifactId>thymeleaf-joda-dialect</artifactId>
+	<version>0.0.3</version>
+	<inceptionYear>2013</inceptionYear>
+	<contributors>
+		<contributor>
+			<name>Tom-Steve Watzke</name>
+			<email>ts.watzke@pitcom.de</email>
+			<roles>
+				<role>Project creator and Lead developer</role>
+			</roles>
+		</contributor>
+		<contributor>
+			<name>Dieter Hubau</name>
+			<email>dhubau@gmail.com</email>
+			<roles>
+				<role>Developer</role>
+			</roles>
+		</contributor>
+	</contributors>
+	<description>Thymeleaf dialect for formatting Joda Time objects</description>
+
+	<properties>
+		<java-version>1.7</java-version>
+		<org.springframework-version>3.2.4.RELEASE</org.springframework-version>
+		<org.springsecurityframework-version>3.2.4.RELEASE</org.springsecurityframework-version>
+		<org.thymeleaf-version>2.1.1.RELEASE</org.thymeleaf-version>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-beans</artifactId>
+			<version>${org.springframework-version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-webmvc</artifactId>
+			<version>${org.springframework-version}</version>
+		</dependency>
+
+		<!-- thymeleaf html5 template resolver -->
+		<dependency>
+			<groupId>org.thymeleaf</groupId>
+			<artifactId>thymeleaf</artifactId>
+			<version>${org.thymeleaf-version}</version>
+			<type>jar</type>
+			<scope>compile</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.thymeleaf</groupId>
+			<artifactId>thymeleaf-spring3</artifactId>
+			<version>${org.thymeleaf-version}</version>
+			<type>jar</type>
+			<scope>compile</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>joda-time</groupId>
+			<artifactId>joda-time</artifactId>
+			<version>2.1</version>
+			<type>jar</type>
+			<scope>compile</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>javax.servlet</groupId>
+			<artifactId>servlet-api</artifactId>
+			<version>2.5</version>
+			<scope>provided</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-test</artifactId>
+			<version>${org.springframework-version}</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.8.1</version>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.tomcat.maven</groupId>
+				<artifactId>tomcat7-maven-plugin</artifactId>
+				<version>2.0</version>
+				<executions>
+					<execution>
+						<id>deploy</id>
+						<phase>pre-integration-test</phase>
+						<goals>
+							<goal>deploy</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<version>2.3.2</version>
+				<configuration>
+					<source>${java-version}</source>
+					<target>${java-version}</target>
+					<compilerArgument>-Xlint:all</compilerArgument>
+					<showWarnings>true</showWarnings>
+					<showDeprecation>true</showDeprecation>
+					<failOnMissingWebXml>false</failOnMissingWebXml>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
+	<repositories>
+		<!-- Necessary if using milestone builds of SpringSource products (as above) -->
+		<repository>
+			<id>spring-snapshot</id>
+			<name>Spring Maven SNAPSHOT Repository</name>
+			<url>http://repo.springsource.org/libs-snapshot</url>
+		</repository>
+		<!-- Required, as Spring JavaConfig has dependencies on released versions 
+			of SpringSource products -->
+		<repository>
+			<id>SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases</id>
+			<url>http://repository.springsource.com/maven/bundles/release</url>
+		</repository>
+		<!-- Required, as Spring JavaConfig has dependencies on External OSGi bundles -->
+		<repository>
+			<id>SpringSource Enterprise Bundle Repository - External Bundle Releases</id>
+			<url>http://repository.springsource.com/maven/bundles/external</url>
+		</repository>
+		<repository>
+			<id>java.net</id>
+			<url>http://download.java.net/maven/2/</url>
+		</repository>
+	</repositories>
+</project>
--- a/server/pom.xml	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/pom.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -4,23 +4,42 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>org.iri_research.renkan</groupId>
     <artifactId>renkan</artifactId>
-    <version>0.7.2</version>
+    <version>0.7.3</version>
     <packaging>war</packaging>
 
     <properties>
-        <surefire-version>2.14</surefire-version>
-        <coweb-version>1.0</coweb-version>
+        <surefire-version>2.16</surefire-version>
+        <coweb-version>1.0.1-SNAPSHOT</coweb-version>
         <cowebx-version>1.0</cowebx-version>
-        <jersey-version>1.17.1</jersey-version>
-        <spring-version>3.2.1.RELEASE</spring-version>
-        <spring-security-version>3.1.3.RELEASE</spring-security-version>
-        <jetty-version>8.1.10.v20130312</jetty-version>
-        <junit-version>4.10</junit-version>
-        <thymeleaf-version>2.0.16</thymeleaf-version>
-        <thymeleaf-springsecurity-version>2.0.0</thymeleaf-springsecurity-version>
-        <cometd-version>2.5.1</cometd-version>
-        <jackson-version>2.1.4</jackson-version>
-        <joda-version>2.1</joda-version>
+        <jersey-version>2.3.1</jersey-version>
+        <spring-version>3.2.4.RELEASE</spring-version>
+        <spring-data-mongodb-version>1.3.1.RELEASE</spring-data-mongodb-version>
+        <spring-security-version>3.1.4.RELEASE</spring-security-version>
+        <spring-data-commons-version>1.6.1.RELEASE</spring-data-commons-version>
+        <spring-data-jpa-version>1.4.1.RELEASE</spring-data-jpa-version>
+        <jetty-plugin-version>8.1.13.v20130916</jetty-plugin-version>
+        <jetty-version>8.1.13.v20130916</jetty-version>
+        <junit-version>4.11</junit-version>
+        <thymeleaf-version>2.1.1.RELEASE</thymeleaf-version>
+        <thymeleaf-springsecurity-version>2.1.0.RELEASE</thymeleaf-springsecurity-version>
+        <thymeleaf-joda-dialect-version>0.0.3</thymeleaf-joda-dialect-version>
+        <cometd-version>2.7.0</cometd-version>
+        <jackson-version>2.2.3</jackson-version>
+        <joda-version>2.3</joda-version>
+        <mongo-driver-version>2.11.3</mongo-driver-version>
+        <jaxrs-api-version>2.0</jaxrs-api-version>
+        <javax-annotation-version>1.2</javax-annotation-version>
+        <javax-inject-version>1</javax-inject-version>
+        <javax-servlet-api-version>3.0.1</javax-servlet-api-version>
+        <javax-servlet-jstl-version>1.2</javax-servlet-jstl-version>
+        <javax-persistence-api-version>1.0.2</javax-persistence-api-version>
+        <javax-validation-api-version>1.1.0.Final</javax-validation-api-version>
+        <hibernate-validator-version>5.0.1.Final</hibernate-validator-version>
+        <slf4j-log4j12-version>1.7.5</slf4j-log4j12-version>
+        <nekohtml-version>1.9.19</nekohtml-version>
+        <commons-codec-version>1.8</commons-codec-version>
+        <bson4jackson-version>2.2.3</bson4jackson-version>
+        <fasterxml-java-uuid-generator-version>3.1.3</fasterxml-java-uuid-generator-version>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     </properties>
 
@@ -30,17 +49,20 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-compiler-plugin</artifactId>
-                <version>3.0</version>
+                <version>3.1</version>
                 <configuration>
                     <source>1.7</source>
                     <target>1.7</target>
+                    <compilerArgs>
+                        <arg>-Xlint</arg>
+                    </compilerArgs>
                 </configuration>
             </plugin>
 
             <plugin>
                 <groupId>org.mortbay.jetty</groupId>
                 <artifactId>jetty-maven-plugin</artifactId>
-                <version>${jetty-version}</version>
+                <version>${jetty-plugin-version}</version>
                 <configuration>
                     <scanIntervalSeconds>10</scanIntervalSeconds>
                     <webApp>
@@ -53,7 +75,7 @@
                 <artifactId>maven-war-plugin</artifactId>
                 <version>2.3</version>
                 <configuration>
-                    <archive>                   
+                    <archive>
                         <manifest>
                             <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
                             <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
@@ -125,10 +147,24 @@
 	          <artifactId>maven-surefire-plugin</artifactId>
 	          <version>${surefire-version}</version>
 	        </plugin>
+	        <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>2.4</version>
+            </plugin>
         </plugins>
     </build>
     <repositories>
         <repository>
+            <id>lib</id>
+            <name>lib</name>
+            <releases>
+                <enabled>true</enabled>
+                <checksumPolicy>ignore</checksumPolicy>
+            </releases>
+            <url>file://${project.basedir}/lib</url>
+        </repository>
+        <repository>
             <id>spring-maven-release</id>
             <name>Spring Maven Release Repository</name>
             <url>http://maven.springframework.org/release</url>
@@ -142,24 +178,39 @@
             <id>spring-release</id>
             <name>Spring Maven SNAPSHOT Repository</name>
             <url>http://repo.springsource.org/release</url>
-        </repository>        
+        </repository>
     </repositories>
     <dependencies>
         <dependency>  
             <groupId>javax.inject</groupId>  
             <artifactId>javax.inject</artifactId>  
-            <version>1</version>  
+            <version>${javax-inject-version}</version>  
         </dependency>
         <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>javax.servlet-api</artifactId>
-            <version>3.0.1</version>
+            <version>${javax-servlet-api-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.ws.rs</groupId>
+            <artifactId>javax.ws.rs-api</artifactId>
+            <version>${jaxrs-api-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+            <version>${javax-annotation-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.cometd.java</groupId>
+            <artifactId>bayeux-api</artifactId>
+            <version>${cometd-version}</version>
         </dependency>
         <dependency>
             <groupId>org.cometd.java</groupId>
             <artifactId>cometd-java-common</artifactId>
             <version>${cometd-version}</version>
-        </dependency>        
+        </dependency>
         <dependency>
             <groupId>org.cometd.java</groupId>
             <artifactId>cometd-java-annotations</artifactId>
@@ -169,7 +220,7 @@
             <groupId>org.cometd.java</groupId>
             <artifactId>cometd-websocket-jetty</artifactId>
             <version>${cometd-version}</version>
-        </dependency>        
+        </dependency>
         <dependency>
             <groupId>org.opencoweb</groupId>
             <artifactId>coweb-bots</artifactId>
@@ -193,57 +244,35 @@
             <type>war</type>
         </dependency>
         <dependency>
-        	<groupId>com.sun.jersey</groupId>
-        	<artifactId>jersey-server</artifactId>
-        	<version>${jersey-version}</version>
+            <groupId>org.glassfish.jersey.core</groupId>
+            <artifactId>jersey-server</artifactId>
+            <version>${jersey-version}</version>
         </dependency>
+        <!--dependency>
+            <groupId>org.glassfish.jersey.media</groupId>
+            <artifactId>jersey-media-json-jackson</artifactId>
+            <version>${jersey-version}</version>
+        </dependency-->
         <dependency>
-            <groupId>com.sun.jersey</groupId>
-            <artifactId>jersey-json</artifactId>
+            <groupId>org.glassfish.jersey.ext</groupId>
+            <artifactId>jersey-spring3</artifactId>
             <version>${jersey-version}</version>
         </dependency>
         <dependency>
-            <groupId>com.sun.jersey.contribs</groupId>
-            <artifactId>jersey-spring</artifactId>
+            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+            <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
             <version>${jersey-version}</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.springframework</groupId>
-                    <artifactId>spring-context</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>org.springframework</groupId>
-                    <artifactId>spring-beans</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>org.springframework</groupId>
-                    <artifactId>spring-core</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>org.springframework</groupId>
-                    <artifactId>spring-web</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>org.springframework</groupId>
-                    <artifactId>spring-aop</artifactId>
-                </exclusion>
-            </exclusions>
+            <scope>test</scope>
         </dependency>
-		<dependency>
-		    <groupId>com.sun.jersey.jersey-test-framework</groupId>
-		    <artifactId>jersey-test-framework-grizzly2</artifactId>
-		    <version>${jersey-version}</version>
-		    <scope>test</scope>
-		</dependency>
         <dependency>
             <groupId>org.mongodb</groupId>
             <artifactId>mongo-java-driver</artifactId>
-            <version>2.10.1</version>
+            <version>${mongo-driver-version}</version>
         </dependency>
         <dependency> 
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-log4j12</artifactId>
-            <version>1.7.2</version>
+            <version>${slf4j-log4j12-version}</version>
         </dependency>
         <dependency>
             <groupId>org.springframework</groupId>
@@ -259,13 +288,13 @@
             <groupId>org.springframework</groupId>
             <artifactId>spring-web</artifactId>
             <version>${spring-version}</version>
-        </dependency>        
+        </dependency>
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-test</artifactId>
             <version>${spring-version}</version>
             <scope>test</scope>
-        </dependency>        
+        </dependency>
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-webmvc</artifactId>
@@ -274,33 +303,33 @@
         <dependency>
             <groupId>org.springframework.data</groupId>
             <artifactId>spring-data-commons</artifactId>
-            <version>1.5.0.RELEASE</version>
+            <version>${spring-data-commons-version}</version>
         </dependency>
         <dependency>
             <groupId>org.springframework.data</groupId>
             <artifactId>spring-data-jpa</artifactId>
-            <version>1.3.0.RELEASE</version>
+            <version>${spring-data-jpa-version}</version>
         </dependency> 
         <dependency>
             <groupId>org.springframework.data</groupId>
             <artifactId>spring-data-mongodb</artifactId>
-            <version>1.2.0.RELEASE</version>
+            <version>${spring-data-mongodb-version}</version>
         </dependency>
         <dependency>
             <groupId>javax.persistence</groupId>
             <artifactId>persistence-api</artifactId>  
-            <version>1.0.2</version>
+            <version>${javax-persistence-api-version}</version>
         </dependency>
-        <dependency>                          
-            <groupId>junit</groupId>           
-            <artifactId>junit</artifactId>     
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
             <version>${junit-version}</version>
-            <scope>test</scope>                
+            <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>jstl</artifactId>
-            <version>1.2</version>
+            <version>${javax-servlet-jstl-version}</version>
             <scope>runtime</scope>
         </dependency>
         <dependency>
@@ -319,9 +348,29 @@
             <version>${thymeleaf-springsecurity-version}</version>
         </dependency>
         <dependency>
+            <groupId>org.thymeleaf.extras</groupId>
+            <artifactId>thymeleaf-joda-dialect</artifactId>
+            <version>${thymeleaf-joda-dialect-version}</version>
+        </dependency>
+        <dependency>
             <groupId>net.sourceforge.nekohtml</groupId>
             <artifactId>nekohtml</artifactId>
-            <version>1.9.16</version>
+            <version>${nekohtml-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+            <version>${jackson-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>${jackson-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+            <version>${jackson-version}</version>
         </dependency>
         <dependency>
             <groupId>com.fasterxml.jackson.jaxrs</groupId>
@@ -329,38 +378,18 @@
             <version>${jackson-version}</version>
         </dependency>
         <dependency>
+            <groupId>com.fasterxml.jackson.datatype</groupId>
+            <artifactId>jackson-datatype-joda</artifactId>
+            <version>${jackson-version}</version>
+        </dependency>  
+        <dependency>
             <groupId>commons-codec</groupId>
             <artifactId>commons-codec</artifactId>
-            <version>1.7</version>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-server</artifactId>
-            <version>${jetty-version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-client</artifactId>
-            <version>${jetty-version}</version>
+            <version>${commons-codec-version}</version>
         </dependency>
         <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-websocket</artifactId>
-            <version>${jetty-version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-jmx</artifactId>
-            <version>${jetty-version}</version>
-        </dependency>        
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-util</artifactId>
-            <version>${jetty-version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.jetty</groupId>
-            <artifactId>jetty-servlets</artifactId>
+            <groupId>org.eclipse.jetty.aggregate</groupId>
+            <artifactId>jetty-all</artifactId>
             <version>${jetty-version}</version>
         </dependency>
         <dependency>
@@ -391,7 +420,7 @@
         <dependency>
 	       <groupId>de.undercouch</groupId>
 	       <artifactId>bson4jackson</artifactId>
-	       <version>2.1.1</version>
+	       <version>${bson4jackson-version}</version>
         </dependency>
         <dependency>
             <groupId>joda-time</groupId>
@@ -401,21 +430,26 @@
         <dependency>
             <groupId>javax.validation</groupId>
             <artifactId>validation-api</artifactId>
-            <version>1.1.0.CR2</version>
+            <version>${javax-validation-api-version}</version>
         </dependency>        
         <dependency>
             <groupId>org.hibernate</groupId>
             <artifactId>hibernate-validator</artifactId>
-            <version>4.2.0.Final</version>
+            <version>${hibernate-validator-version}</version>
         </dependency>
         <dependency>
             <groupId>com.fasterxml.uuid</groupId>
             <artifactId>java-uuid-generator</artifactId>
-            <version>3.1.3</version>
+            <version>${fasterxml-java-uuid-generator-version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-collections4</artifactId>
+            <version>4.0</version>
         </dependency>
     </dependencies>
     <organization>
-    	<name>IRI</name>
-    	<url>http://www.iri.centrepompidou.fr</url>
+        <name>IRI</name>
+        <url>http://www.iri.centrepompidou.fr</url>
     </organization>
 </project>
--- a/server/src/main/java/org/iri_research/renkan/Constants.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/Constants.java	Wed Jan 15 18:36:27 2014 +0100
@@ -10,70 +10,94 @@
 
 public class Constants {
 
-	
-	static {
-		
-	}
-	
-	public final static List<String> VERSION = Collections.unmodifiableList(new ArrayList<String>() {
-		private static final long serialVersionUID = -6935554100028328149L;
-		{
-			add("0");
-			add("7");
-			add("2");
-			add("final");
-			add("0");
-		}
-	});
-		
-	public static String getVersion() {
-		
-		String[] version_array = VERSION.toArray(new String[VERSION.size()]);
-		
-	    String version = String.format("%s.%s",version_array[0], version_array[1]);
-	    if(version_array[2] != null && !version_array[2].isEmpty() &&  Integer.parseInt(version_array[2]) > 0 ) {
-	    	version = String.format("%s.%s", version, version_array[2]);
-	    }
-	    if (version_array[3] == "alpha" && version_array[4] == "0") {
-	    	version = String.format("%s pre-alpha",version);
-	    }
-	    else if(version_array[3] != "final") {
-	        version = String.format("%s %s %s", version, version_array[3], version_array[4]);
-	    }
-	    return version;
+    static {
+
+    }
+
+    public final static List<String> VERSION = Collections
+            .unmodifiableList(new ArrayList<String>() {
+                private static final long serialVersionUID = -6935554100028328149L;
+                {
+                    add("0");
+                    add("7");
+                    add("3");
+                    add("alpha");
+                    add("1");
+                }
+            });
+
+    public static String getVersion() {
+
+        String[] version_array = VERSION.toArray(new String[VERSION.size()]);
+
+        String version = String.format("%s.%s", version_array[0],
+                version_array[1]);
+        if (version_array[2] != null && !version_array[2].isEmpty()
+                && Integer.parseInt(version_array[2]) > 0) {
+            version = String.format("%s.%s", version, version_array[2]);
+        }
+        if (version_array[3] == "alpha" && version_array[4] == "0") {
+            version = String.format("%s pre-alpha", version);
+        } else if (version_array[3] != "final") {
+            version = String.format("%s %s %s", version, version_array[3],
+                    version_array[4]);
+        }
+        return version;
+
+    }
+
+    public final static String KEYHEX = "f2338d2299ac28ef64f82956fde37337b87a2b9e8fc03e28fa0768cac37d838113c7d0fc78c60fce1e23b1b3e03ac7db4676b3189c267f26baaab10f72544441";
+    public final static int SALT_LENGTH = 24;
+    public final static int PAGINATION_SIZE = 10;
+    public final static String PROPERTIES_SERVLET_CONTEXT_NAME = "renkan.properties";
+    public final static String PROPERTIES_CLASSPATH_NAME = "renkan_run.properties";
+    public final static String ANONYMOUS_USER_BASE_NAME = "Anonymous";
 
-	}
-	
-	public final static String KEYHEX = "f2338d2299ac28ef64f82956fde37337b87a2b9e8fc03e28fa0768cac37d838113c7d0fc78c60fce1e23b1b3e03ac7db4676b3189c267f26baaab10f72544441";
-	public final static int SALT_LENGTH = 24;
-	public final static int PAGINATION_SIZE = 10;
-	public final static String PROPERTIES_SERVLET_CONTEXT_NAME = "renkan.properties";
-	public final static String PROPERTIES_CLASSPATH_NAME = "renkan_run.properties";
-	
-	private final static EthernetAddress ETHERNET_ADRESS = EthernetAddress.fromInterface(); 
-	public final static NoArgGenerator UUID_GENERATOR = Generators.timeBasedGenerator(ETHERNET_ADRESS);
+    private final static EthernetAddress ETHERNET_ADRESS = EthernetAddress
+            .fromInterface();
+    public final static NoArgGenerator UUID_GENERATOR = Generators
+            .timeBasedGenerator(ETHERNET_ADRESS);
+
+    public enum EditMode {
+        READ_ONLY(1), EDITION(2);
+
+        private int value;
+
+        private final static EditMode[] editModeValues = EditMode.values();
+
+        private EditMode(int i) {
+            this.value = i;
+        }
 
-	public enum EditMode {
-		READ_ONLY(1),		
-		EDITION(2);
-		
-		private int value;
-		
-		private final static EditMode[] editModeValues = EditMode.values();
-		
-		private EditMode(int i) {
-			this.value = i;
-		}
-		
-		public static EditMode fromInt(int val) {
-			for(int i=0; i < editModeValues.length; i++) {
-				if(editModeValues[i].value == val)
-				{
-					return editModeValues[i];
-				}
-			}
-			return null;
-		}
-	}
+        public static EditMode fromInt(int val) {
+            for (int i = 0; i < editModeValues.length; i++) {
+                if (editModeValues[i].value == val) {
+                    return editModeValues[i];
+                }
+            }
+            return null;
+        }
+    }
+
 
+    public final static String ROLE_USER = "ROLE_USER";
+    
+    public final static List<String> USER_ROLES_SELECT = Collections
+            .unmodifiableList(new ArrayList<String>() {
+                private static final long serialVersionUID = -3041530185134732199L;
+                {
+                    add("ROLE_ADMIN");
+                    add("ROLE_SPACES_ADMIN");
+                    add("ROLE_GROUPS_ADMIN");
+                }
+            });
+
+    public final static List<String> USER_ROLES_ALL = Collections
+            .unmodifiableList(new ArrayList<String>() {
+                private static final long serialVersionUID = -3041530185134732199L;
+                {
+                    add(ROLE_USER);
+                    addAll(USER_ROLES_SELECT);
+                }
+            });
 }
--- a/server/src/main/java/org/iri_research/renkan/RenkanException.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/RenkanException.java	Wed Jan 15 18:36:27 2014 +0100
@@ -2,24 +2,24 @@
 
 public class RenkanException extends Exception {
 
-	/**
+    /**
 	 * 
 	 */
-	private static final long serialVersionUID = -6952770322990047437L;
+    private static final long serialVersionUID = -6952770322990047437L;
 
-	public RenkanException() {
-	}
+    public RenkanException() {
+    }
 
-	public RenkanException(String message) {
-		super(message);
-	}
+    public RenkanException(String message) {
+        super(message);
+    }
 
-	public RenkanException(Throwable exc) {
-		super(exc);
-	}
+    public RenkanException(Throwable exc) {
+        super(exc);
+    }
 
-	public RenkanException(String message, Throwable exc) {
-		super(message, exc);
-	}
+    public RenkanException(String message, Throwable exc) {
+        super(message, exc);
+    }
 
 }
--- a/server/src/main/java/org/iri_research/renkan/RenkanProperties.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/RenkanProperties.java	Wed Jan 15 18:36:27 2014 +0100
@@ -11,35 +11,37 @@
 @Named
 public class RenkanProperties {
 
-	@Resource(name="renkanProperties")
-	private Properties properties;
-	
-	private final Logger logger = LoggerFactory.getLogger(RenkanProperties.class);
-	
+    @Resource(name = "renkanProperties")
+    private Properties properties;
+
+    private final Logger logger = LoggerFactory
+            .getLogger(RenkanProperties.class);
+
     private static volatile RenkanProperties instance = null;
-    
-    private RenkanProperties() 
-    {
-    	this.logger.debug("Building RenkanProperties");    	
+
+    private RenkanProperties() {
+        this.logger.debug("Building RenkanProperties");
     }
-    
+
     public static RenkanProperties getInstance() {
-    	if (instance == null) {
-    		synchronized (RenkanProperties.class) {
-				if(instance == null) {
-					instance = new RenkanProperties();
-				}
-			}
-    	}
-    	return instance;
+        if (instance == null) {
+            synchronized (RenkanProperties.class) {
+                if (instance == null) {
+                    instance = new RenkanProperties();
+                }
+            }
+        }
+        return instance;
     }
-	
-	public int getPaginationSize() {
-		return Integer.parseInt(properties.getProperty("renkan.pagination.size", Integer.toString(Constants.PAGINATION_SIZE)));		
-	}
 
-	public String getProperty(String name, String defaultVal) {
-		return properties.getProperty(name, defaultVal);
-	}
-	
+    public int getPaginationSize() {
+        return Integer.parseInt(properties.getProperty(
+                "renkan.pagination.size",
+                Integer.toString(Constants.PAGINATION_SIZE)));
+    }
+
+    public String getProperty(String name, String defaultVal) {
+        return properties.getProperty(name, defaultVal);
+    }
+
 }
--- a/server/src/main/java/org/iri_research/renkan/RenkanRuntimeException.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/RenkanRuntimeException.java	Wed Jan 15 18:36:27 2014 +0100
@@ -2,25 +2,24 @@
 
 public class RenkanRuntimeException extends RuntimeException {
 
-
-	/**
+    /**
 	 * 
 	 */
-	private static final long serialVersionUID = 736470650035855769L;
+    private static final long serialVersionUID = 736470650035855769L;
 
-	public RenkanRuntimeException() {
-	}
+    public RenkanRuntimeException() {
+    }
 
-	public RenkanRuntimeException(String message) {
-		super(message);
-	}
+    public RenkanRuntimeException(String message) {
+        super(message);
+    }
 
-	public RenkanRuntimeException(Throwable exc) {
-		super(exc);
-	}
+    public RenkanRuntimeException(Throwable exc) {
+        super(exc);
+    }
 
-	public RenkanRuntimeException(String message, Throwable exc) {
-		super(message, exc);
-	}
+    public RenkanRuntimeException(String message, Throwable exc) {
+        super(message, exc);
+    }
 
 }
--- a/server/src/main/java/org/iri_research/renkan/controller/AdminController.java	Fri Oct 25 16:42:11 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-package org.iri_research.renkan.controller;
-
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.Arrays;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.validation.Valid;
-
-import org.apache.commons.codec.binary.Hex;
-import org.iri_research.renkan.Constants;
-import org.iri_research.renkan.RenkanException;
-import org.iri_research.renkan.forms.SpaceForm;
-import org.iri_research.renkan.forms.SpaceFormValidator;
-import org.iri_research.renkan.models.Space;
-import org.iri_research.renkan.repositories.ProjectsRepository;
-import org.iri_research.renkan.repositories.SpacesRepository;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort.Direction;
-import org.springframework.data.web.PageableDefaults;
-import org.springframework.http.HttpStatus;
-import org.springframework.stereotype.Controller;
-import org.springframework.ui.Model;
-import org.springframework.validation.BindingResult;
-import org.springframework.web.bind.WebDataBinder;
-import org.springframework.web.bind.annotation.InitBinder;
-import org.springframework.web.bind.annotation.ModelAttribute;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.client.HttpClientErrorException;
-
-@Controller
-@RequestMapping("/admin")
-public class AdminController {
-
-	private final Logger logger = LoggerFactory.getLogger(AdminController.class);
-	
-	@Autowired
-	private SpacesRepository spacesRepository;
-	@Autowired
-	private ProjectsRepository projectsRepository;
-	
-    @InitBinder(value={"space"})
-    protected void initBinder(WebDataBinder binder) {
-        binder.setValidator(new SpaceFormValidator());
-    }
-	
-	@RequestMapping(value="", method = RequestMethod.GET, produces={"text/html;charset=UTF-8"})
-	public String adminIndex() {
-				
-		return "admin/adminIndex";
-	}
-	
-	@RequestMapping(value="/spaces", method = RequestMethod.GET, produces={"text/html;charset=UTF-8"})
-	public String spacesList(
-			Model model,
-			@PageableDefaults(sort={"created"}, sortDir=Direction.DESC, pageNumber=0, value=Constants.PAGINATION_SIZE) Pageable p,
-			HttpServletRequest request) {
-		
-		Page<Space> page = this.spacesRepository.findAll(p);
-		
-		model.addAttribute("page", page);
-		model.addAttribute("baseUrl", Utils.buildBaseUrl(request));
-		model.addAttribute("projectsCount", this.projectsRepository.getCountBySpace());
-		
-		return "admin/spacesList";
-	}
-	
-	@RequestMapping(value="/spaces/edit/", method = RequestMethod.GET, produces={"text/html;charset=UTF-8"})
-	public String editSpace(Model model) {
-		return editSpace(model, null);
-	}
-	
-	@RequestMapping(value="/spaces/edit/{spaceId}", method = RequestMethod.GET, produces={"text/html;charset=UTF-8"})
-	public String editSpace(Model model, @PathVariable(value="spaceId") String spaceId) {
-		
-		SpaceForm spaceForm = null;
-		
-		if(spaceId == null || spaceId.length() == 0 || "_".equals(spaceId)) {
-			spaceForm = new SpaceForm();
-		}
-		else {
-			Space space = this.spacesRepository.findOne(spaceId);		
-			if(space == null) {
-				throw new HttpClientErrorException(HttpStatus.NOT_FOUND, "space " + spaceId + " not found");			
-			}
-			spaceForm = new SpaceForm(space);
-		}
-		
-		model.addAttribute("space", spaceForm);
-		
-		return "admin/spaceEdit";
-	}
-	
-	
-	@RequestMapping(value="/spaces/save", method = RequestMethod.POST)
-	public String saveSpace(Model model, @ModelAttribute("space") @Valid SpaceForm spaceForm, BindingResult bindingResult) {
-
-		logger.debug("space title " + spaceForm.getTitle());
-		logger.debug("space description " + spaceForm.getDescription());
-		
-		if(bindingResult.hasErrors()) {
-			return "admin/spaceEdit";
-		}
-		
-		spaceForm.setSpacesRepository(spacesRepository);
-		
-		try {
-			spaceForm.save();
-		} catch (RenkanException e) {
-			throw new HttpClientErrorException(HttpStatus.NOT_FOUND, "space " + spaceForm.getId() + " not found");
-		}
-		
-		return "redirect:/admin/spaces";
-	}
-	
-	//@RequestMapping(value="/spaces/confirmdelete/{spaceId}", method = RequestMethod.GET)
-	//public String askDeleteSpace(Model model, @PathVariable(value="spaceId") String spaceId) {
-		
-		
-	//}
-	
-	@RequestMapping(value="/spaces/delete/{spaceId}")
-	public String deleteSpace(
-			HttpServletRequest request,
-			Model model,
-			@PathVariable(value="spaceId") String spaceId,
-			@RequestParam(value="key", required=false) String key,
-			@RequestParam(value="salt", required=false) String salt) throws NoSuchAlgorithmException, RenkanException
-	{
-
-		if(spaceId == null || spaceId.length() == 0) {
-			throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Null or empty space id");
-		}
-		
-		RequestMethod method = RequestMethod.valueOf(request.getMethod());
-		
-		Map<String, Integer> nbProj = this.projectsRepository.getCountBySpace(Arrays.asList(spaceId));
-		if(nbProj.containsKey(spaceId) && nbProj.get(spaceId).intValue()>0) {
-			throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "This space have projects");
-		}
-		
-		if(RequestMethod.GET.equals(method)) {
-
-			Space space = this.spacesRepository.findOne(spaceId);
-			
-			if(space == null) {
-				throw new HttpClientErrorException(HttpStatus.NOT_FOUND, "space " + spaceId + " not found");
-			}
-			
-			SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
-			rand.setSeed(System.currentTimeMillis());
-			byte[] rawSalt = new byte[50];
-			rand.nextBytes(rawSalt);
-			String newSalt = Hex.encodeHexString(rawSalt);
-						
-			
-			model.addAttribute("spaceObj", space);
-			model.addAttribute("salt", newSalt);
-			model.addAttribute("key", space.getKey(newSalt));
-						
-			return "admin/spaceDeleteConfirm";
-		}
-		else if (RequestMethod.POST.equals(method) && key != null && !key.isEmpty() && salt != null && !salt.isEmpty()) {
-						
-			if(spaceId != null && spaceId.length() > 0) {
-				
-				Space space = this.spacesRepository.findOne(spaceId);
-				if(space != null) {
-					if(space.checkKey(key, salt)) {
-						this.spacesRepository.delete(spaceId);
-					}
-					else {
-						throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Key not ckecked");
-					}
-				}
-				
-			}
-			return "redirect:/admin/spaces";
-			
-		}
-		else {
-			throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Bad request method or parameters"); 
-		}
-		
-	}
-	
-}
--- a/server/src/main/java/org/iri_research/renkan/controller/AuthController.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/controller/AuthController.java	Wed Jan 15 18:36:27 2014 +0100
@@ -10,21 +10,20 @@
 @Controller
 @RequestMapping("/auth")
 public class AuthController {
-	
-	@SuppressWarnings("unused")
-	private final Logger logger = LoggerFactory.getLogger(AuthController.class);
-		
-	@RequestMapping(value="/login", method = RequestMethod.GET, produces={"text/html;charset=UTF-8"})
-	public String login() {
-		return "auth/login";
-	}
+
+    @SuppressWarnings("unused")
+    private final Logger logger = LoggerFactory.getLogger(AuthController.class);
+
+    @RequestMapping(value = "/login", method = RequestMethod.GET, produces = { "text/html;charset=UTF-8" })
+    public String login() {
+        return "auth/login";
+    }
 
-	@RequestMapping(value="/loginfailed", method = RequestMethod.GET, produces={"text/html;charset=UTF-8"})
-	public String loginFailed(Model model) {
-		
-		model.addAttribute("login_error", true);		
-		return "auth/login";
-	}
+    @RequestMapping(value = "/loginfailed", method = RequestMethod.GET, produces = { "text/html;charset=UTF-8" })
+    public String loginFailed(Model model) {
 
-	
+        model.addAttribute("login_error", true);
+        return "auth/login";
+    }
+
 }
--- a/server/src/main/java/org/iri_research/renkan/controller/RenkanController.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/controller/RenkanController.java	Wed Jan 15 18:36:27 2014 +0100
@@ -27,104 +27,116 @@
 import org.springframework.web.client.HttpServerErrorException;
 import org.springframework.web.servlet.ModelAndView;
 
-
 @Controller
 @RequestMapping("/p")
 public class RenkanController {
 
-	private final Logger logger = LoggerFactory.getLogger(RenkanController.class);
-		
-	@Autowired
-	private ProjectsRepository projectsRepository;
-	
-	@Autowired
-	private SpacesRepository spacesRepository;
-	
-	private void checkCowebkey(String cowebkey, Project project, Constants.EditMode editMode) {
-		if(cowebkey == null || cowebkey.isEmpty()) {
-			throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Cowebkey missing");
-		}
-		try {
-			if(!project.checkKey(cowebkey, editMode)) {
-				throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Bad cowebkey");
-			}
-		} catch (RenkanException e) {
-			throw new HttpServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage());
-		}
-	}
-	
-	@RequestMapping(value="/copy", method = RequestMethod.POST, produces={"application/json;charset=UTF-8"})
-	public @ResponseBody Project copyProject(@RequestParam(value="project_id") String projectId ) {
-				
-		if(projectId == null || projectId.length() == 0) {
-			throw new IllegalArgumentException("RenkanContoller.renkanProject.copyProject: Project id is null or empty.");
-		}
-		Project project = this.projectsRepository.findOne(projectId);
-		if(project == null) {
-			throw new HttpClientErrorException(HttpStatus.NOT_FOUND, "Project " + projectId + " not found for copyProject.");
-		}
+    private final Logger logger = LoggerFactory
+            .getLogger(RenkanController.class);
+
+    @Autowired
+    private ProjectsRepository projectsRepository;
+
+    @Autowired
+    private SpacesRepository spacesRepository;
+
+    private void checkCowebkey(String cowebkey, Project project,
+            Constants.EditMode editMode) {
+        if (cowebkey == null || cowebkey.isEmpty()) {
+            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST,
+                    "Cowebkey missing");
+        }
+        try {
+            if (!project.checkKey(cowebkey, editMode)) {
+                throw new HttpClientErrorException(HttpStatus.BAD_REQUEST,
+                        "Bad cowebkey");
+            }
+        } catch (RenkanException e) {
+            throw new HttpServerErrorException(
+                    HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage());
+        }
+    }
 
-		Project newProject = this.projectsRepository.copy(project, project.getTitle() + " (copy)");
-		
-		return newProject;
-	}
+    @RequestMapping(value = "/copy", method = RequestMethod.POST, produces = { "application/json;charset=UTF-8" })
+    public @ResponseBody
+    Project copyProject(@RequestParam(value = "project_id") String projectId) {
+
+        if (projectId == null || projectId.length() == 0) {
+            throw new IllegalArgumentException(
+                    "RenkanContoller.renkanProject.copyProject: Project id is null or empty.");
+        }
+        Project project = this.projectsRepository.findOne(projectId);
+        if (project == null) {
+            throw new HttpClientErrorException(HttpStatus.NOT_FOUND, "Project "
+                    + projectId + " not found for copyProject.");
+        }
 
-	 	
-	@RequestMapping(value="/{project_id}", method = RequestMethod.GET, produces={"text/html;charset=UTF-8", "!image/*"})
-	public ModelAndView renkanProject(
-			@PathVariable(value="project_id") String project_id,
-			@RequestHeader(value="Accept") String accept_header,
-			@RequestParam(value="cowebkey") String cowebkey
-			) throws HttpMediaTypeNotSupportedException
-	{
+        Project newProject = this.projectsRepository.copy(project,
+                project.getTitle() + " (copy)");
+
+        return newProject;
+    }
+
+    @RequestMapping(value = "/{project_id}", method = RequestMethod.GET, produces = {
+            "text/html;charset=UTF-8", "!image/*" })
+    public ModelAndView renkanProject(
+            @PathVariable(value = "project_id") String project_id,
+            @RequestHeader(value = "Accept") String accept_header,
+            @RequestParam(value = "cowebkey") String cowebkey)
+            throws HttpMediaTypeNotSupportedException {
 
-		this.logger.debug("renkanProject : " + project_id + " Accept : " + accept_header!=null?accept_header:"" + ", cowebkey: "+ cowebkey!=null?cowebkey:"");
-				
-		
-		if(project_id == null || project_id.length() == 0) {
-			throw new IllegalArgumentException("RenkanContoller.renkanProject: Project id is null or empty.");
-		}
-		
-		Project project = this.projectsRepository.findOne(project_id);
-		
-		if(project == null) {
-			throw new HttpClientErrorException(HttpStatus.NOT_FOUND, "Project " + project_id + " not found.");
-		}
-		
-		this.checkCowebkey(cowebkey, project, EditMode.EDITION);
-		
-		Map<String, Object> model = new HashMap<String, Object>();
-		model.put("coweb_debug", Boolean.parseBoolean(RenkanProperties.getInstance().getProperty("renkan.coweb.debug","false")));
-		model.put("coweb_websockets", Boolean.parseBoolean(RenkanProperties.getInstance().getProperty("renkan.coweb.websocket", "true")));
-		model.put("project", project);
-		model.put("space", spacesRepository.findOne(project.getSpaceId()));
-		
-		return new ModelAndView("renkanProjectEdit", model);
-	}
-	
-	@RequestMapping(value="/pub/{project_id}", method = RequestMethod.GET, produces={"text/html;charset=UTF-8", "!image/*"})
-	public String renkanPublishProject(
-			Model model,
-			@PathVariable(value="project_id") String project_id,
-			@RequestParam(value="cowebkey") String cowebkey
-			)
-	{
-		if(project_id == null || project_id.length() == 0) {
-			throw new IllegalArgumentException("RenkanContoller.renkanProject: Project id is null or empty.");
-		}
-		
-		Project project = this.projectsRepository.findOne(project_id);
-		if(project == null) {
-			throw new HttpClientErrorException(HttpStatus.NOT_FOUND, "Project " + project_id + " not found.");
-		}
+        this.logger.debug("renkanProject : " + project_id + " Accept : "
+                + accept_header != null ? accept_header : "" + ", cowebkey: "
+                + cowebkey != null ? cowebkey : "");
+
+        if (project_id == null || project_id.length() == 0) {
+            throw new IllegalArgumentException(
+                    "RenkanContoller.renkanProject: Project id is null or empty.");
+        }
+
+        Project project = this.projectsRepository.findOne(project_id);
+
+        if (project == null) {
+            throw new HttpClientErrorException(HttpStatus.NOT_FOUND, "Project "
+                    + project_id + " not found.");
+        }
+
+        this.checkCowebkey(cowebkey, project, EditMode.EDITION);
+
+        Map<String, Object> model = new HashMap<String, Object>();
+        model.put("coweb_debug", Boolean.parseBoolean(RenkanProperties
+                .getInstance().getProperty("renkan.coweb.debug", "false")));
+        model.put("coweb_websockets", Boolean.parseBoolean(RenkanProperties
+                .getInstance().getProperty("renkan.coweb.websocket", "true")));
+        model.put("project", project);
+        model.put("space", spacesRepository.findOne(project.getSpaceId()));
 
-		this.checkCowebkey(cowebkey, project, EditMode.READ_ONLY);
-		
-		model.addAttribute("project", project);
-		model.addAttribute("space", spacesRepository.findOne(project.getSpaceId()));
-		
-		return "renkanProjectPublish";
-	}
-	
-	
+        return new ModelAndView("renkanProjectEdit", model);
+    }
+
+    @RequestMapping(value = "/pub/{project_id}", method = RequestMethod.GET, produces = {
+            "text/html;charset=UTF-8", "!image/*" })
+    public String renkanPublishProject(Model model,
+            @PathVariable(value = "project_id") String project_id,
+            @RequestParam(value = "cowebkey") String cowebkey) {
+        if (project_id == null || project_id.length() == 0) {
+            throw new IllegalArgumentException(
+                    "RenkanContoller.renkanProject: Project id is null or empty.");
+        }
+
+        Project project = this.projectsRepository.findOne(project_id);
+        if (project == null) {
+            throw new HttpClientErrorException(HttpStatus.NOT_FOUND, "Project "
+                    + project_id + " not found.");
+        }
+
+        this.checkCowebkey(cowebkey, project, EditMode.READ_ONLY);
+
+        model.addAttribute("project", project);
+        model.addAttribute("space",
+                spacesRepository.findOne(project.getSpaceId()));
+
+        return "renkanProjectPublish";
+    }
+
 }
--- a/server/src/main/java/org/iri_research/renkan/controller/RenkanRootController.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/controller/RenkanRootController.java	Wed Jan 15 18:36:27 2014 +0100
@@ -16,7 +16,7 @@
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Sort.Direction;
-import org.springframework.data.web.PageableDefaults;
+import org.springframework.data.web.PageableDefault;
 import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Controller;
 import org.springframework.ui.Model;
@@ -27,62 +27,70 @@
 import org.springframework.web.client.HttpClientErrorException;
 import org.springframework.web.servlet.ModelAndView;
 
-
 @Controller
 @RequestMapping("/")
 public class RenkanRootController {
 
-	private final Logger logger = LoggerFactory.getLogger(RenkanRootController.class);
-		
-	@Autowired
-	private ProjectsRepository projectsRepository;
-	
-	@Autowired
-	private SpacesRepository spacesRepository;
-		
-	@RequestMapping(value="", method = RequestMethod.GET, produces={"text/html;charset=UTF-8"})
-	public String renkanIndex(Model model, @PageableDefaults(sort={"created"}, sortDir=Direction.DESC, pageNumber=0, value=Constants.PAGINATION_SIZE) Pageable p, HttpServletRequest request) {
+    private final Logger logger = LoggerFactory
+            .getLogger(RenkanRootController.class);
+
+    @Autowired
+    private ProjectsRepository projectsRepository;
+
+    @Autowired
+    private SpacesRepository spacesRepository;
+
+    @RequestMapping(value = "", method = RequestMethod.GET, produces = { "text/html;charset=UTF-8" })
+    public String renkanIndex(
+            Model model,
+            @PageableDefault(sort = { "created" }, direction = Direction.DESC, page = 0, value = Constants.PAGINATION_SIZE) Pageable p,
+            HttpServletRequest request) {
 
-		Page<Space> page = this.spacesRepository.findAll(p);
-				
-		model.addAttribute("page", page);
-		model.addAttribute("baseUrl", Utils.buildBaseUrl(request));
-		model.addAttribute("projectsCount", this.projectsRepository.getCountBySpace());
-		
-		return "renkanIndex";
-	}
+        Page<Space> page = this.spacesRepository.findAll(p);
+
+        model.addAttribute("page", page);
+        model.addAttribute("baseUrl", Utils.buildBaseUrl(request));
+        model.addAttribute("projectsCount",
+                this.projectsRepository.getCountBySpace());
 
-	@RequestMapping(value="/s/{space_id}", method = RequestMethod.GET, produces={"text/html;charset=UTF-8"})
-	public ModelAndView spaceIndex(@PathVariable("space_id") String spaceId, @RequestParam(required=false) String filter, @PageableDefaults(sort={"updated","created"}, sortDir=Direction.DESC, pageNumber=0, value=Constants.PAGINATION_SIZE) Pageable p, HttpServletRequest request) {
-		
-		logger.debug("SpaceId : " + (spaceId== null ? "null" : spaceId));
-		
-		Map<String, Object> model = new HashMap<String, Object>();
+        return "renkanIndex";
+    }
+
+    @RequestMapping(value = "/s/{space_id}", method = RequestMethod.GET, produces = { "text/html;charset=UTF-8" })
+    public ModelAndView spaceIndex(
+            @PathVariable("space_id") String spaceId,
+            @RequestParam(required = false) String filter,
+            @PageableDefault(sort = { "updated", "created" }, direction = Direction.DESC, page = 0, value = Constants.PAGINATION_SIZE) Pageable p,
+            HttpServletRequest request) {
 
-		if("_".equals(spaceId)) {
-			spaceId = null;
-		}
-		
-		Space space = this.spacesRepository.findOne(spaceId);
-		
-		if(null == space) {
-			throw new HttpClientErrorException(HttpStatus.NOT_FOUND, "Space " + spaceId + " not found.");
-		}
-		
-		model.put("space", space);
-		Page<Project> page;
-		if(filter != null && !filter.isEmpty()) {
-			page = this.projectsRepository.findBySpaceIdAndTitleRegex(spaceId, filter, p);
-		}
-		else {
-			page = this.projectsRepository.findBySpaceId(spaceId, p);
-		}
-				
-		model.put("page", page);
-		model.put("baseUrl", Utils.buildBaseUrl(request));
-		
-		return new ModelAndView("projectIndex", model);
-	}
-	
-		
+        logger.debug("SpaceId : " + (spaceId == null ? "null" : spaceId));
+
+        Map<String, Object> model = new HashMap<String, Object>();
+
+        if ("_".equals(spaceId)) {
+            spaceId = null;
+        }
+
+        Space space = this.spacesRepository.findOne(spaceId);
+
+        if (null == space) {
+            throw new HttpClientErrorException(HttpStatus.NOT_FOUND, "Space "
+                    + spaceId + " not found.");
+        }
+
+        model.put("space", space);
+        Page<Project> page;
+        if (filter != null && !filter.isEmpty()) {
+            page = this.projectsRepository.findBySpaceIdAndTitleRegex(spaceId,
+                    filter, p);
+        } else {
+            page = this.projectsRepository.findBySpaceId(spaceId, p);
+        }
+
+        model.put("page", page);
+        model.put("baseUrl", Utils.buildBaseUrl(request));
+
+        return new ModelAndView("projectIndex", model);
+    }
+
 }
--- a/server/src/main/java/org/iri_research/renkan/controller/Utils.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/controller/Utils.java	Wed Jan 15 18:36:27 2014 +0100
@@ -5,29 +5,27 @@
 import javax.servlet.http.HttpServletRequest;
 
 public class Utils {
-		
-	public static String buildBaseUrl(HttpServletRequest request) {
-		StringBuffer baseUrl = request.getRequestURL();
-		boolean firstParam = true;
-		Enumeration<?> namesEnum = request.getParameterNames();
-		while(namesEnum.hasMoreElements()) {
-			String paramName = 
-					(String)namesEnum.nextElement();
-			
-			if("p.page".equals(paramName)) {
-				continue;
-			}
-			for(String val:request.getParameterValues(paramName)) {
-				if(firstParam) {
-					baseUrl.append('?');
-					firstParam = false;		
-				}
-				else {
-					baseUrl.append('&');
-				}
-				baseUrl.append(paramName).append('=').append(val);
-			}			
-		}
-		return baseUrl.toString();
-	}
+
+    public static String buildBaseUrl(HttpServletRequest request) {
+        StringBuffer baseUrl = request.getRequestURL();
+        boolean firstParam = true;
+        Enumeration<?> namesEnum = request.getParameterNames();
+        while (namesEnum.hasMoreElements()) {
+            String paramName = (String) namesEnum.nextElement();
+
+            if ("p.page".equals(paramName)) {
+                continue;
+            }
+            for (String val : request.getParameterValues(paramName)) {
+                if (firstParam) {
+                    baseUrl.append('?');
+                    firstParam = false;
+                } else {
+                    baseUrl.append('&');
+                }
+                baseUrl.append(paramName).append('=').append(val);
+            }
+        }
+        return baseUrl.toString();
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/controller/admin/AbstractRenkanObjectAdminController.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,5 @@
+package org.iri_research.renkan.controller.admin;
+
+public abstract class AbstractRenkanObjectAdminController {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/controller/admin/AdminController.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,22 @@
+package org.iri_research.renkan.controller.admin;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+@Controller
+@RequestMapping("/admin")
+public class AdminController {
+
+    @SuppressWarnings("unused")
+    private final Logger logger = LoggerFactory
+            .getLogger(AdminController.class);
+
+    @RequestMapping(value = "", method = RequestMethod.GET, produces = { "text/html;charset=UTF-8" })
+    public String adminIndex() {
+        return "admin/adminIndex";
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/controller/admin/GroupsAdminController.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,193 @@
+package org.iri_research.renkan.controller.admin;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Locale;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+
+import org.apache.commons.codec.binary.Hex;
+import org.iri_research.renkan.Constants;
+import org.iri_research.renkan.RenkanException;
+import org.iri_research.renkan.controller.Utils;
+import org.iri_research.renkan.forms.GroupForm;
+import org.iri_research.renkan.forms.GroupFormValidator;
+import org.iri_research.renkan.models.Group;
+import org.iri_research.renkan.repositories.GroupsRepository;
+import org.iri_research.renkan.repositories.UsersRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.propertyeditors.StringTrimmerEditor;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort.Direction;
+import org.springframework.data.web.PageableDefault;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.client.HttpClientErrorException;
+
+@Controller
+@RequestMapping("/admin/groups")
+public class GroupsAdminController {
+
+    private final Logger logger = LoggerFactory
+            .getLogger(GroupsAdminController.class);
+
+    @Inject
+    private GroupsRepository groupsRepository;
+
+    @Inject
+    private UsersRepository usersRepository;
+
+
+    @InitBinder(value = { "group" })
+    protected void initBinder(WebDataBinder binder) {
+        binder.setValidator(new GroupFormValidator());
+    }
+
+    @InitBinder
+    public void initDateBinder(final WebDataBinder dataBinder, final Locale locale) {
+        dataBinder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
+    }
+
+    @RequestMapping(value = "", method = RequestMethod.GET, produces = { "text/html;charset=UTF-8" })
+    public String groupsList(
+            Model model,
+            @PageableDefault(sort = { "title" }, direction = Direction.DESC, page = 0, value = Constants.PAGINATION_SIZE) Pageable p,
+            HttpServletRequest request) {
+
+        Page<Group> page = this.groupsRepository.findAll(p);
+
+        model.addAttribute("page", page);
+        model.addAttribute("baseUrl", Utils.buildBaseUrl(request));
+        //TODO: add user count
+
+        return "admin/groupsList";
+    }
+
+    @RequestMapping(value = "/edit/", method = RequestMethod.GET, produces = { "text/html;charset=UTF-8" })
+    public String editGroup(Model model) {
+        return editGroup(model, null);
+    }
+
+    @RequestMapping(value = "/edit/{groupId}", method = RequestMethod.GET, produces = { "text/html;charset=UTF-8" })
+    public String editGroup(Model model,
+            @PathVariable(value = "groupId") String groupId) {
+
+        GroupForm groupForm = null;
+        Group group = null;
+
+        if (groupId != null && groupId.length() > 0 && !"_".equals(groupId)) {
+            group = this.groupsRepository.findOne(groupId);
+            if (group == null) {
+                throw new HttpClientErrorException(HttpStatus.NOT_FOUND,
+                        "group " + groupId + " not found");
+            }
+        }
+        groupForm = new GroupForm(group);
+
+        model.addAttribute("group", groupForm);
+        model.addAttribute("allUsers", this.usersRepository.findAll());
+
+        return "admin/groupEdit";
+    }
+
+    @RequestMapping(value = "/save", method = RequestMethod.POST)
+    public String saveGroup(Model model,
+            @ModelAttribute("group") @Valid GroupForm groupForm,
+            BindingResult bindingResult) {
+
+        logger.debug("group title " + groupForm.getTitle());
+        logger.debug("user description " + groupForm.getDescription());
+
+        if (bindingResult.hasErrors()) {
+            return "admin/groupEdit";
+        }
+
+        groupForm.setGroupsRepository(groupsRepository);
+
+        try {
+            groupForm.save();
+        } catch (RenkanException e) {
+            throw new HttpClientErrorException(HttpStatus.NOT_FOUND, "group "
+                    + groupForm.getId()==null?"":groupForm.getId() + " not found");
+        }
+
+        return "redirect:/admin/groups";
+    }
+
+    @RequestMapping(value = "/delete/{groupId}")
+    public String deleteGroup(HttpServletRequest request, Model model,
+            @PathVariable(value = "groupId") String groupId,
+            @RequestParam(value = "key", required = false) String key,
+            @RequestParam(value = "salt", required = false) String salt)
+            throws NoSuchAlgorithmException, RenkanException {
+
+        if (groupId == null || groupId.length() == 0) {
+            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST,
+                    "Null or empty user id");
+        }
+
+        RequestMethod method = RequestMethod.valueOf(request.getMethod());
+        
+        //TODO: check that group have no user
+
+
+        if (RequestMethod.GET.equals(method)) {
+
+            Group group = this.groupsRepository.findOne(groupId);
+
+            if (group == null) {
+                throw new HttpClientErrorException(HttpStatus.NOT_FOUND,
+                        "group " + groupId + " not found");
+            }
+
+            SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
+            rand.setSeed(System.currentTimeMillis());
+            byte[] rawSalt = new byte[50];
+            rand.nextBytes(rawSalt);
+            String newSalt = Hex.encodeHexString(rawSalt);
+
+            model.addAttribute("groupObj", group);
+            model.addAttribute("salt", newSalt);
+            model.addAttribute("key", group.getKey(newSalt));
+
+            return "admin/groupDeleteConfirm";
+
+        } else if (RequestMethod.POST.equals(method) && key != null
+                && !key.isEmpty() && salt != null && !salt.isEmpty()) {
+
+            if (groupId != null && groupId.length() > 0) {
+
+                Group group = this.groupsRepository.findOne(groupId);
+                if (group != null) {
+                    if (group.checkKey(key, salt)) {
+                        this.groupsRepository.delete(groupId);
+                    } else {
+                        throw new HttpClientErrorException(
+                                HttpStatus.BAD_REQUEST, "Key not ckecked");
+                    }
+                }
+
+            }
+            return "redirect:/admin/groups";
+
+        } else {
+            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST,
+                    "Bad request method or parameters");
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/controller/admin/SpacesAdminController.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,190 @@
+package org.iri_research.renkan.controller.admin;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+
+import org.apache.commons.codec.binary.Hex;
+import org.iri_research.renkan.Constants;
+import org.iri_research.renkan.RenkanException;
+import org.iri_research.renkan.controller.Utils;
+import org.iri_research.renkan.forms.SpaceForm;
+import org.iri_research.renkan.forms.SpaceFormValidator;
+import org.iri_research.renkan.models.Space;
+import org.iri_research.renkan.repositories.ProjectsRepository;
+import org.iri_research.renkan.repositories.SpacesRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort.Direction;
+import org.springframework.data.web.PageableDefault;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.client.HttpClientErrorException;
+
+@Controller
+@RequestMapping("/admin/spaces")
+public class SpacesAdminController {
+
+    private final Logger logger = LoggerFactory
+            .getLogger(SpacesAdminController.class);
+
+    @Autowired
+    private SpacesRepository spacesRepository;
+    @Autowired
+    private ProjectsRepository projectsRepository;
+
+    @InitBinder(value = { "space" })
+    protected void initBinder(WebDataBinder binder) {
+        binder.setValidator(new SpaceFormValidator());
+    }
+
+    @RequestMapping(value = "", method = RequestMethod.GET, produces = { "text/html;charset=UTF-8" })
+    public String spacesList(
+            Model model,
+            @PageableDefault(sort = { "created" }, direction = Direction.DESC, page = 0, value = Constants.PAGINATION_SIZE) Pageable p,
+            HttpServletRequest request) {
+
+        Page<Space> page = this.spacesRepository.findAll(p);
+
+        model.addAttribute("page", page);
+        model.addAttribute("baseUrl", Utils.buildBaseUrl(request));
+        model.addAttribute("projectsCount",
+                this.projectsRepository.getCountBySpace());
+
+        return "admin/spacesList";
+    }
+
+    @RequestMapping(value = "/edit/", method = RequestMethod.GET, produces = { "text/html;charset=UTF-8" })
+    public String editSpace(Model model) {
+        return editSpace(model, null);
+    }
+
+    @RequestMapping(value = "/edit/{spaceId}", method = RequestMethod.GET, produces = { "text/html;charset=UTF-8" })
+    public String editSpace(Model model,
+            @PathVariable(value = "spaceId") String spaceId) {
+
+        SpaceForm spaceForm = null;
+
+        if (spaceId == null || spaceId.length() == 0 || "_".equals(spaceId)) {
+            spaceForm = new SpaceForm();
+        } else {
+            Space space = this.spacesRepository.findOne(spaceId);
+            if (space == null) {
+                throw new HttpClientErrorException(HttpStatus.NOT_FOUND,
+                        "space " + spaceId + " not found");
+            }
+            spaceForm = new SpaceForm(space);
+        }
+
+        model.addAttribute("space", spaceForm);
+
+        return "admin/spaceEdit";
+    }
+
+    @RequestMapping(value = "/save", method = RequestMethod.POST)
+    public String saveSpace(Model model,
+            @ModelAttribute("space") @Valid SpaceForm spaceForm,
+            BindingResult bindingResult) {
+
+        logger.debug("space title " + spaceForm.getTitle());
+        logger.debug("space description " + spaceForm.getDescription());
+
+        if (bindingResult.hasErrors()) {
+            return "admin/spaceEdit";
+        }
+
+        spaceForm.setSpacesRepository(spacesRepository);
+
+        try {
+            spaceForm.save();
+        } catch (RenkanException e) {
+            throw new HttpClientErrorException(HttpStatus.NOT_FOUND, "space "
+                    + spaceForm.getId() + " not found");
+        }
+
+        return "redirect:/admin/spaces";
+    }
+
+    @RequestMapping(value = "/delete/{spaceId}")
+    public String deleteSpace(HttpServletRequest request, Model model,
+            @PathVariable(value = "spaceId") String spaceId,
+            @RequestParam(value = "key", required = false) String key,
+            @RequestParam(value = "salt", required = false) String salt)
+            throws NoSuchAlgorithmException, RenkanException {
+
+        if (spaceId == null || spaceId.length() == 0) {
+            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST,
+                    "Null or empty space id");
+        }
+
+        RequestMethod method = RequestMethod.valueOf(request.getMethod());
+
+        Map<String, Integer> nbProj = this.projectsRepository
+                .getCountBySpace(Arrays.asList(spaceId));
+        if (nbProj.containsKey(spaceId) && nbProj.get(spaceId).intValue() > 0) {
+            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST,
+                    "This space have projects");
+        }
+
+        if (RequestMethod.GET.equals(method)) {
+
+            Space space = this.spacesRepository.findOne(spaceId);
+
+            if (space == null) {
+                throw new HttpClientErrorException(HttpStatus.NOT_FOUND,
+                        "space " + spaceId + " not found");
+            }
+
+            SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
+            rand.setSeed(System.currentTimeMillis());
+            byte[] rawSalt = new byte[50];
+            rand.nextBytes(rawSalt);
+            String newSalt = Hex.encodeHexString(rawSalt);
+
+            model.addAttribute("spaceObj", space);
+            model.addAttribute("salt", newSalt);
+            model.addAttribute("key", space.getKey(newSalt));
+
+            return "admin/spaceDeleteConfirm";
+        } else if (RequestMethod.POST.equals(method) && key != null
+                && !key.isEmpty() && salt != null && !salt.isEmpty()) {
+
+            if (spaceId != null && spaceId.length() > 0) {
+
+                Space space = this.spacesRepository.findOne(spaceId);
+                if (space != null) {
+                    if (space.checkKey(key, salt)) {
+                        this.spacesRepository.delete(spaceId);
+                    } else {
+                        throw new HttpClientErrorException(
+                                HttpStatus.BAD_REQUEST, "Key not ckecked");
+                    }
+                }
+
+            }
+            return "redirect:/admin/spaces";
+
+        } else {
+            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST,
+                    "Bad request method or parameters");
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/controller/admin/UsersAdminController.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,209 @@
+package org.iri_research.renkan.controller.admin;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+
+import org.apache.commons.codec.binary.Hex;
+import org.iri_research.renkan.Constants;
+import org.iri_research.renkan.RenkanException;
+import org.iri_research.renkan.controller.Utils;
+import org.iri_research.renkan.forms.UserForm;
+import org.iri_research.renkan.forms.UserFormValidator;
+import org.iri_research.renkan.models.User;
+import org.iri_research.renkan.repositories.GroupsRepository;
+import org.iri_research.renkan.repositories.ProjectsRepository;
+import org.iri_research.renkan.repositories.UsersRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.propertyeditors.StringTrimmerEditor;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort.Direction;
+import org.springframework.data.web.PageableDefault;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.client.HttpClientErrorException;
+
+@Controller
+@RequestMapping("/admin/users")
+public class UsersAdminController {
+
+    private final Logger logger = LoggerFactory
+            .getLogger(UsersAdminController.class);
+
+    @Inject
+    private UsersRepository usersRepository;
+
+    @Inject
+    private ProjectsRepository projectsRepository;
+    
+    @Inject
+    private GroupsRepository groupsRepository;
+
+    @Resource(name="renkanPasswordEncoder")
+    private PasswordEncoder passwordEncoder;
+    
+    @InitBinder(value = { "user" })
+    protected void initBinder(WebDataBinder binder) {
+        binder.setValidator(new UserFormValidator());
+    }
+
+    @InitBinder
+    public void initDateBinder(final WebDataBinder dataBinder, final Locale locale) {
+        dataBinder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
+    }
+
+    @RequestMapping(value = "", method = RequestMethod.GET, produces = { "text/html;charset=UTF-8" })
+    public String usersList(
+            Model model,
+            @PageableDefault(sort = { "username" }, direction = Direction.DESC, page = 0, value = Constants.PAGINATION_SIZE) Pageable p,
+            HttpServletRequest request) {
+
+        Page<User> page = this.usersRepository.findAll(p);
+
+        model.addAttribute("page", page);
+        model.addAttribute("baseUrl", Utils.buildBaseUrl(request));
+        model.addAttribute("projectsCount",
+                this.projectsRepository.getCountByUser());
+
+        return "admin/usersList";
+    }
+
+    @RequestMapping(value = "/edit/", method = RequestMethod.GET, produces = { "text/html;charset=UTF-8" })
+    public String editUser(Model model) {
+        return editUser(model, null);
+    }
+
+    @RequestMapping(value = "/edit/{userId}", method = RequestMethod.GET, produces = { "text/html;charset=UTF-8" })
+    public String editUser(Model model,
+            @PathVariable(value = "userId") String userId) {
+
+        UserForm userForm = null;
+        User user = null;
+
+        if (userId != null && userId.length() > 0 && !"_".equals(userId)) {
+            user = this.usersRepository.findOne(userId);
+            if (user == null) {
+                throw new HttpClientErrorException(HttpStatus.NOT_FOUND,
+                        "user " + userId + " not found");
+            }
+        }
+        userForm = new UserForm(user);
+
+        model.addAttribute("user", userForm);
+        model.addAttribute("allGroups", this.groupsRepository.findAll());
+
+        return "admin/userEdit";
+    }
+
+    @RequestMapping(value = "/save", method = RequestMethod.POST)
+    public String saveUser(Model model,
+            @ModelAttribute("user") @Valid UserForm userForm,
+            BindingResult bindingResult) {
+
+        logger.debug("user title " + userForm.getTitle());
+        logger.debug("user description " + userForm.getDescription());
+
+        if (bindingResult.hasErrors()) {
+            return "admin/userEdit";
+        }
+
+        userForm.setUsersRepository(usersRepository);
+        userForm.setPasswordEncoder(passwordEncoder);
+
+        try {
+            userForm.save();
+        } catch (RenkanException e) {
+            throw new HttpClientErrorException(HttpStatus.NOT_FOUND, "user "
+                    + userForm.getId()==null?"":userForm.getId() + " not found");
+        }
+
+        return "redirect:/admin/users";
+    }
+
+    @RequestMapping(value = "/delete/{userId}")
+    public String deleteUser(HttpServletRequest request, Model model,
+            @PathVariable(value = "userId") String userId,
+            @RequestParam(value = "key", required = false) String key,
+            @RequestParam(value = "salt", required = false) String salt)
+            throws NoSuchAlgorithmException, RenkanException {
+
+        if (userId == null || userId.length() == 0) {
+            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST,
+                    "Null or empty user id");
+        }
+
+        RequestMethod method = RequestMethod.valueOf(request.getMethod());
+
+        Map<String, Integer> nbProj = this.projectsRepository
+                .getCountByUser(Arrays.asList(userId));
+        if (nbProj.containsKey(userId) && nbProj.get(userId).intValue() > 0) {
+            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST,
+                    "This user have projects");
+        }
+
+        if (RequestMethod.GET.equals(method)) {
+
+            User user = this.usersRepository.findOne(userId);
+
+            if (user == null) {
+                throw new HttpClientErrorException(HttpStatus.NOT_FOUND,
+                        "user " + userId + " not found");
+            }
+
+            SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
+            rand.setSeed(System.currentTimeMillis());
+            byte[] rawSalt = new byte[50];
+            rand.nextBytes(rawSalt);
+            String newSalt = Hex.encodeHexString(rawSalt);
+
+            model.addAttribute("userObj", user);
+            model.addAttribute("salt", newSalt);
+            model.addAttribute("key", user.getKey(newSalt));
+
+            return "admin/userDeleteConfirm";
+
+        } else if (RequestMethod.POST.equals(method) && key != null
+                && !key.isEmpty() && salt != null && !salt.isEmpty()) {
+
+            if (userId != null && userId.length() > 0) {
+
+                User user = this.usersRepository.findOne(userId);
+                if (user != null) {
+                    if (user.checkKey(key, salt)) {
+                        this.usersRepository.delete(userId);
+                    } else {
+                        throw new HttpClientErrorException(
+                                HttpStatus.BAD_REQUEST, "Key not ckecked");
+                    }
+                }
+
+            }
+            return "redirect:/admin/users";
+
+        } else {
+            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST,
+                    "Bad request method or parameters");
+        }
+
+    }
+
+}
--- a/server/src/main/java/org/iri_research/renkan/coweb/RenkanSessionModerator.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/coweb/RenkanSessionModerator.java	Wed Jan 15 18:36:27 2014 +0100
@@ -16,210 +16,256 @@
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.joda.JodaModule;
 
 public class RenkanSessionModerator extends DefaultSessionModerator {
-	
-	private final Logger logger = LoggerFactory.getLogger(RenkanSessionModerator.class);
-	
-	private ProjectsRepository projectsRepository;
-	
-	
-	public RenkanSessionModerator() {
-		super();
-	}
-	
-	public ProjectsRepository getProjectsRepository() {
-		if(this.projectsRepository == null) {
-			ApplicationContext context = SpringConfigurer.getInstance().getApplicationContext();
-			this.projectsRepository = (ProjectsRepository)context.getBean("projectsRepository");
-		}
-		return projectsRepository;
-	}
+
+    private final Logger logger = LoggerFactory
+            .getLogger(RenkanSessionModerator.class);
+
+    private ProjectsRepository projectsRepository;
+
+    public RenkanSessionModerator() {
+        super();
+    }
+
+    public ProjectsRepository getProjectsRepository() {
+        if (this.projectsRepository == null) {
+            ApplicationContext context = SpringConfigurer.getInstance()
+                    .getApplicationContext();
+            this.projectsRepository = (ProjectsRepository) context
+                    .getBean("projectsRepository");
+        }
+        return projectsRepository;
+    }
+
+    @Override
+    public synchronized boolean canClientJoinSession(String clientId,
+            Map<String, Object> userDefined) {
+
+        this.logger.debug("canClientJoinSession: " + clientId + " , "
+                + (userDefined == null ? "null" : userDefined.toString()));
+
+        if (RenkanSessionModeratorState.INSTANCE.getUsersActivationMap()
+                .containsKey(clientId)) {
+            this.logger
+                    .warn("Client id already declared in user activation map: "
+                            + clientId);
+        }
+
+        String projectId = (String) userDefined.get("project_id");
+
+        if (projectId == null) {
+            return false;
+        }
+
+        RenkanSessionModeratorState.INSTANCE.getUsersActivationMap().put(
+                clientId, projectId);
+        return true;
+    }
+
+    private synchronized void activateProject(String clientId) {
 
-	@Override
-	public synchronized boolean canClientJoinSession(String clientId, Map<String,Object> userDefined) {
-		
-		this.logger.debug("canClientJoinSession: " + clientId  + " , " + (userDefined==null?"null":userDefined.toString()));
-		
-		if(RenkanSessionModeratorState.INSTANCE.getUsersActivationMap().containsKey(clientId)) {
-			this.logger.warn("Client id already declared in user activation map: " + clientId);
-		}
-		
-		String projectId = (String)userDefined.get("project_id");
-		
-		if(projectId == null) {
-			return false;
-		}
-		
-		RenkanSessionModeratorState.INSTANCE.getUsersActivationMap().put(clientId, projectId);
-		return true;
-	}
-	
-	private synchronized void activateProject(String clientId) {
-		
-		if(!RenkanSessionModeratorState.INSTANCE.getUsersActivationMap().containsKey(clientId)) {
-			this.logger.warn("Client id not declared in user activation map: " + clientId);
-			return;
-		}
-		String project_id = RenkanSessionModeratorState.INSTANCE.getUsersActivationMap().get(clientId);
-		if(project_id == null) {
-			this.logger.warn("Null project id for client id in user activation map: " + clientId);
-			return;
-		}
-		
-		List<String> user_list = RenkanSessionModeratorState.INSTANCE.getProjectsActivationMap().get(project_id);
-		if(user_list == null) {
-			user_list = new ArrayList<String>();
-			RenkanSessionModeratorState.INSTANCE.getProjectsActivationMap().put(project_id, user_list);
-		}
+        if (!RenkanSessionModeratorState.INSTANCE.getUsersActivationMap()
+                .containsKey(clientId)) {
+            this.logger.warn("Client id not declared in user activation map: "
+                    + clientId);
+            return;
+        }
+        String project_id = RenkanSessionModeratorState.INSTANCE
+                .getUsersActivationMap().get(clientId);
+        if (project_id == null) {
+            this.logger
+                    .warn("Null project id for client id in user activation map: "
+                            + clientId);
+            return;
+        }
+
+        List<String> user_list = RenkanSessionModeratorState.INSTANCE
+                .getProjectsActivationMap().get(project_id);
+        if (user_list == null) {
+            user_list = new ArrayList<String>();
+            RenkanSessionModeratorState.INSTANCE.getProjectsActivationMap()
+                    .put(project_id, user_list);
+        }
+
+        if (!user_list.contains(clientId)) {
+            user_list.add(clientId);
+        }
+
+    }
+
+    @Override
+    public synchronized void onClientJoinSession(String clientId) {
+
+        this.logger.debug("onClientJoinSession: " + clientId);
 
-		if(!user_list.contains(clientId)) {
-			user_list.add(clientId);
-		}
+        this.activateProject(clientId);
+
+    }
+
+    @Override
+    public synchronized void onClientLeaveSession(String clientId) {
+
+        this.logger.debug("onClientLeaveSession: " + clientId);
+
+        String project_id = RenkanSessionModeratorState.INSTANCE
+                .getUsersActivationMap().get(clientId);
+
+        RenkanSessionModeratorState.INSTANCE.getUsersActivationMap().remove(
+                clientId);
+        if (project_id == null) {
+            this.logger.warn("Leaving client have no associated project: "
+                    + clientId);
+            return;
+        }
+
+        List<String> user_list = RenkanSessionModeratorState.INSTANCE
+                .getProjectsActivationMap().get(project_id);
+        if (user_list == null) {
+            this.logger
+                    .warn("Leaving client have associated project but no project list : "
+                            + clientId + ", " + project_id);
+            return;
+        }
+
+        if (!user_list.remove(clientId)) {
+            this.logger
+                    .warn("Leaving client have associated project but not in project list : "
+                            + clientId + ", " + project_id);
+            return;
+        }
 
-	}
- 	
-	@Override
-	public synchronized void onClientJoinSession(String clientId) {
-		
-		this.logger.debug("onClientJoinSession: " + clientId);
-		
-		this.activateProject(clientId);
-		
-	}
-	
-	@Override
-	public synchronized void onClientLeaveSession(String clientId) {
-		
-		this.logger.debug("onClientLeaveSession: " + clientId);
-		
-		String project_id = RenkanSessionModeratorState.INSTANCE.getUsersActivationMap().get(clientId);
-		
-		RenkanSessionModeratorState.INSTANCE.getUsersActivationMap().remove(clientId);
-		if(project_id == null) {
-			this.logger.warn("Leaving client have no associated project: " + clientId);
-			return;
-		}
-		
-		List<String> user_list = RenkanSessionModeratorState.INSTANCE.getProjectsActivationMap().get(project_id);
-		if(user_list == null) {
-			this.logger.warn("Leaving client have associated project but no project list : " + clientId + ", " + project_id);
-			return;
-		}
-		
-		if(!user_list.remove(clientId)) {
-			this.logger.warn("Leaving client have associated project but not in project list : " + clientId + ", " + project_id);
-			return;
-		}
-		
-		if(user_list.isEmpty()) {
-			this.logger.debug("Leaving client, project list empty, removing from active projects: " + clientId + ", " + project_id);
-			RenkanSessionModeratorState.INSTANCE.getProjectsActivationMap().remove(project_id);
-		}
-		
-		List<RosterUser> r_user_list = RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().get(project_id);
-		if(r_user_list == null) {
-			this.logger.warn("Leaving client have associated project but no user list : " + clientId + ", " + project_id);
-			return;
-		}
-		for (RosterUser rosterUser : r_user_list) {
-			if( rosterUser.getClient_id().equals(clientId)) {
-				r_user_list.remove(rosterUser);
-			}
-		}
-		if(r_user_list.isEmpty()) {
-			this.logger.debug("Leaving client, user list empty, removing from active projects: " + clientId + ", " + project_id);
-			RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().remove(project_id);
-		}		
-		
-	}
-	
-	@SuppressWarnings("unchecked")
-	@Override
-	public synchronized void onSync(String clientId, Map<String, Object> data) {
-				
-		this.logger.debug("Debugging onSync client id: " + clientId);
-		this.logger.debug("Debugging onSync: " + data.toString());
-		this.logger.debug("Debugging onSync channel: " + data.get("channel"));
-		this.logger.debug("Debugging onSync type: " + data.get("type"));
-		this.logger.debug("Debugging onSync site: " + data.get("site"));
-		this.logger.debug("Debugging onSync value: " + data.get("value"));
-		this.logger.debug("Debugging onSync position: " + data.get("position"));
-				
-		Map<String, Object> values = null;
-		if(data.containsKey("value") && data.get("value") != null) {
-			values = ((Map<String, Object>) data.get("value"));
-		}
-		
-		if(values == null) {
-			this.logger.warn("onSync : no values in message.");
-			return;		
-		}
-		
-		String sync_type = (String) values.get("_type");
-		if(sync_type == null || sync_type.length() == 0) {
-			this.logger.warn("onSync : no type in value of message.");
-			return;
-		}
-		
-		if(sync_type.startsWith("_")) {
-			this.logger.debug("onSync : type sync begin with _, ignore. " + sync_type);
-			return;
-		}
-		
-		ApplicationContext context = SpringConfigurer.getInstance().getApplicationContext();
-				
-		String beanName = String.format("%sSyncEventManager", sync_type.toLowerCase());
-		
-		try {
-			ISyncEventManager<?, ?> eventManager = (ISyncEventManager<?, ?>)context.getBean(beanName);
-			logger.debug("Debugging on Sync : dispatch to " + beanName);
-			eventManager.dispatchEvent(clientId, data);
-		}
-		catch(Throwable e) {
-			this.logger.error(String.format("onSync EventManagerClass %s not found : error %s : %s", sync_type, e.toString(), e.getMessage()));
-		}
-		
-	}
+        if (user_list.isEmpty()) {
+            this.logger
+                    .debug("Leaving client, project list empty, removing from active projects: "
+                            + clientId + ", " + project_id);
+            RenkanSessionModeratorState.INSTANCE.getProjectsActivationMap()
+                    .remove(project_id);
+        }
+
+        List<RosterUser> r_user_list = RenkanSessionModeratorState.INSTANCE
+                .getProjectsUsersList().get(project_id);
+        if (r_user_list == null) {
+            this.logger
+                    .warn("Leaving client have associated project but no user list : "
+                            + clientId + ", " + project_id);
+            return;
+        }
+        for (RosterUser rosterUser : r_user_list) {
+            if (rosterUser.getClientId().equals(clientId)) {
+                r_user_list.remove(rosterUser);
+            }
+        }
+        if (r_user_list.isEmpty()) {
+            this.logger
+                    .debug("Leaving client, user list empty, removing from active projects: "
+                            + clientId + ", " + project_id);
+            RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().remove(
+                    project_id);
+        }
+
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public synchronized void onSync(String clientId, Map<String, Object> data) {
+
+        this.logger.debug("Debugging onSync client id: " + clientId);
+        this.logger.debug("Debugging onSync: " + data.toString());
+        this.logger.debug("Debugging onSync channel: " + data.get("channel"));
+        this.logger.debug("Debugging onSync type: " + data.get("type"));
+        this.logger.debug("Debugging onSync site: " + data.get("site"));
+        this.logger.debug("Debugging onSync value: " + data.get("value"));
+        this.logger.debug("Debugging onSync position: " + data.get("position"));
+
+        Map<String, Object> values = null;
+        if (data.containsKey("value") && data.get("value") != null) {
+            values = ((Map<String, Object>) data.get("value"));
+        }
+
+        if (values == null) {
+            this.logger.warn("onSync : no values in message.");
+            return;
+        }
+
+        String sync_type = (String) values.get("_type");
+        if (sync_type == null || sync_type.length() == 0) {
+            this.logger.warn("onSync : no type in value of message.");
+            return;
+        }
+
+        if (sync_type.startsWith("_")) {
+            this.logger.debug("onSync : type sync begin with _, ignore. "
+                    + sync_type);
+            return;
+        }
 
-	@Override
-	public Map<String, Object> getLateJoinState() {
-		this.logger.debug("getLateJoinState");
-		
-		Map<String, Object> res = super.getLateJoinState();
-		ObjectMapper mapper = new ObjectMapper();
-		
-		for (String clientId : RenkanSessionModeratorState.INSTANCE.getUsersActivationMap().keySet()) {
-			this.activateProject(clientId);
-		}
-		
-		this.logger.debug("getLateJoinState : Project activated");
-		
-		for (String project_id : RenkanSessionModeratorState.INSTANCE.getProjectsActivationMap().keySet()) {
+        ApplicationContext context = SpringConfigurer.getInstance()
+                .getApplicationContext();
+
+        String beanName = String.format("%sSyncEventManager",
+                sync_type.toLowerCase());
+
+        try {
+            ISyncEventManager<?, ?> eventManager = (ISyncEventManager<?, ?>) context
+                    .getBean(beanName);
+            logger.debug("Debugging on Sync : dispatch to " + beanName);
+            eventManager.dispatchEvent(clientId, data);
+        } catch (Throwable e) {
+            this.logger.error(String.format(
+                    "onSync EventManagerClass %s not found : error %s : %s",
+                    sync_type, e.toString(), e.getMessage()));
+        }
+
+    }
+
+    @Override
+    public Map<String, Object> getLateJoinState() {
+        this.logger.debug("getLateJoinState");
+
+        Map<String, Object> res = super.getLateJoinState();
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JodaModule());
+
+        for (String clientId : RenkanSessionModeratorState.INSTANCE
+                .getUsersActivationMap().keySet()) {
+            this.activateProject(clientId);
+        }
 
-			Project p = this.getProjectsRepository().findOne(project_id);
-			if (p != null) {
-				try {
-					res.put("renkan_"+project_id, mapper.writeValueAsString(p));
-				} catch (JsonProcessingException e) {
-					this.logger.error("Error when deserializing project " + project_id, e);
-				}
-			}
-			
-			String user_res = "[]";
-			if(RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().containsKey(project_id)) {
-				try {
-					user_res = mapper.writeValueAsString(RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().get(project_id));
-				} catch (JsonProcessingException e) {
-					this.logger.error("Error when deserializing user list " + project_id, e);
-				}
-			}
-			res.put("users_"+project_id, user_res);
-		}
-		
-		
-		this.logger.debug("getLateJoinState res : " + res.toString());
-		return res;
-	}
+        this.logger.debug("getLateJoinState : Project activated");
+
+        for (String project_id : RenkanSessionModeratorState.INSTANCE
+                .getProjectsActivationMap().keySet()) {
+
+            Project p = this.getProjectsRepository().findOne(project_id);
+            if (p != null) {
+                try {
+                    res.put("renkan_" + project_id,
+                            mapper.writeValueAsString(p));
+                } catch (JsonProcessingException e) {
+                    this.logger.error("Error when deserializing project "
+                            + project_id, e);
+                }
+            }
+
+            String user_res = "[]";
+            if (RenkanSessionModeratorState.INSTANCE.getProjectsUsersList()
+                    .containsKey(project_id)) {
+                try {
+                    user_res = mapper
+                            .writeValueAsString(RenkanSessionModeratorState.INSTANCE
+                                    .getProjectsUsersList().get(project_id));
+                } catch (JsonProcessingException e) {
+                    this.logger.error("Error when deserializing user list "
+                            + project_id, e);
+                }
+            }
+            res.put("users_" + project_id, user_res);
+        }
+
+        this.logger.debug("getLateJoinState res : " + res.toString());
+        return res;
+    }
 
 }
--- a/server/src/main/java/org/iri_research/renkan/coweb/SpringConfigurer.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/coweb/SpringConfigurer.java	Wed Jan 15 18:36:27 2014 +0100
@@ -10,43 +10,40 @@
 import org.springframework.stereotype.Component;
 
 @Component
-//@Scope("prototype")
-public class SpringConfigurer implements ApplicationContextAware
-{
-	
-    //private BayeuxServer bayeuxServer;
-    //private ServerAnnotationProcessor processor;
-    private final Logger logger = LoggerFactory.getLogger(SpringConfigurer.class);
+// @Scope("prototype")
+public class SpringConfigurer implements ApplicationContextAware {
+
+    // private BayeuxServer bayeuxServer;
+    // private ServerAnnotationProcessor processor;
+    private final Logger logger = LoggerFactory
+            .getLogger(SpringConfigurer.class);
     private ApplicationContext context;
-    
+
     private static volatile SpringConfigurer instance = null;
-        
-    private SpringConfigurer() 
-    {
-    	this.logger.debug("Building SpringConfigurer");    	
-    }
-    
-    public static SpringConfigurer getInstance() {
-    	if (instance == null) {
-    		synchronized (SpringConfigurer.class) {
-				if(instance == null) {
-					instance = new SpringConfigurer();
-				}
-			}
-    	}
-    	return instance;
+
+    private SpringConfigurer() {
+        this.logger.debug("Building SpringConfigurer");
     }
 
+    public static SpringConfigurer getInstance() {
+        if (instance == null) {
+            synchronized (SpringConfigurer.class) {
+                if (instance == null) {
+                    instance = new SpringConfigurer();
+                }
+            }
+        }
+        return instance;
+    }
 
-    
-	@Override
-	@Inject
-	public void setApplicationContext(ApplicationContext context)
-			throws BeansException {
-		this.context = context;
-	}
-	
-	public ApplicationContext getApplicationContext() {
-		return this.context;
-	}
+    @Override
+    @Inject
+    public void setApplicationContext(ApplicationContext context)
+            throws BeansException {
+        this.context = context;
+    }
+
+    public ApplicationContext getApplicationContext() {
+        return this.context;
+    }
 }
\ No newline at end of file
--- a/server/src/main/java/org/iri_research/renkan/coweb/event/AbstractSyncEventManager.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/AbstractSyncEventManager.java	Wed Jan 15 18:36:27 2014 +0100
@@ -1,7 +1,6 @@
 package org.iri_research.renkan.coweb.event;
 
 import java.io.Serializable;
-import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
@@ -15,6 +14,7 @@
 import org.iri_research.renkan.repositories.IRenkanRepository;
 import org.iri_research.renkan.repositories.ProjectSyncsRepository;
 import org.iri_research.renkan.repositories.ProjectsRepository;
+import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -23,194 +23,211 @@
 import com.mongodb.DBObject;
 import com.mongodb.WriteResult;
 
+public abstract class AbstractSyncEventManager<T extends IRenkanModel<ID>, ID extends Serializable>
+        implements IPersistedSyncEventManager<T, ID> {
 
-public abstract class AbstractSyncEventManager<T extends IRenkanModel<ID>, ID extends Serializable> implements IPersistedSyncEventManager<T,ID> {
+    private final Logger logger = LoggerFactory
+            .getLogger(AbstractSyncEventManager.class);
+
+    @Inject
+    private ProjectsRepository projectsRepository;
+
+    @Inject
+    private ProjectSyncsRepository projectSyncsRepository;
+
+    @Override
+    public ProjectsRepository getProjectsRepository() {
+        return this.projectsRepository;
+    }
+
+    @Override
+    public abstract IRenkanRepository<T, ID> getObjectRepository();
+
+    @Override
+    public void dispatchEvent(String clientId, Map<String, Object> data) {
 
-	private final Logger logger = LoggerFactory.getLogger(AbstractSyncEventManager.class);
-	
-	@Inject
-	private ProjectsRepository projectsRepository;
-	
-	@Inject
-	private ProjectSyncsRepository projectSyncsRepository;
-	
-	@Override
-	public ProjectsRepository getProjectsRepository() {
-		return this.projectsRepository;
-	}
-	
-	@Override
-	public abstract IRenkanRepository<T, ID> getObjectRepository();
-		
-	@Override
-	public void dispatchEvent(String clientId, Map<String, Object> data) {
-		
-		this.saveSyncEvent(data);
+        this.saveSyncEvent(data);
+
+        String eventType = (String) data.get("type");
 
-		String eventType = (String) data.get("type");
-		
-		if("null".equalsIgnoreCase(eventType)) {
-			this.nullOperation(null, data);
-		}
-		else if ("update".equalsIgnoreCase(eventType)) {
-			this.update(clientId, data);
-		}
-		else if ("insert".equalsIgnoreCase(eventType)) {
-			this.insert(clientId, data);
-		}
-		else if("delete".equalsIgnoreCase(eventType)) {
-			this.delete(clientId, data);
-		}
-		else {		
-			logger.warn(String.format("dispatchEvent : eventType unknown %s", eventType));
-		}
-	}
+        if ("null".equalsIgnoreCase(eventType)) {
+            this.nullOperation(null, data);
+        } else if ("update".equalsIgnoreCase(eventType)) {
+            this.update(clientId, data);
+        } else if ("insert".equalsIgnoreCase(eventType)) {
+            this.insert(clientId, data);
+        } else if ("delete".equalsIgnoreCase(eventType)) {
+            this.delete(clientId, data);
+        } else {
+            logger.warn(String.format("dispatchEvent : eventType unknown %s",
+                    eventType));
+        }
+    }
+
+    private void saveSyncEvent(Map<String, Object> data) {
+
+        String project_id = null;
+        String user_id = null;
+
+        @SuppressWarnings("unchecked")
+        Map<String, Object> values = (Map<String, Object>) data.get("value");
 
-	private void saveSyncEvent(Map<String, Object> data) {
-		
-		String project_id = null;
-		String user_id = null;
-	
-		@SuppressWarnings("unchecked")
-		Map<String, Object> values = (Map<String, Object>) data.get("value");
-		
-		if(values != null) {
-			project_id = (String) values.get("_project_id");
-		}
-		
-		if (project_id == null || "".equals(project_id)) {
-			logger.warn("saveSyncEvent : project id is null. Can not save sync event");
-			return;
-		}
-		
-		Project p = this.projectsRepository.findOne(project_id);
-		
-		if (p == null) {
-			logger.warn("saveSyncEvent : project not found. Can not save sync event");
-			return;
-		}
-		
-		p.setUpdated(new Date());
-		this.projectsRepository.save(p);
-		
-		user_id = (String) values.get("_user_id");
-		
-		if (user_id == null) {
-			logger.warn("saveSyncEvent : No user id");
-		}
+        if (values != null) {
+            project_id = (String) values.get("_project_id");
+        }
+
+        if (project_id == null || "".equals(project_id)) {
+            logger.warn("saveSyncEvent : project id is null. Can not save sync event");
+            return;
+        }
+
+        Project p = this.projectsRepository.findOne(project_id);
+
+        if (p == null) {
+            logger.warn("saveSyncEvent : project not found. Can not save sync event");
+            return;
+        }
+
+        p.setUpdated(new DateTime());
+        this.projectsRepository.save(p);
+
+        user_id = (String) values.get("_user_id");
+
+        if (user_id == null) {
+            logger.warn("saveSyncEvent : No user id");
+        }
 
-		try {
-			ProjectSync ps = this.projectSyncsRepository.getProjectSync(data.toString(), p, user_id);
-			this.projectSyncsRepository.save(ps);
-		} catch (RenkanException e) {
-			logger.warn("saveSyncEvent : Error when getting Projectr syn object",e);
-		}
-		
-	}
+        try {
+            ProjectSync ps = this.projectSyncsRepository.getProjectSync(
+                    data.toString(), p, user_id);
+            this.projectSyncsRepository.save(ps);
+        } catch (RenkanException e) {
+            logger.warn(
+                    "saveSyncEvent : Error when getting Projectr syn object", e);
+        }
+
+    }
+
+    protected abstract List<T> getObjectList(Project project);
 
-	protected abstract List<T> getObjectList(Project project);
+    @Override
+    public void update(String clientId, Map<String, Object> data) {
+
+        this.logger.debug("AbstractSyncEventManager: update "
+                + this.getClass().getName());
+
+        @SuppressWarnings("unchecked")
+        Map<String, Object> values = (Map<String, Object>) data.get("value");
+        String obj_id = (String) values.get("id");
+
+        this.logger.debug(String.format("update %s %s", this.getClass()
+                .getName(), obj_id));
+
+        DBCollection objCollection = this.getObjectRepository().getCollection();
+        DBObject obj = objCollection.findOne(obj_id);
 
-	@Override
-	public void update(String clientId, Map<String, Object> data) {
-		
-		this.logger.debug("AbstractSyncEventManager: update " + this.getClass().getName());
-		
-		@SuppressWarnings("unchecked")
-		Map<String, Object> values = (Map<String, Object>) data.get("value");
-		String obj_id = (String) values.get("id");
-		
-		this.logger.debug(String.format("update %s %s", this.getClass().getName(), obj_id));
-		
-		DBCollection objCollection = this.getObjectRepository().getCollection();
-		DBObject obj = objCollection.findOne(obj_id);
-		
-		if (null == obj) {
-			throw new CowebException("Object update: object not found", String.format("Object %s not found in %s", obj_id, objCollection.getName()));
-		}
-		
-		boolean obj_changed = false;
-		// update object
-		for (String fieldname : values.keySet()) {
-			if(!"id".equalsIgnoreCase(fieldname) && !fieldname.startsWith("_"))
-			{
-				Object new_value = values.get(fieldname);
-				Object old_value = obj.get(fieldname);
-				if((new_value == null && old_value != null) || (new_value != null && !new_value.equals(old_value))) {
-					obj.put(fieldname, new_value);
-					obj_changed = true;
-				}
-			}
-		}
-		
-		if(obj_changed) {
-			obj.put("_id", obj_id);
-			WriteResult res = this.getObjectRepository().getCollection().update(new BasicDBObject("_id", obj_id), obj, true, false);
-			
-			if(!res.getLastError().ok()) {
-				throw new CowebException(String.format("Error when writing object %s in %s", obj_id, objCollection.getName()), res.getLastError().getErrorMessage()); 
-			}
-		}
-	}
+        if (null == obj) {
+            throw new CowebException("Object update: object not found",
+                    String.format("Object %s not found in %s", obj_id,
+                            objCollection.getName()));
+        }
+
+        boolean obj_changed = false;
+        // update object
+        for (String fieldname : values.keySet()) {
+            if (!"id".equalsIgnoreCase(fieldname) && !fieldname.startsWith("_")) {
+                Object new_value = values.get(fieldname);
+                Object old_value = obj.get(fieldname);
+                if ((new_value == null && old_value != null)
+                        || (new_value != null && !new_value.equals(old_value))) {
+                    obj.put(fieldname, new_value);
+                    obj_changed = true;
+                }
+            }
+        }
+
+        if (obj_changed) {
+            obj.put("_id", obj_id);
+            WriteResult res = this.getObjectRepository().getCollection()
+                    .update(new BasicDBObject("_id", obj_id), obj, true, false);
 
-	@Override
-	public abstract void insert(String clientId, Map<String, Object> data);
+            if (!res.getLastError().ok()) {
+                throw new CowebException(String.format(
+                        "Error when writing object %s in %s", obj_id,
+                        objCollection.getName()), res.getLastError()
+                        .getErrorMessage());
+            }
+        }
+    }
+
+    @Override
+    public abstract void insert(String clientId, Map<String, Object> data);
+
+    @Override
+    public void delete(String clientId, Map<String, Object> data) {
+
+        @SuppressWarnings("unchecked")
+        Map<String, Object> values = (Map<String, Object>) data.get("value");
+        String project_id = (String) values.get("_project_id");
+        Project project = this.getProjectsRepository().findOne(project_id);
+
+        if (null == project) {
+            throw new CowebException(this.getClass().getName()
+                    + " delete: project not found", String.format(
+                    "Project %s not found", project_id));
+        }
+
+        Integer position = (Integer) data.get("position");
 
-	@Override
-	public void delete(String clientId, Map<String, Object> data) {
-		
-		@SuppressWarnings("unchecked")
-		Map<String, Object> values = (Map<String, Object>) data.get("value");
-		String project_id = (String) values.get("_project_id");		
-		Project project = this.getProjectsRepository().findOne(project_id); 
-		
-		if (null == project) {
-			throw new CowebException(this.getClass().getName() + " delete: project not found", String.format("Project %s not found", project_id));
-		}
+        if (position == null || position < 0) {
+            throw new CowebException("object delete: bad delete position",
+                    String.format("Bad position %s not found",
+                            position == null ? "null" : position.toString()));
+        }
+        int index = position.intValue();
+
+        @SuppressWarnings("unchecked")
+        ID object_id = (ID) values.get("id");
+
+        this.logger.debug(String.format(
+                "delete object %s in pos %d for project %s", object_id, index,
+                project_id));
+
+        IRenkanModel<ID> currentObject = null;
+
+        List<T> objList = this.getObjectList(project);
+
+        if (index < objList.size()) {
+            currentObject = objList.get(index);
+        }
 
-		Integer position = (Integer)data.get("position");
-		
-		if(position == null || position < 0) {
-			throw new CowebException("object delete: bad delete position", String.format("Bad position %s not found", position==null?"null":position.toString()));
-		}
-		int index = position.intValue();
-		
-		@SuppressWarnings("unchecked")
-		ID object_id = (ID) values.get("id");
-		
-		this.logger.debug(String.format("delete object %s in pos %d for project %s", object_id, index, project_id));
-		
-		IRenkanModel<ID> currentObject = null;
-		
-		List<T> objList = this.getObjectList(project);
-		
-		if(index < objList.size()) {
-			currentObject = objList.get(index);
-		}
-			
-		if(currentObject == null || !object_id.equals(currentObject.getId())) {
-			index = -1;
-			this.logger.warn(String.format("delete object %s in pos %d for project %s not current object", object_id, index, project_id));
-			for(int i=0;i<project.getNodes().size();i++) {
-				if(object_id.equals(objList.get(i).getId())) {
-					index = i;
-					break;
-				}
-			}
-		}
-		
-		if(index<0) {
-			this.logger.warn(String.format("delete object %s in pos %d for project %s not found", object_id, index, project_id));
-		}
-		else {
-			objList.remove(index);
-			this.getObjectRepository().delete(object_id);
-			this.getProjectsRepository().save(project);
-		}
+        if (currentObject == null || !object_id.equals(currentObject.getId())) {
+            index = -1;
+            this.logger
+                    .warn(String
+                            .format("delete object %s in pos %d for project %s not current object",
+                                    object_id, index, project_id));
+            for (int i = 0; i < project.getNodes().size(); i++) {
+                if (object_id.equals(objList.get(i).getId())) {
+                    index = i;
+                    break;
+                }
+            }
+        }
 
-	}
+        if (index < 0) {
+            this.logger.warn(String.format(
+                    "delete object %s in pos %d for project %s not found",
+                    object_id, index, project_id));
+        } else {
+            objList.remove(index);
+            this.getObjectRepository().delete(object_id);
+            this.getProjectsRepository().save(project);
+        }
 
-	@Override
-	public abstract void nullOperation(String clientId, Map<String, Object> data);
-	
-	
+    }
+
+    @Override
+    public abstract void nullOperation(String clientId, Map<String, Object> data);
+
 }
--- a/server/src/main/java/org/iri_research/renkan/coweb/event/EdgeSyncEventManager.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/EdgeSyncEventManager.java	Wed Jan 15 18:36:27 2014 +0100
@@ -18,101 +18,107 @@
 import org.slf4j.LoggerFactory;
 
 @Named
-public class EdgeSyncEventManager extends AbstractSyncEventManager<Edge, String> {
+public class EdgeSyncEventManager extends
+        AbstractSyncEventManager<Edge, String> {
 
-	private final Logger logger = LoggerFactory.getLogger(EdgeSyncEventManager.class);
+    private final Logger logger = LoggerFactory
+            .getLogger(EdgeSyncEventManager.class);
 
-	@Inject
-	private NodesRepository nodesRepository;
+    @Inject
+    private NodesRepository nodesRepository;
 
-	@Inject
-	private UsersRepository usersRepository;
-	
-	@Inject
-	private EdgesRepository edgesRepository;
+    @Inject
+    private UsersRepository usersRepository;
+
+    @Inject
+    private EdgesRepository edgesRepository;
 
-	
-	public NodesRepository getNodesRepository() {
-		return nodesRepository;
-	}
+    public NodesRepository getNodesRepository() {
+        return nodesRepository;
+    }
+
+    public UsersRepository getUsersRepository() {
+        return usersRepository;
+    }
 
-	public UsersRepository getUsersRepository() {
-		return usersRepository;
-	}
+    public EdgesRepository getEdgesRepository() {
+        return edgesRepository;
+    }
+
+    @Override
+    public IRenkanRepository<Edge, String> getObjectRepository() {
+        return this.getEdgesRepository();
+    }
+
+    @Override
+    public void insert(String clientId, Map<String, Object> data) {
 
-	public EdgesRepository getEdgesRepository() {
-		return edgesRepository;
-	}
-	
-	
-	@Override
-	public IRenkanRepository<Edge, String> getObjectRepository() {
-		return this.getEdgesRepository();
-	}
-	
-	
-	@Override
-	public void insert(String clientId, Map<String, Object> data) {
-	
-		// get project
-		this.logger.debug("EdgeSyncEventManager: insert Edge");
-		
-		@SuppressWarnings("unchecked")
-		Map<String, Object> values = (Map<String, Object>) data.get("value");
-		String project_id = (String) values.get("_project_id");
+        // get project
+        this.logger.debug("EdgeSyncEventManager: insert Edge");
+
+        @SuppressWarnings("unchecked")
+        Map<String, Object> values = (Map<String, Object>) data.get("value");
+        String project_id = (String) values.get("_project_id");
+
+        Project project = this.getProjectsRepository().findOne(project_id);
+
+        if (null == project) {
+            throw new CowebException("Edge insert: project not found",
+                    String.format("Project %s not found", project_id));
+        }
+
+        String creator_id = (String) values.get("created_by");
 
-		Project project = this.getProjectsRepository().findOne(project_id);
-				
-		if (null == project) {
-			throw new CowebException("Edge insert: project not found", String.format("Project %s not found", project_id));
-		}
+        String from_node_id = (String) values.get("from");
+        Node from_node = this.getNodesRepository().findOne(from_node_id);
+
+        if (null == from_node) {
+            throw new CowebException("Edge insert: from not found",
+                    String.format("from %s not found", from_node_id));
+        }
+
+        String to_node_id = (String) values.get("to");
+        Node to_node = this.getNodesRepository().findOne(to_node_id);
+
+        if (null == to_node) {
+            throw new CowebException("Edge insert: to not found",
+                    String.format("to %s not found", to_node_id));
+        }
+
+        String edge_id = (String) values.get("id");
+
+        Edge edge = new Edge(edge_id, (String) values.get("title"),
+                (String) values.get("description"), (String) values.get("uri"),
+                (String) values.get("color"), from_node, to_node, creator_id,
+                project_id);
+
+        Integer position = (Integer) data.get("position");
 
-		String creator_id = (String) values.get("created_by");
-								
-		String from_node_id = (String)values.get("from");
-		Node from_node = this.getNodesRepository().findOne(from_node_id);
-		
-		if(null == from_node) {
-			throw new CowebException("Edge insert: from not found", String.format("from %s not found", from_node_id));
-		}
-		
-		String to_node_id = (String)values.get("to");
-		Node to_node = this.getNodesRepository().findOne(to_node_id);
-		
-		if(null == to_node) {
-			throw new CowebException("Edge insert: to not found", String.format("to %s not found", to_node_id));
-		}
-		
-		String edge_id = (String)values.get("id");
-		
-		Edge edge = new Edge(edge_id, (String)values.get("title"), (String)values.get("description"), (String)values.get("uri"), (String)values.get("color"), from_node, to_node, creator_id, project_id);
-		
-		
-		Integer position = (Integer)data.get("position");
-		
-		if(position == null || position < 0) {
-			throw new CowebException("Edge insert: bad insert position", String.format("Bad position %s not found", position==null?"null":position.toString()));
-		}
-		int index = position.intValue();
-		List<Edge> edges = project.getEdges();
-		if(index > edges.size()) {
-			index = edges.size();
-		}
-		edges.add(index,edge);
+        if (position == null || position < 0) {
+            throw new CowebException("Edge insert: bad insert position",
+                    String.format("Bad position %s not found",
+                            position == null ? "null" : position.toString()));
+        }
+        int index = position.intValue();
+        List<Edge> edges = project.getEdges();
+        if (index > edges.size()) {
+            index = edges.size();
+        }
+        edges.add(index, edge);
 
-		this.getEdgesRepository().save(edge);
-		this.getProjectsRepository().save(project);
-		
-	}
-	
-	@Override
-	public void nullOperation(String clientId, Map<String, Object> data) {
-		this.logger.debug("nullOperation: NOP");
-	}
+        this.getEdgesRepository().save(edge);
+        this.getProjectsRepository().save(project);
+
+    }
 
-	@Override
-	protected List<Edge> getObjectList(Project project) {
-		return project.getEdges();
-	}
+    @Override
+    public void nullOperation(String clientId, Map<String, Object> data) {
+        this.logger.debug("nullOperation: NOP");
+    }
+
+    @Override
+    protected List<Edge> getObjectList(Project project) {
+        return project.getEdges();
+    }
 
 }
--- a/server/src/main/java/org/iri_research/renkan/coweb/event/IPersistedSyncEventManager.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/IPersistedSyncEventManager.java	Wed Jan 15 18:36:27 2014 +0100
@@ -5,9 +5,11 @@
 import org.iri_research.renkan.repositories.IRenkanRepository;
 import org.iri_research.renkan.repositories.ProjectsRepository;
 
-public interface IPersistedSyncEventManager<T, ID extends Serializable>  extends ISyncEventManager<T, ID> {
-		
-	public ProjectsRepository getProjectsRepository();
-	public IRenkanRepository<T,ID> getObjectRepository();
+public interface IPersistedSyncEventManager<T, ID extends Serializable> extends
+        ISyncEventManager<T, ID> {
+
+    public ProjectsRepository getProjectsRepository();
+
+    public IRenkanRepository<T, ID> getObjectRepository();
 
 }
--- a/server/src/main/java/org/iri_research/renkan/coweb/event/ISyncEventManager.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/ISyncEventManager.java	Wed Jan 15 18:36:27 2014 +0100
@@ -4,13 +4,15 @@
 import java.util.Map;
 
 public interface ISyncEventManager<T, ID extends Serializable> {
-	
-	public void dispatchEvent(String clientId, Map<String, Object> data);
+
+    public void dispatchEvent(String clientId, Map<String, Object> data);
+
+    public void update(String clientId, Map<String, Object> data);
 
-	public void update(String clientId, Map<String, Object> data);
-	public void insert(String clientId, Map<String, Object> data);
-	public void delete(String clientId, Map<String, Object> data);
-	public void nullOperation(String clientId, Map<String, Object> data);
-	
+    public void insert(String clientId, Map<String, Object> data);
+
+    public void delete(String clientId, Map<String, Object> data);
+
+    public void nullOperation(String clientId, Map<String, Object> data);
 
 }
--- a/server/src/main/java/org/iri_research/renkan/coweb/event/NodeSyncEventManager.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/NodeSyncEventManager.java	Wed Jan 15 18:36:27 2014 +0100
@@ -17,87 +17,96 @@
 import org.springframework.data.mongodb.core.geo.Point;
 
 @Named
-public class NodeSyncEventManager extends AbstractSyncEventManager<Node, String> {
+public class NodeSyncEventManager extends
+        AbstractSyncEventManager<Node, String> {
 
-	private final Logger logger = LoggerFactory.getLogger(NodeSyncEventManager.class);
+    private final Logger logger = LoggerFactory
+            .getLogger(NodeSyncEventManager.class);
+
+    @Inject
+    private NodesRepository nodesRepository;
 
-	@Inject
-	private NodesRepository nodesRepository;
+    @Inject
+    private UsersRepository usersRepository;
 
-	@Inject
-	private UsersRepository usersRepository;
+    public NodesRepository getNodesRepository() {
+        return nodesRepository;
+    }
+
+    @Override
+    public IRenkanRepository<Node, String> getObjectRepository() {
+        return this.getNodesRepository();
+    }
 
-	
-	public NodesRepository getNodesRepository() {
-		return nodesRepository;
-	}
-	
-	@Override
-	public IRenkanRepository<Node, String> getObjectRepository() {
-		return this.getNodesRepository();
-	}
-	
-	public UsersRepository getUsersRepository() {
-		return this.usersRepository;
-	}
+    public UsersRepository getUsersRepository() {
+        return this.usersRepository;
+    }
+
+    @Override
+    public void insert(String clientId, Map<String, Object> data) {
+
+        // get project
+        this.logger.debug("NodeSyncEventManager: insert Node");
 
-	
-	@Override
-	public void insert(String clientId, Map<String, Object> data) {
-	
-		// get project
-		this.logger.debug("NodeSyncEventManager: insert Node");
-		
-		@SuppressWarnings("unchecked")
-		Map<String, Object> values = (Map<String, Object>) data.get("value");
-		String project_id = (String) values.get("_project_id");
+        @SuppressWarnings("unchecked")
+        Map<String, Object> values = (Map<String, Object>) data.get("value");
+        String project_id = (String) values.get("_project_id");
+
+        Project project = this.getProjectsRepository().findOne(project_id);
 
-		Project project = this.getProjectsRepository().findOne(project_id);
-				
-		if (null == project) {
-			throw new CowebException("node insert: project not found", String.format("Project %s not found", project_id));
-		}
+        if (null == project) {
+            throw new CowebException("node insert: project not found",
+                    String.format("Project %s not found", project_id));
+        }
+
+        String creator_id = (String) values.get("created_by");
 
-		String creator_id = (String) values.get("created_by");
-		
-		@SuppressWarnings("unchecked")
-		Map<String, Object> positionValues = (Map<String, Object>) values.get("position");
-		
-		Point nodePosition = new Point(((Number)positionValues.get("x")).doubleValue(), ((Number)positionValues.get("y")).doubleValue());
-		
-		String image = (String)values.get("image");
-		
-		String node_id = (String)values.get("id");
-		
-		Integer size = (Integer)values.get("size");
-		
-		Node node = new Node(node_id, (String)values.get("title"), (String)values.get("description"), (String)values.get("uri"), (String)values.get("color"), creator_id, nodePosition, image, size, project_id);
-		
-		Integer position = (Integer)data.get("position");
-		
-		if(position == null || position < 0) {
-			throw new CowebException("node insert: bad insert position", String.format("Bad position %s not found", position==null?"null":position.toString()));
-		}
-		int index = position.intValue();
-		List<Node> nodes = project.getNodes();
-		if(index > nodes.size()) {
-			index = nodes.size();
-		}
-		nodes.add(index,node);
+        @SuppressWarnings("unchecked")
+        Map<String, Object> positionValues = (Map<String, Object>) values
+                .get("position");
+
+        Point nodePosition = new Point(
+                ((Number) positionValues.get("x")).doubleValue(),
+                ((Number) positionValues.get("y")).doubleValue());
+
+        String image = (String) values.get("image");
+
+        String node_id = (String) values.get("id");
+
+        Integer size = (Integer) values.get("size");
+
+        Node node = new Node(node_id, (String) values.get("title"),
+                (String) values.get("description"), (String) values.get("uri"),
+                (String) values.get("color"), creator_id, nodePosition, image,
+                size, project_id);
+
+        Integer position = (Integer) data.get("position");
 
-		this.getNodesRepository().save(node);
-		this.getProjectsRepository().save(project);
-		
-	}
-	
-	@Override
-	public void nullOperation(String clientId, Map<String, Object> data) {
-		this.logger.debug("nullOperation: NOP");
-	}
+        if (position == null || position < 0) {
+            throw new CowebException("node insert: bad insert position",
+                    String.format("Bad position %s not found",
+                            position == null ? "null" : position.toString()));
+        }
+        int index = position.intValue();
+        List<Node> nodes = project.getNodes();
+        if (index > nodes.size()) {
+            index = nodes.size();
+        }
+        nodes.add(index, node);
 
-	@Override
-	protected List<Node> getObjectList(Project project) {
-		return project.getNodes();
-	}
+        this.getNodesRepository().save(node);
+        this.getProjectsRepository().save(project);
+
+    }
+
+    @Override
+    public void nullOperation(String clientId, Map<String, Object> data) {
+        this.logger.debug("nullOperation: NOP");
+    }
+
+    @Override
+    protected List<Node> getObjectList(Project project) {
+        return project.getNodes();
+    }
 
 }
--- a/server/src/main/java/org/iri_research/renkan/coweb/event/ProjectSyncEventManager.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/ProjectSyncEventManager.java	Wed Jan 15 18:36:27 2014 +0100
@@ -15,50 +15,63 @@
 
 /**
  * @author ymh
- *
+ * 
  */
 @Named
-public class ProjectSyncEventManager extends AbstractSyncEventManager<Project, String> {
+public class ProjectSyncEventManager extends
+        AbstractSyncEventManager<Project, String> {
+
+    private final Logger logger = LoggerFactory
+            .getLogger(ProjectSyncEventManager.class);
+
+    @Override
+    public IRenkanRepository<Project, String> getObjectRepository() {
+        return this.getProjectsRepository();
+    }
 
-	private final Logger logger = LoggerFactory.getLogger(ProjectSyncEventManager.class);			
-	
-	@Override
-	public IRenkanRepository<Project, String> getObjectRepository() {
-		return this.getProjectsRepository();
-	}
-	
-	/* (non-Javadoc)
-	 * @see org.iri_research.renkan.coweb.event.AbstractSyncEventManager#insert(java.util.Map)
-	 */
-	@Override
-	public void insert(String clientId, Map<String, Object> data) {
-		this.logger.debug("Insert called, do nothing");
-		// do nothing
-	}
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.iri_research.renkan.coweb.event.AbstractSyncEventManager#insert(java
+     * .util.Map)
+     */
+    @Override
+    public void insert(String clientId, Map<String, Object> data) {
+        this.logger.debug("Insert called, do nothing");
+        // do nothing
+    }
 
-	/* (non-Javadoc)
-	 * @see org.iri_research.renkan.coweb.event.AbstractSyncEventManager#delete(java.util.Map)
-	 */
-	@Override
-	public void delete(String clientId, Map<String, Object> data) {
-		this.logger.debug("Delete called, do nothing");
-		// do nothing
-	}
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.iri_research.renkan.coweb.event.AbstractSyncEventManager#delete(java
+     * .util.Map)
+     */
+    @Override
+    public void delete(String clientId, Map<String, Object> data) {
+        this.logger.debug("Delete called, do nothing");
+        // do nothing
+    }
 
-	/* (non-Javadoc)
-	 * @see org.iri_research.renkan.coweb.event.AbstractSyncEventManager#nullOperation(java.util.Map)
-	 */
-	@Override
-	public void nullOperation(String clientId, Map<String, Object> data) {
-		this.logger.debug("Null called, do nothing");
-		// do nothing
-	}
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.iri_research.renkan.coweb.event.AbstractSyncEventManager#nullOperation
+     * (java.util.Map)
+     */
+    @Override
+    public void nullOperation(String clientId, Map<String, Object> data) {
+        this.logger.debug("Null called, do nothing");
+        // do nothing
+    }
 
-	@Override
-	protected List<Project> getObjectList(Project project) {
-		this.logger.error("Get object list called error");
-		throw new UnsupportedOperationException("Get object list called error");
-	}
-
+    @Override
+    protected List<Project> getObjectList(Project project) {
+        this.logger.error("Get object list called error");
+        throw new UnsupportedOperationException("Get object list called error");
+    }
 
 }
--- a/server/src/main/java/org/iri_research/renkan/coweb/event/RosterSyncEventManager.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/RosterSyncEventManager.java	Wed Jan 15 18:36:27 2014 +0100
@@ -12,185 +12,196 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+@Named
+public class RosterSyncEventManager implements
+        ISyncEventManager<RosterUser, String> {
 
-@Named
-public class RosterSyncEventManager implements ISyncEventManager<RosterUser, String> {
+    private final Logger logger = LoggerFactory
+            .getLogger(RosterSyncEventManager.class);
 
-	private final Logger logger = LoggerFactory.getLogger(RosterSyncEventManager.class);
-	
+    @Override
+    public void insert(String clientId, Map<String, Object> data) {
+        logger.debug("RosterUserSyncEventManager.insert " + data.toString());
+
+        @SuppressWarnings("unchecked")
+        Map<String, Object> values = (Map<String, Object>) data.get("value");
+        String projectId = (String) values.get("_project_id");
+
+        List<RosterUser> usersList = null;
 
-	@Override
-	public void insert(String clientId, Map<String, Object> data) {
-		logger.debug("RosterUserSyncEventManager.insert " + data.toString());
-		
-		@SuppressWarnings("unchecked")
-		Map<String, Object> values = (Map<String, Object>) data.get("value");
-		String projectId = (String) values.get("_project_id");
+        if (RenkanSessionModeratorState.INSTANCE.getProjectsUsersList()
+                .containsKey(projectId)) {
+            usersList = RenkanSessionModeratorState.INSTANCE
+                    .getProjectsUsersList().get(projectId);
+        }
+        if (usersList == null) {
+            usersList = new ArrayList<RosterUser>();
+            RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().put(
+                    projectId, usersList);
+        }
+
+        String id = (String) values.get("id");
 
-		List<RosterUser> usersList = null;
-		
-		if(RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().containsKey(projectId)) {
-			usersList = RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().get(projectId);
-		}
-		if(usersList == null) {
-			usersList = new ArrayList<RosterUser>();
-			RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().put(projectId, usersList);
-		}
-				
-		String id = (String)values.get("id");
+        RosterUser user = null;
+
+        for (RosterUser rosterUser : usersList) {
+            if (rosterUser.getId().equals(id)) {
+                user = rosterUser;
+                break;
+            }
+        }
+        if (user != null) {
+            this.update(clientId, data);
+            return;
+        }
 
-		RosterUser user = null;
-		
-		for (RosterUser rosterUser : usersList) {
-			if(rosterUser.getId().equals(id)) {
-				user = rosterUser;
-				break;
-			}
-		}
-		if(user != null) {
-			this.update(clientId, data);
-			return;
-		}
-		
-		String title = (String)values.get("title");
-		String description = (String)values.get("description");
-		String uri = (String)values.get("uri");
-		String color = (String)values.get("color");
-		Long site_id = (Long)values.get("site_id");
-		
-		user = new RosterUser(id, title, description, uri, color, projectId, site_id, clientId);
-		
-		Integer position = (Integer)data.get("position");
-		if(position == null) {
-			position = new Integer(0);
-		}
-		
-		usersList.add(position.intValue(), user);
-		
-		logger.debug("RosterUserSyncEventManager.insert in  " + projectId + " : " + RenkanSessionModeratorState.INSTANCE.getProjectsActivationMap().toString());
-		
-	}
+        String title = (String) values.get("title");
+        String description = (String) values.get("description");
+        String uri = (String) values.get("uri");
+        String color = (String) values.get("color");
+        Long site_id = (Long) values.get("site_id");
+
+        user = new RosterUser(id, title, description, uri, color, projectId,
+                site_id, clientId);
+
+        Integer position = (Integer) data.get("position");
+        if (position == null) {
+            position = new Integer(0);
+        }
+
+        usersList.add(position.intValue(), user);
+
+        logger.debug("RosterUserSyncEventManager.insert in  "
+                + projectId
+                + " : "
+                + RenkanSessionModeratorState.INSTANCE
+                        .getProjectsActivationMap().toString());
+
+    }
 
-	@Override
-	public void nullOperation(String clientId, Map<String, Object> data) {
-		// do nothing
-		return;
-	}
+    @Override
+    public void nullOperation(String clientId, Map<String, Object> data) {
+        // do nothing
+        return;
+    }
 
-	@Override
-	public void update(String clientId, Map<String, Object> data) {
-		logger.debug("RosterUserSyncEventManager.update " + data.toString());
+    @Override
+    public void update(String clientId, Map<String, Object> data) {
+        logger.debug("RosterUserSyncEventManager.update " + data.toString());
+
+        @SuppressWarnings("unchecked")
+        Map<String, Object> values = (Map<String, Object>) data.get("value");
+        String projectId = (String) values.get("_project_id");
 
-		@SuppressWarnings("unchecked")
-		Map<String, Object> values = (Map<String, Object>) data.get("value");
-		String projectId = (String) values.get("_project_id");
+        List<RosterUser> usersList = null;
 
-		List<RosterUser> usersList = null;
-		
-		if(RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().containsKey(projectId)) {
-			usersList = RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().get(projectId);
-		}
-		
-		if(usersList == null) {
-			logger.debug("RosterUserSyncEventManager.update : null user list");
-			return;
-		}
-		
-		String id = (String)values.get("id");
+        if (RenkanSessionModeratorState.INSTANCE.getProjectsUsersList()
+                .containsKey(projectId)) {
+            usersList = RenkanSessionModeratorState.INSTANCE
+                    .getProjectsUsersList().get(projectId);
+        }
+
+        if (usersList == null) {
+            logger.debug("RosterUserSyncEventManager.update : null user list");
+            return;
+        }
+
+        String id = (String) values.get("id");
 
-		RosterUser user = null;
-		
-		for (RosterUser rosterUser : usersList) {
-			if(rosterUser.getId().equals(id)) {
-				user = rosterUser;
-				break;
-			}
-		}
-		
-		if(user == null) {
-			logger.debug("RosterUserSyncEventManager.update : user not found in list");
-			return;
-		}
-		
-		String title = (String)values.get("title");
-		String description = (String)values.get("description");
-		String uri = (String)values.get("uri");
-		String color = (String)values.get("color");
-		
-		if(title != null) {
-			user.setTitle(title);
-		}
-		if(description != null) {
-			user.setDescription(description);
-		}
-		if(uri != null) {
-			user.setUri(uri);
-		}
-		if(color != null) {
-			user.setColor(color);
-		}
-		
-		return;
-		
-	}
+        RosterUser user = null;
+
+        for (RosterUser rosterUser : usersList) {
+            if (rosterUser.getId().equals(id)) {
+                user = rosterUser;
+                break;
+            }
+        }
+
+        if (user == null) {
+            logger.debug("RosterUserSyncEventManager.update : user not found in list");
+            return;
+        }
+
+        String title = (String) values.get("title");
+        String description = (String) values.get("description");
+        String uri = (String) values.get("uri");
+        String color = (String) values.get("color");
 
-	@Override
-	public void delete(String clientId, Map<String, Object> data) {
-		logger.debug("RosterUserSyncEventManager.delete " + data.toString());
-		
-		@SuppressWarnings("unchecked")
-		Map<String, Object> values = (Map<String, Object>) data.get("value");
-		String projectId = (String) values.get("_project_id");
+        if (title != null) {
+            user.setTitle(title);
+        }
+        if (description != null) {
+            user.setDescription(description);
+        }
+        if (uri != null) {
+            user.setUri(uri);
+        }
+        if (color != null) {
+            user.setColor(color);
+        }
+
+        return;
+
+    }
+
+    @Override
+    public void delete(String clientId, Map<String, Object> data) {
+        logger.debug("RosterUserSyncEventManager.delete " + data.toString());
+
+        @SuppressWarnings("unchecked")
+        Map<String, Object> values = (Map<String, Object>) data.get("value");
+        String projectId = (String) values.get("_project_id");
+
+        List<RosterUser> usersList = null;
 
-		List<RosterUser> usersList = null;
-		
-		if(RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().containsKey(projectId)) {
-			usersList = RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().get(projectId);
-		}
-		
-		if(usersList == null) {
-			logger.debug("RosterUserSyncEventManager.delete : null user list");
-			return;
-		}
-		
-		Integer position = (Integer)data.get("position");
-		
-		if(position == null || position < 0) {
-			throw new CowebException("object delete: bad delete position", String.format("Bad position %s not found", position==null?"null":position.toString()));
-		}
-		int index = position.intValue();
-		
-		usersList.remove(index);
-		
-		if(usersList.isEmpty()) {
-			RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().remove(projectId);
-		}
-		
-		return;
-		
-	}
-	
-	@Override
-	public void dispatchEvent(String clientId, Map<String, Object> data) {
-		
-		String eventType = (String) data.get("type");
-		
-		if("null".equalsIgnoreCase(eventType)) {
-			this.nullOperation(clientId, data);
-		}
-		else if ("update".equalsIgnoreCase(eventType)) {
-			this.update(clientId, data);
-		}
-		else if ("insert".equalsIgnoreCase(eventType)) {
-			this.insert(clientId, data);
-		}
-		else if("delete".equalsIgnoreCase(eventType)) {
-			this.delete(clientId, data);
-		}
-		else {		
-			logger.warn(String.format("dispatchEvent : eventType unknown %s", eventType));
-		}
-	}
+        if (RenkanSessionModeratorState.INSTANCE.getProjectsUsersList()
+                .containsKey(projectId)) {
+            usersList = RenkanSessionModeratorState.INSTANCE
+                    .getProjectsUsersList().get(projectId);
+        }
+
+        if (usersList == null) {
+            logger.debug("RosterUserSyncEventManager.delete : null user list");
+            return;
+        }
+
+        Integer position = (Integer) data.get("position");
+
+        if (position == null || position < 0) {
+            throw new CowebException("object delete: bad delete position",
+                    String.format("Bad position %s not found",
+                            position == null ? "null" : position.toString()));
+        }
+        int index = position.intValue();
+
+        usersList.remove(index);
 
+        if (usersList.isEmpty()) {
+            RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().remove(
+                    projectId);
+        }
+
+        return;
+
+    }
+
+    @Override
+    public void dispatchEvent(String clientId, Map<String, Object> data) {
+
+        String eventType = (String) data.get("type");
+
+        if ("null".equalsIgnoreCase(eventType)) {
+            this.nullOperation(clientId, data);
+        } else if ("update".equalsIgnoreCase(eventType)) {
+            this.update(clientId, data);
+        } else if ("insert".equalsIgnoreCase(eventType)) {
+            this.insert(clientId, data);
+        } else if ("delete".equalsIgnoreCase(eventType)) {
+            this.delete(clientId, data);
+        } else {
+            logger.warn(String.format("dispatchEvent : eventType unknown %s",
+                    eventType));
+        }
+    }
 
 }
--- a/server/src/main/java/org/iri_research/renkan/coweb/event/UserSyncEventManager.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/coweb/event/UserSyncEventManager.java	Wed Jan 15 18:36:27 2014 +0100
@@ -1,5 +1,6 @@
 package org.iri_research.renkan.coweb.event;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
@@ -15,74 +16,83 @@
 import org.slf4j.LoggerFactory;
 
 @Named
-public class UserSyncEventManager extends AbstractSyncEventManager<User, String> {
+public class UserSyncEventManager extends
+        AbstractSyncEventManager<User, String> {
+
+    private final Logger logger = LoggerFactory
+            .getLogger(UserSyncEventManager.class);
 
-	private final Logger logger = LoggerFactory.getLogger(UserSyncEventManager.class);
-	
-	private final static String DEFAULT_COLOR = "#000080"; 
+    private final static String DEFAULT_COLOR = "#000080";
+
+    @Inject
+    private UsersRepository usersRepository;
+
+    public UsersRepository getUsersRepository() {
+        return this.usersRepository;
+    }
 
-	@Inject
-	private UsersRepository usersRepository;
-		
-	public UsersRepository getUsersRepository() {
-		return this.usersRepository;
-	}
-	
-	@Override
-	public IRenkanRepository<User, String> getObjectRepository() {
-		return this.getUsersRepository();
-	}
+    @Override
+    public IRenkanRepository<User, String> getObjectRepository() {
+        return this.getUsersRepository();
+    }
+
+    @Override
+    public void insert(String clientId, Map<String, Object> data) {
+
+        // get project
+        this.logger.debug("UserSyncEventManager: insert User");
 
+        @SuppressWarnings("unchecked")
+        Map<String, Object> values = (Map<String, Object>) data.get("value");
+        String project_id = (String) values.get("_project_id");
 
-	@Override
-	public void insert(String clientId, Map<String, Object> data) {
-	
-		// get project
-		this.logger.debug("UserSyncEventManager: insert User");
-		
-		@SuppressWarnings("unchecked")
-		Map<String, Object> values = (Map<String, Object>) data.get("value");
-		String project_id = (String) values.get("_project_id");
+        Project project = this.getProjectsRepository().findOne(project_id);
+
+        if (null == project) {
+            throw new CowebException("user insert: project not found",
+                    String.format("Project %s not found", project_id));
+        }
 
-		Project project = this.getProjectsRepository().findOne(project_id);
-				
-		if (null == project) {
-			throw new CowebException("user insert: project not found", String.format("Project %s not found", project_id));
-		}
-		
-		String user_id = (String)values.get("id");
-		String color = (String)values.get("color");
-		if(color == null || color.length() == 0) {
-			color = UserSyncEventManager.DEFAULT_COLOR;
-		}
-		
-		User user = new User(user_id, (String)values.get("title"), (String)values.get("description"), (String)values.get("uri"), color, project_id);
-		
-		Integer position = (Integer)data.get("position");
-		
-		if(position == null || position < 0) {
-			throw new CowebException("node insert: bad insert position", String.format("Bad position %s not found", position==null?"null":position.toString()));
-		}
-		int index = position.intValue();
-		List<User> users = project.getUsers();
-		if(index > users.size()) {
-			index = users.size();
-		}
-		users.add(index,user);
+        String user_id = (String) values.get("id");
+        String color = (String) values.get("color");
+        if (color == null || color.length() == 0) {
+            color = UserSyncEventManager.DEFAULT_COLOR;
+        }
+
+        User user = new User(user_id, (String) values.get("title"),
+                (String) values.get("description"), (String) values.get("uri"),
+                color);
+
+        Integer position = (Integer) data.get("position");
 
-		this.getUsersRepository().save(user);
-		this.getProjectsRepository().save(project);
-		
-	}
+        if (position == null || position < 0) {
+            throw new CowebException("node insert: bad insert position",
+                    String.format("Bad position %s not found",
+                            position == null ? "null" : position.toString()));
+        }
+        int index = position.intValue();
+        // TODO: correct this. done that to compile
+        List<User> users = new ArrayList<User>();// project.getUsers();
+        if (index > users.size()) {
+            index = users.size();
+        }
+        users.add(index, user);
 
-	@Override
-	public void nullOperation(String clientId, Map<String, Object> data) {
-		this.logger.debug("nullOperation: NOP");
-	}
+        this.getUsersRepository().save(user);
+        this.getProjectsRepository().save(project);
+
+    }
 
-	@Override
-	protected List<User> getObjectList(Project project) {
-		return project.getUsers();
-	}
+    @Override
+    public void nullOperation(String clientId, Map<String, Object> data) {
+        this.logger.debug("nullOperation: NOP");
+    }
+
+    @Override
+    protected List<User> getObjectList(Project project) {
+        // TODO: correct this, this is wrong, just put here to cpmpile
+        return null;
+        // return project.getUsers();
+    }
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/forms/GroupForm.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,84 @@
+package org.iri_research.renkan.forms;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.iri_research.renkan.Constants;
+import org.iri_research.renkan.models.Group;
+import org.iri_research.renkan.repositories.GroupsRepository;
+import org.iri_research.renkan.repositories.IRenkanRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class GroupForm extends RenkanForm<String, Group> {
+
+    private String avatar;
+    private Set<String> users;
+
+    private GroupsRepository groupsRepository;
+    
+    
+    public GroupForm() {
+        super();
+    }
+    
+    public GroupForm(Group model) {
+        super(model);
+        if (model != null) {
+            this.avatar = model.getAvatar();
+            this.setUsers(new HashSet<>(model.getUsers()));
+            if(model.getUsers() != null) {
+                this.getUsers().addAll(model.getUsers());
+            }
+        }
+    }
+
+    public String getAvatar() {
+        return avatar;
+    }
+
+    @Override
+    protected Group getModelInstance() {
+        return new Group();
+   }
+
+    @Override
+    protected IRenkanRepository<Group, String> getRepository() {
+        return this.groupsRepository;
+    }
+
+    public GroupsRepository getGroupsRepository() {
+        return groupsRepository;
+    }
+
+
+    @Override
+    protected void saveToModel() {
+        if (this.getId() == null || this.getId().length() == 0) {
+            this.model.setId(Constants.UUID_GENERATOR.generate().toString());
+        }
+        this.model.setAvatar(this.avatar);
+        if(this.getUsers() != null) {
+            this.groupsRepository.setUsersList(model, this.getUsers());
+        }
+    }
+
+    public void setAvatar(String avatar) {
+        this.avatar = avatar;
+    }
+
+
+    @Autowired
+    public void setGroupsRepository(GroupsRepository groupsRepository) {
+        this.groupsRepository = groupsRepository;
+    }
+    
+    public Set<String> getUsers() {
+        return users;
+    }
+
+    public void setUsers(Set<String> users) {
+        this.users = users;
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/forms/GroupFormValidator.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,27 @@
+package org.iri_research.renkan.forms;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.Errors;
+import org.springframework.validation.ValidationUtils;
+import org.springframework.validation.Validator;
+
+@Component
+public class GroupFormValidator implements Validator {
+
+    @SuppressWarnings("unused")
+    private Logger logger = LoggerFactory.getLogger(GroupFormValidator.class);
+
+    @Override
+    public boolean supports(Class<?> clazz) {
+        return GroupForm.class.equals(clazz);
+    }
+
+    @Override
+    public void validate(Object target, Errors errors) {
+        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "title",
+                "renkan.error.name.empty");
+    }
+
+}
--- a/server/src/main/java/org/iri_research/renkan/forms/RenkanForm.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/forms/RenkanForm.java	Wed Jan 15 18:36:27 2014 +0100
@@ -6,99 +6,111 @@
 import org.iri_research.renkan.models.IRenkanModel;
 import org.iri_research.renkan.repositories.IRenkanRepository;
 
-public abstract class RenkanForm <ID extends Serializable, RM extends IRenkanModel<ID>> {
-	
-	protected RM model;
-	
-	private ID id;
-	private String title;
-	private String description;
-	private String uri;
-	private String color;
-	
-	protected abstract void saveToModel();
-	protected abstract IRenkanRepository<RM, ID> getRepository();
-	protected abstract RM getModelInstance();
-	
-	public RenkanForm() {}
-	
-	public RenkanForm(RM model) {
-		this.model = model;
-		this.id = model.getId();
-		this.title = model.getTitle();
-		this.description = model.getDescription();
-		this.color = model.getColor();
-		this.uri = model.getUri();
-	}
-	
-	public ID getId() {
-		return id;
-	}
-	public void setId(ID id) {
-		this.id = id;
-	}
-	public String getTitle() {
-		return title;
-	}
-	public void setTitle(String title) {
-		this.title = title;
-	}
-	public String getDescription() {
-		return description;
-	}
-	public void setDescription(String description) {
-		this.description = description;
-	}
-	public String getUri() {
-		return uri;
-	}
-	public void setUri(String uri) {
-		this.uri = uri;
-	}
-	public String getColor() {
-		return color;
-	}
-	public void setColor(String color) {
-		this.color = color;
-	}
-	
-	public void setModel(RM model) {
-		this.model = model;
-	}
-	
-	private void saveToRenkanModel() {
-		
-		this.model.setTitle(title);
-		this.model.setDescription(description);
-		this.model.setColor(color);
-		this.model.setUri(uri);
-	}
-	
-	
-	public RM save() throws RenkanException {
+public abstract class RenkanForm<ID extends Serializable, RM extends IRenkanModel<ID>> {
+
+    protected RM model;
+
+    private ID id;
+    private String title;
+    private String description;
+    private String uri;
+    private String color;
+
+    protected abstract void saveToModel();
+
+    protected abstract IRenkanRepository<RM, ID> getRepository();
+
+    protected abstract RM getModelInstance();
+
+    public RenkanForm() {
+    }
+
+    public RenkanForm(RM model) {
+        if (model == null) {
+            return;
+        }
+        this.model = model;
+        this.id = model.getId();
+        this.title = model.getTitle();
+        this.description = model.getDescription();
+        this.color = model.getColor();
+        this.uri = model.getUri();
+    }
+
+    public ID getId() {
+        return id;
+    }
+
+    public void setId(ID id) {
+        this.id = id;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescription() {
+        return description;
+    }
 
-		if(this.model == null) {
-			
-			if(this.getId() != null) {
-				this.model = this.getRepository().findOne(this.getId());
-				if(this.model == null) {
-					throw new RenkanException("Model id " + this.getId().toString() + " not found");
-				}
-			}
-			else {
-				this.model = this.getModelInstance();
-			}
-		}
-		
-		this.saveToRenkanModel();
-		this.saveToModel();
-		
-		this.model = this.getRepository().save(this.model);
-		
-		return this.model;
-		
-	}
-	
-	
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getUri() {
+        return uri;
+    }
+
+    public void setUri(String uri) {
+        this.uri = uri;
+    }
+
+    public String getColor() {
+        return color;
+    }
+
+    public void setColor(String color) {
+        this.color = color;
+    }
+
+    public void setModel(RM model) {
+        this.model = model;
+    }
+
+    private void saveToRenkanModel() {
+
+        this.model.setTitle(title);
+        this.model.setDescription(description);
+        this.model.setColor(color);
+        this.model.setUri(uri);
+    }
+
+    public RM save() throws RenkanException {
+
+        if (this.model == null) {
+
+            if (this.getId() != null) {
+                this.model = this.getRepository().findOne(this.getId());
+                if (this.model == null) {
+                    throw new RenkanException("Model id "
+                            + this.getId().toString() + " not found");
+                }
+            } else {
+                this.model = this.getModelInstance();
+            }
+        }
+
+        this.saveToRenkanModel();
+        this.saveToModel();
+
+        this.model = this.getRepository().save(this.model);
+
+        return this.model;
+
+    }
 
 }
--- a/server/src/main/java/org/iri_research/renkan/forms/SpaceForm.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/forms/SpaceForm.java	Wed Jan 15 18:36:27 2014 +0100
@@ -1,69 +1,66 @@
 package org.iri_research.renkan.forms;
 
-import java.util.Date;
-
 import org.iri_research.renkan.Constants;
 import org.iri_research.renkan.models.Space;
 import org.iri_research.renkan.repositories.IRenkanRepository;
 import org.iri_research.renkan.repositories.SpacesRepository;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
+import org.joda.time.DateTime;
 
-@Component
 public class SpaceForm extends RenkanForm<String, Space> {
-	
-	@Autowired
-	private SpacesRepository spacesRepository;
-	
-	public SpaceForm() {
-		super();
-	}
-	
-	public SpaceForm(Space model) {
-		super(model);
-		this.binConfig = model.getBinConfig();
-		this.image = model.getImage();
-	}	
-	
-	private String binConfig;	
-	private String image;
+
+    private SpacesRepository spacesRepository;
+
+    public SpaceForm() {
+        super();
+    }
+
+    public SpaceForm(Space model) {
+        super(model);
+        this.binConfig = model.getBinConfig();
+        this.image = model.getImage();
+    }
+
+    private String binConfig;
+    private String image;
+
+    public String getBinConfig() {
+        return binConfig;
+    }
+
+    public void setBinConfig(String binConfig) {
+        this.binConfig = binConfig;
+    }
 
-	public String getBinConfig() {
-		return binConfig;
-	}
-	public void setBinConfig(String binConfig) {
-		this.binConfig = binConfig;
-	}
-	public String getImage() {
-		return image;
-	}
-	public void setImage(String image) {
-		this.image = image;
-	}
+    public String getImage() {
+        return image;
+    }
+
+    public void setImage(String image) {
+        this.image = image;
+    }
 
-	@Override
-	protected void saveToModel() {
-		if(this.getId() == null || this.getId().length() == 0) {			
-			this.model.setId(Constants.UUID_GENERATOR.generate().toString());
-			this.model.setCreated(new Date());
-		}
-		this.model.setBinConfig(binConfig);
-		this.model.setImage(image);
-	}
+    @Override
+    protected void saveToModel() {
+        if (this.getId() == null || this.getId().length() == 0) {
+            this.model.setId(Constants.UUID_GENERATOR.generate().toString());
+            this.model.setCreated(new DateTime());
+        }
+        this.model.setBinConfig(binConfig);
+        this.model.setImage(image);
+    }
 
-	@Override
-	protected IRenkanRepository<Space, String> getRepository() {
-		return this.spacesRepository;
-	}
+    @Override
+    protected IRenkanRepository<Space, String> getRepository() {
+        return this.spacesRepository;
+    }
 
-	@Override
-	protected Space getModelInstance() {
-		return new Space();
-	}
+    @Override
+    protected Space getModelInstance() {
+        return new Space();
+    }
 
-	@Autowired
-	public void setSpacesRepository(SpacesRepository spacesRepository) {
-		this.spacesRepository = spacesRepository;
-	}
-	
+    public void setSpacesRepository(SpacesRepository spacesRepository) {
+        this.spacesRepository = spacesRepository;
+    }
+
 }
--- a/server/src/main/java/org/iri_research/renkan/forms/SpaceFormValidator.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/forms/SpaceFormValidator.java	Wed Jan 15 18:36:27 2014 +0100
@@ -11,38 +11,46 @@
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.joda.JodaModule;
 
 @Component
 public class SpaceFormValidator implements Validator {
-	
-	private Logger logger = LoggerFactory.getLogger(SpaceFormValidator.class);
+
+    private Logger logger = LoggerFactory.getLogger(SpaceFormValidator.class);
 
-	@Override
-	public boolean supports(Class<?> clazz) {
-		return SpaceForm.class.equals(clazz);
-	}
+    @Override
+    public boolean supports(Class<?> clazz) {
+        return SpaceForm.class.equals(clazz);
+    }
 
-	@Override
-	public void validate(Object target, Errors errors) {
-		SpaceForm space = (SpaceForm)target;
+    @Override
+    public void validate(Object target, Errors errors) {
+        SpaceForm space = (SpaceForm) target;
+
+        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "title",
+                "renkan.error.title.empty");
 
-		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "title", "renkan.error.title.empty");
-		
-		if(space.getBinConfig() != null && space.getBinConfig().length()>0) {
-			boolean valid = false;
-			ObjectMapper mapper = new ObjectMapper();
-			try {
-				mapper.readTree(space.getBinConfig());
-				valid = true;
-			} catch (JsonProcessingException e) {
-				logger.debug("SpaceValidator JsonProcessingException error validating bin config", e);
-			} catch (IOException e) {
-				logger.debug("SpaceValidator IOException error validating bin config", e);
-			}
-			if(!valid) {
-				errors.rejectValue("binConfig", "renkan.error.bin_config.json");
-			}
-		}
-	}
+        if (space.getBinConfig() != null && space.getBinConfig().length() > 0) {
+            boolean valid = false;
+            ObjectMapper mapper = new ObjectMapper();
+            mapper.registerModule(new JodaModule());
+            
+            try {
+                mapper.readTree(space.getBinConfig());
+                valid = true;
+            } catch (JsonProcessingException e) {
+                logger.debug(
+                        "SpaceValidator JsonProcessingException error validating bin config",
+                        e);
+            } catch (IOException e) {
+                logger.debug(
+                        "SpaceValidator IOException error validating bin config",
+                        e);
+            }
+            if (!valid) {
+                errors.rejectValue("binConfig", "renkan.error.bin_config.json");
+            }
+        }
+    }
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/forms/UserForm.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,183 @@
+package org.iri_research.renkan.forms;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.iri_research.renkan.Constants;
+import org.iri_research.renkan.models.User;
+import org.iri_research.renkan.repositories.IRenkanRepository;
+import org.iri_research.renkan.repositories.UsersRepository;
+import org.joda.time.LocalDate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.format.annotation.DateTimeFormat.ISO;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+public class UserForm extends RenkanForm<String, User> {
+
+    private String avatar;
+
+    @DateTimeFormat(iso = ISO.DATE)
+    private LocalDate credentialsExpirationDate;
+    @DateTimeFormat(iso = ISO.DATE)
+    private LocalDate expirationDate;
+
+    private String email;
+
+    private boolean enabled;
+    private boolean locked;
+    private String password;
+    private String passwordConfirm;
+    private Set<String> groups;
+    private List<String> userAuthorities;
+
+    private UsersRepository usersRepository;
+    
+    
+    private PasswordEncoder passwordEncoder;
+    
+    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
+        this.passwordEncoder = passwordEncoder;
+    }
+    
+    public UserForm() {
+        super();
+    }
+    
+    public UserForm(User model) {
+        super(model);
+        if (model != null) {
+            this.avatar = model.getAvatar();
+            this.credentialsExpirationDate = model.getCredentialsExpirationDate();
+            this.email = model.getEmail();
+            this.expirationDate = model.getExpirationDate();
+            this.enabled = model.isEnabled();
+            this.locked = model.isLocked();
+            this.userAuthorities = model.getUserAuthorities()!=null?new ArrayList<String>(model.getUserAuthorities()):new ArrayList<String>();
+            this.setGroups(new HashSet<>(model.getGroups()));
+        }
+    }
+
+    public String getAvatar() {
+        return avatar;
+    }
+
+    public LocalDate getCredentialsExpirationDate() {
+        return credentialsExpirationDate;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public LocalDate getExpirationDate() {
+        return expirationDate;
+    }
+
+    @Override
+    protected User getModelInstance() {
+        return new User();
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public String getPasswordConfirm() {
+        return passwordConfirm;
+    }
+
+    @Override
+    protected IRenkanRepository<User, String> getRepository() {
+        return this.usersRepository;
+    }
+
+    public UsersRepository getUsersRepository() {
+        return usersRepository;
+    }
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public boolean isLocked() {
+        return locked;
+    }
+
+    @Override
+    protected void saveToModel() {
+        if (this.getId() == null || this.getId().length() == 0) {
+            this.model.setId(Constants.UUID_GENERATOR.generate().toString());
+        }
+        this.model.setAvatar(this.avatar);
+        this.model.setEmail(this.email);
+        this.model.setCredentialsExpirationDate(this.credentialsExpirationDate);
+        this.model.setExpirationDate(this.expirationDate);
+        this.model.setEnabled(this.enabled);
+        this.model.setLocked(this.locked);
+        this.model.setUserAuthorities((this.userAuthorities!=null && !this.userAuthorities.isEmpty())?new ArrayList<String>(this.userAuthorities):null);
+        if(this.getGroups() != null) {
+            this.usersRepository.setGroupsList(this.model, this.getGroups());
+        }
+        if(this.password != null && this.password.length() > 0) {
+            this.model.setPassword(this.passwordEncoder.encode(this.password));
+        }
+
+    }
+
+    public void setAvatar(String avatar) {
+        this.avatar = avatar;
+    }
+
+    public void setCredentialsExpirationDate(LocalDate credentialsExpirationDate) {
+        this.credentialsExpirationDate = credentialsExpirationDate;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public void setExpirationDate(LocalDate expirationDate) {
+        this.expirationDate = expirationDate;
+    }
+
+    public void setLocked(boolean locked) {
+        this.locked = locked;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public void setPasswordConfirm(String passwordConfirm) {
+        this.passwordConfirm = passwordConfirm;
+    }
+
+    @Autowired
+    public void setUsersRepository(UsersRepository usersRepository) {
+        this.usersRepository = usersRepository;
+    }
+
+    public List<String> getUserAuthorities() {
+        return userAuthorities;
+    }
+
+    public void setUserAuthorities(List<String> userAuthorities) {
+        this.userAuthorities = userAuthorities;
+    }
+
+    public Set<String> getGroups() {
+        return groups;
+    }
+
+    public void setGroups(Set<String> groups) {
+        this.groups = groups;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/forms/UserFormValidator.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,47 @@
+package org.iri_research.renkan.forms;
+
+import org.iri_research.renkan.Constants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.Errors;
+import org.springframework.validation.ValidationUtils;
+import org.springframework.validation.Validator;
+
+@Component
+public class UserFormValidator implements Validator {
+
+    @SuppressWarnings("unused")
+    private Logger logger = LoggerFactory.getLogger(UserFormValidator.class);
+
+    @Override
+    public boolean supports(Class<?> clazz) {
+        return UserForm.class.equals(clazz);
+    }
+
+    @Override
+    public void validate(Object target, Errors errors) {
+        UserForm userForm = (UserForm) target;
+
+        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "title",
+                "renkan.error.name.empty");
+        
+        //TODO : check for user name unicity
+        String pswd = userForm.getPassword();
+        String pswdConf = userForm.getPasswordConfirm();
+        
+        if( (pswd == null && pswdConf != null)
+            || ((pswd != null || pswdConf != null) && !pswd.equals(pswdConf))) {
+            errors.rejectValue("password", "renkan.error.password.equals");
+        }
+        
+        if(userForm.getId() == null && (pswd == null || pswd.length() == 0)) {
+            errors.rejectValue("password", "renkan.error.password.missing");
+        }
+        
+        if(userForm.getUserAuthorities() != null && !Constants.USER_ROLES_ALL.containsAll(userForm.getUserAuthorities())) {
+            errors.rejectValue("userAuthorities", "renkan.error.authorities.bad_value", "Bad role value");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/management/MigrateRenkanUser.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,77 @@
+package org.iri_research.renkan.management;
+
+import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.models.RenkanUser;
+import org.iri_research.renkan.models.User;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.stereotype.Component;
+
+import com.mongodb.BasicDBObject;
+import com.mongodb.DBCollection;
+import com.mongodb.DBObject;
+import com.mongodb.WriteConcern;
+
+@Component
+public class MigrateRenkanUser {
+
+    public static void main(String[] args) {
+
+        @SuppressWarnings("resource")
+        ApplicationContext context = new ClassPathXmlApplicationContext(
+                "classpath:WEB-INF/applicationContext.xml");
+
+        MigrateRenkanUser p = context.getBean(MigrateRenkanUser.class);
+        p.start(args);
+
+    }
+
+    @Autowired
+    private MongoTemplate template;
+
+    private void start(String[] args) {
+
+        DBCollection userColl = template.getCollection(template
+                .getCollectionName(User.class));
+        DBCollection renkanUserColl = template.getCollection(template
+                .getCollectionName(RenkanUser.class));
+        DBCollection projectColl = template.getCollection(template
+                .getCollectionName(Project.class));
+
+        for (DBObject user : userColl.find()) {
+            if (!user.containsField("project_id")) {
+                continue;
+            }
+            String projectId = (String) user.get("project_id");
+            if (projectId == null || projectId.isEmpty()) {
+                user.removeField("project_id");
+                userColl.save(user);
+                continue;
+            }
+            DBObject proj = new BasicDBObject();
+            proj.put("_id", projectId);
+            if (projectColl.findOne(proj) != null) {
+                DBObject renkanUser = new BasicDBObject();
+                renkanUser.put("project_id", projectId);
+                renkanUser.put("user_id", user.get("_id"));
+                if (renkanUserColl.findOne(renkanUser) == null) {
+                    System.out.println(String.format("%s : %s : %s",
+                            user.get("_id"), user.get("title"),
+                            user.get("project_id")));
+                    renkanUser = new BasicDBObject();
+                    renkanUser.put("project_id", user.get("project_id"));
+                    renkanUser.put("user_id", user.get("_id"));
+                    renkanUser.put("color", user.get("color"));
+                    renkanUserColl.insert(renkanUser);
+                }
+                user.removeField("project_id");
+                userColl.save(user);
+            } else {
+                userColl.remove(user, WriteConcern.ACKNOWLEDGED);
+            }
+        }
+
+    }
+}
--- a/server/src/main/java/org/iri_research/renkan/models/AbstractRenkanModel.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/models/AbstractRenkanModel.java	Wed Jan 15 18:36:27 2014 +0100
@@ -1,82 +1,139 @@
 package org.iri_research.renkan.models;
 
 import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
 
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.commons.codec.binary.Hex;
+import org.iri_research.renkan.Constants;
+import org.iri_research.renkan.RenkanException;
 import org.iri_research.renkan.RenkanRuntimeException;
 
+public abstract class AbstractRenkanModel<ID extends Serializable> implements
+        IRenkanModel<ID> {
 
-public abstract class AbstractRenkanModel<ID extends Serializable> implements IRenkanModel<ID> {
-	
-	public AbstractRenkanModel(ID id, String title, String description, String uri, String color) {
-		super();
-		this.id = id;
-		this.title = title;
-		this.description = description;
-		this.uri = uri;
-		this.color = color;
-	}
-	
-	protected AbstractRenkanModel() {		
-	}
+    public AbstractRenkanModel(ID id, String title, String description,
+            String uri, String color) {
+        super();
+        this.id = id;
+        this.title = title;
+        this.description = description;
+        this.uri = uri;
+        this.color = color;
+    }
+
+    protected AbstractRenkanModel() {
+    }
+
+    protected ID id;
+    protected String title;
+    protected String description;
+    protected String uri;
+    protected String color;
+
+    @Override
+    public String getTitle() {
+        return this.title;
+    }
 
-	protected ID id;
-	protected String title;
-	protected String description;
-	protected String uri;
-	protected String color;
-	
-	@Override
-	public String getTitle() {
-		return this.title;
-	}
+    @Override
+    public String getDescription() {
+        return this.description;
+    }
+
+    @Override
+    public String getUri() {
+        return this.uri;
+    }
+
+    @Override
+    public String getColor() {
+        return this.color;
+    }
 
-	@Override
-	public String getDescription() {
-		return this.description;
-	}
+    @Override
+    public ID getId() {
+        return this.id;
+    }
+
+    @Override
+    public void setId(ID id) throws RenkanRuntimeException {
+        if (this.id != null) {
+            throw new RenkanRuntimeException(
+                    "Current id is not null, can not change object id");
+        }
+        this.id = id;
+    }
+
+    @Override
+    public void setTitle(String title) {
+        this.title = title;
+    }
 
-	@Override
-	public String getUri() {
-		return this.uri;
-	}
-	
-	@Override
-	public String getColor() {
-		return this.color;
-	}
-	
-	@Override
-	public ID getId() {
-		return this.id;
-	}
-	
-	@Override
-	public void setId(ID id) throws RenkanRuntimeException {
-		if(this.id != null) {
-			throw new RenkanRuntimeException("Current id is not null, can not change object id");
-		}
-		this.id = id;
-	}
+    @Override
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    @Override
+    public void setUri(String uri) {
+        this.uri = uri;
+    }
+
+    @Override
+    public void setColor(String color) {
+        this.color = color;
+    }
+
+    abstract protected String getRawKeyPart();
+
+    private String getRawKey(String salt) {
+        StringBuffer key = new StringBuffer(salt != null ? salt + "|" : "");
+        key.append(this.getId());
+        key.append('|');
+        key.append(this.getRawKeyPart());
+        return key.toString();
+    }
+
+    public String getKey(String salt) throws RenkanException {
+
+        String rawKey = this.getRawKey(salt);
 
-	@Override
-	public void setTitle(String title) {
-		this.title = title;
-	}
-
-	@Override
-	public void setDescription(String description) {
-		this.description = description;
-	}
+        MessageDigest md;
+        try {
+            md = MessageDigest.getInstance("SHA-256");
+        } catch (NoSuchAlgorithmException e) {
+            throw new RenkanException("NoSuchAlgorithmException digest: "
+                    + e.getMessage(), e);
+        }
+        String key;
+        final SecretKeySpec secret_key = new SecretKeySpec(
+                Constants.KEYHEX.getBytes(), "HmacSHA256");
+        md.update(secret_key.getEncoded());
+        try {
+            key = Hex.encodeHexString(md.digest(rawKey.getBytes("UTF-8")));
+        } catch (UnsupportedEncodingException e) {
+            throw new RenkanException("UnsupportedEncodingException digest: "
+                    + e.getMessage(), e);
+        }
 
-	@Override
-	public void setUri(String uri) {
-		this.uri = uri;
-	}
+        return key;
+    }
+
+    public boolean checkKey(String key, String salt) throws RenkanException {
+
+        if (key == null || key.isEmpty()) {
+            return false;
+        }
 
-	@Override
-	public void setColor(String color) {
-		this.color = color;
-	}
-	
-		
+        String signature = key;
+
+        String new_key = this.getKey(salt);
+
+        return new_key.equals(signature);
+    }
+
 }
--- a/server/src/main/java/org/iri_research/renkan/models/Edge.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/models/Edge.java	Wed Jan 15 18:36:27 2014 +0100
@@ -9,82 +9,85 @@
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-
-@Document(collection="edges")
+@Document(collection = "edges")
 public class Edge extends AbstractRenkanModel<String> {
 
-	@DBRef
-	private Node from;
-	
-	@DBRef
-	private Node to;
-	
-	@Field("project_id")
-	@JsonProperty("project_id")
-	private String projectId;
-	
-	@Field("created_by")
-	@JsonProperty("created_by")
-	private String createdBy;
-		
-	@SuppressWarnings("unused")
-	private Edge() {		
-	}
-	
-	public Edge(Edge edge, Node from, Node to, String projectId) {
-		this(Constants.UUID_GENERATOR.generate().toString(), edge.title, edge.description, edge.uri, edge.color, from, to, edge.createdBy, projectId);
-	}	
+    @DBRef
+    private Node from;
+
+    @DBRef
+    private Node to;
+
+    @Field("project_id")
+    @JsonProperty("project_id")
+    private String projectId;
+
+    @Field("created_by")
+    @JsonProperty("created_by")
+    private String createdBy;
+
+    @SuppressWarnings("unused")
+    private Edge() {
+    }
 
-	public Edge(Edge edge) {
-		this(edge, edge.from, edge.to, edge.projectId);
-	}	
+    public Edge(Edge edge, Node from, Node to, String projectId) {
+        this(Constants.UUID_GENERATOR.generate().toString(), edge.title,
+                edge.description, edge.uri, edge.color, from, to,
+                edge.createdBy, projectId);
+    }
+
+    public Edge(Edge edge) {
+        this(edge, edge.from, edge.to, edge.projectId);
+    }
 
-	@Autowired(required=true)
-	public Edge(String id, String title, String description, String uri, String color, Node from, Node to, String createdBy, String projectId) {
-		super(id,title, description, uri, color);
-		this.from = from;
-		this.to = to;
-		this.createdBy = createdBy;
-		this.projectId = projectId;
-	}
-
+    @Autowired(required = true)
+    public Edge(String id, String title, String description, String uri,
+            String color, Node from, Node to, String createdBy, String projectId) {
+        super(id, title, description, uri, color);
+        this.from = from;
+        this.to = to;
+        this.createdBy = createdBy;
+        this.projectId = projectId;
+    }
 
-	@JsonProperty("project_id")
-	public String getProjectId() {
-		return projectId;
-	}
+    @JsonProperty("project_id")
+    public String getProjectId() {
+        return projectId;
+    }
 
+    public String getCreatedBy() {
+        return createdBy;
+    }
+
+    @JsonIgnore
+    public Node getFromNode() {
+        return this.from;
+    }
 
-	public String getCreatedBy() {
-		return createdBy;
-	}
-	
-	@JsonIgnore
-	public Node getFromNode() {
-		return this.from;
-	}
-	
-	public String getFrom() {
-		if(this.from != null) {
-			return this.from.id;
-		}
-		else {
-			return null;
-		}
-	}
+    public String getFrom() {
+        if (this.from != null) {
+            return this.from.id;
+        } else {
+            return null;
+        }
+    }
+
+    @JsonIgnore
+    public Node getToNode() {
+        return this.to;
+    }
 
-	@JsonIgnore
-	public Node getToNode() {
-		return this.to;
-	}
-	
-	public String getTo() {
-		if(this.to != null) {
-			return this.to.id;
-		}
-		else {
-			return null;
-		}
-	}
-	
+    public String getTo() {
+        if (this.to != null) {
+            return this.to.id;
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    protected String getRawKeyPart() {
+        return this.createdBy;
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/models/Group.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,66 @@
+package org.iri_research.renkan.models;
+
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.springframework.data.mongodb.core.mapping.Document;
+
+@Document(collection = "groups")
+public class Group extends AbstractRenkanModel<String> {
+
+    private String avatar;
+    private Set<String> users = new TreeSet<>();
+    
+    public Group() {
+    }
+    
+    public Group(String id, String title, String description, String uri,
+            String color) {
+        super(id, title, description, uri, color);
+    }
+
+    public String getAvatar() {
+        return avatar;
+    }
+    
+    public void setAvatar(String avatar) {
+        this.avatar = avatar;
+    }
+
+    public String getGroupName() {
+        return this.getTitle();
+    }
+
+    @Override
+    protected String getRawKeyPart() {
+        return this.id;
+    }
+    
+    public Set<String> getUsers() {
+        if(this.users == null) {
+            this.users = new TreeSet<>();
+        }
+        return this.users;
+    }
+
+
+    public boolean addUser(User user) {
+        return this.addUser(user.getId());
+    }
+    
+    public boolean addUser(String userId) {
+        return this.getUsers().add(userId);
+    }
+    
+    public boolean removeUser(User user) {
+        return this.removeUser(user.getId());
+    }
+    
+    public boolean removeUser(String userId) {
+        if(this.getUsers() != null) {
+            return this.getUsers().remove(userId);
+        }
+        return false;
+    }
+
+}
--- a/server/src/main/java/org/iri_research/renkan/models/IRenkanModel.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/models/IRenkanModel.java	Wed Jan 15 18:36:27 2014 +0100
@@ -2,28 +2,41 @@
 
 import java.io.Serializable;
 
+import org.iri_research.renkan.RenkanException;
 import org.iri_research.renkan.RenkanRuntimeException;
 
-
 public interface IRenkanModel<ID extends Serializable> {
-	
-	public ID getId();
-	/**
-	 * Set the object id.
-	 * This method must throw a RenkanException if the current object id is not null 
-	 * @param id
-	 * @throws RenkanRuntimeException if the current id is not null
-	 */
-	public void setId(ID id) throws RenkanRuntimeException;
-	public String getTitle();
-	public String getDescription();
-	public String getUri();
-	public String getColor();
+
+    public ID getId();
+
+    /**
+     * Set the object id. This method must throw a RenkanException if the
+     * current object id is not null
+     * 
+     * @param id
+     * @throws RenkanRuntimeException
+     *             if the current id is not null
+     */
+    public void setId(ID id) throws RenkanRuntimeException;
+
+    public String getTitle();
+
+    public String getDescription();
 
-	public void setTitle(String title);
-	public void setDescription(String description);
-	public void setUri(String uri);
-	public void setColor(String color);
+    public String getUri();
+
+    public String getColor();
+
+    public void setTitle(String title);
+
+    public void setDescription(String description);
 
-	
+    public void setUri(String uri);
+
+    public void setColor(String color);
+
+    public String getKey(String salt) throws RenkanException;
+
+    public boolean checkKey(String key, String salt) throws RenkanException;
+
 }
--- a/server/src/main/java/org/iri_research/renkan/models/Node.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/models/Node.java	Wed Jan 15 18:36:27 2014 +0100
@@ -8,66 +8,75 @@
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-@Document(collection="nodes")
+@Document(collection = "nodes")
 public class Node extends AbstractRenkanModel<String> {
 
-	public Node(Node node, String projectId) {
-		this(Constants.UUID_GENERATOR.generate().toString(), node.title, node.description, node.uri, node.color, node.createdBy, node.position, node.image, node.size, projectId);
-	}
-	
-	public Node(Node node) {
-		this(node, node.projectId);
-	}
-	
-	@SuppressWarnings("unused")
-	private Node() {		
-	}
+    public Node(Node node, String projectId) {
+        this(Constants.UUID_GENERATOR.generate().toString(), node.title,
+                node.description, node.uri, node.color, node.createdBy,
+                node.position, node.image, node.size, projectId);
+    }
+
+    public Node(Node node) {
+        this(node, node.projectId);
+    }
+
+    @SuppressWarnings("unused")
+    private Node() {
+    }
 
-	@Autowired(required=true)
-	public Node(String id, String title, String description, String uri, String color, String createdBy, Point position, String image, Integer size, String projectId) {
-		super(id, title, description, uri, color);
-		
-		this.projectId = projectId;
-		this.createdBy = createdBy;
-		this.position = position;
-		this.image = image;
-		this.size = (size == null) ? 0 : size.intValue();
-	}	
+    @Autowired(required = true)
+    public Node(String id, String title, String description, String uri,
+            String color, String createdBy, Point position, String image,
+            Integer size, String projectId) {
+        super(id, title, description, uri, color);
 
-	@Field("project_id")
-	@JsonProperty("project_id")	
-	private String projectId = null;	
+        this.projectId = projectId;
+        this.createdBy = createdBy;
+        this.position = position;
+        this.image = image;
+        this.size = (size == null) ? 0 : size.intValue();
+    }
+
+    @Field("project_id")
+    @JsonProperty("project_id")
+    private String projectId = null;
+
+    @Field("created_by")
+    @JsonProperty("created_by")
+    private String createdBy = null;
 
-	@Field("created_by")
-	@JsonProperty("created_by")
-	private String createdBy = null;
-	
-	private Point position = null;
+    private Point position = null;
+
+    private String image;
+
+    private int size;
 
-	private String image;
-	
-	private int size;
-	
-	public Point getPosition() {
-		return position;
-	}
+    public Point getPosition() {
+        return position;
+    }
+
+    public String getImage() {
+        return image;
+    }
 
-	public String getImage() {
-		return image;
-	}
+    @JsonProperty("project_id")
+    public String getProjectId() {
+        return projectId;
+    }
 
-	@JsonProperty("project_id")
-	public String getProjectId() {
-		return projectId;
-	}
+    @JsonProperty("created_by")
+    public String getCreatedBy() {
+        return createdBy;
+    }
 
-	@JsonProperty("created_by")
-	public String getCreatedBy() {
-		return createdBy;
-	}
+    public int getSize() {
+        return size;
+    }
 
-	public int getSize() {
-		return size;
-	}
-	
+    @Override
+    protected String getRawKeyPart() {
+        return this.createdBy;
+    }
+
 }
--- a/server/src/main/java/org/iri_research/renkan/models/Project.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/models/Project.java	Wed Jan 15 18:36:27 2014 +0100
@@ -4,7 +4,6 @@
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -15,6 +14,8 @@
 import org.iri_research.renkan.Constants;
 import org.iri_research.renkan.Constants.EditMode;
 import org.iri_research.renkan.RenkanException;
+import org.iri_research.renkan.utils.ColorGenerator;
+import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -22,165 +23,240 @@
 import org.springframework.data.mongodb.core.mapping.Document;
 import org.springframework.data.mongodb.core.mapping.Field;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-@Document(collection="projects")
+@Document(collection = "projects")
 public class Project extends AbstractRenkanModel<String> {
-	
-	@SuppressWarnings("unused")
-	private static Logger logger = LoggerFactory.getLogger(Project.class); 
-			
-	@Field("rev_counter")
-	private int revCounter = 1;
-	
-	private Date created;
-	private Date updated;
-	
-	// Space
-	@Field("space_id")
-	@JsonProperty("space_id")
-	private String spaceId = null;
-	
-	// Nodes
-	@DBRef
-	private List<Node> nodes = new ArrayList<Node>();
-	
-	// edges
-	@DBRef
-	private List<Edge> edges = new ArrayList<Edge>();
+
+    @SuppressWarnings("unused")
+    private static Logger logger = LoggerFactory.getLogger(Project.class);
+
+    @Field("rev_counter")
+    private int revCounter = 1;
+
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "GMT")
+    private DateTime created;
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "GMT")
+    private DateTime updated;
+
+    // Space
+    @Field("space_id")
+    @JsonProperty("space_id")
+    private String spaceId = null;
+
+    // Nodes
+    @DBRef
+    private List<Node> nodes = new ArrayList<Node>();
+
+    // edges
+    @DBRef
+    private List<Edge> edges = new ArrayList<Edge>();
+
+    // Users
+    private List<RenkanUser> users = new ArrayList<RenkanUser>();
+
+    public Project(Project project) {
+        this(project.spaceId, Constants.UUID_GENERATOR.generate().toString(),
+                project.title, project.description, project.uri, new DateTime());
+
+        Map<String, Node> nodeCloneMap = new HashMap<String, Node>(
+                project.nodes.size());
+        for (Node node : project.nodes) {
+            Node newNode = new Node(node, this.id);
+            this.nodes.add(newNode);
+            nodeCloneMap.put(node.id, newNode);
+        }
+
+        for (Edge edge : project.edges) {
+            this.edges.add(new Edge(edge, nodeCloneMap.get(edge.getFrom()),
+                    nodeCloneMap.get(edge.getTo()), this.id));
+        }
+        for (RenkanUser user : project.users) {
+            this.users.add(new RenkanUser(user));
+        }
+    }
 
-	// Users
-	@DBRef
-	private List<User> users = new ArrayList<User>();
-	
-	
-	public Project(Project project) {
-		this(project.spaceId, Constants.UUID_GENERATOR.generate().toString(), project.title, project.description, project.uri, new Date());
-		
-		Map<String, Node> nodeCloneMap = new HashMap<String, Node>(project.nodes.size());
-		for (Node node : project.nodes) {
-			Node newNode = new Node(node,this.id);
-			this.nodes.add(newNode);
-			nodeCloneMap.put(node.id, newNode);
-		}
+    public Project(String spaceId, String id, String title, String description,
+            String uri, DateTime created, int revCounter) {
+        super(id, title, description, uri, null);
+        this.revCounter = revCounter;
+        this.spaceId = spaceId;
+        this.created = created;
+        if (this.created == null) {
+            this.created = new DateTime();
+        }
+        this.setUpdated(new DateTime());
+    }
+
+    @Autowired(required = true)
+    public Project(String spaceId, String id, String title, String description,
+            String uri, DateTime created) {
+        this(spaceId, id, title, description, uri, created, 1);
+    }
+
+    @SuppressWarnings("unused")
+    private Project() {
+    }
+
+    public int getRevCounter() {
+        return this.revCounter;
+    }
+
+    public List<Node> getNodes() {
+        return this.nodes;
+    }
 
-		for (Edge edge : project.edges) {
-			this.edges.add(new Edge(edge, nodeCloneMap.get(edge.getFrom()), nodeCloneMap.get(edge.getTo()), this.id));
-		}
-		for(User user : project.users) {
-			this.users.add(user);
-		}
-	}
-	
-	public Project(String spaceId, String id, String title, String description, String uri, Date created,
-			int revCounter) {
-		super(id,title, description, uri, null);
-		this.revCounter = revCounter;
-		this.spaceId = spaceId;
-		this.created = created;
-		if(this.created == null) {
-			this.created = new Date();
-		}
-		this.setUpdated(new Date()); 
-	}
+    public List<Edge> getEdges() {
+        return this.edges;
+    }
+
+    public List<RenkanUser> getUsers() {
+        return this.users;
+    }
+
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "GMT")
+    public DateTime getCreated() {
+        return created;
+    }
+
+    public void setCreated(DateTime date) {
+        this.created = date;
 
-	@Autowired(required=true)
-	public Project(String spaceId, String id, String title, String description, String uri, Date created) {
-		this(spaceId, id,title, description, uri, created, 1);
-	}
-	
-	@SuppressWarnings("unused")
-	private Project() {		
-	}
-		
-	public int getRevCounter() {
-		return this.revCounter;
-	}
-	
-	public List<Node> getNodes() {
-		return this.nodes;
-	}
+    }
+
+    @JsonProperty("space_id")
+    public String getSpaceId() {
+        return spaceId;
+    }
+
+    private String getRawKey(String prefix, Constants.EditMode editMode) {
+        StringBuffer key = new StringBuffer(prefix != null ? prefix + "|" : "");
+        key.append(this.getId());
+        key.append('|');
+        key.append(this.getSpaceId());
+        key.append('|');
+        key.append(this.getCreated().getMillis());
+        key.append('|');
+        key.append(editMode.toString());
+        return key.toString();
+    }
 
-	public List<Edge> getEdges() {
-		return this.edges;
-	}
-	
-	public List<User> getUsers() {
-		return this.users;
-	}
+    public String getKey(int editMode) throws RenkanException {
+        return this.getKey(EditMode.fromInt(editMode));
+    }
+
+    public String getKey(Constants.EditMode editMode) throws RenkanException {
+
+        String rawKey = this.getRawKey("", editMode);
+
+        MessageDigest md;
+        try {
+            md = MessageDigest.getInstance("SHA-256");
+        } catch (NoSuchAlgorithmException e) {
+            throw new RenkanException("NoSuchAlgorithmException digest: "
+                    + e.getMessage(), e);
+        }
+        String key;
+        final SecretKeySpec secret_key = new SecretKeySpec(
+                Constants.KEYHEX.getBytes(), "HmacSHA256");
+        md.update(secret_key.getEncoded());
+        try {
+            key = Hex.encodeHexString(md.digest(rawKey.getBytes("UTF-8")));
+        } catch (UnsupportedEncodingException e) {
+            throw new RenkanException("UnsupportedEncodingException digest: "
+                    + e.getMessage(), e);
+        }
 
-	public Date getCreated() {
-		return created;
-	}
-	
-	public void setCreated(Date date) {
-		this.created = date;
-		
-	}
-	
-	@JsonProperty("space_id")
-	public String getSpaceId() {
-		return spaceId;
-	}
+        return key;
+    }
+
+    public boolean checkKey(String key, Constants.EditMode editMode)
+            throws RenkanException {
+
+        if (key == null || key.isEmpty()) {
+            return false;
+        }
+
+        String signature = key;
+
+        String new_key = this.getKey(editMode);
+
+        return new_key.equals(signature);
+    }
+
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "GMT")
+    public DateTime getUpdated() {
+        return updated;
+    }
+
+    public void setUpdated(DateTime updated) {
+        this.updated = updated;
+    }
+
+    public void addUser(User user) {
 
-	private String getRawKey(String prefix, Constants.EditMode editMode) {		
-		StringBuffer key = new StringBuffer(prefix!=null?prefix+"|":"");
-		key.append(this.getId());
-		key.append('|');
-		key.append(this.getSpaceId());
-		key.append('|');
-		key.append(this.getCreated().getTime());
-		key.append('|');
-		key.append(editMode.toString());
-		return key.toString();
-	}
-	
-	public String getKey(int editMode) throws RenkanException {		
-		return this.getKey(EditMode.fromInt(editMode));
-	}
-	
-	public String getKey(Constants.EditMode editMode) throws RenkanException {
-		
-		String rawKey = this.getRawKey("", editMode);
-		
-		MessageDigest md;
-		try {
-			md = MessageDigest.getInstance("SHA-256");
-		} catch (NoSuchAlgorithmException e) {
-			throw new RenkanException("NoSuchAlgorithmException digest: " + e.getMessage(), e);
-		}
-		String key;
-		final SecretKeySpec secret_key = new SecretKeySpec(Constants.KEYHEX.getBytes(), "HmacSHA256");
-		md.update(secret_key.getEncoded());
-		try {
-			key = Hex.encodeHexString(md.digest(rawKey.getBytes("UTF-8")));
-		} catch (UnsupportedEncodingException e) {
-			throw new RenkanException("UnsupportedEncodingException digest: " + e.getMessage(), e);
-		}
-		
-		return key;
-	}
-	
-	public boolean checkKey(String key, Constants.EditMode editMode) throws RenkanException {
-		
+        if (user == null) {
+            // we add an anonymous user
+            // find an unique user name
+            this.addUser(null, null);
+        } else {
+            // if user is already in list do nothing
+            for (RenkanUser renkanUser : this.users) {
+                if (renkanUser.getUserId() != null
+                        && renkanUser.getUserId().equals(user.getId())) {
+                    return;
+                }
+            }
+            // user not found
+            this.users.add(new RenkanUser(this.getId(), user.getId(), user
+                    .getColor(), user.getUsername()));
+
+        }
+
+    }
+
+    public void addUser(String username, String color) {
 
-		if(key == null || key.isEmpty()) {
-			return false;
-		}
-				
-		String signature = key;
-		
-		String new_key = this.getKey(editMode);
-		
-		return new_key.equals(signature);
-	}
+        if (username == null) {
+            // find a new username
+            int i = 0;
+            boolean usernameFound = true;
+            while (i++ < 1000000 && usernameFound) {
+                username = String.format("%s-%s",
+                        Constants.ANONYMOUS_USER_BASE_NAME, i);
+                usernameFound = false;
+                for (RenkanUser renkanUser : this.users) {
+                    if (username.equals(renkanUser.getUsername())) {
+                        usernameFound = true;
+                        break;
+                    }
+                }
+            }
+        }
 
-	public Date getUpdated() {
-		return updated;
-	}
+        if (color == null) {
+            int i = 0;
+            boolean colorFound = true;
+            while (i++ < 10000000 && colorFound) {
+                color = "#" + ColorGenerator.randomColorHex();
+                colorFound = false;
+                for (RenkanUser renkanUser : this.users) {
+                    if (username.equals(renkanUser.getUsername())) {
+                        colorFound = true;
+                        break;
+                    }
+                }
+            }
+        }
 
-	public void setUpdated(Date updated) {
-		this.updated = updated;
-	}
-	
+        RenkanUser ruser = new RenkanUser(this.getId(), null, color, username);
+        this.users.add(ruser);
+    }
+
+    @Override
+    protected String getRawKeyPart() {
+        return this.getId() + Long.toString(this.getCreated().getMillis());
+    }
+
 }
--- a/server/src/main/java/org/iri_research/renkan/models/ProjectRevision.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/models/ProjectRevision.java	Wed Jan 15 18:36:27 2014 +0100
@@ -5,69 +5,79 @@
 import java.util.List;
 
 import org.bson.types.ObjectId;
+import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.data.mongodb.core.mapping.DBRef;
 import org.springframework.data.mongodb.core.mapping.Document;
 
-@Document(collection="projectRevisions")
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+@Document(collection = "projectRevisions")
 public class ProjectRevision extends AbstractRenkanModel<ObjectId> {
 
-	@SuppressWarnings("unused")	
-	private static Logger logger = LoggerFactory.getLogger(ProjectRevision.class);
-	
-	private int revision;
-	
-	@DBRef
-	private Project project;
-	
-	private Date created;
-	
-	// Nodes
-	private List<Node> nodes = new ArrayList<Node>();
-	
-	// Edgess
-	private List<Edge> edges = new ArrayList<Edge>();
+    @SuppressWarnings("unused")
+    private static Logger logger = LoggerFactory
+            .getLogger(ProjectRevision.class);
+
+    private int revision;
+
+    @DBRef
+    private Project project;
+
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "GMT")
+    private DateTime created;
 
+    // Nodes
+    private List<Node> nodes = new ArrayList<Node>();
 
-	@SuppressWarnings("unused")
-	private ProjectRevision() {
-		super();
-	}
+    // Edgess
+    private List<Edge> edges = new ArrayList<Edge>();
+
+    @SuppressWarnings("unused")
+    private ProjectRevision() {
+        super();
+    }
+
+    public ProjectRevision(String title, String description, String uri,
+            Project project, int revision, Date created) {
+        this(null, title, description, uri, project, revision, created);
+    }
 
-	public ProjectRevision(String title, String description,
-			String uri, Project project, int revision, Date created) {
-		this(null, title, description, uri, project, revision,created);
-	}
-	
-	public ProjectRevision(ObjectId id, String title, String description,
-			String uri, Project project, int revision, Date created) {
-		super(id, title, description, uri, null);
-		this.project = project;
-		this.revision = revision;
-		if(created == null) {
-			this.created = new Date(System.currentTimeMillis());
-		}
-	}
+    public ProjectRevision(ObjectId id, String title, String description,
+            String uri, Project project, int revision, Date created) {
+        super(id, title, description, uri, null);
+        this.project = project;
+        this.revision = revision;
+        if (created == null) {
+            this.created = new DateTime(System.currentTimeMillis());
+        }
+    }
+
+    public int getRevision() {
+        return revision;
+    }
+
+    public Project getProject() {
+        return project;
+    }
 
-	public int getRevision() {
-		return revision;
-	}
-	
-	public Project getProject() {
-		return project;
-	}
-	
-	public List<Node> getNodes() {
-		return nodes;
-	}
+    public List<Node> getNodes() {
+        return nodes;
+    }
+
+    public List<Edge> getEgdes() {
+        return edges;
+    }
 
-	public List<Edge> getEgdes() {
-		return edges;
-	}
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "GMT")
+    public DateTime getCreated() {
+        return created;
+    }
 
-	public Date getCreated() {
-		return created;
-	}
-		
+    @Override
+    protected String getRawKeyPart() {
+        return Long.toString(this.getCreated().getMillis());
+    }
+
 }
--- a/server/src/main/java/org/iri_research/renkan/models/ProjectSync.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/models/ProjectSync.java	Wed Jan 15 18:36:27 2014 +0100
@@ -1,60 +1,60 @@
 package org.iri_research.renkan.models;
 
-import java.util.Date;
-
 import org.bson.types.ObjectId;
+import org.joda.time.DateTime;
 import org.springframework.data.mongodb.core.mapping.DBRef;
 import org.springframework.data.mongodb.core.mapping.Document;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 
-@Document(collection="projectSyncs")
+@Document(collection = "projectSyncs")
 public class ProjectSync {
 
-	private ObjectId id;
-	
-	private String data;
-	
-	@DBRef
-	private Project project;
-	
-	private int revision;
-	
-	private Date created;
-	
-	private String user;
+    private ObjectId id;
+
+    private String data;
+
+    @DBRef
+    private Project project;
+
+    private int revision;
+
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "GMT")
+    private DateTime created;
+
+    private String user;
 
-	public ProjectSync(ObjectId id, String data, Project project, int revision,
-			Date created, String user) {
-		this.id = id;
-		this.data = data;
-		this.project = project;
-		this.revision = revision;
-		this.created = created;
-		this.user = user;
-		if(this.created == null) {
-			this.created = new Date(System.currentTimeMillis());
-		}
-	}
+    public ProjectSync(ObjectId id, String data, Project project, int revision,
+            DateTime created, String user) {
+        this.id = id;
+        this.data = data;
+        this.project = project;
+        this.revision = revision;
+        this.created = created;
+        this.user = user;
+        if (this.created == null) {
+            this.created = new DateTime(System.currentTimeMillis());
+        }
+    }
 
-	public ObjectId getId() {
-		return id;
-	}
+    public ObjectId getId() {
+        return id;
+    }
 
-	public String getData() {
-		return data;
-	}
+    public String getData() {
+        return data;
+    }
 
-	public Project getProject() {
-		return project;
-	}
+    public Project getProject() {
+        return project;
+    }
 
-	public int getRevision() {
-		return revision;
-	}
+    public int getRevision() {
+        return revision;
+    }
 
-	public String getUser() {
-		return user;
-	}
-	
-	
+    public String getUser() {
+        return user;
+    }
+
 }
--- a/server/src/main/java/org/iri_research/renkan/models/RenkanSessionModeratorState.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/models/RenkanSessionModeratorState.java	Wed Jan 15 18:36:27 2014 +0100
@@ -5,23 +5,22 @@
 import java.util.Map;
 
 public enum RenkanSessionModeratorState {
-	INSTANCE;
-	
-	private Map<String, String> usersActivationMap = new HashMap<String, String>();
-	private Map<String, List<String>> projectsActivationMap = new HashMap<String, List<String>>();
-	private Map<String, List<RosterUser>> projectsUsersList = new HashMap<String, List<RosterUser>>();
-	
-	public Map<String, String> getUsersActivationMap() {
-		return usersActivationMap;
-	}
+    INSTANCE;
+
+    private Map<String, String> usersActivationMap = new HashMap<String, String>();
+    private Map<String, List<String>> projectsActivationMap = new HashMap<String, List<String>>();
+    private Map<String, List<RosterUser>> projectsUsersList = new HashMap<String, List<RosterUser>>();
+
+    public Map<String, String> getUsersActivationMap() {
+        return usersActivationMap;
+    }
 
-	public Map<String, List<String>> getProjectsActivationMap() {
-		return projectsActivationMap;
-	}
+    public Map<String, List<String>> getProjectsActivationMap() {
+        return projectsActivationMap;
+    }
 
-	public Map<String, List<RosterUser>> getProjectsUsersList() {
-		return projectsUsersList;
-	}	
-	
-	
+    public Map<String, List<RosterUser>> getProjectsUsersList() {
+        return projectsUsersList;
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/models/RenkanUser.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,61 @@
+package org.iri_research.renkan.models;
+
+import org.springframework.data.mongodb.core.mapping.Field;
+
+public class RenkanUser {
+
+    @Field(value = "user_id")
+    private String userId;
+    private String color;
+    private String username;
+
+    @SuppressWarnings("unused")
+    private RenkanUser() {
+    }
+
+    public RenkanUser(String projectId, String userId, String color,
+            String username) {
+        this.userId = userId;
+        this.color = color;
+        this.username = username;
+    }
+
+    public RenkanUser(RenkanUser user) {
+        if (user != null) {
+            this.setUserId(user.getUserId());
+            this.setColor(user.getColor());
+            this.setUsername(user.getUsername());
+        }
+    }
+
+    @Field(value = "user_id")
+    public String getUserId() {
+        return userId;
+    }
+
+    @Field(value = "user_id")
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    public String getColor() {
+        return color;
+    }
+
+    public void setColor(String color) {
+        this.color = color;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public boolean isAnonymous() {
+        return this.getUserId() == null;
+    }
+
+}
--- a/server/src/main/java/org/iri_research/renkan/models/RosterUser.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/models/RosterUser.java	Wed Jan 15 18:36:27 2014 +0100
@@ -1,46 +1,56 @@
 package org.iri_research.renkan.models;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+
 public class RosterUser extends AbstractRenkanModel<String> {
-	
-	private String project_id;
-	private Long site_id;
-	private String client_id;
+
+    private String projectId;
+    private Long siteId;
+    private String clientId;
+
+    public RosterUser(String id, String title, String description, String uri,
+            String color, String project_id, Long site_id, String client_id) {
+        super(id, title, description, uri, color);
 
-	public RosterUser(String id, String title, String description, String uri, String color, String project_id, Long site_id, String client_id) {
-		super(id, title, description, uri, color);
-		
-		this.project_id = project_id;
-		this.site_id = site_id;
-		this.client_id = client_id;
-	}
-	
-	public void setTitle(String title) {
-		this.title = title;
-	}
+        this.projectId = project_id;
+        this.siteId = site_id;
+        this.clientId = client_id;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public void setUri(String uri) {
+        this.uri = uri;
+    }
 
-	public void setDescription(String description) {
-		this.description = description;
-	}
-	
-	public void setUri(String uri) {
-		this.uri = uri;
-	}
-		
-	public void setColor(String color) {
-		this.color = color;
-	}	
+    public void setColor(String color) {
+        this.color = color;
+    }
+
+    @JsonProperty(value = "project_id")
+    public String getProjectId() {
+        return projectId;
+    }
 
-	public String getProject_id() {
-		return project_id;
-	}
+    @JsonProperty(value = "site_id")
+    public Long getSiteId() {
+        return siteId;
+    }
 
-	public Long getSite_id() {
-		return site_id;
-	}
-	
-	public String getClient_id() {
-		return client_id;
-	}
+    @JsonProperty(value = "client_id")
+    public String getClientId() {
+        return clientId;
+    }
 
-	
+    @Override
+    protected String getRawKeyPart() {
+        return this.id;
+    }
+
 }
--- a/server/src/main/java/org/iri_research/renkan/models/Space.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/models/Space.java	Wed Jan 15 18:36:27 2014 +0100
@@ -1,124 +1,82 @@
 package org.iri_research.renkan.models;
 
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Date;
-
-import javax.crypto.spec.SecretKeySpec;
-
-import org.apache.commons.codec.binary.Hex;
-import org.iri_research.renkan.Constants;
-import org.iri_research.renkan.RenkanException;
+import org.joda.time.DateTime;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.mongodb.core.mapping.Document;
 import org.springframework.data.mongodb.core.mapping.Field;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonProperty;
 
-@Document(collection="spaces")
+@Document(collection = "spaces")
 public class Space extends AbstractRenkanModel<String> {
-	
-	@Autowired
-	public Space(String id, String title, String description, String binConfig, String uri, String color, String createdBy, String image, Date created) {
-		super(id, title, description, uri, color);
-		
-		this.binConfig = binConfig;
-		this.createdBy = createdBy;
-		this.setImage(image);
-		this.created = created;
-		if(this.created == null) {
-			this.created = new Date();
-		}
-	}
-	
-	public Space() {		
-	}
+
+    @Autowired
+    public Space(String id, String title, String description, String binConfig,
+            String uri, String color, String createdBy, String image,
+            DateTime created) {
+        super(id, title, description, uri, color);
 
-	@Field("bin_config")
-	@JsonProperty("bin_config")
-	private String binConfig;
-	
-	@Field("created_by")
-	@JsonProperty("created_by")
-	private String createdBy = null;	
-	private String image;
-	private Date created;
-	
-	public String getImage() {
-		return image;
-	}
+        this.binConfig = binConfig;
+        this.createdBy = createdBy;
+        this.setImage(image);
+        this.created = created;
+        if (this.created == null) {
+            this.created = new DateTime();
+        }
+    }
+
+    public Space() {
+    }
 
-	@JsonProperty("created_by")
-	public String getCreatedBy() {
-		return createdBy;
-	}
-	
-	public Date getCreated() {
-		return created;
-	}
-	
-	public void setCreated(Date date) {
-		this.created = date;
-		
-	}
+    @Field("bin_config")
+    @JsonProperty("bin_config")
+    private String binConfig;
 
-	@JsonProperty("bin_config")
-	public String getBinConfig() {
-		return binConfig;
-	}
+    @Field("created_by")
+    @JsonProperty("created_by")
+    private String createdBy = null;
+    private String image;
+
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "GMT")
+    private DateTime created;
 
-	@JsonProperty("bin_config")
-	public void setBinConfig(String bin_config) {
-		this.binConfig = bin_config;
-	}
+    public String getImage() {
+        return image;
+    }
+
+    @JsonProperty("created_by")
+    public String getCreatedBy() {
+        return createdBy;
+    }
+
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "GMT")
+    public DateTime getCreated() {
+        return created;
+    }
+
+    public void setCreated(DateTime date) {
+        this.created = date;
+
+    }
 
-	public void setImage(String image) {
-		this.image = image;
-	}
-	
-	private String getRawKey(String salt) {		
-		StringBuffer key = new StringBuffer(salt!=null?salt+"|":"");
-		key.append(this.getId());
-		key.append('|');
-		key.append(this.getCreated().getTime());
-		return key.toString();
-	}
-		
-	public String getKey(String salt) throws RenkanException {
-		
-		String rawKey = this.getRawKey(salt);
-		
-		MessageDigest md;
-		try {
-			md = MessageDigest.getInstance("SHA-256");
-		} catch (NoSuchAlgorithmException e) {
-			throw new RenkanException("NoSuchAlgorithmException digest: " + e.getMessage(), e);
-		}
-		String key;
-		final SecretKeySpec secret_key = new SecretKeySpec(Constants.KEYHEX.getBytes(), "HmacSHA256");
-		md.update(secret_key.getEncoded());
-		try {
-			key = Hex.encodeHexString(md.digest(rawKey.getBytes("UTF-8")));
-		} catch (UnsupportedEncodingException e) {
-			throw new RenkanException("UnsupportedEncodingException digest: " + e.getMessage(), e);
-		}
-		
-		return key;
-	}
-	
-	public boolean checkKey(String key, String salt) throws RenkanException {
-		
+    @JsonProperty("bin_config")
+    public String getBinConfig() {
+        return binConfig;
+    }
+
+    @JsonProperty("bin_config")
+    public void setBinConfig(String bin_config) {
+        this.binConfig = bin_config;
+    }
 
-		if(key == null || key.isEmpty()) {
-			return false;
-		}
-				
-		String signature = key;
-		
-		String new_key = this.getKey(salt);
-		
-		return new_key.equals(signature);
-	}
-	
+    public void setImage(String image) {
+        this.image = image;
+    }
+
+    @Override
+    protected String getRawKeyPart() {
+        return this.id+Long.toString(this.getCreated().getMillis());
+    }
+
 }
\ No newline at end of file
--- a/server/src/main/java/org/iri_research/renkan/models/User.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/models/User.java	Wed Jan 15 18:36:27 2014 +0100
@@ -1,24 +1,204 @@
 package org.iri_research.renkan.models;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.iri_research.renkan.Constants;
+import org.joda.time.LocalDate;
 import org.springframework.data.mongodb.core.mapping.Document;
+import org.springframework.data.mongodb.core.mapping.Field;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+@Document(collection = "users")
+public class User extends AbstractRenkanModel<String> implements UserDetails {
+    
+    public static class UserComparator implements Comparator<User> {
+
+        @Override
+        public int compare(User u1, User u2) {
+            if(u1 == null || u1.getId() == null) {
+                return (u2==null || u2.getId() == null)? 0 : Integer.MIN_VALUE;
+            }
+            else {
+                return u2==null?Integer.MAX_VALUE:u1.getId().compareTo(u2.getId());
+            }
+            
+        }
+        
+    }
 
-@Document(collection="users")
-public class User extends AbstractRenkanModel<String> {
-	
-	private String project_id;
+    private static final long serialVersionUID = 6972038893086220548L;
+    
+    
+    private String avatar;
+    @Field("credentials_expiration_date")
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "GMT")
+    private LocalDate credentialsExpirationDate;
+    private String email;
+    private boolean enabled;
+    @Field("expiration_date")
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "GMT")
+    private LocalDate expirationDate;
+    private boolean locked;
+    private String password;
+    @Field("authorities")
+    private List<String> userAuthorities;
+    
+    private Set<String> groups = new TreeSet<>();
+
+    public User() {
+    }
+
+    public User(String id, String title, String description, String uri,
+            String color) {
+        super(id, title, description, uri, color);
+    }
+
+    @Override
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
+        boolean hasUserRole = false;
+        for (String role : this.getUserAuthorities()) {
+            hasUserRole = hasUserRole || Constants.ROLE_USER.equals(role);
+            authorities.add(new SimpleGrantedAuthority(role));
+        }
+        if(!hasUserRole) {
+            authorities.add(new SimpleGrantedAuthority(Constants.ROLE_USER));
+        }
+        
+        return authorities;
+    }
+
+    public String getAvatar() {
+        return avatar;
+    }
+
+    public String getColor() {
+        return this.color;
+    }
+
+    public LocalDate getCredentialsExpirationDate() {
+        return credentialsExpirationDate;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public LocalDate getExpirationDate() {
+        return expirationDate;
+    }
 
-	public User(String id, String title, String description, String uri, String color, String project_id) {
-		super(id, title, description, uri, color);
-		
-		this.project_id = project_id;
-	}	
-	
-	public String getColor() {
-		return this.color;
-	}
+    @Override
+    @JsonIgnore
+    public String getPassword() {
+        return this.password;
+    }
+
+    @Override
+    protected String getRawKeyPart() {
+        return this.id;
+    }
+
+    public List<String> getUserAuthorities() {
+        return userAuthorities;
+    }
+
+    @Override
+    @JsonIgnore
+    public String getUsername() {
+        return this.title;
+    }
+
+    @Override
+    public boolean isAccountNonExpired() {
+        return this.expirationDate == null
+                || this.expirationDate.isAfter(LocalDate.now());
+    }
+
+    @Override
+    public boolean isAccountNonLocked() {
+        return !this.locked;
+    }
+
+    @Override
+    public boolean isCredentialsNonExpired() {
+        return this.credentialsExpirationDate == null
+                || this.credentialsExpirationDate.isAfter(LocalDate.now());
+    }
+
+    @Override
+    public boolean isEnabled() {
+        return this.enabled;
+    }
+
+    public boolean isLocked() {
+        return locked;
+    }
+
+    public void setAvatar(String avatar) {
+        this.avatar = avatar;
+    }
 
-	public String getProject_id() {
-		return project_id;
-	}
-	
+    public void setCredentialsExpirationDate(LocalDate credentialsExpirationDate) {
+        this.credentialsExpirationDate = credentialsExpirationDate;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public void setExpirationDate(LocalDate expirationDate) {
+        this.expirationDate = expirationDate;
+    }
+
+    public void setLocked(boolean locked) {
+        this.locked = locked;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public void setUserAuthorities(List<String> userAuthorities) {
+        this.userAuthorities = userAuthorities;
+    }
+
+    public Set<String> getGroups() {
+        if(this.groups == null) {
+            this.groups = new TreeSet<>();
+        }
+        return groups;
+    }
+    
+    
+    public boolean addGroup(Group g) {
+        return this.addGroup(g.getId());
+    }
+
+    public boolean addGroup(String groupId) {
+        return this.getGroups().add(groupId);
+    }
+
+    public boolean removeGroup(Group g) {
+        return this.removeGroup(g.getId());
+    }
+    
+    public boolean removeGroup(String groupId) {
+        return (this.groups == null)?false:this.groups.remove(groupId);
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/GroupsRepository.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,15 @@
+package org.iri_research.renkan.repositories;
+
+import java.util.List;
+
+import org.iri_research.renkan.models.Group;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+
+public interface GroupsRepository extends IRenkanRepository<Group, String>, GroupsRepositoryCustom {
+
+    public List<Group> findByTitle(String title);
+
+    public Page<Group> findByTitle(String title, Pageable p);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/GroupsRepositoryCustom.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,17 @@
+package org.iri_research.renkan.repositories;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.iri_research.renkan.models.Group;
+import org.iri_research.renkan.models.User;
+
+public interface GroupsRepositoryCustom {
+    /**
+     * Set the list of user for the group
+     * @param group: the group.
+     * @param userIds: the collection of user ids. This parameter must not be null.
+     */
+    public void setUsersList(Group group, Collection<String> userIds);
+    public Map<String, User> getUsersMap(Group group);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/GroupsRepositoryImpl.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,66 @@
+package org.iri_research.renkan.repositories;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections4.IteratorUtils;
+import org.iri_research.renkan.models.Group;
+import org.iri_research.renkan.models.User;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class GroupsRepositoryImpl implements GroupsRepositoryCustom {
+
+    @Autowired
+    private UsersRepository usersRepository;
+    
+    @Autowired
+    private GroupsRepository groupsRepository;
+    
+    @Override
+    // TODO: implement a transaction mecanism...
+    public void setUsersList(Group group, Collection<String> userIds) {
+        
+        assert userIds != null : "list of user ids must not be null";
+        
+        // takes previous user list
+        List<String> oldUsers = new ArrayList<>(group.getUsers());
+        
+        // calculate difference between two list
+        List<String> userIdDel =  new ArrayList<>(oldUsers);
+        userIdDel.removeAll(userIds);
+        
+        List<String> userIdAdd = new ArrayList<>(userIds);
+        userIdAdd.removeAll(oldUsers);
+        
+        List<User> userAdd = IteratorUtils.toList(this.usersRepository.findAll(userIdAdd).iterator());
+        for (User user : userAdd) {
+            user.addGroup(group.getId());
+        }
+        this.usersRepository.save(userAdd);
+        List<User> userDel = IteratorUtils.toList(this.usersRepository.findAll(userIdDel).iterator());
+        for (User user : userDel) {
+            user.removeGroup(group.getId());
+        }
+        this.usersRepository.save(userDel);
+        
+        group.getUsers().clear();
+        group.getUsers().addAll(userIds);
+        
+        this.groupsRepository.save(group);
+    }
+
+    @Override
+    public Map<String, User> getUsersMap(Group group) {
+        HashMap<String, User> res = new HashMap<>(group.getUsers().size());
+        
+        for (User user : this.usersRepository.findAll(group.getUsers())) {
+            res.put(user.getId(), user);
+        }
+        
+        return res;
+    }
+
+}
--- a/server/src/main/java/org/iri_research/renkan/repositories/IRenkanRepository.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/repositories/IRenkanRepository.java	Wed Jan 15 18:36:27 2014 +0100
@@ -7,7 +7,7 @@
 import com.mongodb.DBCollection;
 
 public interface IRenkanRepository<T, ID extends Serializable> extends
-		PagingAndSortingRepository<T, ID> {
+        PagingAndSortingRepository<T, ID> {
 
-	public DBCollection getCollection();
+    public DBCollection getCollection();
 }
--- a/server/src/main/java/org/iri_research/renkan/repositories/ProjectRevisionsRepository.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectRevisionsRepository.java	Wed Jan 15 18:36:27 2014 +0100
@@ -3,8 +3,8 @@
 import org.bson.types.ObjectId;
 import org.iri_research.renkan.models.ProjectRevision;
 
-public interface ProjectRevisionsRepository extends		
-		IRenkanRepository<ProjectRevision, ObjectId>,
-		ProjectRevisionsRepositoryCustom {
+public interface ProjectRevisionsRepository extends
+        IRenkanRepository<ProjectRevision, ObjectId>,
+        ProjectRevisionsRepositoryCustom {
 
 }
--- a/server/src/main/java/org/iri_research/renkan/repositories/ProjectRevisionsRepositoryCustom.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectRevisionsRepositoryCustom.java	Wed Jan 15 18:36:27 2014 +0100
@@ -4,7 +4,7 @@
 import org.iri_research.renkan.models.ProjectRevision;
 
 public interface ProjectRevisionsRepositoryCustom {
-	
-	public ProjectRevision getProjectRevision(Project project, int revision);
-	
+
+    public ProjectRevision getProjectRevision(Project project, int revision);
+
 }
--- a/server/src/main/java/org/iri_research/renkan/repositories/ProjectRevisionsRepositoryImpl.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectRevisionsRepositoryImpl.java	Wed Jan 15 18:36:27 2014 +0100
@@ -8,20 +8,15 @@
 
 @Component
 public class ProjectRevisionsRepositoryImpl implements
-		ProjectRevisionsRepositoryCustom {
-	
-	@Override
-	public ProjectRevision getProjectRevision(Project project, int revision) {
-		ProjectRevision pr = new ProjectRevision(
-				project.getTitle(),
-				project.getDescription(),
-				project.getUri(),
-				project,
-				revision,
-				new Date(System.currentTimeMillis())
-		);
-		
-		return pr;
-	}
+        ProjectRevisionsRepositoryCustom {
+
+    @Override
+    public ProjectRevision getProjectRevision(Project project, int revision) {
+        ProjectRevision pr = new ProjectRevision(project.getTitle(),
+                project.getDescription(), project.getUri(), project, revision,
+                new Date(System.currentTimeMillis()));
+
+        return pr;
+    }
 
 }
--- a/server/src/main/java/org/iri_research/renkan/repositories/ProjectSyncsRepository.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectSyncsRepository.java	Wed Jan 15 18:36:27 2014 +0100
@@ -3,8 +3,7 @@
 import org.bson.types.ObjectId;
 import org.iri_research.renkan.models.ProjectSync;
 
-public interface ProjectSyncsRepository extends		
-		IRenkanRepository<ProjectSync, ObjectId>,
-		ProjectSyncsRepositoryCustom {
+public interface ProjectSyncsRepository extends
+        IRenkanRepository<ProjectSync, ObjectId>, ProjectSyncsRepositoryCustom {
 
 }
--- a/server/src/main/java/org/iri_research/renkan/repositories/ProjectSyncsRepositoryCustom.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectSyncsRepositoryCustom.java	Wed Jan 15 18:36:27 2014 +0100
@@ -5,9 +5,11 @@
 import org.iri_research.renkan.models.ProjectSync;
 
 public interface ProjectSyncsRepositoryCustom {
-	
-	public ProjectSync getProjectSync(String data, Project project, String user) throws RenkanException;
-	
-	public ProjectSync getProjectSync(String data, String project_id, String user) throws RenkanException;
-	
+
+    public ProjectSync getProjectSync(String data, Project project, String user)
+            throws RenkanException;
+
+    public ProjectSync getProjectSync(String data, String project_id,
+            String user) throws RenkanException;
+
 }
--- a/server/src/main/java/org/iri_research/renkan/repositories/ProjectSyncsRepositoryImpl.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectSyncsRepositoryImpl.java	Wed Jan 15 18:36:27 2014 +0100
@@ -1,55 +1,52 @@
 package org.iri_research.renkan.repositories;
 
-import java.util.Date;
-
 import org.iri_research.renkan.RenkanException;
 import org.iri_research.renkan.models.Project;
 import org.iri_research.renkan.models.ProjectSync;
+import org.joda.time.DateTime;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 @Component
-public class ProjectSyncsRepositoryImpl implements
-		ProjectSyncsRepositoryCustom {
+public class ProjectSyncsRepositoryImpl implements ProjectSyncsRepositoryCustom {
+
+    @Autowired
+    private ProjectsRepository projectRepository;
+
+    @Override
+    public ProjectSync getProjectSync(String data, Project project, String user)
+            throws RenkanException {
+
+        if (project == null) {
+            throw new RenkanException("ProjectSyncsRepository : Null Project.");
+        }
+
+        ProjectSync ps = new ProjectSync(null, data, project,
+                this.projectRepository.getRevCounter(project.getId()),
+                new DateTime(), user);
+
+        return ps;
+    }
 
-	@Autowired
-	private ProjectsRepository projectRepository;
-	
-	@Override
-	public ProjectSync getProjectSync(String data, Project project, String user) throws RenkanException {
-		
-		if(project == null) {
-			throw new RenkanException("ProjectSyncsRepository : Null Project."); 
-		}
-		
-		ProjectSync ps = new ProjectSync(
-				null,
-				data,
-				project,
-				this.projectRepository.getRevCounter(project.getId()),
-				new Date(System.currentTimeMillis()),
-				user
-		);
-		
-		return ps;
-	}
+    @Override
+    public ProjectSync getProjectSync(String data, String project_id,
+            String user) throws RenkanException {
+
+        if (project_id == null || "".equals(project_id)) {
+            throw new RenkanException(
+                    "ProjectSyncsRepository : Null or empty project id.");
+        }
 
-	@Override
-	public ProjectSync getProjectSync(String data, String project_id, String user)
-			throws RenkanException {
-		
-		if(project_id == null || "".equals(project_id) ) {
-			throw new RenkanException("ProjectSyncsRepository : Null or empty project id.");
-		}
-		
-		Project p = this.projectRepository.findOne(project_id);
-		
-		if(p == null) {
-			throw new RenkanException("ProjectSyncsRepository : project not found for id " + project_id);
-		}
-		
-		return this.getProjectSync(data, p, user);
-		
-	}
+        Project p = this.projectRepository.findOne(project_id);
+
+        if (p == null) {
+            throw new RenkanException(
+                    "ProjectSyncsRepository : project not found for id "
+                            + project_id);
+        }
+
+        return this.getProjectSync(data, p, user);
+
+    }
 
 }
--- a/server/src/main/java/org/iri_research/renkan/repositories/ProjectsRepository.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectsRepository.java	Wed Jan 15 18:36:27 2014 +0100
@@ -7,13 +7,17 @@
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.mongodb.repository.Query;
 
-public interface ProjectsRepository extends IRenkanRepository<Project, String>, ProjectsRepositoryCustom {
-	
-	List<Project> findBySpaceId(String spaceId);
-	Page<Project> findBySpaceId(String spaceId, Pageable p);
+public interface ProjectsRepository extends IRenkanRepository<Project, String>,
+        ProjectsRepositoryCustom {
+
+    List<Project> findBySpaceId(String spaceId);
+
+    Page<Project> findBySpaceId(String spaceId, Pageable p);
 
-	@Query("{ 'space_id' : ?0, 'title' : { '$regex':?1, '$options': 'i'} }")
-	List<Project> findBySpaceIdAndTitleRegex(String spaceId, String title);
-	@Query("{ 'space_id' : ?0, 'title' : { '$regex':?1, '$options': 'i'} }")
-	Page<Project> findBySpaceIdAndTitleRegex(String spaceId, String title, Pageable p);
+    @Query("{ 'space_id' : ?0, 'title' : { '$regex':?1, '$options': 'i'} }")
+    List<Project> findBySpaceIdAndTitleRegex(String spaceId, String title);
+
+    @Query("{ 'space_id' : ?0, 'title' : { '$regex':?1, '$options': 'i'} }")
+    Page<Project> findBySpaceIdAndTitleRegex(String spaceId, String title,
+            Pageable p);
 }
--- a/server/src/main/java/org/iri_research/renkan/repositories/ProjectsRepositoryCustom.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectsRepositoryCustom.java	Wed Jan 15 18:36:27 2014 +0100
@@ -6,15 +6,27 @@
 import org.iri_research.renkan.models.Project;
 
 public interface ProjectsRepositoryCustom {
-	
-	public int getRevCounter(String projectId);
-	public Map<String, Integer> getCountBySpace();
-	public Map<String, Integer> getCountBySpace(Collection<String> spaceIds);
-	
-	public void deleteRecursive(String projectId);
-	public void deleteRecursive(Project project);
-	public void deleteRecursive(Iterable<? extends Project> projects);
-	
-	public Project copy(Project p, String newTitle);
-	
+
+    public int getRevCounter(String projectId);
+
+    public Map<String, Integer> getCountBySpace();
+
+    public Map<String, Integer> getCountBySpace(Collection<String> spaceIds);
+
+    public Map<String, Integer> getCountByUser();
+
+    public Map<String, Integer> getCountByUser(Collection<String> userIds);
+
+    public Map<String, Integer> getCountByUsername();
+
+    public Map<String, Integer> getCountByUsername(Collection<String> usernames);
+
+    public void deleteRecursive(String projectId);
+
+    public void deleteRecursive(Project project);
+
+    public void deleteRecursive(Iterable<? extends Project> projects);
+
+    public Project copy(Project p, String newTitle);
+
 }
--- a/server/src/main/java/org/iri_research/renkan/repositories/ProjectsRepositoryImpl.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/repositories/ProjectsRepositoryImpl.java	Wed Jan 15 18:36:27 2014 +0100
@@ -1,5 +1,8 @@
 package org.iri_research.renkan.repositories;
 
+import static org.springframework.data.mongodb.core.query.Criteria.where;
+import static org.springframework.data.mongodb.core.query.Query.query;
+
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
@@ -7,120 +10,220 @@
 
 import org.iri_research.renkan.models.Project;
 import org.iri_research.renkan.models.ProjectRevision;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.mongodb.core.MongoTemplate;
-import org.springframework.stereotype.Component;
-import static org.springframework.data.mongodb.core.query.Query.query;
-import static org.springframework.data.mongodb.core.query.Criteria.where;
-
 import org.springframework.data.mongodb.core.mapreduce.GroupBy;
 import org.springframework.data.mongodb.core.mapreduce.GroupByResults;
 import org.springframework.data.mongodb.core.query.Criteria;
 import org.springframework.data.mongodb.core.query.Update;
+import org.springframework.stereotype.Component;
+
+import com.mongodb.AggregationOutput;
+import com.mongodb.BasicDBObject;
+import com.mongodb.DBObject;
 
 @Component
 public class ProjectsRepositoryImpl implements ProjectsRepositoryCustom {
-	
-	@Autowired
-	private ProjectsRepository projectsRepository;
+
+    @SuppressWarnings("unused")
+    private final Logger logger = LoggerFactory
+            .getLogger(ProjectsRepositoryImpl.class);
+
+    @Autowired
+    private ProjectsRepository projectsRepository;
+
+    @Autowired
+    private NodesRepository nodesRepository;
+
+    @Autowired
+    private EdgesRepository edgesRepository;
+
+    @Autowired
+    private ProjectRevisionsRepository projectRevisionsRepository;
+
+    private class GroupSpaceResult {
+        public String space_id;
+        public int count;
+    }
 
-	@Autowired
-	private NodesRepository nodesRepository;
+    @Autowired
+    private MongoTemplate mongoTemplate;
+
+    @Override
+    public int getRevCounter(String projectId) {
+        Project p = this.mongoTemplate.findAndModify(
+                query(where("id").is(projectId)),
+                new Update().inc("rev_counter", 1), Project.class);
 
-	@Autowired
-	private EdgesRepository edgesRepository;
-	
-	@Autowired
-	private ProjectRevisionsRepository projectRevisionsRepository;
+        if (p == null) {
+            return -1;
+        }
+        return p.getRevCounter();
+    }
+
+    @Override
+    public Map<String, Integer> getCountBySpace(Collection<String> spaceIds) {
+
+        Criteria filter = null;
+
+        if (spaceIds != null) {
+            filter = Criteria.where("space_id").in(spaceIds);
+        }
 
-	
-	private class GroupResult {
-		public String space_id;
-		public int count;		
-	}
-	
-	@Autowired
-	private MongoTemplate mongoTemplate;
-	
-	@Override
-	public int getRevCounter(String projectId)  {		
-		Project p = this.mongoTemplate.findAndModify(query(where("id").is(projectId)), new Update().inc("rev_counter", 1), Project.class);
-		
-		if(p == null) {
-			return -1;
-		}
-		return p.getRevCounter();
-	}
-	
+        GroupByResults<GroupSpaceResult> groupResult = this.mongoTemplate
+                .group(filter,
+                        this.mongoTemplate.getCollectionName(Project.class),
+                        GroupBy.key("space_id")
+                                .initialDocument("{ count: 0 }")
+                                .reduceFunction(
+                                        "function(doc, prev) { prev.count += 1; }"),
+                        GroupSpaceResult.class);
+
+        HashMap<String, Integer> res = new HashMap<>();
+        for (GroupSpaceResult gr : groupResult) {
+            res.put(gr.space_id, new Integer(gr.count));
+        }
+
+        return res;
+
+    }
+
+    @Override
+    public Map<String, Integer> getCountBySpace() {
+        return this.getCountBySpace(null);
+    }
+
+    @Override
+    public Project copy(Project p, String newTitle) {
 
-	@Override
-	public Map<String, Integer> getCountBySpace(Collection<String> spaceIds) {
+        Project res = new Project(p);
+        res.setTitle(newTitle);
+        this.nodesRepository.save(res.getNodes());
+        this.edgesRepository.save(res.getEdges());
+
+        return this.projectsRepository.save(res);
+    }
+
+    @Override
+    public void deleteRecursive(String projectId) {
+        this.deleteRecursive(this.projectsRepository.findOne(projectId));
+    }
+
+    @Override
+    public void deleteRecursive(Project project) {
+        this.deleteRecursive(Arrays.asList(new Project[] { project }));
+    }
+
+    @Override
+    public void deleteRecursive(Iterable<? extends Project> projects) {
+
+        for (Project p : projects) {
+            if (p == null) {
+                continue;
+            }
 
-		Criteria filter = null;
-		
-		if(spaceIds != null) {
-			filter = Criteria.where("space_id").in(spaceIds);
-		}
-		
-		GroupByResults<GroupResult> groupResult = this.mongoTemplate.group(
-				filter,
-				this.mongoTemplate.getCollectionName(Project.class),
-				GroupBy.key("space_id").initialDocument("{ count: 0 }").reduceFunction("function(doc, prev) { prev.count += 1; }"),
-				GroupResult.class);
-		
-		HashMap<String, Integer> res = new HashMap<>();
-		for (GroupResult gr : groupResult) {
-			res.put(gr.space_id, new Integer(gr.count));
-		}
-		
-		return res;
-		
-	}
-	
-	@Override
-	public Map<String, Integer> getCountBySpace() {
-		return this.getCountBySpace(null);
-	}
+            ProjectRevision pr = this.projectRevisionsRepository
+                    .getProjectRevision(p,
+                            this.projectsRepository.getRevCounter(p.getId()));
+            this.projectRevisionsRepository.save(pr);
+
+            // delete edges
+            this.edgesRepository.delete(p.getEdges());
+            // delete nodes
+            this.nodesRepository.delete(p.getNodes());
+            // delete project
+            this.projectsRepository.delete(p);
+        }
+    }
+
+    @Override
+    public Map<String, Integer> getCountByUser() {
+        return getCountByUser(null);
+    }
+
+    @Override
+    public Map<String, Integer> getCountByUser(Collection<String> userIds) {
+
+        Criteria filter = null;
 
+        if (userIds != null) {
+            filter = Criteria.where("users.user_id").in(userIds);
+        }
+
+        DBObject projectOp = new BasicDBObject("$project", new BasicDBObject(
+                "users", 1));
+        DBObject unwindOp = new BasicDBObject("$unwind", "$users");
+        DBObject groupOpFields = new BasicDBObject("_id", "$users.user_id");
+        groupOpFields.put("count", new BasicDBObject("$sum", 1));
+        DBObject groupOp = new BasicDBObject("$group", groupOpFields);
+        DBObject matchOp = null;
+        if (filter != null) {
+            matchOp = new BasicDBObject("$match", filter.getCriteriaObject());
+        }
+
+        AggregationOutput output = null;
+        if (filter != null) {
+            output = this.projectsRepository.getCollection().aggregate(matchOp,
+                    projectOp, unwindOp, matchOp, groupOp);
+        } else {
+            output = this.projectsRepository.getCollection().aggregate(
+                    projectOp, unwindOp, groupOp);
+        }
+
+        HashMap<String, Integer> res = new HashMap<>();
 
-	@Override
-	public Project copy(Project p, String newTitle) {
-		
-		Project res = new Project(p);
-		res.setTitle(newTitle);
-		this.nodesRepository.save(res.getNodes());
-		this.edgesRepository.save(res.getEdges());
-		
-		return this.projectsRepository.save(res);
-	}
+        for (DBObject groupRes : output.results()) {
+            res.put((String) groupRes.get("_id"),
+                    (Integer) groupRes.get("count"));
+        }
+
+        return res;
+    }
 
-	@Override
-	public void deleteRecursive(String projectId) {		
-		this.deleteRecursive(this.projectsRepository.findOne(projectId));		
-	}
+    @Override
+    public Map<String, Integer> getCountByUsername() {
+        return this.getCountByUsername(null);
+    }
 
-	@Override
-	public void deleteRecursive(Project project) {
-		this.deleteRecursive(Arrays.asList(new Project[] {project}));
-	}
+    @Override
+    public Map<String, Integer> getCountByUsername(Collection<String> usernames) {
+
+        Criteria filter = null;
+
+        if (usernames != null) {
+            filter = Criteria.where("users.username").in(usernames);
+        }
 
-	@Override
-	public void deleteRecursive(Iterable<? extends Project> projects) {
-		
-		for(Project p: projects) {
-			if( p == null) {
-				continue;
-			}
-			
-			ProjectRevision pr = this.projectRevisionsRepository.getProjectRevision(p, this.projectsRepository.getRevCounter(p.getId()));
-			this.projectRevisionsRepository.save(pr);
-			
-			//delete edges
-			this.edgesRepository.delete(p.getEdges());
-			//delete nodes
-			this.nodesRepository.delete(p.getNodes());
-			//delete project
-			this.projectsRepository.delete(p);
-		}
-	}
+        DBObject projectOp = new BasicDBObject("$project", new BasicDBObject(
+                "users", 1));
+        DBObject unwindOp = new BasicDBObject("$unwind", "$users");
+        DBObject groupOpFields = new BasicDBObject("_id", "$users.username");
+        groupOpFields.put("count", new BasicDBObject("$sum", 1));
+        DBObject groupOp = new BasicDBObject("$group", groupOpFields);
+        DBObject matchOp = null;
+        if (filter != null) {
+            matchOp = new BasicDBObject("$match", filter.getCriteriaObject());
+        }
+
+        AggregationOutput output = null;
+        if (filter != null) {
+            output = this.projectsRepository.getCollection().aggregate(matchOp,
+                    projectOp, unwindOp, matchOp, groupOp);
+        } else {
+            output = this.projectsRepository.getCollection().aggregate(
+                    projectOp, unwindOp, groupOp);
+        }
+
+        HashMap<String, Integer> res = new HashMap<>();
+
+        for (DBObject groupRes : output.results()) {
+            res.put((String) groupRes.get("_id"),
+                    (Integer) groupRes.get("count"));
+        }
+
+        return res;
+
+    }
 }
--- a/server/src/main/java/org/iri_research/renkan/repositories/RenkanRepository.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/repositories/RenkanRepository.java	Wed Jan 15 18:36:27 2014 +0100
@@ -8,16 +8,17 @@
 
 import com.mongodb.DBCollection;
 
-public class RenkanRepository<T, ID extends Serializable> extends SimpleMongoRepository<T, ID> implements
-		IRenkanRepository<T, ID> {
+public class RenkanRepository<T, ID extends Serializable> extends
+        SimpleMongoRepository<T, ID> implements IRenkanRepository<T, ID> {
 
-	public RenkanRepository(MongoEntityInformation<T,ID> metadata,
-			MongoOperations mongoOperations) {
-		super(metadata, mongoOperations);
-	}
+    public RenkanRepository(MongoEntityInformation<T, ID> metadata,
+            MongoOperations mongoOperations) {
+        super(metadata, mongoOperations);
+    }
 
-	@Override
-	public DBCollection getCollection() {		
-		return this.getMongoOperations().getCollection(this.getEntityInformation().getCollectionName());
-	}
+    @Override
+    public DBCollection getCollection() {
+        return this.getMongoOperations().getCollection(
+                this.getEntityInformation().getCollectionName());
+    }
 }
--- a/server/src/main/java/org/iri_research/renkan/repositories/RenkanRepositoryException.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/repositories/RenkanRepositoryException.java	Wed Jan 15 18:36:27 2014 +0100
@@ -2,10 +2,10 @@
 
 public class RenkanRepositoryException extends Exception {
 
-	private static final long serialVersionUID = -7433823426870169568L;
-	
-	public RenkanRepositoryException(String message) {
-		super(message);
-	}
+    private static final long serialVersionUID = -7433823426870169568L;
+
+    public RenkanRepositoryException(String message) {
+        super(message);
+    }
 
 }
--- a/server/src/main/java/org/iri_research/renkan/repositories/RenkanRepositoryFactory.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/repositories/RenkanRepositoryFactory.java	Wed Jan 15 18:36:27 2014 +0100
@@ -10,41 +10,45 @@
 
 public class RenkanRepositoryFactory extends MongoRepositoryFactory {
 
-	private MongoOperations mongoOperations;
-	public RenkanRepositoryFactory(MongoOperations mongoOperations) {
-		super(mongoOperations);
-		this.mongoOperations = mongoOperations;
-	}
+    private MongoOperations mongoOperations;
+
+    public RenkanRepositoryFactory(MongoOperations mongoOperations) {
+        super(mongoOperations);
+        this.mongoOperations = mongoOperations;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.springframework.data.repository.core.support.RepositoryFactorySupport
+     * #getTargetRepository(org.springframework.data.repository.core.
+     * RepositoryMetadata)
+     */
+    @Override
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    protected Object getTargetRepository(RepositoryMetadata metadata) {
+
+        Object res = super.getTargetRepository(metadata);
 
-	/*
-	 * (non-Javadoc)
-	 * @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getTargetRepository(org.springframework.data.repository.core.RepositoryMetadata)
-	 */
-	@Override
-	@SuppressWarnings({ "rawtypes", "unchecked" })
-	protected Object getTargetRepository(RepositoryMetadata metadata) {
-		
-		Object res = super.getTargetRepository(metadata);
-				
-		if(SimpleMongoRepository.class.equals(res.getClass())) {
-			MongoEntityInformation<?, Serializable> entityInformation = this.getEntityInformation(metadata.getDomainType());			
-			return new RenkanRepository(entityInformation, this.mongoOperations);
-		}
-		else {
-			return res;
-		}
+        if (SimpleMongoRepository.class.equals(res.getClass())) {
+            MongoEntityInformation<?, Serializable> entityInformation = this
+                    .getEntityInformation(metadata.getDomainType());
+            return new RenkanRepository(entityInformation, this.mongoOperations);
+        } else {
+            return res;
+        }
+
+    }
 
-	}
-	
-	@Override
-	protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
-		Class<?> res = super.getRepositoryBaseClass(metadata);
-		if(SimpleMongoRepository.class.equals(res)) {
-			return RenkanRepository.class;
-		}
-		else {
-			return res;
-		}
-	}
-	
+    @Override
+    protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
+        Class<?> res = super.getRepositoryBaseClass(metadata);
+        if (SimpleMongoRepository.class.equals(res)) {
+            return RenkanRepository.class;
+        } else {
+            return res;
+        }
+    }
+
 }
--- a/server/src/main/java/org/iri_research/renkan/repositories/RenkanRepositoryFactoryBean.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/repositories/RenkanRepositoryFactoryBean.java	Wed Jan 15 18:36:27 2014 +0100
@@ -7,11 +7,13 @@
 import org.springframework.data.repository.Repository;
 import org.springframework.data.repository.core.support.RepositoryFactorySupport;
 
-public class RenkanRepositoryFactoryBean<T extends Repository<S,ID>,S,ID extends Serializable> extends MongoRepositoryFactoryBean<T,S,ID> {
-	
-	@Override
-	protected RepositoryFactorySupport getFactoryInstance(MongoOperations operations) {
-		return new RenkanRepositoryFactory(operations);
-	}
-	
+public class RenkanRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable>
+        extends MongoRepositoryFactoryBean<T, S, ID> {
+
+    @Override
+    protected RepositoryFactorySupport getFactoryInstance(
+            MongoOperations operations) {
+        return new RenkanRepositoryFactory(operations);
+    }
+
 }
\ No newline at end of file
--- a/server/src/main/java/org/iri_research/renkan/repositories/UsersRepository.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/repositories/UsersRepository.java	Wed Jan 15 18:36:27 2014 +0100
@@ -1,7 +1,15 @@
 package org.iri_research.renkan.repositories;
 
+import java.util.List;
+
 import org.iri_research.renkan.models.User;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
 
-public interface UsersRepository extends IRenkanRepository<User, String> {
+public interface UsersRepository extends IRenkanRepository<User, String>, UsersRepositoryCustom {
+
+    public List<User> findByTitle(String title);
+
+    public Page<User> findByTitle(String title, Pageable p);
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/UsersRepositoryCustom.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,17 @@
+package org.iri_research.renkan.repositories;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.iri_research.renkan.models.Group;
+import org.iri_research.renkan.models.User;
+
+public interface UsersRepositoryCustom {
+    /**
+     * Set the users group list.
+     * @param user : the user
+     * @param groupIds : the list of group ids. this parameter must not be null.
+     */
+    public void setGroupsList(User user, Collection<String> groupIds);    
+    public Map<String, Group> getGroupsMap(User user);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/repositories/UsersRepositoryImpl.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,66 @@
+package org.iri_research.renkan.repositories;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections4.IteratorUtils;
+import org.iri_research.renkan.models.Group;
+import org.iri_research.renkan.models.User;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class UsersRepositoryImpl implements UsersRepositoryCustom {
+
+    @Autowired
+    private UsersRepository usersRepository;
+    
+    @Autowired
+    private GroupsRepository groupsRepository;
+    
+    @Override
+    // TODO: implement a transaction mecanism...
+    public void setGroupsList(User user, Collection<String> groupIds) {
+        
+        assert groupIds != null : "list of group ids must not be null";
+        
+        // takes previous user list
+        List<String> oldGroups = new ArrayList<>(user.getGroups());
+        
+        // calculate difference between two list
+        List<String> groupIdDel =  new ArrayList<>(oldGroups);
+        groupIdDel.removeAll(groupIds);
+        
+        List<String> groupIdAdd = new ArrayList<>(groupIds);
+        groupIdAdd.removeAll(oldGroups);
+        
+        List<Group> groupAdd = IteratorUtils.toList(this.groupsRepository.findAll(groupIdAdd).iterator());
+        for (Group group : groupAdd) {
+            group.addUser(user);
+        }
+        this.groupsRepository.save(groupAdd);
+        List<Group> groupDel = IteratorUtils.toList(this.groupsRepository.findAll(groupIdDel).iterator());
+        for (Group group : groupDel) {
+            group.removeUser(user);
+        }
+        this.groupsRepository.save(groupDel);
+        
+        user.getGroups().clear();
+        user.getGroups().addAll(groupIds);
+        
+        this.usersRepository.save(user);
+    }
+
+    @Override
+    public Map<String, Group> getGroupsMap(User user) {
+        HashMap<String, Group> res = new HashMap<>(user.getGroups().size());
+        
+        for (Group group : this.groupsRepository.findAll(user.getGroups())) {
+            res.put(group.getId(), group);
+        }
+        
+        return res;
+    }
+
+}
--- a/server/src/main/java/org/iri_research/renkan/rest/ObjectMapperProvider.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/rest/ObjectMapperProvider.java	Wed Jan 15 18:36:27 2014 +0100
@@ -7,17 +7,20 @@
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.joda.JodaModule;
 
 @Component
 @Provider
 public class ObjectMapperProvider implements ContextResolver<ObjectMapper> {
 
-	@Override
-	public ObjectMapper getContext(Class<?> type) {
-		ObjectMapper objectMapper = new ObjectMapper();
-		objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
-		
-		return objectMapper;
-	}
+    @Override
+    public ObjectMapper getContext(Class<?> type) {
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
+                false);
+        objectMapper.registerModule(new JodaModule());
+
+        return objectMapper;
+    }
 
 }
--- a/server/src/main/java/org/iri_research/renkan/rest/ProjectsResource.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/rest/ProjectsResource.java	Wed Jan 15 18:36:27 2014 +0100
@@ -1,60 +1,58 @@
 package org.iri_research.renkan.rest;
 
 import java.util.Arrays;
-import java.util.Date;
 import java.util.List;
 
+import javax.inject.Singleton;
 import javax.ws.rs.Path;
 
 import org.iri_research.renkan.Constants;
 import org.iri_research.renkan.models.Project;
 import org.iri_research.renkan.repositories.IRenkanRepository;
 import org.iri_research.renkan.repositories.ProjectsRepository;
+import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import com.sun.jersey.spi.resource.Singleton;
-
-
 @Singleton
 @Path("projects")
 @Component
 public class ProjectsResource extends RenkanResource<Project, String> {
-	
-	@SuppressWarnings("unused")
-	private Logger logger = LoggerFactory.getLogger(ProjectsResource.class);
-	
-	@Autowired
-	private ProjectsRepository projectsRepository;
+
+    @SuppressWarnings("unused")
+    private Logger logger = LoggerFactory.getLogger(ProjectsResource.class);
+
+    @Autowired
+    private ProjectsRepository projectsRepository;
 
-	@Override
-	protected IRenkanRepository<Project, String> getRepository() {
-		return this.projectsRepository;
-	}
+    @Override
+    protected IRenkanRepository<Project, String> getRepository() {
+        return this.projectsRepository;
+    }
 
-	@Override
-	protected String getNewId() {
-		return Constants.UUID_GENERATOR.generate().toString();
-	}
+    @Override
+    protected String getNewId() {
+        return Constants.UUID_GENERATOR.generate().toString();
+    }
 
-	@Override
-	protected void prepareObject(Project obj) {
-		if(obj.getCreated() == null) {
-			obj.setCreated(new Date());
-		}
-		obj.setUpdated(new Date());
-	}
+    @Override
+    protected void prepareObject(Project obj) {
+        if (obj.getCreated() == null) {
+            obj.setCreated(new DateTime());
+        }
+        obj.setUpdated(new DateTime());
+    }
 
-	@Override
-	protected List<String> getObjectListFieldList() {
-		return Arrays.asList(this.baseObjectListFieldList);
-	}	
-	
-	@Override
-	protected void doDeleteObject(String objectId) {
-		this.projectsRepository.deleteRecursive(objectId);
-	}
+    @Override
+    protected List<String> getObjectListFieldList() {
+        return Arrays.asList(this.baseObjectListFieldList);
+    }
+
+    @Override
+    protected void doDeleteObject(String objectId) {
+        this.projectsRepository.deleteRecursive(objectId);
+    }
 
 }
--- a/server/src/main/java/org/iri_research/renkan/rest/RenkanResource.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/rest/RenkanResource.java	Wed Jan 15 18:36:27 2014 +0100
@@ -6,14 +6,12 @@
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
-import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
@@ -21,6 +19,7 @@
 import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.UriInfo;
 
+import org.glassfish.jersey.server.JSONP;
 import org.iri_research.renkan.models.IRenkanModel;
 import org.iri_research.renkan.repositories.IRenkanRepository;
 import org.slf4j.Logger;
@@ -29,155 +28,186 @@
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.joda.JodaModule;
 import com.mongodb.BasicDBObject;
 import com.mongodb.DBCollection;
 import com.mongodb.DBCursor;
 import com.mongodb.DBObject;
-import com.sun.jersey.api.json.JSONWithPadding;
 
 public abstract class RenkanResource<T extends IRenkanModel<ID>, ID extends Serializable> {
-	
-	private Logger logger = LoggerFactory.getLogger(RenkanResource.class);
-	
-	protected String[] baseObjectListFieldList = {"description","title","uri","created", "color"};
+
+    private Logger logger = LoggerFactory.getLogger(RenkanResource.class);
+
+    protected String[] baseObjectListFieldList = { "description", "title",
+            "uri", "created", "color" };
+
+    abstract protected IRenkanRepository<T, ID> getRepository();
+
+    abstract protected ID getNewId();
+
+    abstract protected List<String> getObjectListFieldList();
+
+    @Context
+    private UriInfo uriInfo;
+
+    protected DBCollection getCollection() {
+        return this.getRepository().getCollection();
+    }
 
-	abstract protected IRenkanRepository<T, ID> getRepository();
-	abstract protected ID getNewId();
-	abstract protected List<String> getObjectListFieldList();
+    abstract protected void prepareObject(T obj);
+
+    protected void doDeleteObject(ID objectId) {
+        this.getRepository().delete(objectId);
+    }
 
-	@Context
-	private UriInfo uriInfo;
+    // TODO: this produce application/javascript by default. I would rather have
+    // application/json. The prefered behaviour would be to produde js only od
+    // the callbacl query param is used
+    @GET
+    @Path("{id : [a-zA-Z\\-0-9]+}")
+    @JSONP(callback = "callback", queryParam = "callback")
+    @Produces({ "application/javascript", "application/x-javascript",
+            "text/ecmascript", "application/ecmascript", "text/jscript",
+            MediaType.APPLICATION_JSON + ";charset=utf-8" })
+    public T getObject(@PathParam("id") ID objectId) {
+
+        this.logger.debug("GetObject: " + objectId);
+
+        T obj = this.getRepository().findOne(objectId);
 
-	protected DBCollection getCollection() {
-		return this.getRepository().getCollection();
-	}
-	
-	abstract protected void prepareObject(T obj);
-	
-	protected void doDeleteObject(ID objectId) {
-		this.getRepository().delete(objectId);
-	}
-	
-	
-	//TODO: this produce application/javascript by default. I would rather have application/json. The prefered behaviour would be to produde js only od the callbacl query param is used
-	@GET
-	@Path("{id : [a-zA-Z\\-0-9]+}")
-	@Produces({ "application/javascript",
-        "application/x-javascript", "text/ecmascript", 
-        "application/ecmascript", "text/jscript", MediaType.APPLICATION_JSON + ";charset=utf-8"})
-	public JSONWithPadding getObject(@PathParam("id") ID objectId, @QueryParam("callback") @DefaultValue("callback") String callback) {
-		
-		this.logger.debug("GetObject: " + objectId);
-				
-		T obj = this.getRepository().findOne(objectId);
-		
-		if (null == obj) {
-			throw new WebApplicationException(Status.NOT_FOUND);
-		}
-				
-		return new JSONWithPadding(obj, callback);
-	}
-	
-	@DELETE
-	@Path("{id : [a-zA-Z\\-0-9]+}")
-	@Produces(MediaType.TEXT_PLAIN + ";charset=utf-8")
-	public Response deleteObject(@PathParam("id") ID objectId) {
-		
-		this.logger.debug("DeleteObject : id " + objectId);
-		this.doDeleteObject(objectId);	
-		
-		return Response.ok(this.uriInfo.getAbsolutePathBuilder().build().toString() + " deleted").build();
-		
-	}
-	
-	/**
-	 * test: curl -i -X PUT -H 'Content-Type: application/json' -d @test-data.json  http://localhost:8080/renkan/rest/spaces/12eff140-e65c-11e1-aff1-0800200c9a66
-	 * @param objId
-	 * @param objectContent
-	 */
-	@PUT
-	@Path("{id : [a-zA-Z\\-0-9]+}")
-	@Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
-	public Response putRenkanObject(@PathParam("id") ID objId, T obj) {
+        if (null == obj) {
+            throw new WebApplicationException(Status.NOT_FOUND);
+        }
+
+        return obj;
+    }
+
+    @DELETE
+    @Path("{id : [a-zA-Z\\-0-9]+}")
+    @Produces(MediaType.TEXT_PLAIN + ";charset=utf-8")
+    public Response deleteObject(@PathParam("id") ID objectId) {
+
+        this.logger.debug("DeleteObject : id " + objectId);
+        this.doDeleteObject(objectId);
+
+        return Response.ok(
+                this.uriInfo.getAbsolutePathBuilder().build().toString()
+                        + " deleted").build();
+
+    }
+
+    /**
+     * test: curl -i -X PUT -H 'Content-Type: application/json' -d
+     * 
+     * @test-data.json http://localhost:8080/renkan/rest/spaces/
+     *                 12eff140-e65c-11e1-aff1-0800200c9a66
+     * 
+     * @param objId
+     * @param objectContent
+     */
+    @PUT
+    @Path("{id : [a-zA-Z\\-0-9]+}")
+    @Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    public Response putRenkanObject(@PathParam("id") ID objId, T obj) {
+
+        if (!objId.equals(obj.getId())) {
+            throw new WebApplicationException(Response
+                    .status(Status.BAD_REQUEST)
+                    .entity("Id parameter and id in JSON do not match").build());
+        }
+
+        if (!this.getRepository().exists(objId)) {
+            throw new WebApplicationException(Response.status(Status.NOT_FOUND)
+                    .build());
+        }
 
-		if(!objId.equals(obj.getId())) {
-			throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity("Id parameter and id in JSON do not match").build());
-		}
-		
-		if(!this.getRepository().exists(objId)) {
-			throw new WebApplicationException(Response.status(Status.NOT_FOUND).build());
-		}		
-		
-		this.prepareObject(obj);
-		this.getRepository().save(obj);
-		return Response.noContent().build();
-		
-	}
-	
-	@POST
-	@Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
-	@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
-	public Response postRenkanObject(T obj) {
+        this.prepareObject(obj);
+        this.getRepository().save(obj);
+        return Response.noContent().build();
+
+    }
+
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    public Response postRenkanObject(T obj) {
+
+        if (obj.getId() != null) {
+            throw new WebApplicationException(Response
+                    .status(Status.BAD_REQUEST)
+                    .entity("Id in JSON must be null").build());
+        }
 
-		if(obj.getId() != null) {
-			throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity("Id in JSON must be null").build());
-		}
-				
-		obj.setId(getNewId());
-		this.prepareObject(obj);
-		obj = this.getRepository().save(obj);
-		return Response.created(this.uriInfo.getAbsolutePathBuilder().segment(obj.getId().toString()).build()).entity(obj).build();		
-	}
-			
+        obj.setId(getNewId());
+        this.prepareObject(obj);
+        obj = this.getRepository().save(obj);
+        return Response
+                .created(
+                        this.uriInfo.getAbsolutePathBuilder()
+                                .segment(obj.getId().toString()).build())
+                .entity(obj).build();
+    }
+
+    @GET
+    @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    public String getObjectList() throws JsonProcessingException {
+
+        BasicDBObject keys = new BasicDBObject();
+
+        for (String fieldname : this.getObjectListFieldList()) {
+            keys.put(fieldname, 1);
+        }
+        DBCursor cursor = this.getCollection().find(new BasicDBObject(), keys);
+
+        List<DBObject> res = new ArrayList<DBObject>();
 
-	@GET
-	@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
-	public String getObjectList() throws JsonProcessingException {
-		
-		BasicDBObject keys = new BasicDBObject();
-		
-		for (String fieldname : this.getObjectListFieldList()) {
-			keys.put(fieldname, 1);
-		}
-		DBCursor cursor = this.getCollection().find(new BasicDBObject(), keys);
-		
-		List<DBObject> res = new ArrayList<DBObject>();
-				
-		try {
-			while(cursor.hasNext()) {
-				DBObject obj = cursor.next();
-				obj.put("id", obj.get("_id"));
-				DBObject links = new BasicDBObject();
-				
-				DBObject linkdef = new BasicDBObject();
-				linkdef.put("href", this.uriInfo.getAbsolutePathBuilder().path(obj.get("_id").toString()).build().toString());
-				linkdef.put("method", "get");
-				linkdef.put("produces", MediaType.APPLICATION_JSON + ";charset=utf-8");				
-				links.put("view", linkdef);
-				
-				linkdef = new BasicDBObject();
-				linkdef.put("href", this.uriInfo.getAbsolutePathBuilder().path(obj.get("_id").toString()).build().toString());
-				linkdef.put("method", "put");
-				linkdef.put("consumes", MediaType.APPLICATION_JSON + ";charset=utf-8");				
-				links.put("update", linkdef);
+        try {
+            while (cursor.hasNext()) {
+                DBObject obj = cursor.next();
+                obj.put("id", obj.get("_id"));
+                DBObject links = new BasicDBObject();
+
+                DBObject linkdef = new BasicDBObject();
+                linkdef.put(
+                        "href",
+                        this.uriInfo.getAbsolutePathBuilder()
+                                .path(obj.get("_id").toString()).build()
+                                .toString());
+                linkdef.put("method", "get");
+                linkdef.put("produces", MediaType.APPLICATION_JSON
+                        + ";charset=utf-8");
+                links.put("view", linkdef);
 
-				linkdef = new BasicDBObject();
-				linkdef.put("href", this.uriInfo.getAbsolutePathBuilder().path(obj.get("_id").toString()).build().toString());
-				linkdef.put("method", "delete");
-				links.put("delete", linkdef);				
-				
-				obj.put("__links",  links);
-				res.add(obj);
-			}
-		}
-		finally {
-			cursor.close();
-		}
-		ObjectMapper mapper = new ObjectMapper();
-		mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
-		return mapper.writeValueAsString(res);
-	}
+                linkdef = new BasicDBObject();
+                linkdef.put(
+                        "href",
+                        this.uriInfo.getAbsolutePathBuilder()
+                                .path(obj.get("_id").toString()).build()
+                                .toString());
+                linkdef.put("method", "put");
+                linkdef.put("consumes", MediaType.APPLICATION_JSON
+                        + ";charset=utf-8");
+                links.put("update", linkdef);
 
+                linkdef = new BasicDBObject();
+                linkdef.put(
+                        "href",
+                        this.uriInfo.getAbsolutePathBuilder()
+                                .path(obj.get("_id").toString()).build()
+                                .toString());
+                linkdef.put("method", "delete");
+                links.put("delete", linkdef);
 
-	
+                obj.put("__links", links);
+                res.add(obj);
+            }
+        } finally {
+            cursor.close();
+        }
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+        mapper.registerModule(new JodaModule());
+        return mapper.writeValueAsString(res);
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/rest/RestApplication.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,28 @@
+package org.iri_research.renkan.rest;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.spring.SpringLifecycleListener;
+import org.glassfish.jersey.server.spring.scope.RequestContextFilter;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.datatype.joda.JodaModule;
+import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
+
+public class RestApplication extends ResourceConfig {
+    public RestApplication() {
+
+        this.packages("org.iri_research.renkan.rest");
+        this.register(SpringLifecycleListener.class);
+        this.register(RequestContextFilter.class);
+        
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
+                false);
+        objectMapper.registerModule(new JodaModule());
+        JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider(objectMapper, JacksonJaxbJsonProvider.DEFAULT_ANNOTATIONS);
+        
+        this.register(provider);
+        
+    }
+}
--- a/server/src/main/java/org/iri_research/renkan/rest/SpacesResource.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/rest/SpacesResource.java	Wed Jan 15 18:36:27 2014 +0100
@@ -1,64 +1,61 @@
 package org.iri_research.renkan.rest;
 
-
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Date;
 import java.util.List;
 
+import javax.inject.Singleton;
 import javax.ws.rs.Path;
 
 import org.iri_research.renkan.Constants;
 import org.iri_research.renkan.models.Space;
 import org.iri_research.renkan.repositories.IRenkanRepository;
 import org.iri_research.renkan.repositories.SpacesRepository;
+import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import com.sun.jersey.spi.resource.Singleton;
-
 @Singleton
 @Path("spaces")
 @Component
 public class SpacesResource extends RenkanResource<Space, String> {
-	
-	@SuppressWarnings("unused")
-	private Logger logger = LoggerFactory.getLogger(SpacesResource.class);
-	
-	private String[] spaceObjectListFieldList = {"created_by","bin_config","image"};
-	
-	@Autowired
-	private SpacesRepository spacesRepository;
-		
-	@Override
-	protected IRenkanRepository<Space, String> getRepository() {		
-		return spacesRepository;
-	}
+
+    @SuppressWarnings("unused")
+    private Logger logger = LoggerFactory.getLogger(SpacesResource.class);
+
+    private String[] spaceObjectListFieldList = { "created_by", "bin_config",
+            "image" };
 
+    @Autowired
+    private SpacesRepository spacesRepository;
+
+    @Override
+    protected IRenkanRepository<Space, String> getRepository() {
+        return spacesRepository;
+    }
 
-	@Override
-	protected String getNewId() {
-		return Constants.UUID_GENERATOR.generate().toString();
-	}
-
+    @Override
+    protected String getNewId() {
+        return Constants.UUID_GENERATOR.generate().toString();
+    }
 
-	@Override
-	protected void prepareObject(Space obj) {
-		if(obj.getCreated() == null) {
-			obj.setCreated(new Date());
-		}
-	}
-
+    @Override
+    protected void prepareObject(Space obj) {
+        if (obj.getCreated() == null) {
+            obj.setCreated(new DateTime());
+        }
+    }
 
-	@Override
-	protected List<String> getObjectListFieldList() {
-		ArrayList<String> fieldList = new ArrayList<>(this.baseObjectListFieldList.length + this.spaceObjectListFieldList.length);
-		fieldList.addAll(Arrays.asList(this.baseObjectListFieldList));
-		fieldList.addAll(Arrays.asList(this.spaceObjectListFieldList));
-		return fieldList;
-	}
-
+    @Override
+    protected List<String> getObjectListFieldList() {
+        ArrayList<String> fieldList = new ArrayList<>(
+                this.baseObjectListFieldList.length
+                        + this.spaceObjectListFieldList.length);
+        fieldList.addAll(Arrays.asList(this.baseObjectListFieldList));
+        fieldList.addAll(Arrays.asList(this.spaceObjectListFieldList));
+        return fieldList;
+    }
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/services/RenkanUserDetailsService.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,30 @@
+package org.iri_research.renkan.services;
+
+import java.util.List;
+
+import org.iri_research.renkan.models.User;
+import org.iri_research.renkan.repositories.UsersRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Service;
+
+@Service
+public class RenkanUserDetailsService implements UserDetailsService {
+
+    @Autowired
+    private UsersRepository usersRepository;
+
+    @Override
+    public UserDetails loadUserByUsername(String username)
+            throws UsernameNotFoundException {
+        List<User> res = this.usersRepository.findByTitle(username);
+        if (res == null || res.size() == 0) {
+            throw new UsernameNotFoundException(String.format(
+                    "User {0} not found.", username));
+        }
+        return res.get(0);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/org/iri_research/renkan/utils/ColorGenerator.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,24 @@
+package org.iri_research.renkan.utils;
+
+import java.awt.Color;
+import java.util.Random;
+
+public class ColorGenerator {
+
+    public static Color randomColor() {
+
+        Random rand = new Random();
+
+        float r = rand.nextFloat() * 0.5f + 0.5f;
+        float g = rand.nextFloat() * 0.5f + 0.5f;
+        float b = rand.nextFloat() * 0.5f + 0.5f;
+
+        return new Color(r, g, b);
+    }
+
+    public static String randomColorHex() {
+        Color resColor = ColorGenerator.randomColor();
+        return Integer.toHexString(resColor.getRGB());
+    }
+
+}
--- a/server/src/main/java/org/iri_research/renkan/utils/RenkanLogger.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/utils/RenkanLogger.java	Wed Jan 15 18:36:27 2014 +0100
@@ -7,9 +7,9 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 
-@Retention(RUNTIME)  
-@Target(FIELD)  
-@Documented  
+@Retention(RUNTIME)
+@Target(FIELD)
+@Documented
 public @interface RenkanLogger {
 
 }
--- a/server/src/main/java/org/iri_research/renkan/utils/RenkanLoggerInjector.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/java/org/iri_research/renkan/utils/RenkanLoggerInjector.java	Wed Jan 15 18:36:27 2014 +0100
@@ -7,33 +7,32 @@
 import org.springframework.beans.factory.config.BeanPostProcessor;
 import org.springframework.stereotype.Component;
 import org.springframework.util.ReflectionUtils;
-
-import static org.springframework.util.ReflectionUtils.FieldCallback;
+import org.springframework.util.ReflectionUtils.FieldCallback;
 
 @Component
 public class RenkanLoggerInjector implements BeanPostProcessor {
 
-	@Override
-	public Object postProcessBeforeInitialization(final Object bean,
-			String beanName) throws BeansException {
-		ReflectionUtils.doWithFields(bean.getClass(), new FieldCallback() {
-			public void doWith(Field field) throws IllegalArgumentException,
-					IllegalAccessException {
-				// make the field accessible if defined private
-				ReflectionUtils.makeAccessible(field);
-				if (field.getAnnotation(RenkanLogger.class) != null) {
-					org.slf4j.Logger logger = LoggerFactory.getLogger(bean
-							.getClass());
-					field.set(bean, logger);
-				}
-			}
-		});
-		return bean;
-	}
+    @Override
+    public Object postProcessBeforeInitialization(final Object bean,
+            String beanName) throws BeansException {
+        ReflectionUtils.doWithFields(bean.getClass(), new FieldCallback() {
+            public void doWith(Field field) throws IllegalArgumentException,
+                    IllegalAccessException {
+                // make the field accessible if defined private
+                ReflectionUtils.makeAccessible(field);
+                if (field.getAnnotation(RenkanLogger.class) != null) {
+                    org.slf4j.Logger logger = LoggerFactory.getLogger(bean
+                            .getClass());
+                    field.set(bean, logger);
+                }
+            }
+        });
+        return bean;
+    }
 
-	@Override
-	public Object postProcessAfterInitialization(Object bean, String beanName)
-			throws BeansException {
-		return bean;
-	}
+    @Override
+    public Object postProcessAfterInitialization(Object bean, String beanName)
+            throws BeansException {
+        return bean;
+    }
 }
\ No newline at end of file
--- a/server/src/main/webapp/WEB-INF/applicationContext.xml	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/WEB-INF/applicationContext.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -51,7 +51,7 @@
 	
 	<!-- Configures the annotation-driven Spring MVC Controller programming model.
 	Note that, with Spring 3.0, this tag works in Servlet MVC only!  -->
-
+	
     <!-- Loads MongoDB configuraton -->
     <import resource="mongo-config.xml"/>
     <import resource="spring-security.xml"/>
@@ -68,7 +68,7 @@
      For example @Controller and @Service. Make sure to set the correct base-package-->
     <context:component-scan base-package="org.iri_research.renkan.rest" />
     <context:component-scan base-package="org.iri_research.renkan.coweb" />
-    <context:component-scan base-package="org.iri_research.renkan.forms" />
+    <context:component-scan base-package="org.iri_research.renkan.management" />
     
     <!--mvc:annotation-driven>
         <mvc:argument-resolvers>
@@ -90,7 +90,7 @@
             </list>
         </property>
         <property name="defaultEncoding" value="UTF-8"/>
-        <property name="fallbackToSystemLocale" value="true" />       
+        <property name="fallbackToSystemLocale" value="true" />
     </bean>
     
 
--- a/server/src/main/webapp/WEB-INF/i18n/messages.properties	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/WEB-INF/i18n/messages.properties	Wed Jan 15 18:36:27 2014 +0100
@@ -1,8 +1,11 @@
 
 date.format = yyyy/MM/dd HH:mm
+date.date.format = yyyy/MM/dd
+date.date.datePicker.format = yy/mm/dd
 question.yes = yes
 question.no = no
 
+
 renkanIndex.renkan_exp = Create a Renkan
 renkanIndex.project_list = Renkan list
 renkanIndex.project_name = Name
@@ -47,6 +50,7 @@
 renkanAdmin.space_delete = Delete space
 renkanIndex.space_url = Url
 renkanAdmin.space_confirm_delete = Do you want to delete the space entitled "{0}" ?
+renkanAdmin.space_proj_count = Nb. Proj.
 
 renkanAdmin.object_name = Name
 renkanAdmin.object_edit = Edit
@@ -55,6 +59,7 @@
 renkanAdmin.object_delete_link = Del.
 
 renkanAdmin.form.title = Title
+renkanAdmin.form.name = Name
 renkanAdmin.form.uri = URI
 renkanAdmin.form.description = Description
 renkanAdmin.form.color = Color
@@ -64,8 +69,26 @@
 renkanAdmin.form.space.format = Format
 renkanAdmin.form.space.compact = Compact
 
+renkanAdmin.form.avatar = Avatar
+renkanAdmin.form.credentialsExpirationDate = Cred. exp. date
+renkanAdmin.form.expirationDate = Exp. date
+renkanAdmin.form.email = Email
+renkanAdmin.form.enabled = Enabled
+renkanAdmin.form.locked = Locked
+renkanAdmin.form.password = Password
+renkanAdmin.form.passwordConfirm = Confirm password
+renkanAdmin.form.roles = Roles
+renkanAdmin.form.groups = Groups
+renkanAdmin.form.users = Users
+renkanAdmin.form.user.submit = Ok
+
 renkan.error.title.empty = Title must not be empty or null
+renkan.error.name.empty = Name must not be empty or null
 renkan.error.bin_config.json = bin config field must contain a valid json
+renkan.error.password.equals = Password and Password confimation do not match
+renkan.error.password.missing = Password missing
+renkan.error.authorities.bad_value = Bad value for role
+
 
 renkanAuth.log_in = Log in
 renkanAuth.username_label = Username:
@@ -77,6 +100,25 @@
 
 renkanHeader.login = login
 renkanHeader.logout = logout
-renkanHeader.admin = admin
+renkanHeader.admin = administration
 renkanHeader.home = home
 
+renkan.user.roles.ROLE_USER = User
+renkan.user.roles.ROLE_ADMIN = Admin
+renkan.user.roles.ROLE_SPACES_ADMIN = Space admin
+renkan.user.roles.ROLE_GROUPS_ADMIN = Groups admin
+
+renkanAdmin.user_objects_name = Users
+renkanAdmin.user_add = Add user
+renkanAdmin.user_edit = Edit user
+renkanAdmin.user_delete = Del. user
+renkanIndex.user_url = Url
+renkanAdmin.user_confirm_delete = Do you want to delete the user with username "{0}" ?
+
+renkanAdmin.group_objects_name = Groups
+renkanAdmin.group_add = Add group
+renkanAdmin.group_edit = Edit group
+renkanAdmin.group_delete = Del. group
+renkanIndex.group_url = Url
+renkanAdmin.group_confirm_delete = Do you want to delete the group with groupname "{0}" ?
+
--- a/server/src/main/webapp/WEB-INF/i18n/messages_en.properties	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/WEB-INF/i18n/messages_en.properties	Wed Jan 15 18:36:27 2014 +0100
@@ -1,5 +1,7 @@
 
-date.format = yyyy/MM/dd HH:mm
+date.format = yyyy/dd/MM HH:mm
+date.date.format = yyyy/dd/MM
+date.date.datePicker.format = yy/dd/mm
 question.yes = yes
 question.no = no
 
@@ -44,17 +46,21 @@
 
 renkanAdmin.space_add = Add space
 renkanAdmin.space_edit = Edit space
-renkanAdmin.space_delete = Delete space
+renkanAdmin.space_delete = Del. space
 renkanIndex.space_url = Url
 renkanAdmin.space_confirm_delete = Do you want to delete the space entitled "{0}" ?
+renkanAdmin.space_proj_count = Nb. Proj.
 
 renkanAdmin.object_name = Name
+renkanAdmin.object_created = Created
 renkanAdmin.object_edit = Edit
+renkanAdmin.object_proj_count = Renkan count
 renkanAdmin.object_delete = Delete
 renkanAdmin.object_edit_link = Edit
 renkanAdmin.object_delete_link = Del.
 
 renkanAdmin.form.title = Title
+renkanAdmin.form.name = Name
 renkanAdmin.form.uri = URI
 renkanAdmin.form.description = Description
 renkanAdmin.form.color = Color
@@ -64,8 +70,35 @@
 renkanAdmin.form.space.format = Format
 renkanAdmin.form.space.compact = Compact
 
+
+renkanAdmin.user_objects_name = Users
+renkanAdmin.user_add = Add user
+renkanAdmin.user_edit = Edit user
+renkanAdmin.user_delete = Del. user
+renkanIndex.user_url = Url
+renkanAdmin.user_confirm_delete = Do you want to delete the user with username "{0}" ?
+
+renkanAdmin.form.avatar = Avatar
+renkanAdmin.form.credentialsExpirationDate = Cred. exp. date
+renkanAdmin.form.expirationDate = Exp. date
+renkanAdmin.form.email = Email
+renkanAdmin.form.enabled = Enabled
+renkanAdmin.form.locked = Locked
+renkanAdmin.form.password = Password
+renkanAdmin.form.passwordConfirm = Confirm password
+renkanAdmin.form.roles = Roles
+renkanAdmin.form.groups = Groups
+renkanAdmin.form.users = Users
+renkanAdmin.form.user.submit = Ok
+
+
 renkan.error.title.empty = Title must not be empty or null
+renkan.error.name.empty = Name must not be empty or null
 renkan.error.bin_config.json = bin config field must contain a valid json
+renkan.error.password.equals = Password and Password confimation do not match
+renkan.error.password.missing = Password missing
+renkan.error.authorities.bad_value = Bad value for role
+
 
 renkanAuth.log_in = Log in
 renkanAuth.username_label = Username:
@@ -77,5 +110,19 @@
 
 renkanHeader.login = login
 renkanHeader.logout = logout
-renkanHeader.admin = admin
+renkanHeader.admin = administration
 renkanHeader.home = home
+
+renkan.user.roles.ROLE_USER = User
+renkan.user.roles.ROLE_ADMIN = Admin
+renkan.user.roles.ROLE_SPACES_ADMIN = Space admin
+renkan.user.roles.ROLE_GROUPS_ADMIN = Groups admin
+
+
+renkanAdmin.group_objects_name = Groups
+renkanAdmin.group_add = Add group
+renkanAdmin.group_edit = Edit group
+renkanAdmin.group_delete = Del. group
+renkanIndex.group_url = Url
+renkanAdmin.group_confirm_delete = Do you want to delete the group with groupname "{0}" ?
+
--- a/server/src/main/webapp/WEB-INF/i18n/messages_fr.properties	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/WEB-INF/i18n/messages_fr.properties	Wed Jan 15 18:36:27 2014 +0100
@@ -1,5 +1,7 @@
 
 date.format = dd/MM/yyyy HH:mm
+date.date.format = dd/MM/yyyy
+date.date.datePicker.format = dd/mm/yy
 question.yes = oui
 question.no = non
 
@@ -46,14 +48,18 @@
 renkanAdmin.space_delete = Supression espace
 renkanIndex.space_url = Url
 renkanAdmin.space_confirm_delete = Confirmez-vous l'effacement de l'espace intitulé "{0}" ?
+renkanAdmin.space_proj_count = Nb. Proj.
 
 renkanAdmin.object_name = Nom
+renkanAdmin.object_created = Date Crea.
+renkanAdmin.object_proj_count = Nb. renkan
 renkanAdmin.object_edit = Modif.
 renkanAdmin.object_delete = Eff.
 renkanAdmin.object_edit_link = Modif.
 renkanAdmin.object_delete_link = Eff.
 
 renkanAdmin.form.title = Titre
+renkanAdmin.form.name = Nom
 renkanAdmin.form.uri = URI
 renkanAdmin.form.description = Description
 renkanAdmin.form.color = Couleur
@@ -63,8 +69,33 @@
 renkanAdmin.form.space.format = Formatter
 renkanAdmin.form.space.compact = Compacter
 
+renkanAdmin.user_objects_name = Utilisateurs
+renkanAdmin.user_add = Ajout utilisateur
+renkanAdmin.user_edit = Edition utilisateur
+renkanAdmin.user_delete = Delete space
+renkanIndex.user_url = Url
+renkanAdmin.user_confirm_delete = Do you want to delete the user with username "{0}" ?
+
+renkanAdmin.form.avatar = Avatar
+renkanAdmin.form.credentialsExpirationDate = Date exp. mdp.
+renkanAdmin.form.expirationDate = Date exp.
+renkanAdmin.form.email = Email
+renkanAdmin.form.enabled = Actif
+renkanAdmin.form.locked = Verrouillé
+renkanAdmin.form.password = Mot de passe
+renkanAdmin.form.passwordConfirm = Conf. mot de passe
+renkanAdmin.form.roles = Rôles
+renkanAdmin.form.groups = Groupes
+renkanAdmin.form.users = Utilisateurs
+renkanAdmin.form.user.submit = Ok
+
+
 renkan.error.title.empty = Le champ titre ne doit pas être vide
+renkan.error.name.empty = Le champ nom ne doit pas être vide
 renkan.error.bin_config.json = le champ bin config doit contenir un json valide
+renkan.error.password.equals = Le mot de passe et sa confimation ne corresponde pas
+renkan.error.password.missing = Mot de passe manquant
+renkan.error.authorities.bad_value = Mauvaise valeur de rôle
 
 renkanAuth.log_in = Connection
 renkanAuth.username = Identifiant :
@@ -78,3 +109,15 @@
 renkanHeader.logout = déconnexion
 renkanHeader.admin = administration
 renkanHeader.home = accueil
+
+renkan.user.roles.ROLE_USER = Utilisateur
+renkan.user.roles.ROLE_ADMIN = Administrateur
+renkan.user.roles.ROLE_SPACES_ADMIN =  Admin. espace
+renkan.user.roles.ROLE_GROUPS_ADMIN = Admin. groupes
+
+renkanAdmin.group_objects_name = Groupes
+renkanAdmin.group_add = aj. group
+renkanAdmin.group_edit = Edit. group
+renkanAdmin.group_delete = eff. group
+renkanIndex.group_url = Url
+renkanAdmin.group_confirm_delete = Voulez vous effacer le groupe "{0}" ?
--- a/server/src/main/webapp/WEB-INF/spring-security.xml	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/WEB-INF/spring-security.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -27,22 +27,37 @@
         <property name="location" value="#{propsLocations.classpathProps}"/>
         <property name="ignoreUnresolvablePlaceholders" value="true"/>
         <property name="IgnoreResourceNotFound" value="true"/>
-    </bean>    
+    </bean>
+
+    <bean class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" id="renkanPasswordEncoder">
+        <constructor-arg name="strength" value="10" type="int"/>
+    </bean>
+    
+    <bean class="org.iri_research.renkan.services.RenkanUserDetailsService" id="renkanUserDetailsService" />
  
     <security:http auto-config="true" use-expressions="true">
         <security:intercept-url pattern="/admin" access="hasRole('ROLE_ADMIN')" />
-        <security:intercept-url pattern="/admin/*" access="hasRole('ROLE_ADMIN')" />
+        <security:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
         <security:form-login login-page="/auth/login" authentication-failure-url="/auth/loginfailed" password-parameter="password" username-parameter="username" />
         <security:logout />
     </security:http>
  
-    <security:authentication-manager>        
-	    <security:authentication-provider>
-	        <security:password-encoder hash="sha-256"/>
+    <security:authentication-manager>
+        <security:authentication-provider>
+            <security:password-encoder hash="sha-256"/>
             <security:user-service>
                 <security:user name="${user.admin.name}" password="${user.admin.password}" authorities="ROLE_ADMIN, ROLE_USER"/>
-		    </security:user-service>
-	    </security:authentication-provider>
+            </security:user-service>
+        </security:authentication-provider>
+        <security:authentication-provider user-service-ref='renkanUserDetailsService'>
+            <security:password-encoder ref="renkanPasswordEncoder" />
+        </security:authentication-provider>
     </security:authentication-manager>
+    <!--security:authentication-manager>
+        <security:authentication-provider user-service-ref='renkanUserDetailsService'>
+            <security:password-encoder ref="renkanPasswordEncoder" />
+        </security:authentication-provider>
+    </security:authentication-manager-->
+
  
 </beans>
\ No newline at end of file
--- a/server/src/main/webapp/WEB-INF/spring-servlet.xml	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/WEB-INF/spring-servlet.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -67,6 +67,4 @@
         <property name="characterEncoding" value="UTF-8"/>
         <property name="redirectHttp10Compatible" value="false" />
     </bean>
-    
-    
 </beans>
\ No newline at end of file
--- a/server/src/main/webapp/WEB-INF/templates/admin/adminIndex.html	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/WEB-INF/templates/admin/adminIndex.html	Wed Jan 15 18:36:27 2014 +0100
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" >
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:lang="${#ctx.getLocale().toLanguageTag()}">
   <head>
     <title>Renkan Admin</title>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
@@ -32,11 +32,17 @@
                 <tr>
                   <td colspan="2"><a href="spacesList.html" th:href="@{/admin/spaces}" th:text="#{renkanAdmin.space_objects_name}">Spaces</a></td>
                 </tr>
+                <tr>
+                  <td colspan="2"><a href="usersList.html" th:href="@{/admin/users}" th:text="#{renkanAdmin.user_objects_name}">Users</a></td>
+                </tr>
+                <tr>
+                  <td colspan="2"><a href="groupsList.html" th:href="@{/admin/groups}" th:text="#{renkanAdmin.group_objects_name}">Groups</a></td>
+                </tr>
               </tbody>        
         </table>
       </div>
       <footer id="footer" th:substituteby="fragment/pageFragment::footerFragment">
-        <div id="version">© <span class="version-date">2013</span> <a href="http://www.iri.centrepompidou.fr" target="_blanck">IRI</a> - Version <span class="version-version">0.0</span></div>
+        <div id="version">© <span class="version-date">2013</span> <a href="http://www.iri.centrepompidou.fr" target="_blank">IRI</a> - Version <span class="version-version">0.0</span></div>
       </footer>      
     </div>
   </body>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/WEB-INF/templates/admin/groupDeleteConfirm.html	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:lang="${#ctx.getLocale().toLanguageTag()}" >
+  <head>
+    <title>Renkan Admin - delete group</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta charset="utf-8"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
+
+    <link rel="shortcut icon" href="../../../static/img/favicon.ico" th:href="@{/static/img/favicon.ico}" />
+
+    <link href="../../../static/css/style.css" rel="stylesheet" th:href="@{/static/css/style.css}"/>
+    <link href="../../../static/css/index.css" rel="stylesheet" th:href="@{/static/css/index.css}"/>
+        
+    <script th:remove="all" type="text/javascript" src="../../../static/lib/jquery.min.js" th:src="@{/static/lib/jquery.min.js}" ></script>
+    <script th:remove="all" type="text/javascript" src="../../../static/js/thymol.js"></script>
+  </head>
+  <body>
+    <div id="container">
+      <div id="wrapper">
+        <header id="header">
+            <h1><a href="renkanIndex.html" th:href="@{/admin}" th:text="#{renkanAdmin.renkan_admin}" id="home-link">Renkan administration</a></h1>
+            <div id="headerNav" th:include="fragment/pageFragment :: headerNavFragment"></div>
+        </header>
+        <h2><a href="groupsList.html" th:href="@{/admin/groups}" th:text="#{renkanAdmin.object_list(#{renkanAdmin.group_objects_name})}">Groups List</a>&nbsp;/&nbsp;<span th:text="#{renkanAdmin.group_delete}">Delete group</span></h2>
+        <div id="object-delete-container">
+            <div id="object-delete-question" th:text="#{renkanAdmin.group_confirm_delete(${groupObj.title})}">Do you want to Delete group with name</div>
+            <div id="object-delete-confirm-buttons"><form action="groupsList.html" th:action="@{'/admin/groups/delete/'+${groupObj.id}(key=${key},salt=${salt})}" method="post" id="yes-form"><input type="submit" name="ok" value="yes" th:value="#{question.yes}" id="yes-button"/></form><form action="groupsList.html" method="get" th:action="@{/admin/groups}" id="no-form" onsubmit="return false"><input type="submit" name="ok" value="no" th:value="#{question.no}" id="no-button" onclick="window.location.href='groupsList.html'" th:onclick="'window.location.href=\''+@{/admin/groups}+'\''"/></form></div>
+        </div>
+      </div>
+      <footer id="footer" th:substituteby="fragment/pageFragment::footerFragment">
+        <div id="version">© <span class="version-date">2013</span> <a href="http://www.iri.centrepompidou.fr" target="_blank">IRI</a> - Version <span class="version-version">0.0</span></div>
+      </footer>
+    </div>
+  </body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/WEB-INF/templates/admin/groupEdit.html	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:lang="${#ctx.getLocale().toLanguageTag()}" >
+  <head>
+    <title>Renkan Admin - edit user</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta charset="utf-8"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
+
+    <link rel="shortcut icon" href="../../../static/img/favicon.ico" th:href="@{/static/img/favicon.ico}" />
+
+    <link href="../../../static/css/style.css" rel="stylesheet" th:href="@{/static/css/style.css}"/>
+    <link href="../../../static/css/index.css" rel="stylesheet" th:href="@{/static/css/index.css}"/>
+    <link href='../../../static/css/spectrum.css' rel="stylesheet" th:href="@{/static/css/spectrum.css}"/>
+    <link href='../../../static/lib/jquery-ui/css/ui-lightness/jquery-ui.min.css' rel="stylesheet" th:href="@{/static/lib/jquery-ui/css/ui-lightness/jquery-ui.min.css}"/>
+    
+    <script type="text/javascript" src="../../../static/lib/jquery.min.js" th:src="@{/static/lib/jquery.min.js}" ></script>
+    <script type="text/javascript" src="../../../static/lib/jquery-ui/jquery-ui.min.js" th:src="@{/static/lib/jquery-ui/jquery-ui.min.js}" ></script>
+    <script type="text/javascript" src="../../../static/lib/jquery-ui/i18n/jquery-ui-i18n.min.js" th:src="@{/static/lib/jquery-ui/i18n/jquery-ui-i18n.min.js}" ></script>
+    <script type="text/javascript" src='../../../static/lib/spectrum.js' th:src="@{/static/lib/spectrum.js}"></script>
+    <script type="text/javascript" src='../../../static/js/admin_form.js' th:src="@{/static/js/admin_form.js}"></script>
+    <script th:remove="all" type="text/javascript" src="../../../static/js/thymol.js"></script>
+  </head>
+  <body>
+    <div id="container">
+      <div id="wrapper">
+        <header id="header">
+            <h1><a href="renkanIndex.html" th:href="@{/admin}" th:text="#{renkanAdmin.renkan_admin}" id="home-link">Renkan administration</a></h1>
+            <div id="headerNav" th:include="fragment/pageFragment :: headerNavFragment"></div>
+        </header>
+        <h2><a href="groupsList.html" th:href="@{/admin/groups}" th:text="#{renkanAdmin.object_list(#{renkanAdmin.group_objects_name})}">Groups List</a>&nbsp;/&nbsp;<span th:text="#{renkanAdmin.group_edit}">Edit group</span></h2>
+        <div th:include="fragment/groupForm::groupFormFragment" id="inner-container">
+        </div>
+      </div>
+      <footer id="footer" th:substituteby="fragment/pageFragment::footerFragment">
+        <div id="version">© <span class="version-date">2013</span> <a href="http://www.iri.centrepompidou.fr" target="_blank">IRI</a> - Version <span class="version-version">0.0</span></div>
+      </footer>
+    </div>
+  </body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/WEB-INF/templates/admin/groupsList.html	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:lang="${#ctx.getLocale().toLanguageTag()}" >
+  <head>
+    <title>Renkan Admin - Groups</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta charset="utf-8"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
+
+    <link rel="shortcut icon" href="../../../static/img/favicon.ico" th:href="@{/static/img/favicon.ico}"/>
+
+    <link href="../../../static/css/style.css" rel="stylesheet" th:href="@{/static/css/style.css}"/>
+    <link href="../../../static/css/index.css" rel="stylesheet" th:href="@{/static/css/index.css}"/>
+    
+    <script th:remove="all" type="text/javascript" src="../../../static/lib/jquery.min.js"></script>
+    <script th:remove="all" type="text/javascript" src="../../../static/js/thymol.js"></script>
+  </head>
+  <body>
+    <div id="container">
+      <div id="wrapper">
+        <header id="header">
+            <h1><a href="renkanIndex.html" th:href="@{/admin}" th:text="#{renkanAdmin.renkan_admin}" id="home-link">Renkan administration</a></h1>
+            <div id="headerNav" th:include="fragment/pageFragment :: headerNavFragment"></div>
+        </header>
+        <h2 th:text="#{renkanAdmin.object_list(#{renkanAdmin.group_objects_name})}">List of objects</h2>
+        <div th:include="fragment/paginationFragment :: paginationFragment" class="pagination-container">
+          <div>               
+            <a href="#?p.page=1">&lt;&lt;</a>
+            <a href="#?p.page=3">&lt;</a>
+            <span>...</span>
+            <a href="#?p.page=2">2</a>
+            <a href="#?p.page=3">3</a>
+            <span>4</span>
+            <a href="#?p.page=5">5</a>
+            <a href="#?p.page=6">6</a>
+            <span>...</span>
+            <a href="#?p.page=5">&gt;</a>
+            <a href="#?p.page=7">&gt;&gt;</a> 
+          </div>
+        </div>
+        <div id="objects-content">
+          <ul class="object-tools">
+            <li><a href="groupEdit.html" th:href="@{/admin/groups/edit/}" th:text="#{renkanAdmin.group_add}">Add group</a></li>
+          </ul>
+          <table>
+            <thead>
+              <tr>
+                <th th:text="#{renkanAdmin.object_name}" class="object-table-title">Groupname</th>
+                <th th:text="#{renkanAdmin.object_edit}" class="object-table-actions">Edit</th>
+                <th th:text="#{renkanAdmin.object_delete}" class="object-table-actions">Delete</th>
+              </tr>
+            </thead>
+            <tbody>
+              <tr th:each="object: ${page.content}" >
+                <td th:text="${object.title}" class="object-table-title" >groupname</td>
+                <td><a href="groupEdit.html" th:href="@{'/admin/groups/edit/'+${object.id}}" th:text="#{renkanAdmin.object_edit_link}" class="object-table-actions">Edit</a></td>
+                <td><a href="#" th:href="@{'/admin/groups/delete/'+${object.id}}" th:text="#{renkanAdmin.object_delete_link}" class="users-table-actions">Delete</a></td>
+              </tr>
+            </tbody>
+          </table>
+        </div>
+        
+      </div>
+      <footer id="footer" th:substituteby="fragment/pageFragment::footerFragment">
+        <div id="version">© <span class="version-date">2013</span> <a href="http://www.iri.centrepompidou.fr" target="_blank">IRI</a> - Version <span class="version-version">0.0</span></div>
+      </footer>
+    </div>
+  </body>
+</html>
\ No newline at end of file
--- a/server/src/main/webapp/WEB-INF/templates/admin/spaceDeleteConfirm.html	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/WEB-INF/templates/admin/spaceDeleteConfirm.html	Wed Jan 15 18:36:27 2014 +0100
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" >
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:lang="${#ctx.getLocale().toLanguageTag()}">
   <head>
-    <title>Renkan Admin - edit space</title>
+    <title>Renkan Admin - delete space</title>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
     <meta charset="utf-8"/>
     <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
@@ -22,13 +22,13 @@
             <div id="headerNav" th:include="fragment/pageFragment :: headerNavFragment"></div>
         </header>
         <h2><a href="spacesList.html" th:href="@{/admin/spaces}" th:text="#{renkanAdmin.object_list(#{renkanAdmin.space_objects_name})}">Spaces List</a>&nbsp;/&nbsp;<span th:text="#{renkanAdmin.space_delete}">Delete space</span></h2>
-        <div id="space-delete-container">
-            <div id="space-delete-question" th:text="#{renkanAdmin.space_confirm_delete(${spaceObj.title})}">Do you want to delete space with title</div>
-            <div id="space-delete-confirm-buttons"><form action="spacesList.html" th:action="@{'/admin/spaces/delete/'+${spaceObj.id}(key=${key},salt=${salt})}" method="post" id="yes-form"><input type="submit" name="ok" value="yes" th:value="#{question.yes}" id="yes-button"/></form><form action="spacesList.html" method="get" th:action="@{/admin/spaces}" id="no-form" onsubmit="return false"><input type="submit" name="ok" value="no" th:value="#{question.no}" id="no-button" onclick="window.location.href='spacesList.html'" th:onclick="'window.location.href=\''+@{/admin/spaces}+'\''"/></form></div>
+        <div id="object-delete-container">
+            <div id="object-delete-question" th:text="#{renkanAdmin.space_confirm_delete(${spaceObj.title})}">Do you want to delete space with title</div>
+            <div id="object-delete-confirm-buttons"><form action="spacesList.html" th:action="@{'/admin/spaces/delete/'+${spaceObj.id}(key=${key},salt=${salt})}" method="post" id="yes-form"><input type="submit" name="ok" value="yes" th:value="#{question.yes}" id="yes-button"/></form><form action="spacesList.html" method="get" th:action="@{/admin/spaces}" id="no-form" onsubmit="return false"><input type="submit" name="ok" value="no" th:value="#{question.no}" id="no-button" onclick="window.location.href='spacesList.html'" th:onclick="'window.location.href=\''+@{/admin/spaces}+'\''"/></form></div>
         </div>
       </div>
       <footer id="footer" th:substituteby="fragment/pageFragment::footerFragment">
-        <div id="version">© <span class="version-date">2013</span> <a href="http://www.iri.centrepompidou.fr" target="_blanck">IRI</a> - Version <span class="version-version">0.0</span></div>
+        <div id="version">© <span class="version-date">2013</span> <a href="http://www.iri.centrepompidou.fr" target="_blank">IRI</a> - Version <span class="version-version">0.0</span></div>
       </footer>      
     </div>
   </body>
--- a/server/src/main/webapp/WEB-INF/templates/admin/spaceEdit.html	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/WEB-INF/templates/admin/spaceEdit.html	Wed Jan 15 18:36:27 2014 +0100
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" >
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:lang="${#ctx.getLocale().toLanguageTag()}">
   <head>
     <title>Renkan Admin - edit space</title>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
@@ -13,9 +13,10 @@
     <link href='../../../static/css/spectrum.css' rel="stylesheet" th:href="@{/static/css/spectrum.css}"/>
     
     <script type="text/javascript" src="../../../static/lib/jquery.min.js" th:src="@{/static/lib/jquery.min.js}" ></script>
-    <script type="text/javascript" src="../../../static/lib/jquery-ui.min.js" th:src="@{/static/lib/jquery-ui.min.js}" ></script>
+    <script type="text/javascript" src="../../../static/lib/jquery-ui/jquery-ui.min.js" th:src="@{/static/lib/jquery-ui/jquery-ui.min.js}" ></script>
     <script type="text/javascript" src="../../../static/lib/ace/ace.js" th:src="@{/static/lib/ace/ace.js}" charset="utf-8"></script>
     <script type="text/javascript" src='../../../static/lib/spectrum.js' th:src="@{/static/lib/spectrum.js}"></script>
+    <script type="text/javascript" src='../../../static/js/admin_form.js' th:src="@{/static/js/admin_form.js}"></script>
     <script th:remove="all" type="text/javascript" src="../../../static/js/thymol.js"></script>
   </head>
   <body>
@@ -30,7 +31,7 @@
         </div>
       </div>
       <footer id="footer" th:substituteby="fragment/pageFragment::footerFragment">
-        <div id="version">© <span class="version-date">2013</span> <a href="http://www.iri.centrepompidou.fr" target="_blanck">IRI</a> - Version <span class="version-version">0.0</span></div>
+        <div id="version">© <span class="version-date">2013</span> <a href="http://www.iri.centrepompidou.fr" target="_blank">IRI</a> - Version <span class="version-version">0.0</span></div>
       </footer>      
     </div>
   </body>
--- a/server/src/main/webapp/WEB-INF/templates/admin/spacesList.html	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/WEB-INF/templates/admin/spacesList.html	Wed Jan 15 18:36:27 2014 +0100
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" >
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:lang="${#ctx.getLocale().toLanguageTag()}" >
   <head>
     <title>Renkan Admin - Spaces</title>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
@@ -21,10 +21,10 @@
             <h1><a href="renkanIndex.html" th:href="@{/admin}" th:text="#{renkanAdmin.renkan_admin}" id="home-link">Renkan administration</a></h1>
             <div id="headerNav" th:include="fragment/pageFragment :: headerNavFragment"></div>
         </header>
-        <h2 th:text="#{renkanAdmin.object_list(#{renkanAdmin.space_objects_name})}">List of objects</h2>        
+        <h2 th:text="#{renkanAdmin.object_list(#{renkanAdmin.space_objects_name})}">List of objects</h2>
         <div th:include="fragment/paginationFragment :: paginationFragment" class="pagination-container">
           <div>               
-            <a href="#?p.page=1">&lt;&lt;</a>                    
+            <a href="#?p.page=1">&lt;&lt;</a>
             <a href="#?p.page=3">&lt;</a>
             <span>...</span>
             <a href="#?p.page=2">2</a>
@@ -39,27 +39,27 @@
         </div>
         <div id="objects-content">
           <ul class="object-tools">
-            <li><a href="spacesAdd.html" th:href="@{/admin/spaces/edit/}" th:text="#{renkanAdmin.space_add}">Add space</a></li>
+            <li><a href="spaceAdd.html" th:href="@{/admin/spaces/edit/}" th:text="#{renkanAdmin.space_add}">Add space</a></li>
           </ul>
           <table>
             <thead>
               <tr>
-                <th th:text="#{renkanAdmin.object_name}" class="spaces-table-title">Name</th>
-                <th th:text="#{renkanAdmin.object_name}" class="spaces-table-created">Created</th>
-                <th th:text="#{renkanIndex.space_proj_count}">Project count</th>
-                <th th:text="#{renkanIndex.space_url}">url</th>
-                <th th:text="#{renkanAdmin.object_edit}" class="spaces-table-actions">Edit</th>
-                <th th:text="#{renkanAdmin.object_delete}" class="spaces-table-actions">Delete</th>
+                <th th:text="#{renkanAdmin.object_name}" class="object-table-title">Name</th>
+                <th th:text="#{renkanAdmin.object_created}" class="object-table-created">Created</th>
+                <th th:text="#{renkanAdmin.space_proj_count}" class="object-proj-count">Project count</th>
+                <th th:text="#{renkanIndex.space_url}" class="object-url">url</th>
+                <th th:text="#{renkanAdmin.object_edit}" class="object-table-actions">Edit</th>
+                <th th:text="#{renkanAdmin.object_delete}" class="object-table-actions">Delete</th>
               </tr>
             </thead>
             <tbody>
               <tr th:each="object: ${page.content}" th:with="spaceProjCount=${#maps.containsKey(projectsCount, object.id)}? ${projectsCount[object.id]} : 0">
-                <td th:text="${object.title}" class="spaces-table-title" >title</td>
-                <td th:text="${object.created}?${#dates.format(object.created, #messages.msg('date.format'))}:'n/a'" class="spaces-table-created">created</td>
-                <td th:text="${spaceProjCount}">nb. proj</td>
-                <td><a href="../renkanIndex.html" th:href="@{'/s/'+${object.id}}" th:text="#{renkanIndex.space_url}">url</a></td>
-                <td><a href="spaceEdit.html" th:href="@{'/admin/spaces/edit/'+${object.id}}" th:text="#{renkanAdmin.object_edit_link}" class="spaces-table-actions">Edit</a></td>
-                <td><a href="#" th:if="${spaceProjCount==0}" th:href="@{'/admin/spaces/delete/'+${object.id}}" th:text="#{renkanAdmin.object_delete_link}" class="spaces-table-actions">Delete</a><span th:if="${spaceProjCount>0}" class="spaces-table-actions spaces-table-actions-disabled" th:text="#{renkanAdmin.object_delete_link}">Delete</span></td>
+                <td th:text="${object.title}" class="object-table-title" >title</td>
+                <td th:text="${object.created}?${#dates.format(object.created, #messages.msg('date.format'))}:'n/a'" class="object-table-created">created</td>
+                <td th:text="${spaceProjCount}" class="object-proj-count">nb. proj</td>
+                <td class="object-url"><a href="../renkanIndex.html" th:href="@{'/s/'+${object.id}}" th:text="#{renkanIndex.space_url}" >url</a></td>
+                <td><a href="spaceEdit.html" th:href="@{'/admin/spaces/edit/'+${object.id}}" th:text="#{renkanAdmin.object_edit_link}" class="object-table-actions">Edit</a></td>
+                <td><a href="#" th:if="${spaceProjCount==0}" th:href="@{'/admin/spaces/delete/'+${object.id}}" th:text="#{renkanAdmin.object_delete_link}" class="object-table-actions">Delete</a><span th:if="${spaceProjCount>0}" class="object-table-actions object-table-actions-disabled" th:text="#{renkanAdmin.object_delete_link}">Delete</span></td>
               </tr>
             </tbody>
           </table>
@@ -67,7 +67,7 @@
         
       </div>
       <footer id="footer" th:substituteby="fragment/pageFragment::footerFragment">
-        <div id="version">© <span class="version-date">2013</span> <a href="http://www.iri.centrepompidou.fr" target="_blanck">IRI</a> - Version <span class="version-version">0.0</span></div>
+        <div id="version">© <span class="version-date">2013</span> <a href="http://www.iri.centrepompidou.fr" target="_blank">IRI</a> - Version <span class="version-version">0.0</span></div>
       </footer>
     </div>
   </body>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/WEB-INF/templates/admin/userDeleteConfirm.html	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:lang="${#ctx.getLocale().toLanguageTag()}" >
+  <head>
+    <title>Renkan Admin - delete user</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta charset="utf-8"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
+
+    <link rel="shortcut icon" href="../../../static/img/favicon.ico" th:href="@{/static/img/favicon.ico}" />
+
+    <link href="../../../static/css/style.css" rel="stylesheet" th:href="@{/static/css/style.css}"/>
+    <link href="../../../static/css/index.css" rel="stylesheet" th:href="@{/static/css/index.css}"/>
+        
+    <script th:remove="all" type="text/javascript" src="../../../static/lib/jquery.min.js" th:src="@{/static/lib/jquery.min.js}" ></script>
+    <script th:remove="all" type="text/javascript" src="../../../static/js/thymol.js"></script>
+  </head>
+  <body>
+    <div id="container">
+      <div id="wrapper">
+        <header id="header">
+            <h1><a href="renkanIndex.html" th:href="@{/admin}" th:text="#{renkanAdmin.renkan_admin}" id="home-link">Renkan administration</a></h1>
+            <div id="headerNav" th:include="fragment/pageFragment :: headerNavFragment"></div>
+        </header>
+        <h2><a href="usersList.html" th:href="@{/admin/users}" th:text="#{renkanAdmin.object_list(#{renkanAdmin.user_objects_name})}">Users List</a>&nbsp;/&nbsp;<span th:text="#{renkanAdmin.user_delete}">Delete user</span></h2>
+        <div id="object-delete-container">
+            <div id="object-delete-question" th:text="#{renkanAdmin.user_confirm_delete(${userObj.title})}">Do you want to Delete user with name</div>
+            <div id="object-delete-confirm-buttons"><form action="usersList.html" th:action="@{'/admin/users/delete/'+${userObj.id}(key=${key},salt=${salt})}" method="post" id="yes-form"><input type="submit" name="ok" value="yes" th:value="#{question.yes}" id="yes-button"/></form><form action="usersList.html" method="get" th:action="@{/admin/users}" id="no-form" onsubmit="return false"><input type="submit" name="ok" value="no" th:value="#{question.no}" id="no-button" onclick="window.location.href='usersList.html'" th:onclick="'window.location.href=\''+@{/admin/users}+'\''"/></form></div>
+        </div>
+      </div>
+      <footer id="footer" th:substituteby="fragment/pageFragment::footerFragment">
+        <div id="version">© <span class="version-date">2013</span> <a href="http://www.iri.centrepompidou.fr" target="_blank">IRI</a> - Version <span class="version-version">0.0</span></div>
+      </footer>
+    </div>
+  </body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/WEB-INF/templates/admin/userEdit.html	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:lang="${#ctx.getLocale().toLanguageTag()}" >
+  <head>
+    <title>Renkan Admin - edit user</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta charset="utf-8"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
+
+    <link rel="shortcut icon" href="../../../static/img/favicon.ico" th:href="@{/static/img/favicon.ico}" />
+
+    <link href="../../../static/css/style.css" rel="stylesheet" th:href="@{/static/css/style.css}"/>
+    <link href="../../../static/css/index.css" rel="stylesheet" th:href="@{/static/css/index.css}"/>
+    <link href='../../../static/css/spectrum.css' rel="stylesheet" th:href="@{/static/css/spectrum.css}"/>
+    <link href='../../../static/lib/jquery-ui/css/ui-lightness/jquery-ui.min.css' rel="stylesheet" th:href="@{/static/lib/jquery-ui/css/ui-lightness/jquery-ui.min.css}"/>
+    
+    <script type="text/javascript" src="../../../static/lib/jquery.min.js" th:src="@{/static/lib/jquery.min.js}" ></script>
+    <script type="text/javascript" src="../../../static/lib/jquery-ui/jquery-ui.min.js" th:src="@{/static/lib/jquery-ui/jquery-ui.min.js}" ></script>
+    <script type="text/javascript" src="../../../static/lib/jquery-ui/i18n/jquery-ui-i18n.min.js" th:src="@{/static/lib/jquery-ui/i18n/jquery-ui-i18n.min.js}" ></script>
+    <script type="text/javascript" src='../../../static/lib/spectrum.js' th:src="@{/static/lib/spectrum.js}"></script>
+    <script type="text/javascript" src='../../../static/js/admin_form.js' th:src="@{/static/js/admin_form.js}"></script>
+    <script th:remove="all" type="text/javascript" src="../../../static/js/thymol.js"></script>
+  </head>
+  <body>
+    <div id="container">
+      <div id="wrapper">
+        <header id="header">
+            <h1><a href="renkanIndex.html" th:href="@{/admin}" th:text="#{renkanAdmin.renkan_admin}" id="home-link">Renkan administration</a></h1>
+            <div id="headerNav" th:include="fragment/pageFragment :: headerNavFragment"></div>
+        </header>
+        <h2><a href="userList.html" th:href="@{/admin/users}" th:text="#{renkanAdmin.object_list(#{renkanAdmin.user_objects_name})}">Users List</a>&nbsp;/&nbsp;<span th:text="#{renkanAdmin.user_edit}">Edit user</span></h2>
+        <div th:include="fragment/userForm::userFormFragment" id="inner-container">
+        </div>
+      </div>
+      <footer id="footer" th:substituteby="fragment/pageFragment::footerFragment">
+        <div id="version">© <span class="version-date">2013</span> <a href="http://www.iri.centrepompidou.fr" target="_blank">IRI</a> - Version <span class="version-version">0.0</span></div>
+      </footer>
+    </div>
+  </body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/WEB-INF/templates/admin/usersList.html	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:lang="${#ctx.getLocale().toLanguageTag()}" >
+  <head>
+    <title>Renkan Admin - Users</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta charset="utf-8"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
+
+    <link rel="shortcut icon" href="../../../static/img/favicon.ico" th:href="@{/static/img/favicon.ico}"/>
+
+    <link href="../../../static/css/style.css" rel="stylesheet" th:href="@{/static/css/style.css}"/>
+    <link href="../../../static/css/index.css" rel="stylesheet" th:href="@{/static/css/index.css}"/>
+    
+    <script th:remove="all" type="text/javascript" src="../../../static/lib/jquery.min.js"></script>
+    <script th:remove="all" type="text/javascript" src="../../../static/js/thymol.js"></script>
+  </head>
+  <body>
+    <div id="container">
+      <div id="wrapper">
+        <header id="header">
+            <h1><a href="renkanIndex.html" th:href="@{/admin}" th:text="#{renkanAdmin.renkan_admin}" id="home-link">Renkan administration</a></h1>
+            <div id="headerNav" th:include="fragment/pageFragment :: headerNavFragment"></div>
+        </header>
+        <h2 th:text="#{renkanAdmin.object_list(#{renkanAdmin.user_objects_name})}">List of objects</h2>        
+        <div th:include="fragment/paginationFragment :: paginationFragment" class="pagination-container">
+          <div>               
+            <a href="#?p.page=1">&lt;&lt;</a>
+            <a href="#?p.page=3">&lt;</a>
+            <span>...</span>
+            <a href="#?p.page=2">2</a>
+            <a href="#?p.page=3">3</a>
+            <span>4</span>
+            <a href="#?p.page=5">5</a>
+            <a href="#?p.page=6">6</a>
+            <span>...</span>
+            <a href="#?p.page=5">&gt;</a>
+            <a href="#?p.page=7">&gt;&gt;</a> 
+          </div>
+        </div>
+        <div id="objects-content">
+          <ul class="object-tools">
+            <li><a href="userEdit.html" th:href="@{/admin/users/edit/}" th:text="#{renkanAdmin.user_add}">Add user</a></li>
+          </ul>
+          <table>
+            <thead>
+              <tr>
+                <th th:text="#{renkanAdmin.object_name}" class="object-table-title">Username</th>
+                <th th:text="#{renkanAdmin.object_proj_count}" class="object-proj-count">Project count</th>
+                <th th:text="#{renkanAdmin.object_edit}" class="object-table-actions">Edit</th>
+                <th th:text="#{renkanAdmin.object_delete}" class="object-table-actions">Delete</th>
+              </tr>
+            </thead>
+            <tbody>
+              <tr th:each="object: ${page.content}" th:with="userProjCount=${#maps.containsKey(projectsCount, object.id)}? ${projectsCount[object.id]} : 0">
+                <td th:text="${object.title}" class="object-table-title" >username</td>
+                <td th:text="${userProjCount}" class="object-proj-count">nb. proj</td>
+                <td><a href="userEdit.html" th:href="@{'/admin/users/edit/'+${object.id}}" th:text="#{renkanAdmin.object_edit_link}" class="object-table-actions">Edit</a></td>
+                <td><a href="#" th:if="${userProjCount==0}" th:href="@{'/admin/users/delete/'+${object.id}}" th:text="#{renkanAdmin.object_delete_link}" class="users-table-actions">Delete</a><span th:if="${userProjCount>0}" class="object-table-actions object-table-actions-disabled" th:text="#{renkanAdmin.object_delete_link}">Delete</span></td>
+              </tr>
+            </tbody>
+          </table>
+        </div>
+        
+      </div>
+      <footer id="footer" th:substituteby="fragment/pageFragment::footerFragment">
+        <div id="version">© <span class="version-date">2013</span> <a href="http://www.iri.centrepompidou.fr" target="_blank">IRI</a> - Version <span class="version-version">0.0</span></div>
+      </footer>
+    </div>
+  </body>
+</html>
\ No newline at end of file
--- a/server/src/main/webapp/WEB-INF/templates/auth/login.html	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/WEB-INF/templates/auth/login.html	Wed Jan 15 18:36:27 2014 +0100
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" >
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:lang="${#ctx.getLocale().toLanguageTag()}" >
   <head>
     <title>Renkan Auth Login</title>
     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/WEB-INF/templates/fragment/groupForm.html	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:lang="${#ctx.getLocale().toLanguageTag()}" >
+  <head>
+    <meta charset="utf-8"/>
+    <title>User form</title>
+  </head>
+<body>
+<div id="groupForm" th:fragment="groupFormFragment" >
+  <script type="text/javascript" th:inline="javascript">
+    //<![CDATA[
+
+        function groupFormSubmit() {
+
+            var errors = {};
+            var valid = true;
+
+            if(!$('#title').val()) {
+                errors['title'] = /*[[#{renkan.error.title.empty}]]*/"renkan.error.title.empty";
+                valid = false;
+            }
+
+            showformErrors(errors);
+
+            return valid;
+        }
+        
+        
+        $(function(){
+            
+            $('#color').spectrum({
+                showInput: true,
+                showAlpha: true,
+                showPalette: true,
+                showInitial: true,
+                preferredFormat: 'hex'
+            });
+            $("#model-form").submit(function(e) {
+                return groupFormSubmit();
+            });
+            
+        });
+    //]]>
+  </script>
+  <form action="#" th:object="${group}" th:action="@{/admin/groups/save}" method="post" id="model-form">
+     <fieldset class="form-fields">
+       <input type="hidden" th:field="*{id}" th:if="*{id}" />
+       <div>
+         <label for="title" th:text="#{renkanAdmin.form.name}">Name: </label> 
+         <input type="text" th:field="*{title}" />
+         <div th:if="${#fields.hasErrors('title')}" th:errors="*{title}" class="form-error"></div>
+       </div> 
+       <div>
+         <label for="uri" th:text="#{renkanAdmin.form.uri}">Uri: </label> 
+         <input type="text" th:field="*{uri}" /> 
+       </div> 
+       <div>
+         <label for="description" th:text="#{renkanAdmin.form.description}">Description: </label> 
+         <textarea th:field="*{description}"></textarea> 
+       </div> 
+       <div>
+         <label for="color" th:text="#{renkanAdmin.form.color}">Color: </label> 
+         <input type="text" th:field="*{color}" /> 
+       </div>
+       <div>
+         <label for="avatar" th:text="#{renkanAdmin.form.avatar}">Avatar: </label> 
+         <input type="text" th:field="*{avatar}" /> 
+       </div>
+<!-- todo: only user managing the group can see that -->
+       <div>
+           <label for="users" th:text="#{renkanAdmin.form.users}">Groups: </label>
+           <select th:field="*{users}" multiple="multiple">
+               <option th:each="user: ${allUsers}" th:value="${user.id}" th:text="${user.title}">USER</option>
+           </select>
+       </div>
+       <div class="submit"> 
+         <button type="submit" name="save" th:text="#{renkanAdmin.form.user.submit}">Save</button>
+         <!--button type="button" name="cancel" th:text="#{renkanAdmin.form.user.cancel}" th:onclick="location">Cancel</button-->
+       </div> 
+      
+     </fieldset>
+  </form>
+</div>
+</body>
+</html>
\ No newline at end of file
--- a/server/src/main/webapp/WEB-INF/templates/fragment/pageFragment.html	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/WEB-INF/templates/fragment/pageFragment.html	Wed Jan 15 18:36:27 2014 +0100
@@ -1,7 +1,8 @@
 <!DOCTYPE html>
 <html xmlns="http://www.w3.org/1999/xhtml"
     xmlns:th="http://www.thymeleaf.org"
-    xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
+    xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"
+    th:lang="${#ctx.getLocale().toLanguageTag()}" >
 <head>
 <meta charset="utf-8" />
 <title>pagination fragment</title>
@@ -13,8 +14,8 @@
             <div sec:authorize="isAnonymous()" class="header-nav"><a href="auth/login.html" th:href="@{/auth/login}" th:text="#{renkanHeader.login}">login</a></div>
             <div sec:authorize="isAuthenticated()" class="header-nav">
                 <img src="../../../static/img/user.png" th:src="@{/static/img/user.png}" id="header-nav-user-avatar"/><span sec:authentication="name">username</span>&nbsp;|
-                <a sec:authorize="hasRole('ROLE_USER')" href="" th:href="@{/}" th:text="#{renkanHeader.home}">home</a>&nbsp;|
-                <a sec:authorize="hasRole('ROLE_ADMIN')" href="admin/adminIndex.html" th:href="@{/admin}" th:text="#{renkanHeader.admin}">admin</a>&nbsp;|            
+                <span sec:authorize="hasRole('ROLE_USER')"><a href="" th:href="@{/}" th:text="#{renkanHeader.home}">home</a>&nbsp;|</span>
+                <span sec:authorize="hasRole('ROLE_ADMIN')"><a href="admin/adminIndex.html" th:href="@{/admin}" th:text="#{renkanHeader.admin}">admin</a>&nbsp;|</span>
                 <a href="renkanIndex.html" th:href="@{/j_spring_security_logout}" th:text="#{renkanHeader.logout}">logout</a>
             </div>
             <div id="header-clear"></div>
--- a/server/src/main/webapp/WEB-INF/templates/fragment/paginationFragment.html	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/WEB-INF/templates/fragment/paginationFragment.html	Wed Jan 15 18:36:27 2014 +0100
@@ -1,6 +1,5 @@
 <!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:th="http://www.thymeleaf.org">
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:lang="${#ctx.getLocale().toLanguageTag()}">
 <head>
 <meta charset="utf-8" />
 <title>pagination fragment</title>
@@ -18,8 +17,8 @@
  <a th:if="${page.hasNextPage()}" th:href="@{${baseUrl}(p.page=${page.number+2})}">&gt;</a>
  <a th:if="!${page.lastPage}" th:href="@{${baseUrl}(p.page=${page.totalPages})}">&gt;&gt;</a>
  </div>
- <div th:remove="all">               
-  <a href="#?p.page=1">&lt;&lt;</a>                    
+ <div th:remove="all">
+  <a href="#?p.page=1">&lt;&lt;</a>
   <a href="#?p.page=3">&lt;</a>
   <span>...</span>
   <a href="#?p.page=2">3</a>
--- a/server/src/main/webapp/WEB-INF/templates/fragment/spaceForm.html	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/WEB-INF/templates/fragment/spaceForm.html	Wed Jan 15 18:36:27 2014 +0100
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:lang="${#ctx.getLocale().toLanguageTag()}" >
   <head>
     <meta charset="utf-8"/>
     <title>Space form</title>
@@ -8,63 +8,46 @@
 <div id="spaceForm" th:fragment="spaceFormFragment" >
   <script type="text/javascript" th:inline="javascript">
     //<![CDATA[
-               
-        function showformErrors(errors) {
-        	$(".form-error").remove();
-        	
-        	$.each(errors,function(k,v){
-        		$("#"+k).after('<div class="form-error">'+v+'</div>');
-        	});
-        	$(".form-error").effect("highlight", {}, 1500);
-        }
-              
+
         function spaceFormSubmit() {
+            return true;
+            var errors = {};
+            var valid = true;
 
-        	var errors = {};
-        	var valid = true;
-        	
-        	if(!$('#title').val()) {
-        		errors['title'] = /*[[#{renkan.error.title.empty}]]*/"renkan.error.title.empty";
-        		valid = false;
-        	}
+            if(!$('#title').val()) {
+                errors['title'] = /*[[#{renkan.error.title.empty}]]*/"renkan.error.title.empty";
+                valid = false;
+            }
             
-        	if($('#binConfig').val()) {
-        		
-        		var editor = ace.edit("binConfigDiv");
-        		var annotations = editor.getSession().getAnnotations();
-        		if(annotations.length>0) {
+            if($('#binConfig').val()) {
+
+                var editor = ace.edit("binConfigDiv");
+                var annotations = editor.getSession().getAnnotations();
+                if(annotations.length>0) {
                     var error_message = /*[[#{renkan.error.bin_config.json}]]*/"renkan.error.bin_config.json";
                     errors['binConfigDiv'] = error_message + ". "+ annotations[0].type + ": (" +(annotations[0].row+1)+","+annotations[0].column+") " + annotations[0].text; 
-        			valid = false;        			
-        		}
-        	}
+                    valid = false;
+                }
+            }
             
             showformErrors(errors);
-                        
+
             return valid;
         }
-        
-        function formatJson(jsonText, tabSize) {
-        	var obj = JSON.parse(jsonText);
-        	return JSON.stringify(obj, undefined, tabSize);
-        }
-        function compactJson(jsonText) {
-        	var obj = JSON.parse(jsonText);
-        	return JSON.stringify(obj);
-        }
-        
+
+
         function _setBinConfigStatus(editor) {
             var annotations = editor.getSession().getAnnotations();
             if(annotations.length>0) {
-                $('.binConfigButton').attr("disabled", "disabled");                 
+                $('.binConfigButton').attr("disabled", "disabled");
             }
             else {
                 $('.binConfigButton').removeAttr("disabled");
-            }        	
+            }
         }
-        
+
         $(function(){
-        	var tabSize = 2;
+            var tabSize = 2;
             var editor = ace.edit("binConfigDiv");
             editor.setTheme("ace/theme/xcode");
             editor.getSession().setMode("ace/mode/json");
@@ -72,23 +55,23 @@
             editor.getSession().setUseSoftTabs(true);
             _setBinConfigStatus(editor);
             editor.getSession().on('change', function(e) {
-            	$('#binConfig').val(editor.getValue());
+                $('#binConfig').val(editor.getValue());
             });
             editor.getSession().on('changeAnnotation', function() {
                 _setBinConfigStatus(editor);
             });
-            
+
             $('#binConfigFormatButton').click(function(){
-            	var jsonText = editor.getValue();
-            	try {
-					editor.setValue(formatJson(jsonText, tabSize),0);
-					editor.moveCursorTo(0,0);
-					editor.clearSelection();
-				} catch (e) {
-					//do nothing
-				}
+                var jsonText = editor.getValue();
+                try {
+                    editor.setValue(formatJson(jsonText, tabSize),0);
+                    editor.moveCursorTo(0,0);
+                    editor.clearSelection();
+                } catch (e) {
+                    //do nothing
+                }
             });
-            
+
             $('#binConfigCompactButton').click(function(){
                 var jsonText = editor.getValue();
                 try {
@@ -99,17 +82,22 @@
                     //do nothing
                 }
             });
-            
+
             $('#color').spectrum({
-            	showInput: true,
-            	showAlpha: true,
-            	showPalette: true,
-            	showInitial: true
+                showInput: true,
+                showAlpha: true,
+                showPalette: true,
+                showInitial: true
             });
+
+            $("#model-form").submit(function(e) {
+                return spaceFormSubmit();
+            });
+
         });
     //]]>
   </script>
-  <form action="#" th:object="${space}" th:action="@{/admin/spaces/save}" method="post" onsubmit="return spaceFormSubmit()">
+  <form action="#" th:object="${space}" th:action="@{/admin/spaces/save}" method="post" id="model-form">
      <fieldset class="form-fields">
        <input type="hidden" th:field="*{id}" th:if="*{id}" />
        <input type="hidden" th:field="*{binConfig}"/>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/WEB-INF/templates/fragment/userForm.html	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,155 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:lang="${#ctx.getLocale().toLanguageTag()}" >
+  <head>
+    <meta charset="utf-8"/>
+    <title>User form</title>
+  </head>
+<body>
+<div id="userForm" th:fragment="userFormFragment" >
+  <script type="text/javascript" th:inline="javascript">
+    //<![CDATA[
+
+        function userFormSubmit() {
+
+            var errors = {};
+            var valid = true;
+
+            if(!$('#title').val()) {
+                errors['title'] = /*[[#{renkan.error.title.empty}]]*/"renkan.error.title.empty";
+                valid = false;
+            }
+
+            var password = $('#password').val();
+            var passwordConf = $('#passwordConfirm').val();
+            var objId = $('#id').val();
+            
+            if(!objId && !password) {
+                errors['password'] = /*[[#{renkan.error.password.missing}]]*/"renkan.error.passwsord.missing";
+                valid = false;
+            }
+            if(valid && password !== passwordConf) {
+                errors['password'] = /*[[#{renkan.error.password.equals}]]*/"renkan.error.passwsord.equals";
+                valid = false;
+            }
+
+            showformErrors(errors);
+
+            return valid;
+        }
+        
+        
+        $(function(){
+            var regionalValue = /*[[${#ctx.getLocale().getLanguage()}]]*/"";
+            var dateFormat = /*[[#{date.date.datePicker.format}]]*/"yy/mm/dd";
+            $.datepicker.setDefaults($.datepicker.regional[ "" ]);
+            $('.datepicker').each(function (i,elt) {
+                var picker_options = $.extend({showButtonPanel: true},$.datepicker.regional[regionalValue=="en"?"":regionalValue]);
+                picker_options.dateFormat = dateFormat;
+                picker_options.altFormat = $.datepicker.ISO_8601;
+                var elt = $(elt);
+                picker_options.altField = '#'+elt.attr('id').replace('-disp', '');
+                elt.datepicker(picker_options);
+            });
+            
+            $('#color').spectrum({
+                showInput: true,
+                showAlpha: true,
+                showPalette: true,
+                showInitial: true,
+                preferredFormat: 'hex'
+            });
+            $("#model-form").submit(function(e) {
+                $('.datepicker').each(function (i,elt) {
+                    var elt = $(elt);
+                    elt_val = elt.val();
+                    console.log(elt.attr('id'),elt_val);
+                    if(!elt_val) {
+                        $('#'+elt.attr('id').replace('-disp', '')).val("");
+                    }
+                });
+                return userFormSubmit();
+            });
+            
+        });
+    //]]>
+  </script>
+  <form action="#" th:object="${user}" th:action="@{/admin/users/save}" method="post" id="model-form">
+     <fieldset class="form-fields">
+       <input type="hidden" th:field="*{id}" th:if="*{id}" />
+       <div>
+         <label for="title" th:text="#{renkanAdmin.form.name}">Name: </label> 
+         <input type="text" th:field="*{title}" />
+         <div th:if="${#fields.hasErrors('title')}" th:errors="*{title}" class="form-error"></div>
+       </div> 
+       <div>
+         <label for="uri" th:text="#{renkanAdmin.form.uri}">Uri: </label> 
+         <input type="text" th:field="*{uri}" /> 
+       </div> 
+       <div>
+         <label for="description" th:text="#{renkanAdmin.form.description}">Description: </label> 
+         <textarea th:field="*{description}"></textarea> 
+       </div> 
+       <div>
+         <label for="color" th:text="#{renkanAdmin.form.color}">Color: </label> 
+         <input type="text" th:field="*{color}" /> 
+       </div>
+       <div>
+         <label for="avatar" th:text="#{renkanAdmin.form.avatar}">Avatar: </label> 
+         <input type="text" th:field="*{avatar}" /> 
+       </div>
+       <div>
+         <label for="password" th:text="#{renkanAdmin.form.password}">Password: </label> 
+         <input type="password" th:field="*{password}" /> 
+         <div th:if="${#fields.hasErrors('password')}" th:errors="*{password}" class="form-error"></div>
+       </div>
+       <div>
+         <label for="passwordConfirm" th:text="#{renkanAdmin.form.passwordConfirm}">Confirm password: </label> 
+         <input type="password" th:field="*{passwordConfirm}" /> 
+         <div th:if="${#fields.hasErrors('passwordConfirm')}" th:errors="*{passwordConfirm}" class="form-error"></div>
+       </div>       
+       <div>
+         <label for="credentialsExpirationDate" th:text="#{renkanAdmin.form.credentialsExpirationDate}">Credential expiration date: </label>
+         <input type="hidden" name="credentialsExpirationDate" th:field="*{credentialsExpirationDate}"/>
+         <input type="text" id="credentialsExpirationDate-disp" class="datepicker" value="01/01/1970" th:value="${user.credentialsExpirationDate != null}?${user.credentialsExpirationDate.toString(#messages.msg('date.date.format'))}:''"/>
+          
+       </div>
+       <div>
+         <label for="expirationDate" th:text="#{renkanAdmin.form.expirationDate}">Expiration date: </label>
+         <input type="hidden" name="expirationDate" th:field="*{expirationDate}" />
+         <input type="text" id="expirationDate-disp" class="datepicker" value="01/01/1970" th:value="${user.expirationDate != null}?${user.expirationDate.toString(#messages.msg('date.date.format'))}:''"/> 
+       </div>
+       <div>
+         <label for="email" th:text="#{renkanAdmin.form.email}">Email: </label> 
+         <input type="email" th:field="*{email}" /> 
+       </div>
+       <div>
+         <label for="enabled" th:text="#{renkanAdmin.form.enabled}">Enabled: </label> 
+         <input type="checkbox" th:field="*{enabled}" /> 
+       </div>
+       <div>
+         <label for="locked" th:text="#{renkanAdmin.form.locked}">Locked: </label> 
+         <input type="checkbox" th:field="*{locked}" /> 
+       </div>
+<!-- todo: only user of admin group can see that -->
+       <div>
+           <label for="groups" th:text="#{renkanAdmin.form.groups}">Groups: </label>
+           <select th:field="*{groups}" multiple="multiple">
+               <option th:each="group: ${allGroups}" th:value="${group.id}" th:text="${group.title}">GROUP</option>
+           </select>
+       </div>
+       <div>
+           <label for="userAuthorities" th:text="#{renkanAdmin.form.roles}">Roles: </label>
+           <select th:field="*{userAuthorities}" multiple="multiple">
+               <option th:each="role: ${T(org.iri_research.renkan.Constants).USER_ROLES_SELECT}" th:value="${role}"  th:text="#{${'renkan.user.roles.'+role}}">USER_ROLE</option>
+           </select>
+       </div>
+       <div class="submit"> 
+         <button type="submit" name="save" th:text="#{renkanAdmin.form.user.submit}">Save</button>
+         <!--button type="button" name="cancel" th:text="#{renkanAdmin.form.user.cancel}" th:onclick="location">Cancel</button-->
+       </div> 
+      
+     </fieldset>  
+  </form>
+</div>
+</body>
+</html>
\ No newline at end of file
--- a/server/src/main/webapp/WEB-INF/templates/projectIndex.html	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/WEB-INF/templates/projectIndex.html	Wed Jan 15 18:36:27 2014 +0100
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" >
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:lang="${#ctx.getLocale().toLanguageTag()}" >
     <head>
         <title>Renkan</title>
 
--- a/server/src/main/webapp/WEB-INF/templates/renkanIndex.html	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/WEB-INF/templates/renkanIndex.html	Wed Jan 15 18:36:27 2014 +0100
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" >
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:lang="${#ctx.getLocale().toLanguageTag()}" >
     <head>
         <title>Renkan</title>
 
@@ -54,7 +54,7 @@
                     <th th:text="#{renkanIndex.space_name}">Name</th>
                     <th th:text="#{renkanIndex.space_creation}">Creation</th>
                     <th th:text="#{renkanIndex.space_proj_count}">Project count</th>
-                    <th th:text="#{renkanIndex.space_open}">Edit</th>
+                    <th th:text="#{renkanIndex.space_open}">Open</th>
                 </tr>
               </thead>
               <tbody>
--- a/server/src/main/webapp/WEB-INF/templates/renkanProjectEdit.html	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/WEB-INF/templates/renkanProjectEdit.html	Wed Jan 15 18:36:27 2014 +0100
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html lang="fr" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" >
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:lang="${#ctx.getLocale().toLanguageTag()}">
     <head>
         <meta charset="utf-8" />
         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
--- a/server/src/main/webapp/WEB-INF/templates/renkanProjectPublish.html	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/WEB-INF/templates/renkanProjectPublish.html	Wed Jan 15 18:36:27 2014 +0100
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html lang="fr" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" >
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" th:lang="${#ctx.getLocale().toLanguageTag()}">
     <head>
         <meta charset="utf-8" />
         <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
--- a/server/src/main/webapp/WEB-INF/web.xml	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/WEB-INF/web.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -2,15 +2,15 @@
 <web-app 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns="http://java.sun.com/xml/ns/javaee"
-    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
-    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
-    version="2.5">
+    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+    version="3.0">
   <listener>  
       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
   </listener>
   <listener>  
       <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>  
-  </listener>  
+  </listener>
   <context-param>  
     <param-name>contextConfigLocation</param-name>  
     <param-value>/WEB-INF/applicationContext.xml</param-value>  
@@ -66,20 +66,16 @@
     <url-pattern>/ocw_admin/*</url-pattern>
   </servlet-mapping>
   <servlet>
-    <servlet-name>rest Servlet</servlet-name>
-    <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
+    <servlet-name>restServlet</servlet-name>
+    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
     <init-param>
-      <param-name>com.sun.jersey.config.property.packages</param-name>
-      <param-value>org.iri_research.renkan.rest</param-value>
-    </init-param>
-    <init-param>
-      <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
-      <param-value>true</param-value>
+      <param-name>javax.ws.rs.Application</param-name>
+      <param-value>org.iri_research.renkan.rest.RestApplication</param-value>
     </init-param>
     <load-on-startup>1</load-on-startup>
   </servlet>
   <servlet-mapping>
-    <servlet-name>rest Servlet</servlet-name>
+    <servlet-name>restServlet</servlet-name>
     <url-pattern>/rest/*</url-pattern>
   </servlet-mapping>
   <servlet>
--- a/server/src/main/webapp/static/css/index.css	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/main/webapp/static/css/index.css	Wed Jan 15 18:36:27 2014 +0100
@@ -239,24 +239,24 @@
     text-decoration: none;
 }
 
-.spaces-table-title {
+.object-table-title {
 	width: 250px;
 }
-.spaces-table-created {
+.object-table-created {
     width: 120px;
 }
 
-.spaces-table-actions {
+.object-table-actions {
     width: 40px;
 }
 
-.spaces-table-actions-disabled, .spaces-table-actions-disabled:link, .spaces-table-actions-disabled:visited, .spaces-table-actions-disabled:hover, .spaces-table-actions-disabled:active, .spaces-table-actions-disabled:focus {
+.object-table-actions-disabled, .object-table-actions-disabled:link, .object-table-actions-disabled:visited, .object-table-actions-disabled:hover, .object-table-actions-disabled:active, .object-table-actions-disabled:focus {
 	color: gray;
 	text-decoration: none;
 	cursor: default;
 }
 
-td.spaces-table-created {
+td.object-table-created {
 	text-align: center;
 }
 
@@ -269,7 +269,7 @@
   float: left;
 }
 
-.form-fields input, .form-fields textarea {
+.form-fields input, .form-fields textarea, .form-fields select {
   width:200px;
 }
 
@@ -299,23 +299,23 @@
     margin-bottom: 0; 
 }
 
-#space-delete-container {
+#object-delete-container {
 	margin-left: 12px;
 	margin-top: 1em;
 }
 
 
-#space-delete-confirm-buttons {
+#object-delete-confirm-buttons {
 	margin-top: 1em;
 }
 
-#space-delete-confirm-buttons form {
+#object-delete-confirm-buttons form {
 	margin: 0;
 	padding: 0;
 	display: inline;
 }
 
-#space-delete-confirm-buttons input[type=submit] {
+#object-delete-confirm-buttons input[type=submit] {
 	margin-right: 12px;
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/js/admin_form.js	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,18 @@
+function showformErrors(errors) {
+    $(".form-error").remove();
+    
+    $.each(errors,function(k,v){
+        $("#"+k).after('<div class="form-error">'+v+'</div>');
+    });
+    $(".form-error").effect("highlight", {}, 1500);
+}
+
+
+function formatJson(jsonText, tabSize) {
+    var obj = JSON.parse(jsonText);
+    return JSON.stringify(obj, undefined, tabSize);
+}
+function compactJson(jsonText) {
+    var obj = JSON.parse(jsonText);
+    return JSON.stringify(obj);
+}
--- a/server/src/main/webapp/static/lib/jquery-ui.min.js	Fri Oct 25 16:42:11 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-/*! jQuery UI - v1.10.2 - 2013-04-01
-* http://jqueryui.com
-* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js
-* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
-
-(function(e,t){function i(t,i){var a,n,r,o=t.nodeName.toLowerCase();return"area"===o?(a=t.parentNode,n=a.name,t.href&&n&&"map"===a.nodeName.toLowerCase()?(r=e("img[usemap=#"+n+"]")[0],!!r&&s(r)):!1):(/input|select|textarea|button|object/.test(o)?!t.disabled:"a"===o?t.href||i:i)&&s(t)}function s(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}var a=0,n=/^ui-id-\d+$/;e.ui=e.ui||{},e.extend(e.ui,{version:"1.10.2",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({focus:function(t){return function(i,s){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),s&&s.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),scrollParent:function(){var t;return t=e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(i){if(i!==t)return this.css("zIndex",i);if(this.length)for(var s,a,n=e(this[0]);n.length&&n[0]!==document;){if(s=n.css("position"),("absolute"===s||"relative"===s||"fixed"===s)&&(a=parseInt(n.css("zIndex"),10),!isNaN(a)&&0!==a))return a;n=n.parent()}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++a)})},removeUniqueId:function(){return this.each(function(){n.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,s){return!!e.data(t,s[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var s=e.attr(t,"tabindex"),a=isNaN(s);return(a||s>=0)&&i(t,!a)}}),e("<a>").outerWidth(1).jquery||e.each(["Width","Height"],function(i,s){function a(t,i,s,a){return e.each(n,function(){i-=parseFloat(e.css(t,"padding"+this))||0,s&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),a&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var n="Width"===s?["Left","Right"]:["Top","Bottom"],r=s.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+s]=function(i){return i===t?o["inner"+s].call(this):this.each(function(){e(this).css(r,a(this,i)+"px")})},e.fn["outer"+s]=function(t,i){return"number"!=typeof t?o["outer"+s].call(this,t):this.each(function(){e(this).css(r,a(this,t,!0,i)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.support.selectstart="onselectstart"in document.createElement("div"),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,i,s){var a,n=e.ui[t].prototype;for(a in s)n.plugins[a]=n.plugins[a]||[],n.plugins[a].push([i,s[a]])},call:function(e,t,i){var s,a=e.plugins[t];if(a&&e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType)for(s=0;a.length>s;s++)e.options[a[s][0]]&&a[s][1].apply(e.element,i)}},hasScroll:function(t,i){if("hidden"===e(t).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",a=!1;return t[s]>0?!0:(t[s]=1,a=t[s]>0,t[s]=0,a)}})})(jQuery);(function(e,t){var i=0,s=Array.prototype.slice,n=e.cleanData;e.cleanData=function(t){for(var i,s=0;null!=(i=t[s]);s++)try{e(i).triggerHandler("remove")}catch(a){}n(t)},e.widget=function(i,s,n){var a,r,o,h,l={},u=i.split(".")[0];i=i.split(".")[1],a=u+"-"+i,n||(n=s,s=e.Widget),e.expr[":"][a.toLowerCase()]=function(t){return!!e.data(t,a)},e[u]=e[u]||{},r=e[u][i],o=e[u][i]=function(e,i){return this._createWidget?(arguments.length&&this._createWidget(e,i),t):new o(e,i)},e.extend(o,r,{version:n.version,_proto:e.extend({},n),_childConstructors:[]}),h=new s,h.options=e.widget.extend({},h.options),e.each(n,function(i,n){return e.isFunction(n)?(l[i]=function(){var e=function(){return s.prototype[i].apply(this,arguments)},t=function(e){return s.prototype[i].apply(this,e)};return function(){var i,s=this._super,a=this._superApply;return this._super=e,this._superApply=t,i=n.apply(this,arguments),this._super=s,this._superApply=a,i}}(),t):(l[i]=n,t)}),o.prototype=e.widget.extend(h,{widgetEventPrefix:r?h.widgetEventPrefix:i},l,{constructor:o,namespace:u,widgetName:i,widgetFullName:a}),r?(e.each(r._childConstructors,function(t,i){var s=i.prototype;e.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete r._childConstructors):s._childConstructors.push(o),e.widget.bridge(i,o)},e.widget.extend=function(i){for(var n,a,r=s.call(arguments,1),o=0,h=r.length;h>o;o++)for(n in r[o])a=r[o][n],r[o].hasOwnProperty(n)&&a!==t&&(i[n]=e.isPlainObject(a)?e.isPlainObject(i[n])?e.widget.extend({},i[n],a):e.widget.extend({},a):a);return i},e.widget.bridge=function(i,n){var a=n.prototype.widgetFullName||i;e.fn[i]=function(r){var o="string"==typeof r,h=s.call(arguments,1),l=this;return r=!o&&h.length?e.widget.extend.apply(null,[r].concat(h)):r,o?this.each(function(){var s,n=e.data(this,a);return n?e.isFunction(n[r])&&"_"!==r.charAt(0)?(s=n[r].apply(n,h),s!==n&&s!==t?(l=s&&s.jquery?l.pushStack(s.get()):s,!1):t):e.error("no such method '"+r+"' for "+i+" widget instance"):e.error("cannot call methods on "+i+" prior to initialization; "+"attempted to call method '"+r+"'")}):this.each(function(){var t=e.data(this,a);t?t.option(r||{})._init():e.data(this,a,new n(r,this))}),l}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(t,s){s=e(s||this.defaultElement||this)[0],this.element=e(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),s!==this&&(e.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===s&&this.destroy()}}),this.document=e(s.style?s.ownerDocument:s.document||s),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(i,s){var n,a,r,o=i;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof i)if(o={},n=i.split("."),i=n.shift(),n.length){for(a=o[i]=e.widget.extend({},this.options[i]),r=0;n.length-1>r;r++)a[n[r]]=a[n[r]]||{},a=a[n[r]];if(i=n.pop(),s===t)return a[i]===t?null:a[i];a[i]=s}else{if(s===t)return this.options[i]===t?null:this.options[i];o[i]=s}return this._setOptions(o),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!t).attr("aria-disabled",t),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(i,s,n){var a,r=this;"boolean"!=typeof i&&(n=s,s=i,i=!1),n?(s=a=e(s),this.bindings=this.bindings.add(s)):(n=s,s=this.element,a=this.widget()),e.each(n,function(n,o){function h(){return i||r.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof o?r[o]:o).apply(r,arguments):t}"string"!=typeof o&&(h.guid=o.guid=o.guid||h.guid||e.guid++);var l=n.match(/^(\w+)\s*(.*)$/),u=l[1]+r.eventNamespace,c=l[2];c?a.delegate(c,u,h):s.bind(u,h)})},_off:function(e,t){t=(t||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.unbind(t).undelegate(t)},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var n,a,r=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],a=i.originalEvent)for(n in a)n in i||(i[n]=a[n]);return this.element.trigger(i,s),!(e.isFunction(r)&&r.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,n,a){"string"==typeof n&&(n={effect:n});var r,o=n?n===!0||"number"==typeof n?i:n.effect||i:t;n=n||{},"number"==typeof n&&(n={duration:n}),r=!e.isEmptyObject(n),n.complete=a,n.delay&&s.delay(n.delay),r&&e.effects&&e.effects.effect[o]?s[t](n):o!==t&&s[o]?s[o](n.duration,n.easing,a):s.queue(function(i){e(this)[t](),a&&a.call(s[0]),i()})}})})(jQuery);(function(e){var t=!1;e(document).mouseup(function(){t=!1}),e.widget("ui.mouse",{version:"1.10.2",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var t=this;this.element.bind("mousedown."+this.widgetName,function(e){return t._mouseDown(e)}).bind("click."+this.widgetName,function(i){return!0===e.data(i.target,t.widgetName+".preventClickEvent")?(e.removeData(i.target,t.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):undefined}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(i){if(!t){this._mouseStarted&&this._mouseUp(i),this._mouseDownEvent=i;var s=this,n=1===i.which,a="string"==typeof this.options.cancel&&i.target.nodeName?e(i.target).closest(this.options.cancel).length:!1;return n&&!a&&this._mouseCapture(i)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){s.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(i)&&this._mouseDelayMet(i)&&(this._mouseStarted=this._mouseStart(i)!==!1,!this._mouseStarted)?(i.preventDefault(),!0):(!0===e.data(i.target,this.widgetName+".preventClickEvent")&&e.removeData(i.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(e){return s._mouseMove(e)},this._mouseUpDelegate=function(e){return s._mouseUp(e)},e(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),i.preventDefault(),t=!0,!0)):!0}},_mouseMove:function(t){return e.ui.ie&&(!document.documentMode||9>document.documentMode)&&!t.button?this._mouseUp(t):this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted)},_mouseUp:function(t){return e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})})(jQuery);(function(t,e){function i(t,e,i){return[parseFloat(t[0])*(p.test(t[0])?e/100:1),parseFloat(t[1])*(p.test(t[1])?i/100:1)]}function s(e,i){return parseInt(t.css(e,i),10)||0}function n(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}t.ui=t.ui||{};var a,o=Math.max,r=Math.abs,h=Math.round,l=/left|center|right/,c=/top|center|bottom/,u=/[\+\-]\d+(\.[\d]+)?%?/,d=/^\w+/,p=/%$/,f=t.fn.position;t.position={scrollbarWidth:function(){if(a!==e)return a;var i,s,n=t("<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),o=n.children()[0];return t("body").append(n),i=o.offsetWidth,n.css("overflow","scroll"),s=o.offsetWidth,i===s&&(s=n[0].clientWidth),n.remove(),a=i-s},getScrollInfo:function(e){var i=e.isWindow?"":e.element.css("overflow-x"),s=e.isWindow?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.width<e.element[0].scrollWidth,a="scroll"===s||"auto"===s&&e.height<e.element[0].scrollHeight;return{width:a?t.position.scrollbarWidth():0,height:n?t.position.scrollbarWidth():0}},getWithinInfo:function(e){var i=t(e||window),s=t.isWindow(i[0]);return{element:i,isWindow:s,offset:i.offset()||{left:0,top:0},scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:s?i.width():i.outerWidth(),height:s?i.height():i.outerHeight()}}},t.fn.position=function(e){if(!e||!e.of)return f.apply(this,arguments);e=t.extend({},e);var a,p,m,g,v,_,b=t(e.of),y=t.position.getWithinInfo(e.within),w=t.position.getScrollInfo(y),x=(e.collision||"flip").split(" "),k={};return _=n(b),b[0].preventDefault&&(e.at="left top"),p=_.width,m=_.height,g=_.offset,v=t.extend({},g),t.each(["my","at"],function(){var t,i,s=(e[this]||"").split(" ");1===s.length&&(s=l.test(s[0])?s.concat(["center"]):c.test(s[0])?["center"].concat(s):["center","center"]),s[0]=l.test(s[0])?s[0]:"center",s[1]=c.test(s[1])?s[1]:"center",t=u.exec(s[0]),i=u.exec(s[1]),k[this]=[t?t[0]:0,i?i[0]:0],e[this]=[d.exec(s[0])[0],d.exec(s[1])[0]]}),1===x.length&&(x[1]=x[0]),"right"===e.at[0]?v.left+=p:"center"===e.at[0]&&(v.left+=p/2),"bottom"===e.at[1]?v.top+=m:"center"===e.at[1]&&(v.top+=m/2),a=i(k.at,p,m),v.left+=a[0],v.top+=a[1],this.each(function(){var n,l,c=t(this),u=c.outerWidth(),d=c.outerHeight(),f=s(this,"marginLeft"),_=s(this,"marginTop"),D=u+f+s(this,"marginRight")+w.width,T=d+_+s(this,"marginBottom")+w.height,C=t.extend({},v),M=i(k.my,c.outerWidth(),c.outerHeight());"right"===e.my[0]?C.left-=u:"center"===e.my[0]&&(C.left-=u/2),"bottom"===e.my[1]?C.top-=d:"center"===e.my[1]&&(C.top-=d/2),C.left+=M[0],C.top+=M[1],t.support.offsetFractions||(C.left=h(C.left),C.top=h(C.top)),n={marginLeft:f,marginTop:_},t.each(["left","top"],function(i,s){t.ui.position[x[i]]&&t.ui.position[x[i]][s](C,{targetWidth:p,targetHeight:m,elemWidth:u,elemHeight:d,collisionPosition:n,collisionWidth:D,collisionHeight:T,offset:[a[0]+M[0],a[1]+M[1]],my:e.my,at:e.at,within:y,elem:c})}),e.using&&(l=function(t){var i=g.left-C.left,s=i+p-u,n=g.top-C.top,a=n+m-d,h={target:{element:b,left:g.left,top:g.top,width:p,height:m},element:{element:c,left:C.left,top:C.top,width:u,height:d},horizontal:0>s?"left":i>0?"right":"center",vertical:0>a?"top":n>0?"bottom":"middle"};u>p&&p>r(i+s)&&(h.horizontal="center"),d>m&&m>r(n+a)&&(h.vertical="middle"),h.important=o(r(i),r(s))>o(r(n),r(a))?"horizontal":"vertical",e.using.call(this,t,h)}),c.offset(t.extend(C,{using:l}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,a=n.offset.left+n.scrollLeft,o=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-o-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-o-a,(0>i||r(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>r(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,a=n.offset.top+n.scrollTop,o=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-o-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,m=-2*e.offset[1];0>c?(s=t.top+p+f+m+e.collisionHeight-o-a,t.top+p+f+m>c&&(0>s||r(c)>s)&&(t.top+=p+f+m)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+m-h,t.top+p+f+m>u&&(i>0||u>r(i))&&(t.top+=p+f+m))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}},function(){var e,i,s,n,a,o=document.getElementsByTagName("body")[0],r=document.createElement("div");e=document.createElement(o?"div":"body"),s={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},o&&t.extend(s,{position:"absolute",left:"-1000px",top:"-1000px"});for(a in s)e.style[a]=s[a];e.appendChild(r),i=o||document.documentElement,i.insertBefore(e,i.firstChild),r.style.cssText="position: absolute; left: 10.7432222px;",n=t(r).offset().left,t.support.offsetFractions=n>10&&11>n,e.innerHTML="",i.removeChild(e)}()})(jQuery);(function(e){e.widget("ui.draggable",e.ui.mouse,{version:"1.10.2",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"!==this.options.helper||/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},_destroy:function(){this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy()},_mouseCapture:function(t){var i=this.options;return this.helper||i.disabled||e(t.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(t),this.handle?(e(i.iframeFix===!0?"iframe":i.iframeFix).each(function(){e("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>").css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(e(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(t){var i=this.options;return this.helper=this._createHelper(t),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),e.ui.ddmanager&&(e.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),i.containment&&this._setContainment(),this._trigger("start",t)===!1?(this._clear(),!1):(this._cacheHelperProportions(),e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this._mouseDrag(t,!0),e.ui.ddmanager&&e.ui.ddmanager.dragStart(this,t),!0)},_mouseDrag:function(t,i){if(this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",t,s)===!1)return this._mouseUp({}),!1;this.position=s.position}return this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var i,s=this,n=!1,a=!1;for(e.ui.ddmanager&&!this.options.dropBehaviour&&(a=e.ui.ddmanager.drop(this,t)),this.dropped&&(a=this.dropped,this.dropped=!1),i=this.element[0];i&&(i=i.parentNode);)i===document&&(n=!0);return n||"original"!==this.options.helper?("invalid"===this.options.revert&&!a||"valid"===this.options.revert&&a||this.options.revert===!0||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,a)?e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){s._trigger("stop",t)!==!1&&s._clear()}):this._trigger("stop",t)!==!1&&this._clear(),!1):!1},_mouseUp:function(t){return e("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),e.ui.ddmanager&&e.ui.ddmanager.dragStop(this,t),e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(t){return this.options.handle?!!e(t.target).closest(this.element.find(this.options.handle)).length:!0},_createHelper:function(t){var i=this.options,s=e.isFunction(i.helper)?e(i.helper.apply(this.element[0],[t])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return s.parents("body").length||s.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s[0]===this.element[0]||/(fixed|absolute)/.test(s.css("position"))||s.css("position","absolute"),s},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&e.ui.ie)&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var e=this.element.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,i,s,n=this.options;if("parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=["document"===n.containment?0:e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,"document"===n.containment?0:e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,("document"===n.containment?0:e(window).scrollLeft())+e("document"===n.containment?document:window).width()-this.helperProportions.width-this.margins.left,("document"===n.containment?0:e(window).scrollTop())+(e("document"===n.containment?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||n.containment.constructor===Array)n.containment.constructor===Array&&(this.containment=n.containment);else{if(i=e(n.containment),s=i[0],!s)return;t="hidden"!==e(s).css("overflow"),this.containment=[(parseInt(e(s).css("borderLeftWidth"),10)||0)+(parseInt(e(s).css("paddingLeft"),10)||0),(parseInt(e(s).css("borderTopWidth"),10)||0)+(parseInt(e(s).css("paddingTop"),10)||0),(t?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(e(s).css("borderRightWidth"),10)||0)-(parseInt(e(s).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(t?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(e(s).css("borderBottomWidth"),10)||0)-(parseInt(e(s).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=i}},_convertPositionTo:function(t,i){i||(i=this.position);var s="absolute"===t?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,a=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():a?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():a?0:n.scrollLeft())*s}},_generatePosition:function(t){var i,s,n,a,o=this.options,r="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName),l=t.pageX,u=t.pageY;return this.originalPosition&&(this.containment&&(this.relative_container?(s=this.relative_container.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,t.pageX-this.offset.click.left<i[0]&&(l=i[0]+this.offset.click.left),t.pageY-this.offset.click.top<i[1]&&(u=i[1]+this.offset.click.top),t.pageX-this.offset.click.left>i[2]&&(l=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3]&&(u=i[3]+this.offset.click.top)),o.grid&&(n=o.grid[1]?this.originalPageY+Math.round((u-this.originalPageY)/o.grid[1])*o.grid[1]:this.originalPageY,u=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-o.grid[1]:n+o.grid[1]:n,a=o.grid[0]?this.originalPageX+Math.round((l-this.originalPageX)/o.grid[0])*o.grid[0]:this.originalPageX,l=i?a-this.offset.click.left>=i[0]||a-this.offset.click.left>i[2]?a:a-this.offset.click.left>=i[0]?a-o.grid[0]:a+o.grid[0]:a)),{top:u-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:l-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(t,i,s){return s=s||this._uiHash(),e.ui.plugin.call(this,t,[i,s]),"drag"===t&&(this.positionAbs=this._convertPositionTo("absolute")),e.Widget.prototype._trigger.call(this,t,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),e.ui.plugin.add("draggable","connectToSortable",{start:function(t,i){var s=e(this).data("ui-draggable"),n=s.options,a=e.extend({},i,{item:s.element});s.sortables=[],e(n.connectToSortable).each(function(){var i=e.data(this,"ui-sortable");i&&!i.options.disabled&&(s.sortables.push({instance:i,shouldRevert:i.options.revert}),i.refreshPositions(),i._trigger("activate",t,a))})},stop:function(t,i){var s=e(this).data("ui-draggable"),n=e.extend({},i,{item:s.element});e.each(s.sortables,function(){this.instance.isOver?(this.instance.isOver=0,s.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=this.shouldRevert),this.instance._mouseStop(t),this.instance.options.helper=this.instance.options._helper,"original"===s.options.helper&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",t,n))})},drag:function(t,i){var s=e(this).data("ui-draggable"),n=this;e.each(s.sortables,function(){var a=!1,o=this;this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this.instance._intersectsWith(this.instance.containerCache)&&(a=!0,e.each(s.sortables,function(){return this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this!==o&&this.instance._intersectsWith(this.instance.containerCache)&&e.contains(o.instance.element[0],this.instance.element[0])&&(a=!1),a})),a?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=e(n).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return i.helper[0]},t.target=this.instance.currentItem[0],this.instance._mouseCapture(t,!0),this.instance._mouseStart(t,!0,!0),this.instance.offset.click.top=s.offset.click.top,this.instance.offset.click.left=s.offset.click.left,this.instance.offset.parent.left-=s.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=s.offset.parent.top-this.instance.offset.parent.top,s._trigger("toSortable",t),s.dropped=this.instance.element,s.currentItem=s.element,this.instance.fromOutside=s),this.instance.currentItem&&this.instance._mouseDrag(t)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",t,this.instance._uiHash(this.instance)),this.instance._mouseStop(t,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),s._trigger("fromSortable",t),s.dropped=!1)})}}),e.ui.plugin.add("draggable","cursor",{start:function(){var t=e("body"),i=e(this).data("ui-draggable").options;t.css("cursor")&&(i._cursor=t.css("cursor")),t.css("cursor",i.cursor)},stop:function(){var t=e(this).data("ui-draggable").options;t._cursor&&e("body").css("cursor",t._cursor)}}),e.ui.plugin.add("draggable","opacity",{start:function(t,i){var s=e(i.helper),n=e(this).data("ui-draggable").options;s.css("opacity")&&(n._opacity=s.css("opacity")),s.css("opacity",n.opacity)},stop:function(t,i){var s=e(this).data("ui-draggable").options;s._opacity&&e(i.helper).css("opacity",s._opacity)}}),e.ui.plugin.add("draggable","scroll",{start:function(){var t=e(this).data("ui-draggable");t.scrollParent[0]!==document&&"HTML"!==t.scrollParent[0].tagName&&(t.overflowOffset=t.scrollParent.offset())},drag:function(t){var i=e(this).data("ui-draggable"),s=i.options,n=!1;i.scrollParent[0]!==document&&"HTML"!==i.scrollParent[0].tagName?(s.axis&&"x"===s.axis||(i.overflowOffset.top+i.scrollParent[0].offsetHeight-t.pageY<s.scrollSensitivity?i.scrollParent[0].scrollTop=n=i.scrollParent[0].scrollTop+s.scrollSpeed:t.pageY-i.overflowOffset.top<s.scrollSensitivity&&(i.scrollParent[0].scrollTop=n=i.scrollParent[0].scrollTop-s.scrollSpeed)),s.axis&&"y"===s.axis||(i.overflowOffset.left+i.scrollParent[0].offsetWidth-t.pageX<s.scrollSensitivity?i.scrollParent[0].scrollLeft=n=i.scrollParent[0].scrollLeft+s.scrollSpeed:t.pageX-i.overflowOffset.left<s.scrollSensitivity&&(i.scrollParent[0].scrollLeft=n=i.scrollParent[0].scrollLeft-s.scrollSpeed))):(s.axis&&"x"===s.axis||(t.pageY-e(document).scrollTop()<s.scrollSensitivity?n=e(document).scrollTop(e(document).scrollTop()-s.scrollSpeed):e(window).height()-(t.pageY-e(document).scrollTop())<s.scrollSensitivity&&(n=e(document).scrollTop(e(document).scrollTop()+s.scrollSpeed))),s.axis&&"y"===s.axis||(t.pageX-e(document).scrollLeft()<s.scrollSensitivity?n=e(document).scrollLeft(e(document).scrollLeft()-s.scrollSpeed):e(window).width()-(t.pageX-e(document).scrollLeft())<s.scrollSensitivity&&(n=e(document).scrollLeft(e(document).scrollLeft()+s.scrollSpeed)))),n!==!1&&e.ui.ddmanager&&!s.dropBehaviour&&e.ui.ddmanager.prepareOffsets(i,t)}}),e.ui.plugin.add("draggable","snap",{start:function(){var t=e(this).data("ui-draggable"),i=t.options;t.snapElements=[],e(i.snap.constructor!==String?i.snap.items||":data(ui-draggable)":i.snap).each(function(){var i=e(this),s=i.offset();this!==t.element[0]&&t.snapElements.push({item:this,width:i.outerWidth(),height:i.outerHeight(),top:s.top,left:s.left})})},drag:function(t,i){var s,n,a,o,r,h,l,u,c,d,p=e(this).data("ui-draggable"),f=p.options,m=f.snapTolerance,g=i.offset.left,v=g+p.helperProportions.width,y=i.offset.top,b=y+p.helperProportions.height;for(c=p.snapElements.length-1;c>=0;c--)r=p.snapElements[c].left,h=r+p.snapElements[c].width,l=p.snapElements[c].top,u=l+p.snapElements[c].height,g>r-m&&h+m>g&&y>l-m&&u+m>y||g>r-m&&h+m>g&&b>l-m&&u+m>b||v>r-m&&h+m>v&&y>l-m&&u+m>y||v>r-m&&h+m>v&&b>l-m&&u+m>b?("inner"!==f.snapMode&&(s=m>=Math.abs(l-b),n=m>=Math.abs(u-y),a=m>=Math.abs(r-v),o=m>=Math.abs(h-g),s&&(i.position.top=p._convertPositionTo("relative",{top:l-p.helperProportions.height,left:0}).top-p.margins.top),n&&(i.position.top=p._convertPositionTo("relative",{top:u,left:0}).top-p.margins.top),a&&(i.position.left=p._convertPositionTo("relative",{top:0,left:r-p.helperProportions.width}).left-p.margins.left),o&&(i.position.left=p._convertPositionTo("relative",{top:0,left:h}).left-p.margins.left)),d=s||n||a||o,"outer"!==f.snapMode&&(s=m>=Math.abs(l-y),n=m>=Math.abs(u-b),a=m>=Math.abs(r-g),o=m>=Math.abs(h-v),s&&(i.position.top=p._convertPositionTo("relative",{top:l,left:0}).top-p.margins.top),n&&(i.position.top=p._convertPositionTo("relative",{top:u-p.helperProportions.height,left:0}).top-p.margins.top),a&&(i.position.left=p._convertPositionTo("relative",{top:0,left:r}).left-p.margins.left),o&&(i.position.left=p._convertPositionTo("relative",{top:0,left:h-p.helperProportions.width}).left-p.margins.left)),!p.snapElements[c].snapping&&(s||n||a||o||d)&&p.options.snap.snap&&p.options.snap.snap.call(p.element,t,e.extend(p._uiHash(),{snapItem:p.snapElements[c].item})),p.snapElements[c].snapping=s||n||a||o||d):(p.snapElements[c].snapping&&p.options.snap.release&&p.options.snap.release.call(p.element,t,e.extend(p._uiHash(),{snapItem:p.snapElements[c].item})),p.snapElements[c].snapping=!1)}}),e.ui.plugin.add("draggable","stack",{start:function(){var t,i=this.data("ui-draggable").options,s=e.makeArray(e(i.stack)).sort(function(t,i){return(parseInt(e(t).css("zIndex"),10)||0)-(parseInt(e(i).css("zIndex"),10)||0)});s.length&&(t=parseInt(e(s[0]).css("zIndex"),10)||0,e(s).each(function(i){e(this).css("zIndex",t+i)}),this.css("zIndex",t+s.length))}}),e.ui.plugin.add("draggable","zIndex",{start:function(t,i){var s=e(i.helper),n=e(this).data("ui-draggable").options;s.css("zIndex")&&(n._zIndex=s.css("zIndex")),s.css("zIndex",n.zIndex)},stop:function(t,i){var s=e(this).data("ui-draggable").options;s._zIndex&&e(i.helper).css("zIndex",s._zIndex)}})})(jQuery);(function(e){function t(e,t,i){return e>t&&t+i>e}e.widget("ui.droppable",{version:"1.10.2",widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var t=this.options,i=t.accept;this.isover=!1,this.isout=!0,this.accept=e.isFunction(i)?i:function(e){return e.is(i)},this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight},e.ui.ddmanager.droppables[t.scope]=e.ui.ddmanager.droppables[t.scope]||[],e.ui.ddmanager.droppables[t.scope].push(this),t.addClasses&&this.element.addClass("ui-droppable")},_destroy:function(){for(var t=0,i=e.ui.ddmanager.droppables[this.options.scope];i.length>t;t++)i[t]===this&&i.splice(t,1);this.element.removeClass("ui-droppable ui-droppable-disabled")},_setOption:function(t,i){"accept"===t&&(this.accept=e.isFunction(i)?i:function(e){return e.is(i)}),e.Widget.prototype._setOption.apply(this,arguments)},_activate:function(t){var i=e.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),i&&this._trigger("activate",t,this.ui(i))},_deactivate:function(t){var i=e.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),i&&this._trigger("deactivate",t,this.ui(i))},_over:function(t){var i=e.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",t,this.ui(i)))},_out:function(t){var i=e.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",t,this.ui(i)))},_drop:function(t,i){var s=i||e.ui.ddmanager.current,n=!1;return s&&(s.currentItem||s.element)[0]!==this.element[0]?(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var t=e.data(this,"ui-droppable");return t.options.greedy&&!t.options.disabled&&t.options.scope===s.options.scope&&t.accept.call(t.element[0],s.currentItem||s.element)&&e.ui.intersect(s,e.extend(t,{offset:t.element.offset()}),t.options.tolerance)?(n=!0,!1):undefined}),n?!1:this.accept.call(this.element[0],s.currentItem||s.element)?(this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",t,this.ui(s)),this.element):!1):!1},ui:function(e){return{draggable:e.currentItem||e.element,helper:e.helper,position:e.position,offset:e.positionAbs}}}),e.ui.intersect=function(e,i,s){if(!i.offset)return!1;var n,a,o=(e.positionAbs||e.position.absolute).left,r=o+e.helperProportions.width,h=(e.positionAbs||e.position.absolute).top,l=h+e.helperProportions.height,u=i.offset.left,c=u+i.proportions.width,d=i.offset.top,p=d+i.proportions.height;switch(s){case"fit":return o>=u&&c>=r&&h>=d&&p>=l;case"intersect":return o+e.helperProportions.width/2>u&&c>r-e.helperProportions.width/2&&h+e.helperProportions.height/2>d&&p>l-e.helperProportions.height/2;case"pointer":return n=(e.positionAbs||e.position.absolute).left+(e.clickOffset||e.offset.click).left,a=(e.positionAbs||e.position.absolute).top+(e.clickOffset||e.offset.click).top,t(a,d,i.proportions.height)&&t(n,u,i.proportions.width);case"touch":return(h>=d&&p>=h||l>=d&&p>=l||d>h&&l>p)&&(o>=u&&c>=o||r>=u&&c>=r||u>o&&r>c);default:return!1}},e.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(t,i){var s,n,a=e.ui.ddmanager.droppables[t.options.scope]||[],o=i?i.type:null,r=(t.currentItem||t.element).find(":data(ui-droppable)").addBack();e:for(s=0;a.length>s;s++)if(!(a[s].options.disabled||t&&!a[s].accept.call(a[s].element[0],t.currentItem||t.element))){for(n=0;r.length>n;n++)if(r[n]===a[s].element[0]){a[s].proportions.height=0;continue e}a[s].visible="none"!==a[s].element.css("display"),a[s].visible&&("mousedown"===o&&a[s]._activate.call(a[s],i),a[s].offset=a[s].element.offset(),a[s].proportions={width:a[s].element[0].offsetWidth,height:a[s].element[0].offsetHeight})}},drop:function(t,i){var s=!1;return e.each((e.ui.ddmanager.droppables[t.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&e.ui.intersect(t,this,this.options.tolerance)&&(s=this._drop.call(this,i)||s),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],t.currentItem||t.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,i)))}),s},dragStart:function(t,i){t.element.parentsUntil("body").bind("scroll.droppable",function(){t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,i)})},drag:function(t,i){t.options.refreshPositions&&e.ui.ddmanager.prepareOffsets(t,i),e.each(e.ui.ddmanager.droppables[t.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var s,n,a,o=e.ui.intersect(t,this,this.options.tolerance),r=!o&&this.isover?"isout":o&&!this.isover?"isover":null;r&&(this.options.greedy&&(n=this.options.scope,a=this.element.parents(":data(ui-droppable)").filter(function(){return e.data(this,"ui-droppable").options.scope===n}),a.length&&(s=e.data(a[0],"ui-droppable"),s.greedyChild="isover"===r)),s&&"isover"===r&&(s.isover=!1,s.isout=!0,s._out.call(s,i)),this[r]=!0,this["isout"===r?"isover":"isout"]=!1,this["isover"===r?"_over":"_out"].call(this,i),s&&"isout"===r&&(s.isout=!1,s.isover=!0,s._over.call(s,i)))}})},dragStop:function(t,i){t.element.parentsUntil("body").unbind("scroll.droppable"),t.options.refreshPositions||e.ui.ddmanager.prepareOffsets(t,i)}}})(jQuery);(function(e){function t(e){return parseInt(e,10)||0}function i(e){return!isNaN(parseInt(e,10))}e.widget("ui.resizable",e.ui.mouse,{version:"1.10.2",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_create:function(){var t,i,s,n,a,o=this,r=this.options;if(this.element.addClass("ui-resizable"),e.extend(this,{_aspectRatio:!!r.aspectRatio,aspectRatio:r.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:r.helper||r.ghost||r.animate?r.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(e("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.data("ui-resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=r.handles||(e(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),t=this.handles.split(","),this.handles={},i=0;t.length>i;i++)s=e.trim(t[i]),a="ui-resizable-"+s,n=e("<div class='ui-resizable-handle "+a+"'></div>"),n.css({zIndex:r.zIndex}),"se"===s&&n.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(n);this._renderAxis=function(t){var i,s,n,a;t=t||this.element;for(i in this.handles)this.handles[i].constructor===String&&(this.handles[i]=e(this.handles[i],this.element).show()),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)&&(s=e(this.handles[i],this.element),a=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),t.css(n,a),this._proportionallyResize()),e(this.handles[i]).length},this._renderAxis(this.element),this._handles=e(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){o.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),o.axis=n&&n[1]?n[1]:"se")}),r.autoHide&&(this._handles.hide(),e(this.element).addClass("ui-resizable-autohide").mouseenter(function(){r.disabled||(e(this).removeClass("ui-resizable-autohide"),o._handles.show())}).mouseleave(function(){r.disabled||o.resizing||(e(this).addClass("ui-resizable-autohide"),o._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var t,i=function(t){e(t).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),t=this.element,this.originalElement.css({position:t.css("position"),width:t.outerWidth(),height:t.outerHeight(),top:t.css("top"),left:t.css("left")}).insertAfter(t),t.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_mouseCapture:function(t){var i,s,n=!1;for(i in this.handles)s=e(this.handles[i])[0],(s===t.target||e.contains(s,t.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(i){var s,n,a,o=this.options,r=this.element.position(),h=this.element;return this.resizing=!0,/absolute/.test(h.css("position"))?h.css({position:"absolute",top:h.css("top"),left:h.css("left")}):h.is(".ui-draggable")&&h.css({position:"absolute",top:r.top,left:r.left}),this._renderProxy(),s=t(this.helper.css("left")),n=t(this.helper.css("top")),o.containment&&(s+=e(o.containment).scrollLeft()||0,n+=e(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:s,top:n},this.size=this._helper?{width:h.outerWidth(),height:h.outerHeight()}:{width:h.width(),height:h.height()},this.originalSize=this._helper?{width:h.outerWidth(),height:h.outerHeight()}:{width:h.width(),height:h.height()},this.originalPosition={left:s,top:n},this.sizeDiff={width:h.outerWidth()-h.width(),height:h.outerHeight()-h.height()},this.originalMousePosition={left:i.pageX,top:i.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,a=e(".ui-resizable-"+this.axis).css("cursor"),e("body").css("cursor","auto"===a?this.axis+"-resize":a),h.addClass("ui-resizable-resizing"),this._propagate("start",i),!0},_mouseDrag:function(t){var i,s=this.helper,n={},a=this.originalMousePosition,o=this.axis,r=this.position.top,h=this.position.left,l=this.size.width,u=this.size.height,c=t.pageX-a.left||0,d=t.pageY-a.top||0,p=this._change[o];return p?(i=p.apply(this,[t,c,d]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(i=this._updateRatio(i,t)),i=this._respectSize(i,t),this._updateCache(i),this._propagate("resize",t),this.position.top!==r&&(n.top=this.position.top+"px"),this.position.left!==h&&(n.left=this.position.left+"px"),this.size.width!==l&&(n.width=this.size.width+"px"),this.size.height!==u&&(n.height=this.size.height+"px"),s.css(n),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),e.isEmptyObject(n)||this._trigger("resize",t,this.ui()),!1):!1},_mouseStop:function(t){this.resizing=!1;var i,s,n,a,o,r,h,l=this.options,u=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&e.ui.hasScroll(i[0],"left")?0:u.sizeDiff.height,a=s?0:u.sizeDiff.width,o={width:u.helper.width()-a,height:u.helper.height()-n},r=parseInt(u.element.css("left"),10)+(u.position.left-u.originalPosition.left)||null,h=parseInt(u.element.css("top"),10)+(u.position.top-u.originalPosition.top)||null,l.animate||this.element.css(e.extend(o,{top:h,left:r})),u.helper.height(u.size.height),u.helper.width(u.size.width),this._helper&&!l.animate&&this._proportionallyResize()),e("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(e){var t,s,n,a,o,r=this.options;o={minWidth:i(r.minWidth)?r.minWidth:0,maxWidth:i(r.maxWidth)?r.maxWidth:1/0,minHeight:i(r.minHeight)?r.minHeight:0,maxHeight:i(r.maxHeight)?r.maxHeight:1/0},(this._aspectRatio||e)&&(t=o.minHeight*this.aspectRatio,n=o.minWidth/this.aspectRatio,s=o.maxHeight*this.aspectRatio,a=o.maxWidth/this.aspectRatio,t>o.minWidth&&(o.minWidth=t),n>o.minHeight&&(o.minHeight=n),o.maxWidth>s&&(o.maxWidth=s),o.maxHeight>a&&(o.maxHeight=a)),this._vBoundaries=o},_updateCache:function(e){this.offset=this.helper.offset(),i(e.left)&&(this.position.left=e.left),i(e.top)&&(this.position.top=e.top),i(e.height)&&(this.size.height=e.height),i(e.width)&&(this.size.width=e.width)},_updateRatio:function(e){var t=this.position,s=this.size,n=this.axis;return i(e.height)?e.width=e.height*this.aspectRatio:i(e.width)&&(e.height=e.width/this.aspectRatio),"sw"===n&&(e.left=t.left+(s.width-e.width),e.top=null),"nw"===n&&(e.top=t.top+(s.height-e.height),e.left=t.left+(s.width-e.width)),e},_respectSize:function(e){var t=this._vBoundaries,s=this.axis,n=i(e.width)&&t.maxWidth&&t.maxWidth<e.width,a=i(e.height)&&t.maxHeight&&t.maxHeight<e.height,o=i(e.width)&&t.minWidth&&t.minWidth>e.width,r=i(e.height)&&t.minHeight&&t.minHeight>e.height,h=this.originalPosition.left+this.originalSize.width,l=this.position.top+this.size.height,u=/sw|nw|w/.test(s),c=/nw|ne|n/.test(s);return o&&(e.width=t.minWidth),r&&(e.height=t.minHeight),n&&(e.width=t.maxWidth),a&&(e.height=t.maxHeight),o&&u&&(e.left=h-t.minWidth),n&&u&&(e.left=h-t.maxWidth),r&&c&&(e.top=l-t.minHeight),a&&c&&(e.top=l-t.maxHeight),e.width||e.height||e.left||!e.top?e.width||e.height||e.top||!e.left||(e.left=null):e.top=null,e},_proportionallyResize:function(){if(this._proportionallyResizeElements.length){var e,t,i,s,n,a=this.helper||this.element;for(e=0;this._proportionallyResizeElements.length>e;e++){if(n=this._proportionallyResizeElements[e],!this.borderDif)for(this.borderDif=[],i=[n.css("borderTopWidth"),n.css("borderRightWidth"),n.css("borderBottomWidth"),n.css("borderLeftWidth")],s=[n.css("paddingTop"),n.css("paddingRight"),n.css("paddingBottom"),n.css("paddingLeft")],t=0;i.length>t;t++)this.borderDif[t]=(parseInt(i[t],10)||0)+(parseInt(s[t],10)||0);n.css({height:a.height()-this.borderDif[0]-this.borderDif[2]||0,width:a.width()-this.borderDif[1]-this.borderDif[3]||0})}}},_renderProxy:function(){var t=this.element,i=this.options;this.elementOffset=t.offset(),this._helper?(this.helper=this.helper||e("<div style='overflow:hidden;'></div>"),this.helper.addClass(this._helper).css({width:this.element.outerWidth()-1,height:this.element.outerHeight()-1,position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(e,t){return{width:this.originalSize.width+t}},w:function(e,t){var i=this.originalSize,s=this.originalPosition;return{left:s.left+t,width:i.width-t}},n:function(e,t,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(e,t,i){return{height:this.originalSize.height+i}},se:function(t,i,s){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,i,s]))},sw:function(t,i,s){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,i,s]))},ne:function(t,i,s){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,i,s]))},nw:function(t,i,s){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,i,s]))}},_propagate:function(t,i){e.ui.plugin.call(this,t,[i,this.ui()]),"resize"!==t&&this._trigger(t,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),e.ui.plugin.add("resizable","animate",{stop:function(t){var i=e(this).data("ui-resizable"),s=i.options,n=i._proportionallyResizeElements,a=n.length&&/textarea/i.test(n[0].nodeName),o=a&&e.ui.hasScroll(n[0],"left")?0:i.sizeDiff.height,r=a?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-o},l=parseInt(i.element.css("left"),10)+(i.position.left-i.originalPosition.left)||null,u=parseInt(i.element.css("top"),10)+(i.position.top-i.originalPosition.top)||null;i.element.animate(e.extend(h,u&&l?{top:u,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseInt(i.element.css("width"),10),height:parseInt(i.element.css("height"),10),top:parseInt(i.element.css("top"),10),left:parseInt(i.element.css("left"),10)};n&&n.length&&e(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",t)}})}}),e.ui.plugin.add("resizable","containment",{start:function(){var i,s,n,a,o,r,h,l=e(this).data("ui-resizable"),u=l.options,c=l.element,d=u.containment,p=d instanceof e?d.get(0):/parent/.test(d)?c.parent().get(0):d;p&&(l.containerElement=e(p),/document/.test(d)||d===document?(l.containerOffset={left:0,top:0},l.containerPosition={left:0,top:0},l.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}):(i=e(p),s=[],e(["Top","Right","Left","Bottom"]).each(function(e,n){s[e]=t(i.css("padding"+n))}),l.containerOffset=i.offset(),l.containerPosition=i.position(),l.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},n=l.containerOffset,a=l.containerSize.height,o=l.containerSize.width,r=e.ui.hasScroll(p,"left")?p.scrollWidth:o,h=e.ui.hasScroll(p)?p.scrollHeight:a,l.parentData={element:p,left:n.left,top:n.top,width:r,height:h}))},resize:function(t){var i,s,n,a,o=e(this).data("ui-resizable"),r=o.options,h=o.containerOffset,l=o.position,u=o._aspectRatio||t.shiftKey,c={top:0,left:0},d=o.containerElement;d[0]!==document&&/static/.test(d.css("position"))&&(c=h),l.left<(o._helper?h.left:0)&&(o.size.width=o.size.width+(o._helper?o.position.left-h.left:o.position.left-c.left),u&&(o.size.height=o.size.width/o.aspectRatio),o.position.left=r.helper?h.left:0),l.top<(o._helper?h.top:0)&&(o.size.height=o.size.height+(o._helper?o.position.top-h.top:o.position.top),u&&(o.size.width=o.size.height*o.aspectRatio),o.position.top=o._helper?h.top:0),o.offset.left=o.parentData.left+o.position.left,o.offset.top=o.parentData.top+o.position.top,i=Math.abs((o._helper?o.offset.left-c.left:o.offset.left-c.left)+o.sizeDiff.width),s=Math.abs((o._helper?o.offset.top-c.top:o.offset.top-h.top)+o.sizeDiff.height),n=o.containerElement.get(0)===o.element.parent().get(0),a=/relative|absolute/.test(o.containerElement.css("position")),n&&a&&(i-=o.parentData.left),i+o.size.width>=o.parentData.width&&(o.size.width=o.parentData.width-i,u&&(o.size.height=o.size.width/o.aspectRatio)),s+o.size.height>=o.parentData.height&&(o.size.height=o.parentData.height-s,u&&(o.size.width=o.size.height*o.aspectRatio))},stop:function(){var t=e(this).data("ui-resizable"),i=t.options,s=t.containerOffset,n=t.containerPosition,a=t.containerElement,o=e(t.helper),r=o.offset(),h=o.outerWidth()-t.sizeDiff.width,l=o.outerHeight()-t.sizeDiff.height;t._helper&&!i.animate&&/relative/.test(a.css("position"))&&e(this).css({left:r.left-n.left-s.left,width:h,height:l}),t._helper&&!i.animate&&/static/.test(a.css("position"))&&e(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),e.ui.plugin.add("resizable","alsoResize",{start:function(){var t=e(this).data("ui-resizable"),i=t.options,s=function(t){e(t).each(function(){var t=e(this);t.data("ui-resizable-alsoresize",{width:parseInt(t.width(),10),height:parseInt(t.height(),10),left:parseInt(t.css("left"),10),top:parseInt(t.css("top"),10)})})};"object"!=typeof i.alsoResize||i.alsoResize.parentNode?s(i.alsoResize):i.alsoResize.length?(i.alsoResize=i.alsoResize[0],s(i.alsoResize)):e.each(i.alsoResize,function(e){s(e)})},resize:function(t,i){var s=e(this).data("ui-resizable"),n=s.options,a=s.originalSize,o=s.originalPosition,r={height:s.size.height-a.height||0,width:s.size.width-a.width||0,top:s.position.top-o.top||0,left:s.position.left-o.left||0},h=function(t,s){e(t).each(function(){var t=e(this),n=e(this).data("ui-resizable-alsoresize"),a={},o=s&&s.length?s:t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(o,function(e,t){var i=(n[t]||0)+(r[t]||0);i&&i>=0&&(a[t]=i||null)}),t.css(a)})};"object"!=typeof n.alsoResize||n.alsoResize.nodeType?h(n.alsoResize):e.each(n.alsoResize,function(e,t){h(e,t)})},stop:function(){e(this).removeData("resizable-alsoresize")}}),e.ui.plugin.add("resizable","ghost",{start:function(){var t=e(this).data("ui-resizable"),i=t.options,s=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof i.ghost?i.ghost:""),t.ghost.appendTo(t.helper)},resize:function(){var t=e(this).data("ui-resizable");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=e(this).data("ui-resizable");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),e.ui.plugin.add("resizable","grid",{resize:function(){var t=e(this).data("ui-resizable"),i=t.options,s=t.size,n=t.originalSize,a=t.originalPosition,o=t.axis,r="number"==typeof i.grid?[i.grid,i.grid]:i.grid,h=r[0]||1,l=r[1]||1,u=Math.round((s.width-n.width)/h)*h,c=Math.round((s.height-n.height)/l)*l,d=n.width+u,p=n.height+c,f=i.maxWidth&&d>i.maxWidth,m=i.maxHeight&&p>i.maxHeight,g=i.minWidth&&i.minWidth>d,v=i.minHeight&&i.minHeight>p;i.grid=r,g&&(d+=h),v&&(p+=l),f&&(d-=h),m&&(p-=l),/^(se|s|e)$/.test(o)?(t.size.width=d,t.size.height=p):/^(ne)$/.test(o)?(t.size.width=d,t.size.height=p,t.position.top=a.top-c):/^(sw)$/.test(o)?(t.size.width=d,t.size.height=p,t.position.left=a.left-u):(t.size.width=d,t.size.height=p,t.position.top=a.top-c,t.position.left=a.left-u)}})})(jQuery);(function(e){e.widget("ui.selectable",e.ui.mouse,{version:"1.10.2",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var t,i=this;this.element.addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){t=e(i.options.filter,i.element[0]),t.addClass("ui-selectee"),t.each(function(){var t=e(this),i=t.offset();e.data(this,"selectable-item",{element:this,$element:t,left:i.left,top:i.top,right:i.left+t.outerWidth(),bottom:i.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=t.addClass("ui-selectee"),this._mouseInit(),this.helper=e("<div class='ui-selectable-helper'></div>")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(t){var i=this,s=this.options;this.opos=[t.pageX,t.pageY],this.options.disabled||(this.selectees=e(s.filter,this.element[0]),this._trigger("start",t),e(s.appendTo).append(this.helper),this.helper.css({left:t.pageX,top:t.pageY,width:0,height:0}),s.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var s=e.data(this,"selectable-item");s.startselected=!0,t.metaKey||t.ctrlKey||(s.$element.removeClass("ui-selected"),s.selected=!1,s.$element.addClass("ui-unselecting"),s.unselecting=!0,i._trigger("unselecting",t,{unselecting:s.element}))}),e(t.target).parents().addBack().each(function(){var s,n=e.data(this,"selectable-item");return n?(s=!t.metaKey&&!t.ctrlKey||!n.$element.hasClass("ui-selected"),n.$element.removeClass(s?"ui-unselecting":"ui-selected").addClass(s?"ui-selecting":"ui-unselecting"),n.unselecting=!s,n.selecting=s,n.selected=s,s?i._trigger("selecting",t,{selecting:n.element}):i._trigger("unselecting",t,{unselecting:n.element}),!1):undefined}))},_mouseDrag:function(t){if(this.dragged=!0,!this.options.disabled){var i,s=this,n=this.options,a=this.opos[0],o=this.opos[1],r=t.pageX,h=t.pageY;return a>r&&(i=r,r=a,a=i),o>h&&(i=h,h=o,o=i),this.helper.css({left:a,top:o,width:r-a,height:h-o}),this.selectees.each(function(){var i=e.data(this,"selectable-item"),l=!1;i&&i.element!==s.element[0]&&("touch"===n.tolerance?l=!(i.left>r||a>i.right||i.top>h||o>i.bottom):"fit"===n.tolerance&&(l=i.left>a&&r>i.right&&i.top>o&&h>i.bottom),l?(i.selected&&(i.$element.removeClass("ui-selected"),i.selected=!1),i.unselecting&&(i.$element.removeClass("ui-unselecting"),i.unselecting=!1),i.selecting||(i.$element.addClass("ui-selecting"),i.selecting=!0,s._trigger("selecting",t,{selecting:i.element}))):(i.selecting&&((t.metaKey||t.ctrlKey)&&i.startselected?(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.$element.addClass("ui-selected"),i.selected=!0):(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.startselected&&(i.$element.addClass("ui-unselecting"),i.unselecting=!0),s._trigger("unselecting",t,{unselecting:i.element}))),i.selected&&(t.metaKey||t.ctrlKey||i.startselected||(i.$element.removeClass("ui-selected"),i.selected=!1,i.$element.addClass("ui-unselecting"),i.unselecting=!0,s._trigger("unselecting",t,{unselecting:i.element})))))}),!1}},_mouseStop:function(t){var i=this;return this.dragged=!1,e(".ui-unselecting",this.element[0]).each(function(){var s=e.data(this,"selectable-item");s.$element.removeClass("ui-unselecting"),s.unselecting=!1,s.startselected=!1,i._trigger("unselected",t,{unselected:s.element})}),e(".ui-selecting",this.element[0]).each(function(){var s=e.data(this,"selectable-item");s.$element.removeClass("ui-selecting").addClass("ui-selected"),s.selecting=!1,s.selected=!0,s.startselected=!0,i._trigger("selected",t,{selected:s.element})}),this._trigger("stop",t),this.helper.remove(),!1}})})(jQuery);(function(t){function e(t,e,i){return t>e&&e+i>t}function i(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))}t.widget("ui.sortable",t.ui.mouse,{version:"1.10.2",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_create:function(){var t=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?"x"===t.axis||i(this.items[0].item):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var t=this.items.length-1;t>=0;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_setOption:function(e,i){"disabled"===e?(this.options[e]=i,this.widget().toggleClass("ui-sortable-disabled",!!i)):t.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(e,i){var s=null,n=!1,a=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(e),t(e.target).parents().each(function(){return t.data(this,a.widgetName+"-item")===a?(s=t(this),!1):undefined}),t.data(e.target,a.widgetName+"-item")===a&&(s=t(e.target)),s?!this.options.handle||i||(t(this.options.handle,s).find("*").addBack().each(function(){this===e.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(e,i,s){var n,a,o=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(e),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,o.cursorAt&&this._adjustOffsetFromHelper(o.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),o.containment&&this._setContainment(),o.cursor&&"auto"!==o.cursor&&(a=this.document.find("body"),this.storedCursor=a.css("cursor"),a.css("cursor",o.cursor),this.storedStylesheet=t("<style>*{ cursor: "+o.cursor+" !important; }</style>").appendTo(a)),o.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",o.opacity)),o.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",o.zIndex)),this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!o.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,n,a,o=this.options,r=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY<o.scrollSensitivity?this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop+o.scrollSpeed:e.pageY-this.overflowOffset.top<o.scrollSensitivity&&(this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop-o.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-e.pageX<o.scrollSensitivity?this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft+o.scrollSpeed:e.pageX-this.overflowOffset.left<o.scrollSensitivity&&(this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft-o.scrollSpeed)):(e.pageY-t(document).scrollTop()<o.scrollSensitivity?r=t(document).scrollTop(t(document).scrollTop()-o.scrollSpeed):t(window).height()-(e.pageY-t(document).scrollTop())<o.scrollSensitivity&&(r=t(document).scrollTop(t(document).scrollTop()+o.scrollSpeed)),e.pageX-t(document).scrollLeft()<o.scrollSensitivity?r=t(document).scrollLeft(t(document).scrollLeft()-o.scrollSpeed):t(window).width()-(e.pageX-t(document).scrollLeft())<o.scrollSensitivity&&(r=t(document).scrollLeft(t(document).scrollLeft()+o.scrollSpeed))),r!==!1&&t.ui.ddmanager&&!o.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e)),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),i=this.items.length-1;i>=0;i--)if(s=this.items[i],n=s.item[0],a=this._intersectsWithPointer(s),a&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===a?"next":"prev"]()[0]!==n&&!t.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!t.contains(this.element[0],n):!0)){if(this.direction=1===a?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,n=this.placeholder.offset(),a=this.options.axis,o={};a&&"x"!==a||(o.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollLeft)),a&&"y"!==a||(o.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(o,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,a=t.left,o=a+t.width,r=t.top,h=r+t.height,l=this.offset.click.top,c=this.offset.click.left,u=s+l>r&&h>s+l&&e+c>a&&o>e+c;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?u:e+this.helperProportions.width/2>a&&o>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(t){var i="x"===this.options.axis||e(this.positionAbs.top+this.offset.click.top,t.top,t.height),s="y"===this.options.axis||e(this.positionAbs.left+this.offset.click.left,t.left,t.width),n=i&&s,a=this._getDragVerticalDirection(),o=this._getDragHorizontalDirection();return n?this.floating?o&&"right"===o||"down"===a?2:1:a&&("down"===a?2:1):!1},_intersectsWithSides:function(t){var i=e(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),s=e(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),n=this._getDragVerticalDirection(),a=this._getDragHorizontalDirection();return this.floating&&a?"right"===a&&s||"left"===a&&!s:n&&("down"===n&&i||"up"===n&&!i)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){var i,s,n,a,o=[],r=[],h=this._connectWith();if(h&&e)for(i=h.length-1;i>=0;i--)for(n=t(h[i]),s=n.length-1;s>=0;s--)a=t.data(n[s],this.widgetFullName),a&&a!==this&&!a.options.disabled&&r.push([t.isFunction(a.options.items)?a.options.items.call(a.element):t(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a]);for(r.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),i=r.length-1;i>=0;i--)r[i][0].each(function(){o.push(this)});return t(o)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;e.length>i;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,n,a,o,r,h,l,c=this.items,u=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=t(d[i]),s=n.length-1;s>=0;s--)a=t.data(n[s],this.widgetFullName),a&&a!==this&&!a.options.disabled&&(u.push([t.isFunction(a.options.items)?a.options.items.call(a.element[0],e,{item:this.currentItem}):t(a.options.items,a.element),a]),this.containers.push(a));for(i=u.length-1;i>=0;i--)for(o=u[i][1],r=u[i][0],s=0,l=r.length;l>s;s++)h=t(r[s]),h.data(this.widgetName+"-item",o),c.push({item:h,instance:o,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,a;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=n.outerWidth(),s.height=n.outerHeight()),a=n.offset(),s.left=a.left,s.top=a.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)a=this.containers[i].element.offset(),this.containers[i].containerCache.left=a.left,this.containers[i].containerCache.top=a.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),n=t(e.document[0].createElement(s)).addClass(i||e.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper");return"tr"===s?n.append("<td colspan='99'>&#160;</td>"):"img"===s&&n.attr("src",e.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(t,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_contactContainers:function(s){var n,a,o,r,h,l,c,u,d,p,f=null,m=null;for(n=this.containers.length-1;n>=0;n--)if(!t.contains(this.currentItem[0],this.containers[n].element[0]))if(this._intersectsWith(this.containers[n].containerCache)){if(f&&t.contains(this.containers[n].element[0],f.element[0]))continue;f=this.containers[n],m=n}else this.containers[n].containerCache.over&&(this.containers[n]._trigger("out",s,this._uiHash(this)),this.containers[n].containerCache.over=0);if(f)if(1===this.containers.length)this.containers[m].containerCache.over||(this.containers[m]._trigger("over",s,this._uiHash(this)),this.containers[m].containerCache.over=1);else{for(o=1e4,r=null,p=f.floating||i(this.currentItem),h=p?"left":"top",l=p?"width":"height",c=this.positionAbs[h]+this.offset.click[h],a=this.items.length-1;a>=0;a--)t.contains(this.containers[m].element[0],this.items[a].item[0])&&this.items[a].item[0]!==this.currentItem[0]&&(!p||e(this.positionAbs.top+this.offset.click.top,this.items[a].top,this.items[a].height))&&(u=this.items[a].item.offset()[h],d=!1,Math.abs(u-c)>Math.abs(u+this.items[a][l]-c)&&(d=!0,u+=this.items[a][l]),o>Math.abs(u-c)&&(o=Math.abs(u-c),r=this.items[a],this.direction=d?"up":"down"));if(!r&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[m])return;r?this._rearrange(s,r,null,!0):this._rearrange(s,null,this.containers[m].element,!0),this._trigger("change",s,this._uiHash()),this.containers[m]._trigger("change",s,this._uiHash(this)),this.currentContainer=this.containers[m],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[m]._trigger("over",s,this._uiHash(this)),this.containers[m].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,t("document"===n.containment?document:window).width()-this.helperProportions.width-this.margins.left,(t("document"===n.containment?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(e=t(n.containment)[0],i=t(n.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,a=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():a?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():a?0:n.scrollLeft())*s}},_generatePosition:function(e){var i,s,n=this.options,a=e.pageX,o=e.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==document&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.left<this.containment[0]&&(a=this.containment[0]+this.offset.click.left),e.pageY-this.offset.click.top<this.containment[1]&&(o=this.containment[1]+this.offset.click.top),e.pageX-this.offset.click.left>this.containment[2]&&(a=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(o=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1],o=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((a-this.originalPageX)/n.grid[0])*n.grid[0],a=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:o-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:a-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){this.reverting=!1;var i,s=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(i in this._storedCSS)("auto"===this._storedCSS[i]||"static"===this._storedCSS[i])&&(this._storedCSS[i]="");this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&s.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||s.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(s.push(function(t){this._trigger("remove",t,this._uiHash())}),s.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),s.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),i=this.containers.length-1;i>=0;i--)e||s.push(function(t){return function(e){t._trigger("deactivate",e,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over&&(s.push(function(t){return function(e){t._trigger("out",e,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,this.cancelHelperRemoval){if(!e){for(this._trigger("beforeStop",t,this._uiHash()),i=0;s.length>i;i++)s[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!1}if(e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null,!e){for(i=0;s.length>i;i++)s[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!0},_trigger:function(){t.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}})})(jQuery);(function(t){var e=0,i={},s={};i.height=i.paddingTop=i.paddingBottom=i.borderTopWidth=i.borderBottomWidth="hide",s.height=s.paddingTop=s.paddingBottom=s.borderTopWidth=s.borderBottomWidth="show",t.widget("ui.accordion",{version:"1.10.2",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},_create:function(){var e=this.options;this.prevShow=this.prevHide=t(),this.element.addClass("ui-accordion ui-widget ui-helper-reset").attr("role","tablist"),e.collapsible||e.active!==!1&&null!=e.active||(e.active=0),this._processPanels(),0>e.active&&(e.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():t(),content:this.active.length?this.active.next():t()}},_createIcons:function(){var e=this.options.icons;e&&(t("<span>").addClass("ui-accordion-header-icon ui-icon "+e.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(e.header).addClass(e.activeHeader),this.headers.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var t;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this._destroyIcons(),t=this.headers.next().css("display","").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),"content"!==this.options.heightStyle&&t.css("height","")},_setOption:function(t,e){return"active"===t?(this._activate(e),undefined):("event"===t&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(e)),this._super(t,e),"collapsible"!==t||e||this.options.active!==!1||this._activate(0),"icons"===t&&(this._destroyIcons(),e&&this._createIcons()),"disabled"===t&&this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!e),undefined)},_keydown:function(e){if(!e.altKey&&!e.ctrlKey){var i=t.ui.keyCode,s=this.headers.length,n=this.headers.index(e.target),a=!1;switch(e.keyCode){case i.RIGHT:case i.DOWN:a=this.headers[(n+1)%s];break;case i.LEFT:case i.UP:a=this.headers[(n-1+s)%s];break;case i.SPACE:case i.ENTER:this._eventHandler(e);break;case i.HOME:a=this.headers[0];break;case i.END:a=this.headers[s-1]}a&&(t(e.target).attr("tabIndex",-1),t(a).attr("tabIndex",0),a.focus(),e.preventDefault())}},_panelKeyDown:function(e){e.keyCode===t.ui.keyCode.UP&&e.ctrlKey&&t(e.currentTarget).prev().focus()},refresh:function(){var e=this.options;this._processPanels(),(e.active===!1&&e.collapsible===!0||!this.headers.length)&&(e.active=!1,this.active=t()),e.active===!1?this._activate(0):this.active.length&&!t.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(e.active=!1,this.active=t()):this._activate(Math.max(0,e.active-1)):e.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){this.headers=this.element.find(this.options.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all"),this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").filter(":not(.ui-accordion-content-active)").hide()},_refresh:function(){var i,s=this.options,n=s.heightStyle,a=this.element.parent(),o=this.accordionId="ui-accordion-"+(this.element.attr("id")||++e);this.active=this._findActive(s.active).addClass("ui-accordion-header-active ui-state-active ui-corner-top").removeClass("ui-corner-all"),this.active.next().addClass("ui-accordion-content-active").show(),this.headers.attr("role","tab").each(function(e){var i=t(this),s=i.attr("id"),n=i.next(),a=n.attr("id");s||(s=o+"-header-"+e,i.attr("id",s)),a||(a=o+"-panel-"+e,n.attr("id",a)),i.attr("aria-controls",a),n.attr("aria-labelledby",s)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false",tabIndex:-1}).next().attr({"aria-expanded":"false","aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true",tabIndex:0}).next().attr({"aria-expanded":"true","aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(s.event),"fill"===n?(i=a.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.headers.each(function(){i-=t(this).outerHeight(!0)}),this.headers.next().each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===n&&(i=0,this.headers.next().each(function(){i=Math.max(i,t(this).css("height","").height())}).height(i))},_activate:function(e){var i=this._findActive(e)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return"number"==typeof e?this.headers.eq(e):t()},_setupEvents:function(e){var i={keydown:"_keydown"};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),a=n[0]===s[0],o=a&&i.collapsible,r=o?t():n.next(),h=s.next(),l={oldHeader:s,oldPanel:h,newHeader:o?t():n,newPanel:r};e.preventDefault(),a&&!i.collapsible||this._trigger("beforeActivate",e,l)===!1||(i.active=o?!1:this.headers.index(n),this.active=a?t():n,this._toggle(l),s.removeClass("ui-accordion-header-active ui-state-active"),i.icons&&s.children(".ui-accordion-header-icon").removeClass(i.icons.activeHeader).addClass(i.icons.header),a||(n.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),i.icons&&n.children(".ui-accordion-header-icon").removeClass(i.icons.header).addClass(i.icons.activeHeader),n.next().addClass("ui-accordion-content-active")))},_toggle:function(e){var i=e.newPanel,s=this.prevShow.length?this.prevShow:e.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=s,this.options.animate?this._animate(i,s,e):(s.hide(),i.show(),this._toggleComplete(e)),s.attr({"aria-expanded":"false","aria-hidden":"true"}),s.prev().attr("aria-selected","false"),i.length&&s.length?s.prev().attr("tabIndex",-1):i.length&&this.headers.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),i.attr({"aria-expanded":"true","aria-hidden":"false"}).prev().attr({"aria-selected":"true",tabIndex:0})},_animate:function(t,e,n){var a,o,r,h=this,l=0,c=t.length&&(!e.length||t.index()<e.index()),u=this.options.animate||{},d=c&&u.down||u,p=function(){h._toggleComplete(n)};return"number"==typeof d&&(r=d),"string"==typeof d&&(o=d),o=o||d.easing||u.easing,r=r||d.duration||u.duration,e.length?t.length?(a=t.show().outerHeight(),e.animate(i,{duration:r,easing:o,step:function(t,e){e.now=Math.round(t)}}),t.hide().animate(s,{duration:r,easing:o,complete:p,step:function(t,i){i.now=Math.round(t),"height"!==i.prop?l+=i.now:"content"!==h.options.heightStyle&&(i.now=Math.round(a-e.outerHeight()-l),l=0)}}),undefined):e.animate(i,r,o,p):t.animate(s,r,o,p)},_toggleComplete:function(t){var e=t.oldPanel;e.removeClass("ui-accordion-content-active").prev().removeClass("ui-corner-top").addClass("ui-corner-all"),e.length&&(e.parent()[0].className=e.parent()[0].className),this._trigger("activate",null,t)}})})(jQuery);(function(e){var t=0;e.widget("ui.autocomplete",{version:"1.10.2",defaultElement:"<input>",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},pending:0,_create:function(){var t,i,s,n=this.element[0].nodeName.toLowerCase(),a="textarea"===n,o="input"===n;this.isMultiLine=a?!0:o?!1:this.element.prop("isContentEditable"),this.valueMethod=this.element[a||o?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))return t=!0,s=!0,i=!0,undefined;t=!1,s=!1,i=!1;var a=e.ui.keyCode;switch(n.keyCode){case a.PAGE_UP:t=!0,this._move("previousPage",n);break;case a.PAGE_DOWN:t=!0,this._move("nextPage",n);break;case a.UP:t=!0,this._keyEvent("previous",n);break;case a.DOWN:t=!0,this._keyEvent("next",n);break;case a.ENTER:case a.NUMPAD_ENTER:this.menu.active&&(t=!0,n.preventDefault(),this.menu.select(n));break;case a.TAB:this.menu.active&&this.menu.select(n);break;case a.ESCAPE:this.menu.element.is(":visible")&&(this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}},keypress:function(s){if(t)return t=!1,s.preventDefault(),undefined;if(!i){var n=e.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(e){return s?(s=!1,e.preventDefault(),undefined):(this._searchTimeout(e),undefined)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(e){return this.cancelBlur?(delete this.cancelBlur,undefined):(clearTimeout(this.searching),this.close(e),this._change(e),undefined)}}),this._initSource(),this.menu=e("<ul>").addClass("ui-autocomplete ui-front").appendTo(this._appendTo()).menu({input:e(),role:null}).hide().data("ui-menu"),this._on(this.menu.element,{mousedown:function(t){t.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur});var i=this.menu.element[0];e(t.target).closest(".ui-menu-item").length||this._delay(function(){var t=this;this.document.one("mousedown",function(s){s.target===t.element[0]||s.target===i||e.contains(i,s.target)||t.close()})})},menufocus:function(t,i){if(this.isNewMenu&&(this.isNewMenu=!1,t.originalEvent&&/^mouse/.test(t.originalEvent.type)))return this.menu.blur(),this.document.one("mousemove",function(){e(t.target).trigger(t.originalEvent)}),undefined;var s=i.item.data("ui-autocomplete-item");!1!==this._trigger("focus",t,{item:s})?t.originalEvent&&/^key/.test(t.originalEvent.type)&&this._value(s.value):this.liveRegion.text(s.value)},menuselect:function(e,t){var i=t.item.data("ui-autocomplete-item"),s=this.previous;this.element[0]!==this.document[0].activeElement&&(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s,this.selectedItem=i})),!1!==this._trigger("select",e,{item:i})&&this._value(i.value),this.term=this._value(),this.close(e),this.selectedItem=i}}),this.liveRegion=e("<span>",{role:"status","aria-live":"polite"}).addClass("ui-helper-hidden-accessible").insertAfter(this.element),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(e,t){this._super(e,t),"source"===e&&this._initSource(),"appendTo"===e&&this.menu.element.appendTo(this._appendTo()),"disabled"===e&&t&&this.xhr&&this.xhr.abort()},_appendTo:function(){var t=this.options.appendTo;return t&&(t=t.jquery||t.nodeType?e(t):this.document.find(t).eq(0)),t||(t=this.element.closest(".ui-front")),t.length||(t=this.document[0].body),t},_initSource:function(){var t,i,s=this;e.isArray(this.options.source)?(t=this.options.source,this.source=function(i,s){s(e.ui.autocomplete.filter(t,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(t,n){s.xhr&&s.xhr.abort(),s.xhr=e.ajax({url:i,data:t,dataType:"json",success:function(e){n(e)},error:function(){n([])}})}):this.source=this.options.source},_searchTimeout:function(e){clearTimeout(this.searching),this.searching=this._delay(function(){this.term!==this._value()&&(this.selectedItem=null,this.search(null,e))},this.options.delay)},search:function(e,t){return e=null!=e?e:this._value(),this.term=this._value(),e.length<this.options.minLength?this.close(t):this._trigger("search",t)!==!1?this._search(e):undefined},_search:function(e){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:e},this._response())},_response:function(){var e=this,i=++t;return function(s){i===t&&e.__response(s),e.pending--,e.pending||e.element.removeClass("ui-autocomplete-loading")}},__response:function(e){e&&(e=this._normalize(e)),this._trigger("response",null,{content:e}),!this.options.disabled&&e&&e.length&&!this.cancelSearch?(this._suggest(e),this._trigger("open")):this._close()},close:function(e){this.cancelSearch=!0,this._close(e)},_close:function(e){this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",e))},_change:function(e){this.previous!==this._value()&&this._trigger("change",e,{item:this.selectedItem})},_normalize:function(t){return t.length&&t[0].label&&t[0].value?t:e.map(t,function(t){return"string"==typeof t?{label:t,value:t}:e.extend({label:t.label||t.value,value:t.value||t.label},t)})},_suggest:function(t){var i=this.menu.element.empty();this._renderMenu(i,t),this.isNewMenu=!0,this.menu.refresh(),i.show(),this._resizeMenu(),i.position(e.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next()},_resizeMenu:function(){var e=this.menu.element;e.outerWidth(Math.max(e.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(t,i){var s=this;e.each(i,function(e,i){s._renderItemData(t,i)})},_renderItemData:function(e,t){return this._renderItem(e,t).data("ui-autocomplete-item",t)},_renderItem:function(t,i){return e("<li>").append(e("<a>").text(i.label)).appendTo(t)},_move:function(e,t){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(e)||this.menu.isLastItem()&&/^next/.test(e)?(this._value(this.term),this.menu.blur(),undefined):(this.menu[e](t),undefined):(this.search(null,t),undefined)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(e,t){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(e,t),t.preventDefault())}}),e.extend(e.ui.autocomplete,{escapeRegex:function(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(t,i){var s=RegExp(e.ui.autocomplete.escapeRegex(i),"i");return e.grep(t,function(e){return s.test(e.label||e.value||e)})}}),e.widget("ui.autocomplete",e.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(e){return e+(e>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(e){var t;this._superApply(arguments),this.options.disabled||this.cancelSearch||(t=e&&e.length?this.options.messages.results(e.length):this.options.messages.noResults,this.liveRegion.text(t))}})})(jQuery);(function(t){var e,i,s,n,a="ui-button ui-widget ui-state-default ui-corner-all",o="ui-state-hover ui-state-active ",r="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",h=function(){var e=t(this).find(":ui-button");setTimeout(function(){e.button("refresh")},1)},l=function(e){var i=e.name,s=e.form,n=t([]);return i&&(i=i.replace(/'/g,"\\'"),n=s?t(s).find("[name='"+i+"']"):t("[name='"+i+"']",e.ownerDocument).filter(function(){return!this.form})),n};t.widget("ui.button",{version:"1.10.2",defaultElement:"<button>",options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset"+this.eventNamespace).bind("reset"+this.eventNamespace,h),"boolean"!=typeof this.options.disabled?this.options.disabled=!!this.element.prop("disabled"):this.element.prop("disabled",this.options.disabled),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var o=this,r=this.options,c="checkbox"===this.type||"radio"===this.type,u=c?"":"ui-state-active",d="ui-state-focus";null===r.label&&(r.label="input"===this.type?this.buttonElement.val():this.buttonElement.html()),this._hoverable(this.buttonElement),this.buttonElement.addClass(a).attr("role","button").bind("mouseenter"+this.eventNamespace,function(){r.disabled||this===e&&t(this).addClass("ui-state-active")}).bind("mouseleave"+this.eventNamespace,function(){r.disabled||t(this).removeClass(u)}).bind("click"+this.eventNamespace,function(t){r.disabled&&(t.preventDefault(),t.stopImmediatePropagation())}),this.element.bind("focus"+this.eventNamespace,function(){o.buttonElement.addClass(d)}).bind("blur"+this.eventNamespace,function(){o.buttonElement.removeClass(d)}),c&&(this.element.bind("change"+this.eventNamespace,function(){n||o.refresh()}),this.buttonElement.bind("mousedown"+this.eventNamespace,function(t){r.disabled||(n=!1,i=t.pageX,s=t.pageY)}).bind("mouseup"+this.eventNamespace,function(t){r.disabled||(i!==t.pageX||s!==t.pageY)&&(n=!0)})),"checkbox"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){return r.disabled||n?!1:undefined}):"radio"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){if(r.disabled||n)return!1;t(this).addClass("ui-state-active"),o.buttonElement.attr("aria-pressed","true");var e=o.element[0];l(e).not(e).map(function(){return t(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown"+this.eventNamespace,function(){return r.disabled?!1:(t(this).addClass("ui-state-active"),e=this,o.document.one("mouseup",function(){e=null}),undefined)}).bind("mouseup"+this.eventNamespace,function(){return r.disabled?!1:(t(this).removeClass("ui-state-active"),undefined)}).bind("keydown"+this.eventNamespace,function(e){return r.disabled?!1:((e.keyCode===t.ui.keyCode.SPACE||e.keyCode===t.ui.keyCode.ENTER)&&t(this).addClass("ui-state-active"),undefined)}).bind("keyup"+this.eventNamespace+" blur"+this.eventNamespace,function(){t(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(e){e.keyCode===t.ui.keyCode.SPACE&&t(this).click()})),this._setOption("disabled",r.disabled),this._resetButton()},_determineButtonType:function(){var t,e,i;this.type=this.element.is("[type=checkbox]")?"checkbox":this.element.is("[type=radio]")?"radio":this.element.is("input")?"input":"button","checkbox"===this.type||"radio"===this.type?(t=this.element.parents().last(),e="label[for='"+this.element.attr("id")+"']",this.buttonElement=t.find(e),this.buttonElement.length||(t=t.length?t.siblings():this.element.siblings(),this.buttonElement=t.filter(e),this.buttonElement.length||(this.buttonElement=t.find(e))),this.element.addClass("ui-helper-hidden-accessible"),i=this.element.is(":checked"),i&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.prop("aria-pressed",i)):this.buttonElement=this.element},widget:function(){return this.buttonElement},_destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(a+" "+o+" "+r).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title")},_setOption:function(t,e){return this._super(t,e),"disabled"===t?(e?this.element.prop("disabled",!0):this.element.prop("disabled",!1),undefined):(this._resetButton(),undefined)},refresh:function(){var e=this.element.is("input, button")?this.element.is(":disabled"):this.element.hasClass("ui-button-disabled");e!==this.options.disabled&&this._setOption("disabled",e),"radio"===this.type?l(this.element[0]).each(function(){t(this).is(":checked")?t(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):t(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):"checkbox"===this.type&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if("input"===this.type)return this.options.label&&this.element.val(this.options.label),undefined;var e=this.buttonElement.removeClass(r),i=t("<span></span>",this.document[0]).addClass("ui-button-text").html(this.options.label).appendTo(e.empty()).text(),s=this.options.icons,n=s.primary&&s.secondary,a=[];s.primary||s.secondary?(this.options.text&&a.push("ui-button-text-icon"+(n?"s":s.primary?"-primary":"-secondary")),s.primary&&e.prepend("<span class='ui-button-icon-primary ui-icon "+s.primary+"'></span>"),s.secondary&&e.append("<span class='ui-button-icon-secondary ui-icon "+s.secondary+"'></span>"),this.options.text||(a.push(n?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||e.attr("title",t.trim(i)))):a.push("ui-button-text-only"),e.addClass(a.join(" "))}}),t.widget("ui.buttonset",{version:"1.10.2",options:{items:"button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(t,e){"disabled"===t&&this.buttons.button("option",t,e),this._super(t,e)},refresh:function(){var e="rtl"===this.element.css("direction");this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return t(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(e?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(e?"ui-corner-left":"ui-corner-right").end().end()},_destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return t(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy")}})})(jQuery);(function(t,e){function i(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},t.extend(this._defaults,this.regional[""]),this.dpDiv=s(t("<div id='"+this._mainDivId+"' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"))}function s(e){var i="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return e.delegate(i,"mouseout",function(){t(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).removeClass("ui-datepicker-next-hover")}).delegate(i,"mouseover",function(){t.datepicker._isDisabledDatepicker(a.inline?e.parent()[0]:a.input[0])||(t(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),t(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).addClass("ui-datepicker-next-hover"))})}function n(e,i){t.extend(e,i);for(var s in i)null==i[s]&&(e[s]=i[s]);return e}t.extend(t.ui,{datepicker:{version:"1.10.2"}});var a,r="datepicker",o=(new Date).getTime();t.extend(i.prototype,{markerClassName:"hasDatepicker",maxRows:4,_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(t){return n(this._defaults,t||{}),this},_attachDatepicker:function(e,i){var s,n,a;s=e.nodeName.toLowerCase(),n="div"===s||"span"===s,e.id||(this.uuid+=1,e.id="dp"+this.uuid),a=this._newInst(t(e),n),a.settings=t.extend({},i||{}),"input"===s?this._connectDatepicker(e,a):n&&this._inlineDatepicker(e,a)},_newInst:function(e,i){var n=e[0].id.replace(/([^A-Za-z0-9_\-])/g,"\\\\$1");return{id:n,input:e,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:i,dpDiv:i?s(t("<div class='"+this._inlineClass+" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")):this.dpDiv}},_connectDatepicker:function(e,i){var s=t(e);i.append=t([]),i.trigger=t([]),s.hasClass(this.markerClassName)||(this._attachments(s,i),s.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp),this._autoSize(i),t.data(e,r,i),i.settings.disabled&&this._disableDatepicker(e))},_attachments:function(e,i){var s,n,a,r=this._get(i,"appendText"),o=this._get(i,"isRTL");i.append&&i.append.remove(),r&&(i.append=t("<span class='"+this._appendClass+"'>"+r+"</span>"),e[o?"before":"after"](i.append)),e.unbind("focus",this._showDatepicker),i.trigger&&i.trigger.remove(),s=this._get(i,"showOn"),("focus"===s||"both"===s)&&e.focus(this._showDatepicker),("button"===s||"both"===s)&&(n=this._get(i,"buttonText"),a=this._get(i,"buttonImage"),i.trigger=t(this._get(i,"buttonImageOnly")?t("<img/>").addClass(this._triggerClass).attr({src:a,alt:n,title:n}):t("<button type='button'></button>").addClass(this._triggerClass).html(a?t("<img/>").attr({src:a,alt:n,title:n}):n)),e[o?"before":"after"](i.trigger),i.trigger.click(function(){return t.datepicker._datepickerShowing&&t.datepicker._lastInput===e[0]?t.datepicker._hideDatepicker():t.datepicker._datepickerShowing&&t.datepicker._lastInput!==e[0]?(t.datepicker._hideDatepicker(),t.datepicker._showDatepicker(e[0])):t.datepicker._showDatepicker(e[0]),!1}))},_autoSize:function(t){if(this._get(t,"autoSize")&&!t.inline){var e,i,s,n,a=new Date(2009,11,20),r=this._get(t,"dateFormat");r.match(/[DM]/)&&(e=function(t){for(i=0,s=0,n=0;t.length>n;n++)t[n].length>i&&(i=t[n].length,s=n);return s},a.setMonth(e(this._get(t,r.match(/MM/)?"monthNames":"monthNamesShort"))),a.setDate(e(this._get(t,r.match(/DD/)?"dayNames":"dayNamesShort"))+20-a.getDay())),t.input.attr("size",this._formatDate(t,a).length)}},_inlineDatepicker:function(e,i){var s=t(e);s.hasClass(this.markerClassName)||(s.addClass(this.markerClassName).append(i.dpDiv),t.data(e,r,i),this._setDate(i,this._getDefaultDate(i),!0),this._updateDatepicker(i),this._updateAlternate(i),i.settings.disabled&&this._disableDatepicker(e),i.dpDiv.css("display","block"))},_dialogDatepicker:function(e,i,s,a,o){var h,l,c,u,d,p=this._dialogInst;return p||(this.uuid+=1,h="dp"+this.uuid,this._dialogInput=t("<input type='text' id='"+h+"' style='position: absolute; top: -100px; width: 0px;'/>"),this._dialogInput.keydown(this._doKeyDown),t("body").append(this._dialogInput),p=this._dialogInst=this._newInst(this._dialogInput,!1),p.settings={},t.data(this._dialogInput[0],r,p)),n(p.settings,a||{}),i=i&&i.constructor===Date?this._formatDate(p,i):i,this._dialogInput.val(i),this._pos=o?o.length?o:[o.pageX,o.pageY]:null,this._pos||(l=document.documentElement.clientWidth,c=document.documentElement.clientHeight,u=document.documentElement.scrollLeft||document.body.scrollLeft,d=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[l/2-100+u,c/2-150+d]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),p.settings.onSelect=s,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),t.blockUI&&t.blockUI(this.dpDiv),t.data(this._dialogInput[0],r,p),this},_destroyDatepicker:function(e){var i,s=t(e),n=t.data(e,r);s.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),t.removeData(e,r),"input"===i?(n.append.remove(),n.trigger.remove(),s.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):("div"===i||"span"===i)&&s.removeClass(this.markerClassName).empty())},_enableDatepicker:function(e){var i,s,n=t(e),a=t.data(e,r);n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!1,a.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().removeClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}))},_disableDatepicker:function(e){var i,s,n=t(e),a=t.data(e,r);n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!0,a.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().addClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}),this._disabledInputs[this._disabledInputs.length]=e)},_isDisabledDatepicker:function(t){if(!t)return!1;for(var e=0;this._disabledInputs.length>e;e++)if(this._disabledInputs[e]===t)return!0;return!1},_getInst:function(e){try{return t.data(e,r)}catch(i){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(i,s,a){var r,o,h,l,c=this._getInst(i);return 2===arguments.length&&"string"==typeof s?"defaults"===s?t.extend({},t.datepicker._defaults):c?"all"===s?t.extend({},c.settings):this._get(c,s):null:(r=s||{},"string"==typeof s&&(r={},r[s]=a),c&&(this._curInst===c&&this._hideDatepicker(),o=this._getDateDatepicker(i,!0),h=this._getMinMaxDate(c,"min"),l=this._getMinMaxDate(c,"max"),n(c.settings,r),null!==h&&r.dateFormat!==e&&r.minDate===e&&(c.settings.minDate=this._formatDate(c,h)),null!==l&&r.dateFormat!==e&&r.maxDate===e&&(c.settings.maxDate=this._formatDate(c,l)),"disabled"in r&&(r.disabled?this._disableDatepicker(i):this._enableDatepicker(i)),this._attachments(t(i),c),this._autoSize(c),this._setDate(c,o),this._updateAlternate(c),this._updateDatepicker(c)),e)},_changeDatepicker:function(t,e,i){this._optionDatepicker(t,e,i)},_refreshDatepicker:function(t){var e=this._getInst(t);e&&this._updateDatepicker(e)},_setDateDatepicker:function(t,e){var i=this._getInst(t);i&&(this._setDate(i,e),this._updateDatepicker(i),this._updateAlternate(i))},_getDateDatepicker:function(t,e){var i=this._getInst(t);return i&&!i.inline&&this._setDateFromField(i,e),i?this._getDate(i):null},_doKeyDown:function(e){var i,s,n,a=t.datepicker._getInst(e.target),r=!0,o=a.dpDiv.is(".ui-datepicker-rtl");if(a._keyEvent=!0,t.datepicker._datepickerShowing)switch(e.keyCode){case 9:t.datepicker._hideDatepicker(),r=!1;break;case 13:return n=t("td."+t.datepicker._dayOverClass+":not(."+t.datepicker._currentClass+")",a.dpDiv),n[0]&&t.datepicker._selectDay(e.target,a.selectedMonth,a.selectedYear,n[0]),i=t.datepicker._get(a,"onSelect"),i?(s=t.datepicker._formatDate(a),i.apply(a.input?a.input[0]:null,[s,a])):t.datepicker._hideDatepicker(),!1;case 27:t.datepicker._hideDatepicker();break;case 33:t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(a,"stepBigMonths"):-t.datepicker._get(a,"stepMonths"),"M");break;case 34:t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(a,"stepBigMonths"):+t.datepicker._get(a,"stepMonths"),"M");break;case 35:(e.ctrlKey||e.metaKey)&&t.datepicker._clearDate(e.target),r=e.ctrlKey||e.metaKey;break;case 36:(e.ctrlKey||e.metaKey)&&t.datepicker._gotoToday(e.target),r=e.ctrlKey||e.metaKey;break;case 37:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,o?1:-1,"D"),r=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(a,"stepBigMonths"):-t.datepicker._get(a,"stepMonths"),"M");break;case 38:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,-7,"D"),r=e.ctrlKey||e.metaKey;break;case 39:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,o?-1:1,"D"),r=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(a,"stepBigMonths"):+t.datepicker._get(a,"stepMonths"),"M");break;case 40:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,7,"D"),r=e.ctrlKey||e.metaKey;break;default:r=!1}else 36===e.keyCode&&e.ctrlKey?t.datepicker._showDatepicker(this):r=!1;r&&(e.preventDefault(),e.stopPropagation())},_doKeyPress:function(i){var s,n,a=t.datepicker._getInst(i.target);return t.datepicker._get(a,"constrainInput")?(s=t.datepicker._possibleChars(t.datepicker._get(a,"dateFormat")),n=String.fromCharCode(null==i.charCode?i.keyCode:i.charCode),i.ctrlKey||i.metaKey||" ">n||!s||s.indexOf(n)>-1):e},_doKeyUp:function(e){var i,s=t.datepicker._getInst(e.target);if(s.input.val()!==s.lastVal)try{i=t.datepicker.parseDate(t.datepicker._get(s,"dateFormat"),s.input?s.input.val():null,t.datepicker._getFormatConfig(s)),i&&(t.datepicker._setDateFromField(s),t.datepicker._updateAlternate(s),t.datepicker._updateDatepicker(s))}catch(n){}return!0},_showDatepicker:function(e){if(e=e.target||e,"input"!==e.nodeName.toLowerCase()&&(e=t("input",e.parentNode)[0]),!t.datepicker._isDisabledDatepicker(e)&&t.datepicker._lastInput!==e){var i,s,a,r,o,h,l;i=t.datepicker._getInst(e),t.datepicker._curInst&&t.datepicker._curInst!==i&&(t.datepicker._curInst.dpDiv.stop(!0,!0),i&&t.datepicker._datepickerShowing&&t.datepicker._hideDatepicker(t.datepicker._curInst.input[0])),s=t.datepicker._get(i,"beforeShow"),a=s?s.apply(e,[e,i]):{},a!==!1&&(n(i.settings,a),i.lastVal=null,t.datepicker._lastInput=e,t.datepicker._setDateFromField(i),t.datepicker._inDialog&&(e.value=""),t.datepicker._pos||(t.datepicker._pos=t.datepicker._findPos(e),t.datepicker._pos[1]+=e.offsetHeight),r=!1,t(e).parents().each(function(){return r|="fixed"===t(this).css("position"),!r}),o={left:t.datepicker._pos[0],top:t.datepicker._pos[1]},t.datepicker._pos=null,i.dpDiv.empty(),i.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),t.datepicker._updateDatepicker(i),o=t.datepicker._checkOffset(i,o,r),i.dpDiv.css({position:t.datepicker._inDialog&&t.blockUI?"static":r?"fixed":"absolute",display:"none",left:o.left+"px",top:o.top+"px"}),i.inline||(h=t.datepicker._get(i,"showAnim"),l=t.datepicker._get(i,"duration"),i.dpDiv.zIndex(t(e).zIndex()+1),t.datepicker._datepickerShowing=!0,t.effects&&t.effects.effect[h]?i.dpDiv.show(h,t.datepicker._get(i,"showOptions"),l):i.dpDiv[h||"show"](h?l:null),i.input.is(":visible")&&!i.input.is(":disabled")&&i.input.focus(),t.datepicker._curInst=i))}},_updateDatepicker:function(e){this.maxRows=4,a=e,e.dpDiv.empty().append(this._generateHTML(e)),this._attachHandlers(e),e.dpDiv.find("."+this._dayOverClass+" a").mouseover();var i,s=this._getNumberOfMonths(e),n=s[1],r=17;e.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),n>1&&e.dpDiv.addClass("ui-datepicker-multi-"+n).css("width",r*n+"em"),e.dpDiv[(1!==s[0]||1!==s[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),e.dpDiv[(this._get(e,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),e===t.datepicker._curInst&&t.datepicker._datepickerShowing&&e.input&&e.input.is(":visible")&&!e.input.is(":disabled")&&e.input[0]!==document.activeElement&&e.input.focus(),e.yearshtml&&(i=e.yearshtml,setTimeout(function(){i===e.yearshtml&&e.yearshtml&&e.dpDiv.find("select.ui-datepicker-year:first").replaceWith(e.yearshtml),i=e.yearshtml=null},0))},_getBorders:function(t){var e=function(t){return{thin:1,medium:2,thick:3}[t]||t};return[parseFloat(e(t.css("border-left-width"))),parseFloat(e(t.css("border-top-width")))]},_checkOffset:function(e,i,s){var n=e.dpDiv.outerWidth(),a=e.dpDiv.outerHeight(),r=e.input?e.input.outerWidth():0,o=e.input?e.input.outerHeight():0,h=document.documentElement.clientWidth+(s?0:t(document).scrollLeft()),l=document.documentElement.clientHeight+(s?0:t(document).scrollTop());return i.left-=this._get(e,"isRTL")?n-r:0,i.left-=s&&i.left===e.input.offset().left?t(document).scrollLeft():0,i.top-=s&&i.top===e.input.offset().top+o?t(document).scrollTop():0,i.left-=Math.min(i.left,i.left+n>h&&h>n?Math.abs(i.left+n-h):0),i.top-=Math.min(i.top,i.top+a>l&&l>a?Math.abs(a+o):0),i},_findPos:function(e){for(var i,s=this._getInst(e),n=this._get(s,"isRTL");e&&("hidden"===e.type||1!==e.nodeType||t.expr.filters.hidden(e));)e=e[n?"previousSibling":"nextSibling"];return i=t(e).offset(),[i.left,i.top]},_hideDatepicker:function(e){var i,s,n,a,o=this._curInst;!o||e&&o!==t.data(e,r)||this._datepickerShowing&&(i=this._get(o,"showAnim"),s=this._get(o,"duration"),n=function(){t.datepicker._tidyDialog(o)},t.effects&&(t.effects.effect[i]||t.effects[i])?o.dpDiv.hide(i,t.datepicker._get(o,"showOptions"),s,n):o.dpDiv["slideDown"===i?"slideUp":"fadeIn"===i?"fadeOut":"hide"](i?s:null,n),i||n(),this._datepickerShowing=!1,a=this._get(o,"onClose"),a&&a.apply(o.input?o.input[0]:null,[o.input?o.input.val():"",o]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),t.blockUI&&(t.unblockUI(),t("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(t){t.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(e){if(t.datepicker._curInst){var i=t(e.target),s=t.datepicker._getInst(i[0]);(i[0].id!==t.datepicker._mainDivId&&0===i.parents("#"+t.datepicker._mainDivId).length&&!i.hasClass(t.datepicker.markerClassName)&&!i.closest("."+t.datepicker._triggerClass).length&&t.datepicker._datepickerShowing&&(!t.datepicker._inDialog||!t.blockUI)||i.hasClass(t.datepicker.markerClassName)&&t.datepicker._curInst!==s)&&t.datepicker._hideDatepicker()}},_adjustDate:function(e,i,s){var n=t(e),a=this._getInst(n[0]);this._isDisabledDatepicker(n[0])||(this._adjustInstDate(a,i+("M"===s?this._get(a,"showCurrentAtPos"):0),s),this._updateDatepicker(a))},_gotoToday:function(e){var i,s=t(e),n=this._getInst(s[0]);this._get(n,"gotoCurrent")&&n.currentDay?(n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear):(i=new Date,n.selectedDay=i.getDate(),n.drawMonth=n.selectedMonth=i.getMonth(),n.drawYear=n.selectedYear=i.getFullYear()),this._notifyChange(n),this._adjustDate(s)},_selectMonthYear:function(e,i,s){var n=t(e),a=this._getInst(n[0]);a["selected"+("M"===s?"Month":"Year")]=a["draw"+("M"===s?"Month":"Year")]=parseInt(i.options[i.selectedIndex].value,10),this._notifyChange(a),this._adjustDate(n)},_selectDay:function(e,i,s,n){var a,r=t(e);t(n).hasClass(this._unselectableClass)||this._isDisabledDatepicker(r[0])||(a=this._getInst(r[0]),a.selectedDay=a.currentDay=t("a",n).html(),a.selectedMonth=a.currentMonth=i,a.selectedYear=a.currentYear=s,this._selectDate(e,this._formatDate(a,a.currentDay,a.currentMonth,a.currentYear)))},_clearDate:function(e){var i=t(e);this._selectDate(i,"")},_selectDate:function(e,i){var s,n=t(e),a=this._getInst(n[0]);i=null!=i?i:this._formatDate(a),a.input&&a.input.val(i),this._updateAlternate(a),s=this._get(a,"onSelect"),s?s.apply(a.input?a.input[0]:null,[i,a]):a.input&&a.input.trigger("change"),a.inline?this._updateDatepicker(a):(this._hideDatepicker(),this._lastInput=a.input[0],"object"!=typeof a.input[0]&&a.input.focus(),this._lastInput=null)},_updateAlternate:function(e){var i,s,n,a=this._get(e,"altField");a&&(i=this._get(e,"altFormat")||this._get(e,"dateFormat"),s=this._getDate(e),n=this.formatDate(i,s,this._getFormatConfig(e)),t(a).each(function(){t(this).val(n)}))},noWeekends:function(t){var e=t.getDay();return[e>0&&6>e,""]},iso8601Week:function(t){var e,i=new Date(t.getTime());return i.setDate(i.getDate()+4-(i.getDay()||7)),e=i.getTime(),i.setMonth(0),i.setDate(1),Math.floor(Math.round((e-i)/864e5)/7)+1},parseDate:function(i,s,n){if(null==i||null==s)throw"Invalid arguments";if(s="object"==typeof s?""+s:s+"",""===s)return null;var a,r,o,h,l=0,c=(n?n.shortYearCutoff:null)||this._defaults.shortYearCutoff,u="string"!=typeof c?c:(new Date).getFullYear()%100+parseInt(c,10),d=(n?n.dayNamesShort:null)||this._defaults.dayNamesShort,p=(n?n.dayNames:null)||this._defaults.dayNames,f=(n?n.monthNamesShort:null)||this._defaults.monthNamesShort,m=(n?n.monthNames:null)||this._defaults.monthNames,g=-1,v=-1,_=-1,b=-1,y=!1,w=function(t){var e=i.length>a+1&&i.charAt(a+1)===t;return e&&a++,e},k=function(t){var e=w(t),i="@"===t?14:"!"===t?20:"y"===t&&e?4:"o"===t?3:2,n=RegExp("^\\d{1,"+i+"}"),a=s.substring(l).match(n);if(!a)throw"Missing number at position "+l;return l+=a[0].length,parseInt(a[0],10)},x=function(i,n,a){var r=-1,o=t.map(w(i)?a:n,function(t,e){return[[e,t]]}).sort(function(t,e){return-(t[1].length-e[1].length)});if(t.each(o,function(t,i){var n=i[1];return s.substr(l,n.length).toLowerCase()===n.toLowerCase()?(r=i[0],l+=n.length,!1):e}),-1!==r)return r+1;throw"Unknown name at position "+l},D=function(){if(s.charAt(l)!==i.charAt(a))throw"Unexpected literal at position "+l;l++};for(a=0;i.length>a;a++)if(y)"'"!==i.charAt(a)||w("'")?D():y=!1;else switch(i.charAt(a)){case"d":_=k("d");break;case"D":x("D",d,p);break;case"o":b=k("o");break;case"m":v=k("m");break;case"M":v=x("M",f,m);break;case"y":g=k("y");break;case"@":h=new Date(k("@")),g=h.getFullYear(),v=h.getMonth()+1,_=h.getDate();break;case"!":h=new Date((k("!")-this._ticksTo1970)/1e4),g=h.getFullYear(),v=h.getMonth()+1,_=h.getDate();break;case"'":w("'")?D():y=!0;break;default:D()}if(s.length>l&&(o=s.substr(l),!/^\s+/.test(o)))throw"Extra/unparsed characters found in date: "+o;if(-1===g?g=(new Date).getFullYear():100>g&&(g+=(new Date).getFullYear()-(new Date).getFullYear()%100+(u>=g?0:-100)),b>-1)for(v=1,_=b;;){if(r=this._getDaysInMonth(g,v-1),r>=_)break;v++,_-=r}if(h=this._daylightSavingAdjust(new Date(g,v-1,_)),h.getFullYear()!==g||h.getMonth()+1!==v||h.getDate()!==_)throw"Invalid date";return h},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:1e7*60*60*24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925)),formatDate:function(t,e,i){if(!e)return"";var s,n=(i?i.dayNamesShort:null)||this._defaults.dayNamesShort,a=(i?i.dayNames:null)||this._defaults.dayNames,r=(i?i.monthNamesShort:null)||this._defaults.monthNamesShort,o=(i?i.monthNames:null)||this._defaults.monthNames,h=function(e){var i=t.length>s+1&&t.charAt(s+1)===e;return i&&s++,i},l=function(t,e,i){var s=""+e;if(h(t))for(;i>s.length;)s="0"+s;return s},c=function(t,e,i,s){return h(t)?s[e]:i[e]},u="",d=!1;if(e)for(s=0;t.length>s;s++)if(d)"'"!==t.charAt(s)||h("'")?u+=t.charAt(s):d=!1;else switch(t.charAt(s)){case"d":u+=l("d",e.getDate(),2);break;case"D":u+=c("D",e.getDay(),n,a);break;case"o":u+=l("o",Math.round((new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime()-new Date(e.getFullYear(),0,0).getTime())/864e5),3);break;case"m":u+=l("m",e.getMonth()+1,2);break;case"M":u+=c("M",e.getMonth(),r,o);break;case"y":u+=h("y")?e.getFullYear():(10>e.getYear()%100?"0":"")+e.getYear()%100;break;case"@":u+=e.getTime();break;case"!":u+=1e4*e.getTime()+this._ticksTo1970;break;case"'":h("'")?u+="'":d=!0;break;default:u+=t.charAt(s)}return u},_possibleChars:function(t){var e,i="",s=!1,n=function(i){var s=t.length>e+1&&t.charAt(e+1)===i;return s&&e++,s};for(e=0;t.length>e;e++)if(s)"'"!==t.charAt(e)||n("'")?i+=t.charAt(e):s=!1;else switch(t.charAt(e)){case"d":case"m":case"y":case"@":i+="0123456789";break;case"D":case"M":return null;case"'":n("'")?i+="'":s=!0;break;default:i+=t.charAt(e)}return i},_get:function(t,i){return t.settings[i]!==e?t.settings[i]:this._defaults[i]},_setDateFromField:function(t,e){if(t.input.val()!==t.lastVal){var i=this._get(t,"dateFormat"),s=t.lastVal=t.input?t.input.val():null,n=this._getDefaultDate(t),a=n,r=this._getFormatConfig(t);try{a=this.parseDate(i,s,r)||n}catch(o){s=e?"":s}t.selectedDay=a.getDate(),t.drawMonth=t.selectedMonth=a.getMonth(),t.drawYear=t.selectedYear=a.getFullYear(),t.currentDay=s?a.getDate():0,t.currentMonth=s?a.getMonth():0,t.currentYear=s?a.getFullYear():0,this._adjustInstDate(t)}},_getDefaultDate:function(t){return this._restrictMinMax(t,this._determineDate(t,this._get(t,"defaultDate"),new Date))},_determineDate:function(e,i,s){var n=function(t){var e=new Date;return e.setDate(e.getDate()+t),e},a=function(i){try{return t.datepicker.parseDate(t.datepicker._get(e,"dateFormat"),i,t.datepicker._getFormatConfig(e))}catch(s){}for(var n=(i.toLowerCase().match(/^c/)?t.datepicker._getDate(e):null)||new Date,a=n.getFullYear(),r=n.getMonth(),o=n.getDate(),h=/([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,l=h.exec(i);l;){switch(l[2]||"d"){case"d":case"D":o+=parseInt(l[1],10);break;case"w":case"W":o+=7*parseInt(l[1],10);break;case"m":case"M":r+=parseInt(l[1],10),o=Math.min(o,t.datepicker._getDaysInMonth(a,r));break;case"y":case"Y":a+=parseInt(l[1],10),o=Math.min(o,t.datepicker._getDaysInMonth(a,r))}l=h.exec(i)}return new Date(a,r,o)},r=null==i||""===i?s:"string"==typeof i?a(i):"number"==typeof i?isNaN(i)?s:n(i):new Date(i.getTime());return r=r&&"Invalid Date"==""+r?s:r,r&&(r.setHours(0),r.setMinutes(0),r.setSeconds(0),r.setMilliseconds(0)),this._daylightSavingAdjust(r)},_daylightSavingAdjust:function(t){return t?(t.setHours(t.getHours()>12?t.getHours()+2:0),t):null},_setDate:function(t,e,i){var s=!e,n=t.selectedMonth,a=t.selectedYear,r=this._restrictMinMax(t,this._determineDate(t,e,new Date));t.selectedDay=t.currentDay=r.getDate(),t.drawMonth=t.selectedMonth=t.currentMonth=r.getMonth(),t.drawYear=t.selectedYear=t.currentYear=r.getFullYear(),n===t.selectedMonth&&a===t.selectedYear||i||this._notifyChange(t),this._adjustInstDate(t),t.input&&t.input.val(s?"":this._formatDate(t))},_getDate:function(t){var e=!t.currentYear||t.input&&""===t.input.val()?null:this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return e},_attachHandlers:function(e){var i=this._get(e,"stepMonths"),s="#"+e.id.replace(/\\\\/g,"\\");e.dpDiv.find("[data-handler]").map(function(){var e={prev:function(){window["DP_jQuery_"+o].datepicker._adjustDate(s,-i,"M")},next:function(){window["DP_jQuery_"+o].datepicker._adjustDate(s,+i,"M")},hide:function(){window["DP_jQuery_"+o].datepicker._hideDatepicker()},today:function(){window["DP_jQuery_"+o].datepicker._gotoToday(s)},selectDay:function(){return window["DP_jQuery_"+o].datepicker._selectDay(s,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return window["DP_jQuery_"+o].datepicker._selectMonthYear(s,this,"M"),!1},selectYear:function(){return window["DP_jQuery_"+o].datepicker._selectMonthYear(s,this,"Y"),!1}};t(this).bind(this.getAttribute("data-event"),e[this.getAttribute("data-handler")])})},_generateHTML:function(t){var e,i,s,n,a,r,o,h,l,c,u,d,p,f,m,g,v,_,b,y,w,k,x,D,T,C,S,M,N,I,P,A,z,H,E,F,O,W,j,R=new Date,L=this._daylightSavingAdjust(new Date(R.getFullYear(),R.getMonth(),R.getDate())),Y=this._get(t,"isRTL"),B=this._get(t,"showButtonPanel"),J=this._get(t,"hideIfNoPrevNext"),Q=this._get(t,"navigationAsDateFormat"),K=this._getNumberOfMonths(t),V=this._get(t,"showCurrentAtPos"),U=this._get(t,"stepMonths"),q=1!==K[0]||1!==K[1],X=this._daylightSavingAdjust(t.currentDay?new Date(t.currentYear,t.currentMonth,t.currentDay):new Date(9999,9,9)),G=this._getMinMaxDate(t,"min"),$=this._getMinMaxDate(t,"max"),Z=t.drawMonth-V,te=t.drawYear;if(0>Z&&(Z+=12,te--),$)for(e=this._daylightSavingAdjust(new Date($.getFullYear(),$.getMonth()-K[0]*K[1]+1,$.getDate())),e=G&&G>e?G:e;this._daylightSavingAdjust(new Date(te,Z,1))>e;)Z--,0>Z&&(Z=11,te--);for(t.drawMonth=Z,t.drawYear=te,i=this._get(t,"prevText"),i=Q?this.formatDate(i,this._daylightSavingAdjust(new Date(te,Z-U,1)),this._getFormatConfig(t)):i,s=this._canAdjustMonth(t,-1,te,Z)?"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>":J?"":"<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>",n=this._get(t,"nextText"),n=Q?this.formatDate(n,this._daylightSavingAdjust(new Date(te,Z+U,1)),this._getFormatConfig(t)):n,a=this._canAdjustMonth(t,1,te,Z)?"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>":J?"":"<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>",r=this._get(t,"currentText"),o=this._get(t,"gotoCurrent")&&t.currentDay?X:L,r=Q?this.formatDate(r,o,this._getFormatConfig(t)):r,h=t.inline?"":"<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>"+this._get(t,"closeText")+"</button>",l=B?"<div class='ui-datepicker-buttonpane ui-widget-content'>"+(Y?h:"")+(this._isInRange(t,o)?"<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'>"+r+"</button>":"")+(Y?"":h)+"</div>":"",c=parseInt(this._get(t,"firstDay"),10),c=isNaN(c)?0:c,u=this._get(t,"showWeek"),d=this._get(t,"dayNames"),p=this._get(t,"dayNamesMin"),f=this._get(t,"monthNames"),m=this._get(t,"monthNamesShort"),g=this._get(t,"beforeShowDay"),v=this._get(t,"showOtherMonths"),_=this._get(t,"selectOtherMonths"),b=this._getDefaultDate(t),y="",k=0;K[0]>k;k++){for(x="",this.maxRows=4,D=0;K[1]>D;D++){if(T=this._daylightSavingAdjust(new Date(te,Z,t.selectedDay)),C=" ui-corner-all",S="",q){if(S+="<div class='ui-datepicker-group",K[1]>1)switch(D){case 0:S+=" ui-datepicker-group-first",C=" ui-corner-"+(Y?"right":"left");break;case K[1]-1:S+=" ui-datepicker-group-last",C=" ui-corner-"+(Y?"left":"right");break;default:S+=" ui-datepicker-group-middle",C=""}S+="'>"}for(S+="<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix"+C+"'>"+(/all|left/.test(C)&&0===k?Y?a:s:"")+(/all|right/.test(C)&&0===k?Y?s:a:"")+this._generateMonthYearHeader(t,Z,te,G,$,k>0||D>0,f,m)+"</div><table class='ui-datepicker-calendar'><thead>"+"<tr>",M=u?"<th class='ui-datepicker-week-col'>"+this._get(t,"weekHeader")+"</th>":"",w=0;7>w;w++)N=(w+c)%7,M+="<th"+((w+c+6)%7>=5?" class='ui-datepicker-week-end'":"")+">"+"<span title='"+d[N]+"'>"+p[N]+"</span></th>";for(S+=M+"</tr></thead><tbody>",I=this._getDaysInMonth(te,Z),te===t.selectedYear&&Z===t.selectedMonth&&(t.selectedDay=Math.min(t.selectedDay,I)),P=(this._getFirstDayOfMonth(te,Z)-c+7)%7,A=Math.ceil((P+I)/7),z=q?this.maxRows>A?this.maxRows:A:A,this.maxRows=z,H=this._daylightSavingAdjust(new Date(te,Z,1-P)),E=0;z>E;E++){for(S+="<tr>",F=u?"<td class='ui-datepicker-week-col'>"+this._get(t,"calculateWeek")(H)+"</td>":"",w=0;7>w;w++)O=g?g.apply(t.input?t.input[0]:null,[H]):[!0,""],W=H.getMonth()!==Z,j=W&&!_||!O[0]||G&&G>H||$&&H>$,F+="<td class='"+((w+c+6)%7>=5?" ui-datepicker-week-end":"")+(W?" ui-datepicker-other-month":"")+(H.getTime()===T.getTime()&&Z===t.selectedMonth&&t._keyEvent||b.getTime()===H.getTime()&&b.getTime()===T.getTime()?" "+this._dayOverClass:"")+(j?" "+this._unselectableClass+" ui-state-disabled":"")+(W&&!v?"":" "+O[1]+(H.getTime()===X.getTime()?" "+this._currentClass:"")+(H.getTime()===L.getTime()?" ui-datepicker-today":""))+"'"+(W&&!v||!O[2]?"":" title='"+O[2].replace(/'/g,"&#39;")+"'")+(j?"":" data-handler='selectDay' data-event='click' data-month='"+H.getMonth()+"' data-year='"+H.getFullYear()+"'")+">"+(W&&!v?"&#xa0;":j?"<span class='ui-state-default'>"+H.getDate()+"</span>":"<a class='ui-state-default"+(H.getTime()===L.getTime()?" ui-state-highlight":"")+(H.getTime()===X.getTime()?" ui-state-active":"")+(W?" ui-priority-secondary":"")+"' href='#'>"+H.getDate()+"</a>")+"</td>",H.setDate(H.getDate()+1),H=this._daylightSavingAdjust(H);S+=F+"</tr>"}Z++,Z>11&&(Z=0,te++),S+="</tbody></table>"+(q?"</div>"+(K[0]>0&&D===K[1]-1?"<div class='ui-datepicker-row-break'></div>":""):""),x+=S}y+=x}return y+=l,t._keyEvent=!1,y},_generateMonthYearHeader:function(t,e,i,s,n,a,r,o){var h,l,c,u,d,p,f,m,g=this._get(t,"changeMonth"),v=this._get(t,"changeYear"),_=this._get(t,"showMonthAfterYear"),b="<div class='ui-datepicker-title'>",y="";if(a||!g)y+="<span class='ui-datepicker-month'>"+r[e]+"</span>";else{for(h=s&&s.getFullYear()===i,l=n&&n.getFullYear()===i,y+="<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>",c=0;12>c;c++)(!h||c>=s.getMonth())&&(!l||n.getMonth()>=c)&&(y+="<option value='"+c+"'"+(c===e?" selected='selected'":"")+">"+o[c]+"</option>");
-y+="</select>"}if(_||(b+=y+(!a&&g&&v?"":"&#xa0;")),!t.yearshtml)if(t.yearshtml="",a||!v)b+="<span class='ui-datepicker-year'>"+i+"</span>";else{for(u=this._get(t,"yearRange").split(":"),d=(new Date).getFullYear(),p=function(t){var e=t.match(/c[+\-].*/)?i+parseInt(t.substring(1),10):t.match(/[+\-].*/)?d+parseInt(t,10):parseInt(t,10);return isNaN(e)?d:e},f=p(u[0]),m=Math.max(f,p(u[1]||"")),f=s?Math.max(f,s.getFullYear()):f,m=n?Math.min(m,n.getFullYear()):m,t.yearshtml+="<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";m>=f;f++)t.yearshtml+="<option value='"+f+"'"+(f===i?" selected='selected'":"")+">"+f+"</option>";t.yearshtml+="</select>",b+=t.yearshtml,t.yearshtml=null}return b+=this._get(t,"yearSuffix"),_&&(b+=(!a&&g&&v?"":"&#xa0;")+y),b+="</div>"},_adjustInstDate:function(t,e,i){var s=t.drawYear+("Y"===i?e:0),n=t.drawMonth+("M"===i?e:0),a=Math.min(t.selectedDay,this._getDaysInMonth(s,n))+("D"===i?e:0),r=this._restrictMinMax(t,this._daylightSavingAdjust(new Date(s,n,a)));t.selectedDay=r.getDate(),t.drawMonth=t.selectedMonth=r.getMonth(),t.drawYear=t.selectedYear=r.getFullYear(),("M"===i||"Y"===i)&&this._notifyChange(t)},_restrictMinMax:function(t,e){var i=this._getMinMaxDate(t,"min"),s=this._getMinMaxDate(t,"max"),n=i&&i>e?i:e;return s&&n>s?s:n},_notifyChange:function(t){var e=this._get(t,"onChangeMonthYear");e&&e.apply(t.input?t.input[0]:null,[t.selectedYear,t.selectedMonth+1,t])},_getNumberOfMonths:function(t){var e=this._get(t,"numberOfMonths");return null==e?[1,1]:"number"==typeof e?[1,e]:e},_getMinMaxDate:function(t,e){return this._determineDate(t,this._get(t,e+"Date"),null)},_getDaysInMonth:function(t,e){return 32-this._daylightSavingAdjust(new Date(t,e,32)).getDate()},_getFirstDayOfMonth:function(t,e){return new Date(t,e,1).getDay()},_canAdjustMonth:function(t,e,i,s){var n=this._getNumberOfMonths(t),a=this._daylightSavingAdjust(new Date(i,s+(0>e?e:n[0]*n[1]),1));return 0>e&&a.setDate(this._getDaysInMonth(a.getFullYear(),a.getMonth())),this._isInRange(t,a)},_isInRange:function(t,e){var i,s,n=this._getMinMaxDate(t,"min"),a=this._getMinMaxDate(t,"max"),r=null,o=null,h=this._get(t,"yearRange");return h&&(i=h.split(":"),s=(new Date).getFullYear(),r=parseInt(i[0],10),o=parseInt(i[1],10),i[0].match(/[+\-].*/)&&(r+=s),i[1].match(/[+\-].*/)&&(o+=s)),(!n||e.getTime()>=n.getTime())&&(!a||e.getTime()<=a.getTime())&&(!r||e.getFullYear()>=r)&&(!o||o>=e.getFullYear())},_getFormatConfig:function(t){var e=this._get(t,"shortYearCutoff");return e="string"!=typeof e?e:(new Date).getFullYear()%100+parseInt(e,10),{shortYearCutoff:e,dayNamesShort:this._get(t,"dayNamesShort"),dayNames:this._get(t,"dayNames"),monthNamesShort:this._get(t,"monthNamesShort"),monthNames:this._get(t,"monthNames")}},_formatDate:function(t,e,i,s){e||(t.currentDay=t.selectedDay,t.currentMonth=t.selectedMonth,t.currentYear=t.selectedYear);var n=e?"object"==typeof e?e:this._daylightSavingAdjust(new Date(s,i,e)):this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return this.formatDate(this._get(t,"dateFormat"),n,this._getFormatConfig(t))}}),t.fn.datepicker=function(e){if(!this.length)return this;t.datepicker.initialized||(t(document).mousedown(t.datepicker._checkExternalClick),t.datepicker.initialized=!0),0===t("#"+t.datepicker._mainDivId).length&&t("body").append(t.datepicker.dpDiv);var i=Array.prototype.slice.call(arguments,1);return"string"!=typeof e||"isDisabled"!==e&&"getDate"!==e&&"widget"!==e?"option"===e&&2===arguments.length&&"string"==typeof arguments[1]?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i)):this.each(function(){"string"==typeof e?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this].concat(i)):t.datepicker._attachDatepicker(this,e)}):t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i))},t.datepicker=new i,t.datepicker.initialized=!1,t.datepicker.uuid=(new Date).getTime(),t.datepicker.version="1.10.2",window["DP_jQuery_"+o]=t})(jQuery);(function(t){var e={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},i={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0};t.widget("ui.dialog",{version:"1.10.2",options:{appendTo:"body",autoOpen:!0,buttons:[],closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(e){var i=t(this).css(e).offset().top;0>i&&t(this).css("top",e.top-i)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),this.options.title=this.options.title||this.originalTitle,this._createWrapper(),this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(this.uiDialog),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&t.fn.draggable&&this._makeDraggable(),this.options.resizable&&t.fn.resizable&&this._makeResizable(),this._isOpen=!1},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var e=this.options.appendTo;return e&&(e.jquery||e.nodeType)?t(e):this.document.find(e||"body").eq(0)},_destroy:function(){var t,e=this.originalPosition;this._destroyOverlay(),this.element.removeUniqueId().removeClass("ui-dialog-content ui-widget-content").css(this.originalCss).detach(),this.uiDialog.stop(!0,!0).remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),t=e.parent.children().eq(e.index),t.length&&t[0]!==this.element[0]?t.before(this.element):e.parent.append(this.element)},widget:function(){return this.uiDialog},disable:t.noop,enable:t.noop,close:function(e){var i=this;this._isOpen&&this._trigger("beforeClose",e)!==!1&&(this._isOpen=!1,this._destroyOverlay(),this.opener.filter(":focusable").focus().length||t(this.document[0].activeElement).blur(),this._hide(this.uiDialog,this.options.hide,function(){i._trigger("close",e)}))},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(t,e){var i=!!this.uiDialog.nextAll(":visible").insertBefore(this.uiDialog).length;return i&&!e&&this._trigger("focus",t),i},open:function(){var e=this;return this._isOpen?(this._moveToTop()&&this._focusTabbable(),undefined):(this._isOpen=!0,this.opener=t(this.document[0].activeElement),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this._show(this.uiDialog,this.options.show,function(){e._focusTabbable(),e._trigger("focus")}),this._trigger("open"),undefined)},_focusTabbable:function(){var t=this.element.find("[autofocus]");t.length||(t=this.element.find(":tabbable")),t.length||(t=this.uiDialogButtonPane.find(":tabbable")),t.length||(t=this.uiDialogTitlebarClose.filter(":tabbable")),t.length||(t=this.uiDialog),t.eq(0).focus()},_keepFocus:function(e){function i(){var e=this.document[0].activeElement,i=this.uiDialog[0]===e||t.contains(this.uiDialog[0],e);i||this._focusTabbable()}e.preventDefault(),i.call(this),this._delay(i)},_createWrapper:function(){this.uiDialog=t("<div>").addClass("ui-dialog ui-widget ui-widget-content ui-corner-all ui-front "+this.options.dialogClass).hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._on(this.uiDialog,{keydown:function(e){if(this.options.closeOnEscape&&!e.isDefaultPrevented()&&e.keyCode&&e.keyCode===t.ui.keyCode.ESCAPE)return e.preventDefault(),this.close(e),undefined;if(e.keyCode===t.ui.keyCode.TAB){var i=this.uiDialog.find(":tabbable"),s=i.filter(":first"),n=i.filter(":last");e.target!==n[0]&&e.target!==this.uiDialog[0]||e.shiftKey?e.target!==s[0]&&e.target!==this.uiDialog[0]||!e.shiftKey||(n.focus(1),e.preventDefault()):(s.focus(1),e.preventDefault())}},mousedown:function(t){this._moveToTop(t)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var e;this.uiDialogTitlebar=t("<div>").addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(this.uiDialog),this._on(this.uiDialogTitlebar,{mousedown:function(e){t(e.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.focus()}}),this.uiDialogTitlebarClose=t("<button></button>").button({label:this.options.closeText,icons:{primary:"ui-icon-closethick"},text:!1}).addClass("ui-dialog-titlebar-close").appendTo(this.uiDialogTitlebar),this._on(this.uiDialogTitlebarClose,{click:function(t){t.preventDefault(),this.close(t)}}),e=t("<span>").uniqueId().addClass("ui-dialog-title").prependTo(this.uiDialogTitlebar),this._title(e),this.uiDialog.attr({"aria-labelledby":e.attr("id")})},_title:function(t){this.options.title||t.html("&#160;"),t.text(this.options.title)},_createButtonPane:function(){this.uiDialogButtonPane=t("<div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),this.uiButtonSet=t("<div>").addClass("ui-dialog-buttonset").appendTo(this.uiDialogButtonPane),this._createButtons()},_createButtons:function(){var e=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),t.isEmptyObject(i)||t.isArray(i)&&!i.length?(this.uiDialog.removeClass("ui-dialog-buttons"),undefined):(t.each(i,function(i,s){var n,a;s=t.isFunction(s)?{click:s,text:i}:s,s=t.extend({type:"button"},s),n=s.click,s.click=function(){n.apply(e.element[0],arguments)},a={icons:s.icons,text:s.showText},delete s.icons,delete s.showText,t("<button></button>",s).button(a).appendTo(e.uiButtonSet)}),this.uiDialog.addClass("ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),undefined)},_makeDraggable:function(){function e(t){return{position:t.position,offset:t.offset}}var i=this,s=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(s,n){t(this).addClass("ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",s,e(n))},drag:function(t,s){i._trigger("drag",t,e(s))},stop:function(n,a){s.position=[a.position.left-i.document.scrollLeft(),a.position.top-i.document.scrollTop()],t(this).removeClass("ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",n,e(a))}})},_makeResizable:function(){function e(t){return{originalPosition:t.originalPosition,originalSize:t.originalSize,position:t.position,size:t.size}}var i=this,s=this.options,n=s.resizable,a=this.uiDialog.css("position"),o="string"==typeof n?n:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:s.maxWidth,maxHeight:s.maxHeight,minWidth:s.minWidth,minHeight:this._minHeight(),handles:o,start:function(s,n){t(this).addClass("ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",s,e(n))},resize:function(t,s){i._trigger("resize",t,e(s))},stop:function(n,a){s.height=t(this).height(),s.width=t(this).width(),t(this).removeClass("ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",n,e(a))}}).css("position",a)},_minHeight:function(){var t=this.options;return"auto"===t.height?t.minHeight:Math.min(t.minHeight,t.height)},_position:function(){var t=this.uiDialog.is(":visible");t||this.uiDialog.show(),this.uiDialog.position(this.options.position),t||this.uiDialog.hide()},_setOptions:function(s){var n=this,a=!1,o={};t.each(s,function(t,s){n._setOption(t,s),t in e&&(a=!0),t in i&&(o[t]=s)}),a&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",o)},_setOption:function(t,e){var i,s,n=this.uiDialog;"dialogClass"===t&&n.removeClass(this.options.dialogClass).addClass(e),"disabled"!==t&&(this._super(t,e),"appendTo"===t&&this.uiDialog.appendTo(this._appendTo()),"buttons"===t&&this._createButtons(),"closeText"===t&&this.uiDialogTitlebarClose.button({label:""+e}),"draggable"===t&&(i=n.is(":data(ui-draggable)"),i&&!e&&n.draggable("destroy"),!i&&e&&this._makeDraggable()),"position"===t&&this._position(),"resizable"===t&&(s=n.is(":data(ui-resizable)"),s&&!e&&n.resizable("destroy"),s&&"string"==typeof e&&n.resizable("option","handles",e),s||e===!1||this._makeResizable()),"title"===t&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var t,e,i,s=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),s.minWidth>s.width&&(s.width=s.minWidth),t=this.uiDialog.css({height:"auto",width:s.width}).outerHeight(),e=Math.max(0,s.minHeight-t),i="number"==typeof s.maxHeight?Math.max(0,s.maxHeight-t):"none","auto"===s.height?this.element.css({minHeight:e,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,s.height-t)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var e=t(this);return t("<div>").css({position:"absolute",width:e.outerWidth(),height:e.outerHeight()}).appendTo(e.parent()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(e){return t(e.target).closest(".ui-dialog").length?!0:!!t(e.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var e=this,i=this.widgetFullName;t.ui.dialog.overlayInstances||this._delay(function(){t.ui.dialog.overlayInstances&&this.document.bind("focusin.dialog",function(s){e._allowInteraction(s)||(s.preventDefault(),t(".ui-dialog:visible:last .ui-dialog-content").data(i)._focusTabbable())})}),this.overlay=t("<div>").addClass("ui-widget-overlay ui-front").appendTo(this._appendTo()),this._on(this.overlay,{mousedown:"_keepFocus"}),t.ui.dialog.overlayInstances++}},_destroyOverlay:function(){this.options.modal&&this.overlay&&(t.ui.dialog.overlayInstances--,t.ui.dialog.overlayInstances||this.document.unbind("focusin.dialog"),this.overlay.remove(),this.overlay=null)}}),t.ui.dialog.overlayInstances=0,t.uiBackCompat!==!1&&t.widget("ui.dialog",t.ui.dialog,{_position:function(){var e,i=this.options.position,s=[],n=[0,0];i?(("string"==typeof i||"object"==typeof i&&"0"in i)&&(s=i.split?i.split(" "):[i[0],i[1]],1===s.length&&(s[1]=s[0]),t.each(["left","top"],function(t,e){+s[t]===s[t]&&(n[t]=s[t],s[t]=e)}),i={my:s[0]+(0>n[0]?n[0]:"+"+n[0])+" "+s[1]+(0>n[1]?n[1]:"+"+n[1]),at:s.join(" ")}),i=t.extend({},t.ui.dialog.prototype.options.position,i)):i=t.ui.dialog.prototype.options.position,e=this.uiDialog.is(":visible"),e||this.uiDialog.show(),this.uiDialog.position(i),e||this.uiDialog.hide()}})})(jQuery);(function(t){t.widget("ui.menu",{version:"1.10.2",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content ui-corner-all").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}).bind("click"+this.eventNamespace,t.proxy(function(t){this.options.disabled&&t.preventDefault()},this)),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({"mousedown .ui-menu-item > a":function(t){t.preventDefault()},"click .ui-state-disabled > a":function(t){t.preventDefault()},"click .ui-menu-item:has(a)":function(e){var i=t(e.target).closest(".ui-menu-item");!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.mouseHandled=!0,this.select(e),i.has(".ui-menu").length?this.expand(e):this.element.is(":focus")||(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(e){var i=t(e.currentTarget);i.siblings().children(".ui-state-active").removeClass("ui-state-active"),this.focus(e,i)},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this.element.children(".ui-menu-item").eq(0);e||this.focus(t,i)},blur:function(e){this._delay(function(){t.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(e)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(e){t(e.target).closest(".ui-menu").length||this.collapseAll(e),this.mouseHandled=!1}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeClass("ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").children("a").removeUniqueId().removeClass("ui-corner-all ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var e=t(this);e.data("ui-menu-submenu-carat")&&e.remove()}),this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(e){function i(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}var s,n,a,o,r,h=!0;switch(e.keyCode){case t.ui.keyCode.PAGE_UP:this.previousPage(e);break;case t.ui.keyCode.PAGE_DOWN:this.nextPage(e);break;case t.ui.keyCode.HOME:this._move("first","first",e);break;case t.ui.keyCode.END:this._move("last","last",e);break;case t.ui.keyCode.UP:this.previous(e);break;case t.ui.keyCode.DOWN:this.next(e);break;case t.ui.keyCode.LEFT:this.collapse(e);break;case t.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(e);break;case t.ui.keyCode.ENTER:case t.ui.keyCode.SPACE:this._activate(e);break;case t.ui.keyCode.ESCAPE:this.collapse(e);break;default:h=!1,n=this.previousFilter||"",a=String.fromCharCode(e.keyCode),o=!1,clearTimeout(this.filterTimer),a===n?o=!0:a=n+a,r=RegExp("^"+i(a),"i"),s=this.activeMenu.children(".ui-menu-item").filter(function(){return r.test(t(this).children("a").text())}),s=o&&-1!==s.index(this.active.next())?this.active.nextAll(".ui-menu-item"):s,s.length||(a=String.fromCharCode(e.keyCode),r=RegExp("^"+i(a),"i"),s=this.activeMenu.children(".ui-menu-item").filter(function(){return r.test(t(this).children("a").text())})),s.length?(this.focus(e,s),s.length>1?(this.previousFilter=a,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter):delete this.previousFilter}h&&e.preventDefault()},_activate:function(t){this.active.is(".ui-state-disabled")||(this.active.children("a[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var e,i=this.options.icons.submenu,s=this.element.find(this.options.menus);s.filter(":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-corner-all").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var e=t(this),s=e.prev("a"),n=t("<span>").addClass("ui-menu-icon ui-icon "+i).data("ui-menu-submenu-carat",!0);s.attr("aria-haspopup","true").prepend(n),e.attr("aria-labelledby",s.attr("id"))}),e=s.add(this.element),e.children(":not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","presentation").children("a").uniqueId().addClass("ui-corner-all").attr({tabIndex:-1,role:this._itemRole()}),e.children(":not(.ui-menu-item)").each(function(){var e=t(this);/[^\-\u2014\u2013\s]/.test(e.text())||e.addClass("ui-widget-content ui-menu-divider")}),e.children(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!t.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){"icons"===t&&this.element.find(".ui-menu-icon").removeClass(this.options.icons.submenu).addClass(e.submenu),this._super(t,e)},focus:function(t,e){var i,s;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),s=this.active.children("a").addClass("ui-state-focus"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),this.active.parent().closest(".ui-menu-item").children("a:first").addClass("ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=e.children(".ui-menu"),i.length&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(e){var i,s,n,a,o,r;this._hasScroll()&&(i=parseFloat(t.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(t.css(this.activeMenu[0],"paddingTop"))||0,n=e.offset().top-this.activeMenu.offset().top-i-s,a=this.activeMenu.scrollTop(),o=this.activeMenu.height(),r=e.height(),0>n?this.activeMenu.scrollTop(a+n):n+r>o&&this.activeMenu.scrollTop(a+n-o+r))},blur:function(t,e){e||clearTimeout(this.timer),this.active&&(this.active.children("a").removeClass("ui-state-focus"),this.active=null,this._trigger("blur",t,{item:this.active}))},_startOpening:function(t){clearTimeout(this.timer),"true"===t.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(t)},this.delay))},_open:function(e){var i=t.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(e.parents(".ui-menu")).hide().attr("aria-hidden","true"),e.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(e,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:t(e&&e.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(e),this.activeMenu=s},this.delay)},_close:function(t){t||(t=this.active?this.active.parent():this.element),t.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find("a.ui-state-active").removeClass("ui-state-active")},collapse:function(t){var e=this.active&&this.active.parent().closest(".ui-menu-item",this.element);e&&e.length&&(this._close(),this.focus(t,e))},expand:function(t){var e=this.active&&this.active.children(".ui-menu ").children(".ui-menu-item").first();e&&e.length&&(this._open(e.parent()),this._delay(function(){this.focus(t,e)}))},next:function(t){this._move("next","first",t)},previous:function(t){this._move("prev","last",t)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(t,e,i){var s;this.active&&(s="first"===t||"last"===t?this.active["first"===t?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[t+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.children(".ui-menu-item")[e]()),this.focus(i,s)},nextPage:function(e){var i,s,n;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=t(this),0>i.offset().top-s-n}),this.focus(e,i)):this.focus(e,this.activeMenu.children(".ui-menu-item")[this.active?"last":"first"]())),undefined):(this.next(e),undefined)},previousPage:function(e){var i,s,n;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=t(this),i.offset().top-s+n>0}),this.focus(e,i)):this.focus(e,this.activeMenu.children(".ui-menu-item").first())),undefined):(this.next(e),undefined)},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(e){this.active=this.active||t(e.target).closest(".ui-menu-item");var i={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(e,!0),this._trigger("select",e,i)}})})(jQuery);(function(t,e){t.widget("ui.progressbar",{version:"1.10.2",options:{max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min}),this.valueDiv=t("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element),this._refreshValue()},_destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove()},value:function(t){return t===e?this.options.value:(this.options.value=this._constrainedValue(t),this._refreshValue(),e)},_constrainedValue:function(t){return t===e&&(t=this.options.value),this.indeterminate=t===!1,"number"!=typeof t&&(t=0),this.indeterminate?!1:Math.min(this.options.max,Math.max(this.min,t))},_setOptions:function(t){var e=t.value;delete t.value,this._super(t),this.options.value=this._constrainedValue(e),this._refreshValue()},_setOption:function(t,e){"max"===t&&(e=Math.max(this.min,e)),this._super(t,e)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var e=this.options.value,i=this._percentage();this.valueDiv.toggle(this.indeterminate||e>this.min).toggleClass("ui-corner-right",e===this.options.max).width(i.toFixed(0)+"%"),this.element.toggleClass("ui-progressbar-indeterminate",this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=t("<div class='ui-progressbar-overlay'></div>").appendTo(this.valueDiv))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":e}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==e&&(this.oldValue=e,this._trigger("change")),e===this.options.max&&this._trigger("complete")}})})(jQuery);(function(t){var e=5;t.widget("ui.slider",t.ui.mouse,{version:"1.10.2",widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"),this._refresh(),this._setOption("disabled",this.options.disabled),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var e,i,s=this.options,n=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),a="<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",o=[];for(i=s.values&&s.values.length||1,n.length>i&&(n.slice(i).remove(),n=n.slice(0,i)),e=n.length;i>e;e++)o.push(a);this.handles=n.add(t(o.join("")).appendTo(this.element)),this.handle=this.handles.eq(0),this.handles.each(function(e){t(this).data("ui-slider-handle-index",e)})},_createRange:function(){var e=this.options,i="";e.range?(e.range===!0&&(e.values?e.values.length&&2!==e.values.length?e.values=[e.values[0],e.values[0]]:t.isArray(e.values)&&(e.values=e.values.slice(0)):e.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?this.range.removeClass("ui-slider-range-min ui-slider-range-max").css({left:"",bottom:""}):(this.range=t("<div></div>").appendTo(this.element),i="ui-slider-range ui-widget-header ui-corner-all"),this.range.addClass(i+("min"===e.range||"max"===e.range?" ui-slider-range-"+e.range:""))):this.range=t([])},_setupEvents:function(){var t=this.handles.add(this.range).filter("a");this._off(t),this._on(t,this._handleEvents),this._hoverable(t),this._focusable(t)},_destroy:function(){this.handles.remove(),this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-widget ui-widget-content ui-corner-all"),this._mouseDestroy()},_mouseCapture:function(e){var i,s,n,a,o,r,h,l,u=this,c=this.options;return c.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),i={x:e.pageX,y:e.pageY},s=this._normValueFromMouse(i),n=this._valueMax()-this._valueMin()+1,this.handles.each(function(e){var i=Math.abs(s-u.values(e));(n>i||n===i&&(e===u._lastChangedValue||u.values(e)===c.min))&&(n=i,a=t(this),o=e)}),r=this._start(e,o),r===!1?!1:(this._mouseSliding=!0,this._handleIndex=o,a.addClass("ui-state-active").focus(),h=a.offset(),l=!t(e.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:e.pageX-h.left-a.width()/2,top:e.pageY-h.top-a.height()/2-(parseInt(a.css("borderTopWidth"),10)||0)-(parseInt(a.css("borderBottomWidth"),10)||0)+(parseInt(a.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(e,o,s),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(t){var e={x:t.pageX,y:t.pageY},i=this._normValueFromMouse(e);return this._slide(t,this._handleIndex,i),!1},_mouseStop:function(t){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(t,this._handleIndex),this._change(t,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(t){var e,i,s,n,a;return"horizontal"===this.orientation?(e=this.elementSize.width,i=t.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(e=this.elementSize.height,i=t.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),s=i/e,s>1&&(s=1),0>s&&(s=0),"vertical"===this.orientation&&(s=1-s),n=this._valueMax()-this._valueMin(),a=this._valueMin()+s*n,this._trimAlignValue(a)},_start:function(t,e){var i={handle:this.handles[e],value:this.value()};return this.options.values&&this.options.values.length&&(i.value=this.values(e),i.values=this.values()),this._trigger("start",t,i)},_slide:function(t,e,i){var s,n,a;this.options.values&&this.options.values.length?(s=this.values(e?0:1),2===this.options.values.length&&this.options.range===!0&&(0===e&&i>s||1===e&&s>i)&&(i=s),i!==this.values(e)&&(n=this.values(),n[e]=i,a=this._trigger("slide",t,{handle:this.handles[e],value:i,values:n}),s=this.values(e?0:1),a!==!1&&this.values(e,i,!0))):i!==this.value()&&(a=this._trigger("slide",t,{handle:this.handles[e],value:i}),a!==!1&&this.value(i))},_stop:function(t,e){var i={handle:this.handles[e],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(e),i.values=this.values()),this._trigger("stop",t,i)},_change:function(t,e){if(!this._keySliding&&!this._mouseSliding){var i={handle:this.handles[e],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(e),i.values=this.values()),this._lastChangedValue=e,this._trigger("change",t,i)}},value:function(t){return arguments.length?(this.options.value=this._trimAlignValue(t),this._refreshValue(),this._change(null,0),undefined):this._value()},values:function(e,i){var s,n,a;if(arguments.length>1)return this.options.values[e]=this._trimAlignValue(i),this._refreshValue(),this._change(null,e),undefined;if(!arguments.length)return this._values();if(!t.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(e):this.value();for(s=this.options.values,n=arguments[0],a=0;s.length>a;a+=1)s[a]=this._trimAlignValue(n[a]),this._change(null,a);this._refreshValue()},_setOption:function(e,i){var s,n=0;switch("range"===e&&this.options.range===!0&&("min"===i?(this.options.value=this._values(0),this.options.values=null):"max"===i&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),t.isArray(this.options.values)&&(n=this.options.values.length),t.Widget.prototype._setOption.apply(this,arguments),e){case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue();break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),s=0;n>s;s+=1)this._change(null,s);this._animateOff=!1;break;case"min":case"max":this._animateOff=!0,this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_value:function(){var t=this.options.value;return t=this._trimAlignValue(t)},_values:function(t){var e,i,s;if(arguments.length)return e=this.options.values[t],e=this._trimAlignValue(e);if(this.options.values&&this.options.values.length){for(i=this.options.values.slice(),s=0;i.length>s;s+=1)i[s]=this._trimAlignValue(i[s]);return i}return[]},_trimAlignValue:function(t){if(this._valueMin()>=t)return this._valueMin();if(t>=this._valueMax())return this._valueMax();var e=this.options.step>0?this.options.step:1,i=(t-this._valueMin())%e,s=t-i;return 2*Math.abs(i)>=e&&(s+=i>0?e:-e),parseFloat(s.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var e,i,s,n,a,o=this.options.range,r=this.options,h=this,l=this._animateOff?!1:r.animate,u={};this.options.values&&this.options.values.length?this.handles.each(function(s){i=100*((h.values(s)-h._valueMin())/(h._valueMax()-h._valueMin())),u["horizontal"===h.orientation?"left":"bottom"]=i+"%",t(this).stop(1,1)[l?"animate":"css"](u,r.animate),h.options.range===!0&&("horizontal"===h.orientation?(0===s&&h.range.stop(1,1)[l?"animate":"css"]({left:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({width:i-e+"%"},{queue:!1,duration:r.animate})):(0===s&&h.range.stop(1,1)[l?"animate":"css"]({bottom:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({height:i-e+"%"},{queue:!1,duration:r.animate}))),e=i}):(s=this.value(),n=this._valueMin(),a=this._valueMax(),i=a!==n?100*((s-n)/(a-n)):0,u["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[l?"animate":"css"](u,r.animate),"min"===o&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:i+"%"},r.animate),"max"===o&&"horizontal"===this.orientation&&this.range[l?"animate":"css"]({width:100-i+"%"},{queue:!1,duration:r.animate}),"min"===o&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:i+"%"},r.animate),"max"===o&&"vertical"===this.orientation&&this.range[l?"animate":"css"]({height:100-i+"%"},{queue:!1,duration:r.animate}))},_handleEvents:{keydown:function(i){var s,n,a,o,r=t(i.target).data("ui-slider-handle-index");switch(i.keyCode){case t.ui.keyCode.HOME:case t.ui.keyCode.END:case t.ui.keyCode.PAGE_UP:case t.ui.keyCode.PAGE_DOWN:case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(i.preventDefault(),!this._keySliding&&(this._keySliding=!0,t(i.target).addClass("ui-state-active"),s=this._start(i,r),s===!1))return}switch(o=this.options.step,n=a=this.options.values&&this.options.values.length?this.values(r):this.value(),i.keyCode){case t.ui.keyCode.HOME:a=this._valueMin();break;case t.ui.keyCode.END:a=this._valueMax();break;case t.ui.keyCode.PAGE_UP:a=this._trimAlignValue(n+(this._valueMax()-this._valueMin())/e);break;case t.ui.keyCode.PAGE_DOWN:a=this._trimAlignValue(n-(this._valueMax()-this._valueMin())/e);break;case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:if(n===this._valueMax())return;a=this._trimAlignValue(n+o);break;case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(n===this._valueMin())return;a=this._trimAlignValue(n-o)}this._slide(i,r,a)},click:function(t){t.preventDefault()},keyup:function(e){var i=t(e.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(e,i),this._change(e,i),t(e.target).removeClass("ui-state-active"))}}})})(jQuery);(function(t){function e(t){return function(){var e=this.element.val();t.apply(this,arguments),this._refresh(),e!==this.element.val()&&this._trigger("change")}}t.widget("ui.spinner",{version:"1.10.2",defaultElement:"<input>",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var e={},i=this.element;return t.each(["min","max","step"],function(t,s){var n=i.attr(s);void 0!==n&&n.length&&(e[s]=n)}),e},_events:{keydown:function(t){this._start(t)&&this._keydown(t)&&t.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",t),void 0)},mousewheel:function(t,e){if(e){if(!this.spinning&&!this._start(t))return!1;this._spin((e>0?1:-1)*this.options.step,t),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(t)},100),t.preventDefault()}},"mousedown .ui-spinner-button":function(e){function i(){var t=this.element[0]===this.document[0].activeElement;t||(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s}))}var s;s=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),e.preventDefault(),i.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,i.call(this)}),this._start(e)!==!1&&this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(e){return t(e.currentTarget).hasClass("ui-state-active")?this._start(e)===!1?!1:(this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e),void 0):void 0},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var t=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this.element.attr("role","spinbutton"),this.buttons=t.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(.5*t.height())&&t.height()>0&&t.height(t.height()),this.options.disabled&&this.disable()},_keydown:function(e){var i=this.options,s=t.ui.keyCode;switch(e.keyCode){case s.UP:return this._repeat(null,1,e),!0;case s.DOWN:return this._repeat(null,-1,e),!0;case s.PAGE_UP:return this._repeat(null,i.page,e),!0;case s.PAGE_DOWN:return this._repeat(null,-i.page,e),!0}return!1},_uiSpinnerHtml:function(){return"<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"},_buttonHtml:function(){return"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'><span class='ui-icon "+this.options.icons.up+"'>&#9650;</span>"+"</a>"+"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>"+"<span class='ui-icon "+this.options.icons.down+"'>&#9660;</span>"+"</a>"},_start:function(t){return this.spinning||this._trigger("start",t)!==!1?(this.counter||(this.counter=1),this.spinning=!0,!0):!1},_repeat:function(t,e,i){t=t||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,e,i)},t),this._spin(e*this.options.step,i)},_spin:function(t,e){var i=this.value()||0;this.counter||(this.counter=1),i=this._adjustValue(i+t*this._increment(this.counter)),this.spinning&&this._trigger("spin",e,{value:i})===!1||(this._value(i),this.counter++)},_increment:function(e){var i=this.options.incremental;return i?t.isFunction(i)?i(e):Math.floor(e*e*e/5e4-e*e/500+17*e/200+1):1},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_adjustValue:function(t){var e,i,s=this.options;return e=null!==s.min?s.min:0,i=t-e,i=Math.round(i/s.step)*s.step,t=e+i,t=parseFloat(t.toFixed(this._precision())),null!==s.max&&t>s.max?s.max:null!==s.min&&s.min>t?s.min:t},_stop:function(t){this.spinning&&(clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",t))},_setOption:function(t,e){if("culture"===t||"numberFormat"===t){var i=this._parse(this.element.val());return this.options[t]=e,this.element.val(this._format(i)),void 0}("max"===t||"min"===t||"step"===t)&&"string"==typeof e&&(e=this._parse(e)),"icons"===t&&(this.buttons.first().find(".ui-icon").removeClass(this.options.icons.up).addClass(e.up),this.buttons.last().find(".ui-icon").removeClass(this.options.icons.down).addClass(e.down)),this._super(t,e),"disabled"===t&&(e?(this.element.prop("disabled",!0),this.buttons.button("disable")):(this.element.prop("disabled",!1),this.buttons.button("enable")))},_setOptions:e(function(t){this._super(t),this._value(this.element.val())}),_parse:function(t){return"string"==typeof t&&""!==t&&(t=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(t,10,this.options.culture):+t),""===t||isNaN(t)?null:t},_format:function(t){return""===t?"":window.Globalize&&this.options.numberFormat?Globalize.format(t,this.options.numberFormat,this.options.culture):t},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},_value:function(t,e){var i;""!==t&&(i=this._parse(t),null!==i&&(e||(i=this._adjustValue(i)),t=this._format(i))),this.element.val(t),this._refresh()},_destroy:function(){this.element.removeClass("ui-spinner-input").prop("disabled",!1).removeAttr("autocomplete").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:e(function(t){this._stepUp(t)}),_stepUp:function(t){this._start()&&(this._spin((t||1)*this.options.step),this._stop())},stepDown:e(function(t){this._stepDown(t)}),_stepDown:function(t){this._start()&&(this._spin((t||1)*-this.options.step),this._stop())},pageUp:e(function(t){this._stepUp((t||1)*this.options.page)}),pageDown:e(function(t){this._stepDown((t||1)*this.options.page)}),value:function(t){return arguments.length?(e(this._value).call(this,t),void 0):this._parse(this.element.val())},widget:function(){return this.uiSpinner}})})(jQuery);(function(t,e){function i(){return++n}function s(t){return t.hash.length>1&&decodeURIComponent(t.href.replace(a,""))===decodeURIComponent(location.href.replace(a,""))}var n=0,a=/#.*$/;t.widget("ui.tabs",{version:"1.10.2",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var e=this,i=this.options;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",i.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(e){t(this).is(".ui-state-disabled")&&e.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){t(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs(),i.active=this._initialActive(),t.isArray(i.disabled)&&(i.disabled=t.unique(i.disabled.concat(t.map(this.tabs.filter(".ui-state-disabled"),function(t){return e.tabs.index(t)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):t(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var i=this.options.active,s=this.options.collapsible,n=location.hash.substring(1);return null===i&&(n&&this.tabs.each(function(s,a){return t(a).attr("aria-controls")===n?(i=s,!1):e}),null===i&&(i=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===i||-1===i)&&(i=this.tabs.length?0:!1)),i!==!1&&(i=this.tabs.index(this.tabs.eq(i)),-1===i&&(i=s?!1:0)),!s&&i===!1&&this.anchors.length&&(i=0),i},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):t()}},_tabKeydown:function(i){var s=t(this.document[0].activeElement).closest("li"),n=this.tabs.index(s),a=!0;if(!this._handlePageNav(i)){switch(i.keyCode){case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:n++;break;case t.ui.keyCode.UP:case t.ui.keyCode.LEFT:a=!1,n--;break;case t.ui.keyCode.END:n=this.anchors.length-1;break;case t.ui.keyCode.HOME:n=0;break;case t.ui.keyCode.SPACE:return i.preventDefault(),clearTimeout(this.activating),this._activate(n),e;case t.ui.keyCode.ENTER:return i.preventDefault(),clearTimeout(this.activating),this._activate(n===this.options.active?!1:n),e;default:return}i.preventDefault(),clearTimeout(this.activating),n=this._focusNextTab(n,a),i.ctrlKey||(s.attr("aria-selected","false"),this.tabs.eq(n).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",n)},this.delay))}},_panelKeydown:function(e){this._handlePageNav(e)||e.ctrlKey&&e.keyCode===t.ui.keyCode.UP&&(e.preventDefault(),this.active.focus())},_handlePageNav:function(i){return i.altKey&&i.keyCode===t.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):i.altKey&&i.keyCode===t.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):e},_findNextTab:function(e,i){function s(){return e>n&&(e=0),0>e&&(e=n),e}for(var n=this.tabs.length-1;-1!==t.inArray(s(),this.options.disabled);)e=i?e+1:e-1;return e},_focusNextTab:function(t,e){return t=this._findNextTab(t,e),this.tabs.eq(t).focus(),t},_setOption:function(t,i){return"active"===t?(this._activate(i),e):"disabled"===t?(this._setupDisabled(i),e):(this._super(t,i),"collapsible"===t&&(this.element.toggleClass("ui-tabs-collapsible",i),i||this.options.active!==!1||this._activate(0)),"event"===t&&this._setupEvents(i),"heightStyle"===t&&this._setupHeightStyle(i),e)},_tabId:function(t){return t.attr("aria-controls")||"ui-tabs-"+i()},_sanitizeSelector:function(t){return t?t.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var e=this.options,i=this.tablist.children(":has(a[href])");e.disabled=t.map(i.filter(".ui-state-disabled"),function(t){return i.index(t)}),this._processTabs(),e.active!==!1&&this.anchors.length?this.active.length&&!t.contains(this.tablist[0],this.active[0])?this.tabs.length===e.disabled.length?(e.active=!1,this.active=t()):this._activate(this._findNextTab(Math.max(0,e.active-1),!1)):e.active=this.tabs.index(this.active):(e.active=!1,this.active=t()),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var e=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return t("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=t(),this.anchors.each(function(i,n){var a,o,r,h=t(n).uniqueId().attr("id"),l=t(n).closest("li"),u=l.attr("aria-controls");s(n)?(a=n.hash,o=e.element.find(e._sanitizeSelector(a))):(r=e._tabId(l),a="#"+r,o=e.element.find(a),o.length||(o=e._createPanel(r),o.insertAfter(e.panels[i-1]||e.tablist)),o.attr("aria-live","polite")),o.length&&(e.panels=e.panels.add(o)),u&&l.data("ui-tabs-aria-controls",u),l.attr({"aria-controls":a.substring(1),"aria-labelledby":h}),o.attr("aria-labelledby",h)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.element.find("ol,ul").eq(0)},_createPanel:function(e){return t("<div>").attr("id",e).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(e){t.isArray(e)&&(e.length?e.length===this.anchors.length&&(e=!0):e=!1);for(var i,s=0;i=this.tabs[s];s++)e===!0||-1!==t.inArray(s,e)?t(i).addClass("ui-state-disabled").attr("aria-disabled","true"):t(i).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=e},_setupEvents:function(e){var i={click:function(t){t.preventDefault()}};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(e){var i,s=this.element.parent();"fill"===e?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=t(this).outerHeight(!0)}),this.panels.each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.panels.each(function(){i=Math.max(i,t(this).height("").height())}).height(i))},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),a=n.closest("li"),o=a[0]===s[0],r=o&&i.collapsible,h=r?t():this._getPanelForTab(a),l=s.length?this._getPanelForTab(s):t(),u={oldTab:s,oldPanel:l,newTab:r?t():a,newPanel:h};e.preventDefault(),a.hasClass("ui-state-disabled")||a.hasClass("ui-tabs-loading")||this.running||o&&!i.collapsible||this._trigger("beforeActivate",e,u)===!1||(i.active=r?!1:this.tabs.index(a),this.active=o?t():a,this.xhr&&this.xhr.abort(),l.length||h.length||t.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(a),e),this._toggle(e,u))},_toggle:function(e,i){function s(){a.running=!1,a._trigger("activate",e,i)}function n(){i.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),o.length&&a.options.show?a._show(o,a.options.show,s):(o.show(),s())}var a=this,o=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),n()}):(i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),r.hide(),n()),r.attr({"aria-expanded":"false","aria-hidden":"true"}),i.oldTab.attr("aria-selected","false"),o.length&&r.length?i.oldTab.attr("tabIndex",-1):o.length&&this.tabs.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),o.attr({"aria-expanded":"true","aria-hidden":"false"}),i.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(e){var i,s=this._findActive(e);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return e===!1?t():this.tabs.eq(e)},_getIndex:function(t){return"string"==typeof t&&(t=this.anchors.index(this.anchors.filter("[href$='"+t+"']"))),t},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){t.data(this,"ui-tabs-destroy")?t(this).remove():t(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var e=t(this),i=e.data("ui-tabs-aria-controls");i?e.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):e.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(i){var s=this.options.disabled;s!==!1&&(i===e?s=!1:(i=this._getIndex(i),s=t.isArray(s)?t.map(s,function(t){return t!==i?t:null}):t.map(this.tabs,function(t,e){return e!==i?e:null})),this._setupDisabled(s))},disable:function(i){var s=this.options.disabled;if(s!==!0){if(i===e)s=!0;else{if(i=this._getIndex(i),-1!==t.inArray(i,s))return;s=t.isArray(s)?t.merge([i],s).sort():[i]}this._setupDisabled(s)}},load:function(e,i){e=this._getIndex(e);var n=this,a=this.tabs.eq(e),o=a.find(".ui-tabs-anchor"),r=this._getPanelForTab(a),h={tab:a,panel:r};s(o[0])||(this.xhr=t.ajax(this._ajaxSettings(o,i,h)),this.xhr&&"canceled"!==this.xhr.statusText&&(a.addClass("ui-tabs-loading"),r.attr("aria-busy","true"),this.xhr.success(function(t){setTimeout(function(){r.html(t),n._trigger("load",i,h)},1)}).complete(function(t,e){setTimeout(function(){"abort"===e&&n.panels.stop(!1,!0),a.removeClass("ui-tabs-loading"),r.removeAttr("aria-busy"),t===n.xhr&&delete n.xhr},1)})))},_ajaxSettings:function(e,i,s){var n=this;return{url:e.attr("href"),beforeSend:function(e,a){return n._trigger("beforeLoad",i,t.extend({jqXHR:e,ajaxSettings:a},s))}}},_getPanelForTab:function(e){var i=t(e).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}})})(jQuery);(function(t){function e(e,i){var s=(e.attr("aria-describedby")||"").split(/\s+/);s.push(i),e.data("ui-tooltip-id",i).attr("aria-describedby",t.trim(s.join(" ")))}function i(e){var i=e.data("ui-tooltip-id"),s=(e.attr("aria-describedby")||"").split(/\s+/),n=t.inArray(i,s);-1!==n&&s.splice(n,1),e.removeData("ui-tooltip-id"),s=t.trim(s.join(" ")),s?e.attr("aria-describedby",s):e.removeAttr("aria-describedby")}var s=0;t.widget("ui.tooltip",{version:"1.10.2",options:{content:function(){var e=t(this).attr("title")||"";return t("<a>").text(e).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.options.disabled&&this._disable()},_setOption:function(e,i){var s=this;return"disabled"===e?(this[i?"_disable":"_enable"](),this.options[e]=i,void 0):(this._super(e,i),"content"===e&&t.each(this.tooltips,function(t,e){s._updateContent(e)}),void 0)},_disable:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s[0],e.close(n,!0)}),this.element.find(this.options.items).addBack().each(function(){var e=t(this);e.is("[title]")&&e.data("ui-tooltip-title",e.attr("title")).attr("title","")})},_enable:function(){this.element.find(this.options.items).addBack().each(function(){var e=t(this);e.data("ui-tooltip-title")&&e.attr("title",e.data("ui-tooltip-title"))})},open:function(e){var i=this,s=t(e?e.target:this.element).closest(this.options.items);s.length&&!s.data("ui-tooltip-id")&&(s.attr("title")&&s.data("ui-tooltip-title",s.attr("title")),s.data("ui-tooltip-open",!0),e&&"mouseover"===e.type&&s.parents().each(function(){var e,s=t(this);s.data("ui-tooltip-open")&&(e=t.Event("blur"),e.target=e.currentTarget=this,i.close(e,!0)),s.attr("title")&&(s.uniqueId(),i.parents[this.id]={element:this,title:s.attr("title")},s.attr("title",""))}),this._updateContent(s,e))},_updateContent:function(t,e){var i,s=this.options.content,n=this,a=e?e.type:null;return"string"==typeof s?this._open(e,t,s):(i=s.call(t[0],function(i){t.data("ui-tooltip-open")&&n._delay(function(){e&&(e.type=a),this._open(e,t,i)})}),i&&this._open(e,t,i),void 0)},_open:function(i,s,n){function a(t){l.of=t,o.is(":hidden")||o.position(l)}var o,r,h,l=t.extend({},this.options.position);if(n){if(o=this._find(s),o.length)return o.find(".ui-tooltip-content").html(n),void 0;s.is("[title]")&&(i&&"mouseover"===i.type?s.attr("title",""):s.removeAttr("title")),o=this._tooltip(s),e(s,o.attr("id")),o.find(".ui-tooltip-content").html(n),this.options.track&&i&&/^mouse/.test(i.type)?(this._on(this.document,{mousemove:a}),a(i)):o.position(t.extend({of:s},this.options.position)),o.hide(),this._show(o,this.options.show),this.options.show&&this.options.show.delay&&(h=this.delayedShow=setInterval(function(){o.is(":visible")&&(a(l.of),clearInterval(h))},t.fx.interval)),this._trigger("open",i,{tooltip:o}),r={keyup:function(e){if(e.keyCode===t.ui.keyCode.ESCAPE){var i=t.Event(e);i.currentTarget=s[0],this.close(i,!0)}},remove:function(){this._removeTooltip(o)}},i&&"mouseover"!==i.type||(r.mouseleave="close"),i&&"focusin"!==i.type||(r.focusout="close"),this._on(!0,s,r)}},close:function(e){var s=this,n=t(e?e.currentTarget:this.element),a=this._find(n);this.closing||(clearInterval(this.delayedShow),n.data("ui-tooltip-title")&&n.attr("title",n.data("ui-tooltip-title")),i(n),a.stop(!0),this._hide(a,this.options.hide,function(){s._removeTooltip(t(this))}),n.removeData("ui-tooltip-open"),this._off(n,"mouseleave focusout keyup"),n[0]!==this.element[0]&&this._off(n,"remove"),this._off(this.document,"mousemove"),e&&"mouseleave"===e.type&&t.each(this.parents,function(e,i){t(i.element).attr("title",i.title),delete s.parents[e]}),this.closing=!0,this._trigger("close",e,{tooltip:a}),this.closing=!1)},_tooltip:function(e){var i="ui-tooltip-"+s++,n=t("<div>").attr({id:i,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));return t("<div>").addClass("ui-tooltip-content").appendTo(n),n.appendTo(this.document[0].body),this.tooltips[i]=e,n},_find:function(e){var i=e.data("ui-tooltip-id");return i?t("#"+i):t()},_removeTooltip:function(t){t.remove(),delete this.tooltips[t.attr("id")]},_destroy:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s[0],e.close(n,!0),t("#"+i).remove(),s.data("ui-tooltip-title")&&(s.attr("title",s.data("ui-tooltip-title")),s.removeData("ui-tooltip-title"))})}})})(jQuery);(function(t,e){var i="ui-effects-";t.effects={effect:{}},function(t,e){function i(t,e,i){var s=u[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:0>t?0:t>s.max?s.max:t)}function s(i){var s=l(),n=s._rgba=[];return i=i.toLowerCase(),f(h,function(t,a){var o,r=a.re.exec(i),h=r&&a.parse(r),l=a.space||"rgba";return h?(o=s[l](h),s[c[l].cache]=o[c[l].cache],n=s._rgba=o._rgba,!1):e}),n.length?("0,0,0,0"===n.join()&&t.extend(n,a.transparent),s):a[i]}function n(t,e,i){return i=(i+1)%1,1>6*i?t+6*(e-t)*i:1>2*i?e:2>3*i?t+6*(e-t)*(2/3-i):t}var a,o="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",r=/^([\-+])=\s*(\d+\.?\d*)/,h=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],l=t.Color=function(e,i,s,n){return new t.Color.fn.parse(e,i,s,n)},c={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},u={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},d=l.support={},p=t("<p>")[0],f=t.each;p.style.cssText="background-color:rgba(1,1,1,.5)",d.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(c,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),l.fn=t.extend(l.prototype,{parse:function(n,o,r,h){if(n===e)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=t(n).css(o),o=e);var u=this,d=t.type(n),p=this._rgba=[];return o!==e&&(n=[n,o,r,h],d="array"),"string"===d?this.parse(s(n)||a._default):"array"===d?(f(c.rgba.props,function(t,e){p[e.idx]=i(n[e.idx],e)}),this):"object"===d?(n instanceof l?f(c,function(t,e){n[e.cache]&&(u[e.cache]=n[e.cache].slice())}):f(c,function(e,s){var a=s.cache;f(s.props,function(t,e){if(!u[a]&&s.to){if("alpha"===t||null==n[t])return;u[a]=s.to(u._rgba)}u[a][e.idx]=i(n[t],e,!0)}),u[a]&&0>t.inArray(null,u[a].slice(0,3))&&(u[a][3]=1,s.from&&(u._rgba=s.from(u[a])))}),this):e},is:function(t){var i=l(t),s=!0,n=this;return f(c,function(t,a){var o,r=i[a.cache];return r&&(o=n[a.cache]||a.to&&a.to(n._rgba)||[],f(a.props,function(t,i){return null!=r[i.idx]?s=r[i.idx]===o[i.idx]:e})),s}),s},_space:function(){var t=[],e=this;return f(c,function(i,s){e[s.cache]&&t.push(i)}),t.pop()},transition:function(t,e){var s=l(t),n=s._space(),a=c[n],o=0===this.alpha()?l("transparent"):this,r=o[a.cache]||a.to(o._rgba),h=r.slice();return s=s[a.cache],f(a.props,function(t,n){var a=n.idx,o=r[a],l=s[a],c=u[n.type]||{};null!==l&&(null===o?h[a]=l:(c.mod&&(l-o>c.mod/2?o+=c.mod:o-l>c.mod/2&&(o-=c.mod)),h[a]=i((l-o)*e+o,n)))}),this[n](h)},blend:function(e){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),n=l(e)._rgba;return l(t.map(i,function(t,e){return(1-s)*n[e]+s*t}))},toRgbaString:function(){var e="rgba(",i=t.map(this._rgba,function(t,e){return null==t?e>2?1:0:t});return 1===i[3]&&(i.pop(),e="rgb("),e+i.join()+")"},toHslaString:function(){var e="hsla(",i=t.map(this.hsla(),function(t,e){return null==t&&(t=e>2?1:0),e&&3>e&&(t=Math.round(100*t)+"%"),t});return 1===i[3]&&(i.pop(),e="hsl("),e+i.join()+")"},toHexString:function(e){var i=this._rgba.slice(),s=i.pop();return e&&i.push(~~(255*s)),"#"+t.map(i,function(t){return t=(t||0).toString(16),1===t.length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),l.fn.parse.prototype=l.fn,c.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e,i,s=t[0]/255,n=t[1]/255,a=t[2]/255,o=t[3],r=Math.max(s,n,a),h=Math.min(s,n,a),l=r-h,c=r+h,u=.5*c;return e=h===r?0:s===r?60*(n-a)/l+360:n===r?60*(a-s)/l+120:60*(s-n)/l+240,i=0===l?0:.5>=u?l/c:l/(2-c),[Math.round(e)%360,i,u,null==o?1:o]},c.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],a=t[3],o=.5>=s?s*(1+i):s+i-s*i,r=2*s-o;return[Math.round(255*n(r,o,e+1/3)),Math.round(255*n(r,o,e)),Math.round(255*n(r,o,e-1/3)),a]},f(c,function(s,n){var a=n.props,o=n.cache,h=n.to,c=n.from;l.fn[s]=function(s){if(h&&!this[o]&&(this[o]=h(this._rgba)),s===e)return this[o].slice();var n,r=t.type(s),u="array"===r||"object"===r?s:arguments,d=this[o].slice();return f(a,function(t,e){var s=u["object"===r?t:e.idx];null==s&&(s=d[e.idx]),d[e.idx]=i(s,e)}),c?(n=l(c(d)),n[o]=d,n):l(d)},f(a,function(e,i){l.fn[e]||(l.fn[e]=function(n){var a,o=t.type(n),h="alpha"===e?this._hsla?"hsla":"rgba":s,l=this[h](),c=l[i.idx];return"undefined"===o?c:("function"===o&&(n=n.call(this,c),o=t.type(n)),null==n&&i.empty?this:("string"===o&&(a=r.exec(n),a&&(n=c+parseFloat(a[2])*("+"===a[1]?1:-1))),l[i.idx]=n,this[h](l)))})})}),l.hook=function(e){var i=e.split(" ");f(i,function(e,i){t.cssHooks[i]={set:function(e,n){var a,o,r="";if("transparent"!==n&&("string"!==t.type(n)||(a=s(n)))){if(n=l(a||n),!d.rgba&&1!==n._rgba[3]){for(o="backgroundColor"===i?e.parentNode:e;(""===r||"transparent"===r)&&o&&o.style;)try{r=t.css(o,"backgroundColor"),o=o.parentNode}catch(h){}n=n.blend(r&&"transparent"!==r?r:"_default")}n=n.toRgbaString()}try{e.style[i]=n}catch(h){}}},t.fx.step[i]=function(e){e.colorInit||(e.start=l(e.elem,i),e.end=l(e.end),e.colorInit=!0),t.cssHooks[i].set(e.elem,e.start.transition(e.end,e.pos))}})},l.hook(o),t.cssHooks.borderColor={expand:function(t){var e={};return f(["Top","Right","Bottom","Left"],function(i,s){e["border"+s+"Color"]=t}),e}},a=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function i(e){var i,s,n=e.ownerDocument.defaultView?e.ownerDocument.defaultView.getComputedStyle(e,null):e.currentStyle,a={};if(n&&n.length&&n[0]&&n[n[0]])for(s=n.length;s--;)i=n[s],"string"==typeof n[i]&&(a[t.camelCase(i)]=n[i]);else for(i in n)"string"==typeof n[i]&&(a[i]=n[i]);return a}function s(e,i){var s,n,o={};for(s in i)n=i[s],e[s]!==n&&(a[s]||(t.fx.step[s]||!isNaN(parseFloat(n)))&&(o[s]=n));return o}var n=["add","remove","toggle"],a={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};t.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(e,i){t.fx.step[i]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(jQuery.style(t.elem,i,t.end),t.setAttr=!0)}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.effects.animateClass=function(e,a,o,r){var h=t.speed(a,o,r);return this.queue(function(){var a,o=t(this),r=o.attr("class")||"",l=h.children?o.find("*").addBack():o;l=l.map(function(){var e=t(this);return{el:e,start:i(this)}}),a=function(){t.each(n,function(t,i){e[i]&&o[i+"Class"](e[i])})},a(),l=l.map(function(){return this.end=i(this.el[0]),this.diff=s(this.start,this.end),this}),o.attr("class",r),l=l.map(function(){var e=this,i=t.Deferred(),s=t.extend({},h,{queue:!1,complete:function(){i.resolve(e)}});return this.el.animate(this.diff,s),i.promise()}),t.when.apply(t,l.get()).done(function(){a(),t.each(arguments,function(){var e=this.el;t.each(this.diff,function(t){e.css(t,"")})}),h.complete.call(o[0])})})},t.fn.extend({addClass:function(e){return function(i,s,n,a){return s?t.effects.animateClass.call(this,{add:i},s,n,a):e.apply(this,arguments)}}(t.fn.addClass),removeClass:function(e){return function(i,s,n,a){return arguments.length>1?t.effects.animateClass.call(this,{remove:i},s,n,a):e.apply(this,arguments)}}(t.fn.removeClass),toggleClass:function(i){return function(s,n,a,o,r){return"boolean"==typeof n||n===e?a?t.effects.animateClass.call(this,n?{add:s}:{remove:s},a,o,r):i.apply(this,arguments):t.effects.animateClass.call(this,{toggle:s},n,a,o)}}(t.fn.toggleClass),switchClass:function(e,i,s,n,a){return t.effects.animateClass.call(this,{add:i,remove:e},s,n,a)}})}(),function(){function s(e,i,s,n){return t.isPlainObject(e)&&(i=e,e=e.effect),e={effect:e},null==i&&(i={}),t.isFunction(i)&&(n=i,s=null,i={}),("number"==typeof i||t.fx.speeds[i])&&(n=s,s=i,i={}),t.isFunction(s)&&(n=s,s=null),i&&t.extend(e,i),s=s||i.duration,e.duration=t.fx.off?0:"number"==typeof s?s:s in t.fx.speeds?t.fx.speeds[s]:t.fx.speeds._default,e.complete=n||i.complete,e}function n(e){return!e||"number"==typeof e||t.fx.speeds[e]?!0:"string"!=typeof e||t.effects.effect[e]?t.isFunction(e)?!0:"object"!=typeof e||e.effect?!1:!0:!0}t.extend(t.effects,{version:"1.10.2",save:function(t,e){for(var s=0;e.length>s;s++)null!==e[s]&&t.data(i+e[s],t[0].style[e[s]])},restore:function(t,s){var n,a;for(a=0;s.length>a;a++)null!==s[a]&&(n=t.data(i+s[a]),n===e&&(n=""),t.css(s[a],n))},setMode:function(t,e){return"toggle"===e&&(e=t.is(":hidden")?"show":"hide"),e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createWrapper:function(e){if(e.parent().is(".ui-effects-wrapper"))return e.parent();var i={width:e.outerWidth(!0),height:e.outerHeight(!0),"float":e.css("float")},s=t("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),n={width:e.width(),height:e.height()},a=document.activeElement;try{a.id}catch(o){a=document.body}return e.wrap(s),(e[0]===a||t.contains(e[0],a))&&t(a).focus(),s=e.parent(),"static"===e.css("position")?(s.css({position:"relative"}),e.css({position:"relative"})):(t.extend(i,{position:e.css("position"),zIndex:e.css("z-index")}),t.each(["top","left","bottom","right"],function(t,s){i[s]=e.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),e.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),e.css(n),s.css(i).show()},removeWrapper:function(e){var i=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),(e[0]===i||t.contains(e[0],i))&&t(i).focus()),e},setTransition:function(e,i,s,n){return n=n||{},t.each(i,function(t,i){var a=e.cssUnit(i);a[0]>0&&(n[i]=a[0]*s+a[1])}),n}}),t.fn.extend({effect:function(){function e(e){function s(){t.isFunction(a)&&a.call(n[0]),t.isFunction(e)&&e()}var n=t(this),a=i.complete,r=i.mode;(n.is(":hidden")?"hide"===r:"show"===r)?(n[r](),s()):o.call(n[0],i,s)}var i=s.apply(this,arguments),n=i.mode,a=i.queue,o=t.effects.effect[i.effect];return t.fx.off||!o?n?this[n](i.duration,i.complete):this.each(function(){i.complete&&i.complete.call(this)}):a===!1?this.each(e):this.queue(a||"fx",e)},show:function(t){return function(e){if(n(e))return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="show",this.effect.call(this,i)}}(t.fn.show),hide:function(t){return function(e){if(n(e))return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="hide",this.effect.call(this,i)}}(t.fn.hide),toggle:function(t){return function(e){if(n(e)||"boolean"==typeof e)return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="toggle",this.effect.call(this,i)}}(t.fn.toggle),cssUnit:function(e){var i=this.css(e),s=[];return t.each(["em","px","%","pt"],function(t,e){i.indexOf(e)>0&&(s=[parseFloat(i),e])}),s}})}(),function(){var e={};t.each(["Quad","Cubic","Quart","Quint","Expo"],function(t,i){e[i]=function(e){return Math.pow(e,t+2)}}),t.extend(e,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;((e=Math.pow(2,--i))-1)/11>t;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),t.each(e,function(e,i){t.easing["easeIn"+e]=i,t.easing["easeOut"+e]=function(t){return 1-i(1-t)},t.easing["easeInOut"+e]=function(t){return.5>t?i(2*t)/2:1-i(-2*t+2)/2}})}()})(jQuery);(function(t){var e=/up|down|vertical/,i=/up|left|vertical|horizontal/;t.effects.effect.blind=function(s,n){var a,o,r,h=t(this),l=["position","top","bottom","left","right","height","width"],c=t.effects.setMode(h,s.mode||"hide"),u=s.direction||"up",d=e.test(u),p=d?"height":"width",f=d?"top":"left",m=i.test(u),g={},v="show"===c;h.parent().is(".ui-effects-wrapper")?t.effects.save(h.parent(),l):t.effects.save(h,l),h.show(),a=t.effects.createWrapper(h).css({overflow:"hidden"}),o=a[p](),r=parseFloat(a.css(f))||0,g[p]=v?o:0,m||(h.css(d?"bottom":"right",0).css(d?"top":"left","auto").css({position:"absolute"}),g[f]=v?r:o+r),v&&(a.css(p,0),m||a.css(f,r+o)),a.animate(g,{duration:s.duration,easing:s.easing,queue:!1,complete:function(){"hide"===c&&h.hide(),t.effects.restore(h,l),t.effects.removeWrapper(h),n()}})}})(jQuery);(function(t){t.effects.effect.bounce=function(e,i){var s,n,a,o=t(this),r=["position","top","bottom","left","right","height","width"],h=t.effects.setMode(o,e.mode||"effect"),l="hide"===h,c="show"===h,u=e.direction||"up",d=e.distance,p=e.times||5,f=2*p+(c||l?1:0),m=e.duration/f,g=e.easing,v="up"===u||"down"===u?"top":"left",_="up"===u||"left"===u,b=o.queue(),y=b.length;for((c||l)&&r.push("opacity"),t.effects.save(o,r),o.show(),t.effects.createWrapper(o),d||(d=o["top"===v?"outerHeight":"outerWidth"]()/3),c&&(a={opacity:1},a[v]=0,o.css("opacity",0).css(v,_?2*-d:2*d).animate(a,m,g)),l&&(d/=Math.pow(2,p-1)),a={},a[v]=0,s=0;p>s;s++)n={},n[v]=(_?"-=":"+=")+d,o.animate(n,m,g).animate(a,m,g),d=l?2*d:d/2;l&&(n={opacity:0},n[v]=(_?"-=":"+=")+d,o.animate(n,m,g)),o.queue(function(){l&&o.hide(),t.effects.restore(o,r),t.effects.removeWrapper(o),i()}),y>1&&b.splice.apply(b,[1,0].concat(b.splice(y,f+1))),o.dequeue()}})(jQuery);(function(t){t.effects.effect.clip=function(e,i){var s,n,a,o=t(this),r=["position","top","bottom","left","right","height","width"],h=t.effects.setMode(o,e.mode||"hide"),l="show"===h,c=e.direction||"vertical",u="vertical"===c,d=u?"height":"width",p=u?"top":"left",f={};t.effects.save(o,r),o.show(),s=t.effects.createWrapper(o).css({overflow:"hidden"}),n="IMG"===o[0].tagName?s:o,a=n[d](),l&&(n.css(d,0),n.css(p,a/2)),f[d]=l?a:0,f[p]=l?0:a/2,n.animate(f,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){l||o.hide(),t.effects.restore(o,r),t.effects.removeWrapper(o),i()}})}})(jQuery);(function(t){t.effects.effect.drop=function(e,i){var s,n=t(this),a=["position","top","bottom","left","right","opacity","height","width"],o=t.effects.setMode(n,e.mode||"hide"),r="show"===o,h=e.direction||"left",l="up"===h||"down"===h?"top":"left",c="up"===h||"left"===h?"pos":"neg",u={opacity:r?1:0};t.effects.save(n,a),n.show(),t.effects.createWrapper(n),s=e.distance||n["top"===l?"outerHeight":"outerWidth"](!0)/2,r&&n.css("opacity",0).css(l,"pos"===c?-s:s),u[l]=(r?"pos"===c?"+=":"-=":"pos"===c?"-=":"+=")+s,n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===o&&n.hide(),t.effects.restore(n,a),t.effects.removeWrapper(n),i()}})}})(jQuery);(function(t){t.effects.effect.explode=function(e,i){function s(){b.push(this),b.length===u*d&&n()}function n(){p.css({visibility:"visible"}),t(b).remove(),m||p.hide(),i()}var a,o,r,h,l,c,u=e.pieces?Math.round(Math.sqrt(e.pieces)):3,d=u,p=t(this),f=t.effects.setMode(p,e.mode||"hide"),m="show"===f,g=p.show().css("visibility","hidden").offset(),v=Math.ceil(p.outerWidth()/d),_=Math.ceil(p.outerHeight()/u),b=[];for(a=0;u>a;a++)for(h=g.top+a*_,c=a-(u-1)/2,o=0;d>o;o++)r=g.left+o*v,l=o-(d-1)/2,p.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-o*v,top:-a*_}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:v,height:_,left:r+(m?l*v:0),top:h+(m?c*_:0),opacity:m?0:1}).animate({left:r+(m?0:l*v),top:h+(m?0:c*_),opacity:m?1:0},e.duration||500,e.easing,s)}})(jQuery);(function(t){t.effects.effect.fade=function(e,i){var s=t(this),n=t.effects.setMode(s,e.mode||"toggle");s.animate({opacity:n},{queue:!1,duration:e.duration,easing:e.easing,complete:i})}})(jQuery);(function(t){t.effects.effect.fold=function(e,i){var s,n,a=t(this),o=["position","top","bottom","left","right","height","width"],r=t.effects.setMode(a,e.mode||"hide"),h="show"===r,l="hide"===r,c=e.size||15,u=/([0-9]+)%/.exec(c),d=!!e.horizFirst,p=h!==d,f=p?["width","height"]:["height","width"],m=e.duration/2,g={},v={};t.effects.save(a,o),a.show(),s=t.effects.createWrapper(a).css({overflow:"hidden"}),n=p?[s.width(),s.height()]:[s.height(),s.width()],u&&(c=parseInt(u[1],10)/100*n[l?0:1]),h&&s.css(d?{height:0,width:c}:{height:c,width:0}),g[f[0]]=h?n[0]:c,v[f[1]]=h?n[1]:0,s.animate(g,m,e.easing).animate(v,m,e.easing,function(){l&&a.hide(),t.effects.restore(a,o),t.effects.removeWrapper(a),i()})}})(jQuery);(function(t){t.effects.effect.highlight=function(e,i){var s=t(this),n=["backgroundImage","backgroundColor","opacity"],a=t.effects.setMode(s,e.mode||"show"),o={backgroundColor:s.css("backgroundColor")};"hide"===a&&(o.opacity=0),t.effects.save(s,n),s.show().css({backgroundImage:"none",backgroundColor:e.color||"#ffff99"}).animate(o,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===a&&s.hide(),t.effects.restore(s,n),i()}})}})(jQuery);(function(t){t.effects.effect.pulsate=function(e,i){var s,n=t(this),a=t.effects.setMode(n,e.mode||"show"),o="show"===a,r="hide"===a,h=o||"hide"===a,l=2*(e.times||5)+(h?1:0),c=e.duration/l,u=0,d=n.queue(),p=d.length;for((o||!n.is(":visible"))&&(n.css("opacity",0).show(),u=1),s=1;l>s;s++)n.animate({opacity:u},c,e.easing),u=1-u;n.animate({opacity:u},c,e.easing),n.queue(function(){r&&n.hide(),i()}),p>1&&d.splice.apply(d,[1,0].concat(d.splice(p,l+1))),n.dequeue()}})(jQuery);(function(t){t.effects.effect.puff=function(e,i){var s=t(this),n=t.effects.setMode(s,e.mode||"hide"),a="hide"===n,o=parseInt(e.percent,10)||150,r=o/100,h={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()};t.extend(e,{effect:"scale",queue:!1,fade:!0,mode:n,complete:i,percent:a?o:100,from:a?h:{height:h.height*r,width:h.width*r,outerHeight:h.outerHeight*r,outerWidth:h.outerWidth*r}}),s.effect(e)},t.effects.effect.scale=function(e,i){var s=t(this),n=t.extend(!0,{},e),a=t.effects.setMode(s,e.mode||"effect"),o=parseInt(e.percent,10)||(0===parseInt(e.percent,10)?0:"hide"===a?0:100),r=e.direction||"both",h=e.origin,l={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()},c={y:"horizontal"!==r?o/100:1,x:"vertical"!==r?o/100:1};n.effect="size",n.queue=!1,n.complete=i,"effect"!==a&&(n.origin=h||["middle","center"],n.restore=!0),n.from=e.from||("show"===a?{height:0,width:0,outerHeight:0,outerWidth:0}:l),n.to={height:l.height*c.y,width:l.width*c.x,outerHeight:l.outerHeight*c.y,outerWidth:l.outerWidth*c.x},n.fade&&("show"===a&&(n.from.opacity=0,n.to.opacity=1),"hide"===a&&(n.from.opacity=1,n.to.opacity=0)),s.effect(n)},t.effects.effect.size=function(e,i){var s,n,a,o=t(this),r=["position","top","bottom","left","right","width","height","overflow","opacity"],h=["position","top","bottom","left","right","overflow","opacity"],l=["width","height","overflow"],c=["fontSize"],u=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],d=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=t.effects.setMode(o,e.mode||"effect"),f=e.restore||"effect"!==p,m=e.scale||"both",g=e.origin||["middle","center"],v=o.css("position"),_=f?r:h,b={height:0,width:0,outerHeight:0,outerWidth:0};"show"===p&&o.show(),s={height:o.height(),width:o.width(),outerHeight:o.outerHeight(),outerWidth:o.outerWidth()},"toggle"===e.mode&&"show"===p?(o.from=e.to||b,o.to=e.from||s):(o.from=e.from||("show"===p?b:s),o.to=e.to||("hide"===p?b:s)),a={from:{y:o.from.height/s.height,x:o.from.width/s.width},to:{y:o.to.height/s.height,x:o.to.width/s.width}},("box"===m||"both"===m)&&(a.from.y!==a.to.y&&(_=_.concat(u),o.from=t.effects.setTransition(o,u,a.from.y,o.from),o.to=t.effects.setTransition(o,u,a.to.y,o.to)),a.from.x!==a.to.x&&(_=_.concat(d),o.from=t.effects.setTransition(o,d,a.from.x,o.from),o.to=t.effects.setTransition(o,d,a.to.x,o.to))),("content"===m||"both"===m)&&a.from.y!==a.to.y&&(_=_.concat(c).concat(l),o.from=t.effects.setTransition(o,c,a.from.y,o.from),o.to=t.effects.setTransition(o,c,a.to.y,o.to)),t.effects.save(o,_),o.show(),t.effects.createWrapper(o),o.css("overflow","hidden").css(o.from),g&&(n=t.effects.getBaseline(g,s),o.from.top=(s.outerHeight-o.outerHeight())*n.y,o.from.left=(s.outerWidth-o.outerWidth())*n.x,o.to.top=(s.outerHeight-o.to.outerHeight)*n.y,o.to.left=(s.outerWidth-o.to.outerWidth)*n.x),o.css(o.from),("content"===m||"both"===m)&&(u=u.concat(["marginTop","marginBottom"]).concat(c),d=d.concat(["marginLeft","marginRight"]),l=r.concat(u).concat(d),o.find("*[width]").each(function(){var i=t(this),s={height:i.height(),width:i.width(),outerHeight:i.outerHeight(),outerWidth:i.outerWidth()};f&&t.effects.save(i,l),i.from={height:s.height*a.from.y,width:s.width*a.from.x,outerHeight:s.outerHeight*a.from.y,outerWidth:s.outerWidth*a.from.x},i.to={height:s.height*a.to.y,width:s.width*a.to.x,outerHeight:s.height*a.to.y,outerWidth:s.width*a.to.x},a.from.y!==a.to.y&&(i.from=t.effects.setTransition(i,u,a.from.y,i.from),i.to=t.effects.setTransition(i,u,a.to.y,i.to)),a.from.x!==a.to.x&&(i.from=t.effects.setTransition(i,d,a.from.x,i.from),i.to=t.effects.setTransition(i,d,a.to.x,i.to)),i.css(i.from),i.animate(i.to,e.duration,e.easing,function(){f&&t.effects.restore(i,l)})})),o.animate(o.to,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){0===o.to.opacity&&o.css("opacity",o.from.opacity),"hide"===p&&o.hide(),t.effects.restore(o,_),f||("static"===v?o.css({position:"relative",top:o.to.top,left:o.to.left}):t.each(["top","left"],function(t,e){o.css(e,function(e,i){var s=parseInt(i,10),n=t?o.to.left:o.to.top;return"auto"===i?n+"px":s+n+"px"})})),t.effects.removeWrapper(o),i()}})}})(jQuery);(function(t){t.effects.effect.shake=function(e,i){var s,n=t(this),a=["position","top","bottom","left","right","height","width"],o=t.effects.setMode(n,e.mode||"effect"),r=e.direction||"left",h=e.distance||20,l=e.times||3,c=2*l+1,u=Math.round(e.duration/c),d="up"===r||"down"===r?"top":"left",p="up"===r||"left"===r,f={},m={},g={},v=n.queue(),_=v.length;for(t.effects.save(n,a),n.show(),t.effects.createWrapper(n),f[d]=(p?"-=":"+=")+h,m[d]=(p?"+=":"-=")+2*h,g[d]=(p?"-=":"+=")+2*h,n.animate(f,u,e.easing),s=1;l>s;s++)n.animate(m,u,e.easing).animate(g,u,e.easing);n.animate(m,u,e.easing).animate(f,u/2,e.easing).queue(function(){"hide"===o&&n.hide(),t.effects.restore(n,a),t.effects.removeWrapper(n),i()}),_>1&&v.splice.apply(v,[1,0].concat(v.splice(_,c+1))),n.dequeue()}})(jQuery);(function(t){t.effects.effect.slide=function(e,i){var s,n=t(this),a=["position","top","bottom","left","right","width","height"],o=t.effects.setMode(n,e.mode||"show"),r="show"===o,h=e.direction||"left",l="up"===h||"down"===h?"top":"left",c="up"===h||"left"===h,u={};t.effects.save(n,a),n.show(),s=e.distance||n["top"===l?"outerHeight":"outerWidth"](!0),t.effects.createWrapper(n).css({overflow:"hidden"}),r&&n.css(l,c?isNaN(s)?"-"+s:-s:s),u[l]=(r?c?"+=":"-=":c?"-=":"+=")+s,n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===o&&n.hide(),t.effects.restore(n,a),t.effects.removeWrapper(n),i()}})}})(jQuery);(function(t){t.effects.effect.transfer=function(e,i){var s=t(this),n=t(e.to),a="fixed"===n.css("position"),o=t("body"),r=a?o.scrollTop():0,h=a?o.scrollLeft():0,l=n.offset(),c={top:l.top-r,left:l.left-h,height:n.innerHeight(),width:n.innerWidth()},u=s.offset(),d=t("<div class='ui-effects-transfer'></div>").appendTo(document.body).addClass(e.className).css({top:u.top-r,left:u.left-h,height:s.innerHeight(),width:s.innerWidth(),position:a?"fixed":"absolute"}).animate(c,e.duration,e.easing,function(){d.remove(),i()})}})(jQuery);
\ No newline at end of file
Binary file server/src/main/webapp/static/lib/jquery-ui/css/ui-lightness/images/animated-overlay.gif has changed
Binary file server/src/main/webapp/static/lib/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png has changed
Binary file server/src/main/webapp/static/lib/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png has changed
Binary file server/src/main/webapp/static/lib/jquery-ui/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png has changed
Binary file server/src/main/webapp/static/lib/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png has changed
Binary file server/src/main/webapp/static/lib/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png has changed
Binary file server/src/main/webapp/static/lib/jquery-ui/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png has changed
Binary file server/src/main/webapp/static/lib/jquery-ui/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png has changed
Binary file server/src/main/webapp/static/lib/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png has changed
Binary file server/src/main/webapp/static/lib/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png has changed
Binary file server/src/main/webapp/static/lib/jquery-ui/css/ui-lightness/images/ui-icons_222222_256x240.png has changed
Binary file server/src/main/webapp/static/lib/jquery-ui/css/ui-lightness/images/ui-icons_228ef1_256x240.png has changed
Binary file server/src/main/webapp/static/lib/jquery-ui/css/ui-lightness/images/ui-icons_ef8c08_256x240.png has changed
Binary file server/src/main/webapp/static/lib/jquery-ui/css/ui-lightness/images/ui-icons_ffd27a_256x240.png has changed
Binary file server/src/main/webapp/static/lib/jquery-ui/css/ui-lightness/images/ui-icons_ffffff_256x240.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/lib/jquery-ui/css/ui-lightness/jquery-ui.css	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,1177 @@
+/*! jQuery UI - v1.10.3 - 2013-10-19
+* http://jqueryui.com
+* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css, jquery.ui.theme.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS%2CTahoma%2CVerdana%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=gloss_wave&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=highlight_soft&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=glass&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=glass&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=highlight_soft&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=diagonals_thick&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=diagonals_thick&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=flat&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
+* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden {
+	display: none;
+}
+.ui-helper-hidden-accessible {
+	border: 0;
+	clip: rect(0 0 0 0);
+	height: 1px;
+	margin: -1px;
+	overflow: hidden;
+	padding: 0;
+	position: absolute;
+	width: 1px;
+}
+.ui-helper-reset {
+	margin: 0;
+	padding: 0;
+	border: 0;
+	outline: 0;
+	line-height: 1.3;
+	text-decoration: none;
+	font-size: 100%;
+	list-style: none;
+}
+.ui-helper-clearfix:before,
+.ui-helper-clearfix:after {
+	content: "";
+	display: table;
+	border-collapse: collapse;
+}
+.ui-helper-clearfix:after {
+	clear: both;
+}
+.ui-helper-clearfix {
+	min-height: 0; /* support: IE7 */
+}
+.ui-helper-zfix {
+	width: 100%;
+	height: 100%;
+	top: 0;
+	left: 0;
+	position: absolute;
+	opacity: 0;
+	filter:Alpha(Opacity=0);
+}
+
+.ui-front {
+	z-index: 100;
+}
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled {
+	cursor: default !important;
+}
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+	display: block;
+	text-indent: -99999px;
+	overflow: hidden;
+	background-repeat: no-repeat;
+}
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay {
+	position: fixed;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+}
+.ui-resizable {
+	position: relative;
+}
+.ui-resizable-handle {
+	position: absolute;
+	font-size: 0.1px;
+	display: block;
+}
+.ui-resizable-disabled .ui-resizable-handle,
+.ui-resizable-autohide .ui-resizable-handle {
+	display: none;
+}
+.ui-resizable-n {
+	cursor: n-resize;
+	height: 7px;
+	width: 100%;
+	top: -5px;
+	left: 0;
+}
+.ui-resizable-s {
+	cursor: s-resize;
+	height: 7px;
+	width: 100%;
+	bottom: -5px;
+	left: 0;
+}
+.ui-resizable-e {
+	cursor: e-resize;
+	width: 7px;
+	right: -5px;
+	top: 0;
+	height: 100%;
+}
+.ui-resizable-w {
+	cursor: w-resize;
+	width: 7px;
+	left: -5px;
+	top: 0;
+	height: 100%;
+}
+.ui-resizable-se {
+	cursor: se-resize;
+	width: 12px;
+	height: 12px;
+	right: 1px;
+	bottom: 1px;
+}
+.ui-resizable-sw {
+	cursor: sw-resize;
+	width: 9px;
+	height: 9px;
+	left: -5px;
+	bottom: -5px;
+}
+.ui-resizable-nw {
+	cursor: nw-resize;
+	width: 9px;
+	height: 9px;
+	left: -5px;
+	top: -5px;
+}
+.ui-resizable-ne {
+	cursor: ne-resize;
+	width: 9px;
+	height: 9px;
+	right: -5px;
+	top: -5px;
+}
+.ui-selectable-helper {
+	position: absolute;
+	z-index: 100;
+	border: 1px dotted black;
+}
+.ui-accordion .ui-accordion-header {
+	display: block;
+	cursor: pointer;
+	position: relative;
+	margin-top: 2px;
+	padding: .5em .5em .5em .7em;
+	min-height: 0; /* support: IE7 */
+}
+.ui-accordion .ui-accordion-icons {
+	padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-noicons {
+	padding-left: .7em;
+}
+.ui-accordion .ui-accordion-icons .ui-accordion-icons {
+	padding-left: 2.2em;
+}
+.ui-accordion .ui-accordion-header .ui-accordion-header-icon {
+	position: absolute;
+	left: .5em;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-accordion .ui-accordion-content {
+	padding: 1em 2.2em;
+	border-top: 0;
+	overflow: auto;
+}
+.ui-autocomplete {
+	position: absolute;
+	top: 0;
+	left: 0;
+	cursor: default;
+}
+.ui-button {
+	display: inline-block;
+	position: relative;
+	padding: 0;
+	line-height: normal;
+	margin-right: .1em;
+	cursor: pointer;
+	vertical-align: middle;
+	text-align: center;
+	overflow: visible; /* removes extra width in IE */
+}
+.ui-button,
+.ui-button:link,
+.ui-button:visited,
+.ui-button:hover,
+.ui-button:active {
+	text-decoration: none;
+}
+/* to make room for the icon, a width needs to be set here */
+.ui-button-icon-only {
+	width: 2.2em;
+}
+/* button elements seem to need a little more width */
+button.ui-button-icon-only {
+	width: 2.4em;
+}
+.ui-button-icons-only {
+	width: 3.4em;
+}
+button.ui-button-icons-only {
+	width: 3.7em;
+}
+
+/* button text element */
+.ui-button .ui-button-text {
+	display: block;
+	line-height: normal;
+}
+.ui-button-text-only .ui-button-text {
+	padding: .4em 1em;
+}
+.ui-button-icon-only .ui-button-text,
+.ui-button-icons-only .ui-button-text {
+	padding: .4em;
+	text-indent: -9999999px;
+}
+.ui-button-text-icon-primary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+	padding: .4em 1em .4em 2.1em;
+}
+.ui-button-text-icon-secondary .ui-button-text,
+.ui-button-text-icons .ui-button-text {
+	padding: .4em 2.1em .4em 1em;
+}
+.ui-button-text-icons .ui-button-text {
+	padding-left: 2.1em;
+	padding-right: 2.1em;
+}
+/* no icon support for input elements, provide padding by default */
+input.ui-button {
+	padding: .4em 1em;
+}
+
+/* button icon element(s) */
+.ui-button-icon-only .ui-icon,
+.ui-button-text-icon-primary .ui-icon,
+.ui-button-text-icon-secondary .ui-icon,
+.ui-button-text-icons .ui-icon,
+.ui-button-icons-only .ui-icon {
+	position: absolute;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-button-icon-only .ui-icon {
+	left: 50%;
+	margin-left: -8px;
+}
+.ui-button-text-icon-primary .ui-button-icon-primary,
+.ui-button-text-icons .ui-button-icon-primary,
+.ui-button-icons-only .ui-button-icon-primary {
+	left: .5em;
+}
+.ui-button-text-icon-secondary .ui-button-icon-secondary,
+.ui-button-text-icons .ui-button-icon-secondary,
+.ui-button-icons-only .ui-button-icon-secondary {
+	right: .5em;
+}
+
+/* button sets */
+.ui-buttonset {
+	margin-right: 7px;
+}
+.ui-buttonset .ui-button {
+	margin-left: 0;
+	margin-right: -.3em;
+}
+
+/* workarounds */
+/* reset extra padding in Firefox, see h5bp.com/l */
+input.ui-button::-moz-focus-inner,
+button.ui-button::-moz-focus-inner {
+	border: 0;
+	padding: 0;
+}
+.ui-datepicker {
+	width: 17em;
+	padding: .2em .2em 0;
+	display: none;
+}
+.ui-datepicker .ui-datepicker-header {
+	position: relative;
+	padding: .2em 0;
+}
+.ui-datepicker .ui-datepicker-prev,
+.ui-datepicker .ui-datepicker-next {
+	position: absolute;
+	top: 2px;
+	width: 1.8em;
+	height: 1.8em;
+}
+.ui-datepicker .ui-datepicker-prev-hover,
+.ui-datepicker .ui-datepicker-next-hover {
+	top: 1px;
+}
+.ui-datepicker .ui-datepicker-prev {
+	left: 2px;
+}
+.ui-datepicker .ui-datepicker-next {
+	right: 2px;
+}
+.ui-datepicker .ui-datepicker-prev-hover {
+	left: 1px;
+}
+.ui-datepicker .ui-datepicker-next-hover {
+	right: 1px;
+}
+.ui-datepicker .ui-datepicker-prev span,
+.ui-datepicker .ui-datepicker-next span {
+	display: block;
+	position: absolute;
+	left: 50%;
+	margin-left: -8px;
+	top: 50%;
+	margin-top: -8px;
+}
+.ui-datepicker .ui-datepicker-title {
+	margin: 0 2.3em;
+	line-height: 1.8em;
+	text-align: center;
+}
+.ui-datepicker .ui-datepicker-title select {
+	font-size: 1em;
+	margin: 1px 0;
+}
+.ui-datepicker select.ui-datepicker-month-year {
+	width: 100%;
+}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year {
+	width: 49%;
+}
+.ui-datepicker table {
+	width: 100%;
+	font-size: .9em;
+	border-collapse: collapse;
+	margin: 0 0 .4em;
+}
+.ui-datepicker th {
+	padding: .7em .3em;
+	text-align: center;
+	font-weight: bold;
+	border: 0;
+}
+.ui-datepicker td {
+	border: 0;
+	padding: 1px;
+}
+.ui-datepicker td span,
+.ui-datepicker td a {
+	display: block;
+	padding: .2em;
+	text-align: right;
+	text-decoration: none;
+}
+.ui-datepicker .ui-datepicker-buttonpane {
+	background-image: none;
+	margin: .7em 0 0 0;
+	padding: 0 .2em;
+	border-left: 0;
+	border-right: 0;
+	border-bottom: 0;
+}
+.ui-datepicker .ui-datepicker-buttonpane button {
+	float: right;
+	margin: .5em .2em .4em;
+	cursor: pointer;
+	padding: .2em .6em .3em .6em;
+	width: auto;
+	overflow: visible;
+}
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
+	float: left;
+}
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi {
+	width: auto;
+}
+.ui-datepicker-multi .ui-datepicker-group {
+	float: left;
+}
+.ui-datepicker-multi .ui-datepicker-group table {
+	width: 95%;
+	margin: 0 auto .4em;
+}
+.ui-datepicker-multi-2 .ui-datepicker-group {
+	width: 50%;
+}
+.ui-datepicker-multi-3 .ui-datepicker-group {
+	width: 33.3%;
+}
+.ui-datepicker-multi-4 .ui-datepicker-group {
+	width: 25%;
+}
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
+	border-left-width: 0;
+}
+.ui-datepicker-multi .ui-datepicker-buttonpane {
+	clear: left;
+}
+.ui-datepicker-row-break {
+	clear: both;
+	width: 100%;
+	font-size: 0;
+}
+
+/* RTL support */
+.ui-datepicker-rtl {
+	direction: rtl;
+}
+.ui-datepicker-rtl .ui-datepicker-prev {
+	right: 2px;
+	left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next {
+	left: 2px;
+	right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-prev:hover {
+	right: 1px;
+	left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next:hover {
+	left: 1px;
+	right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane {
+	clear: right;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button {
+	float: left;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
+.ui-datepicker-rtl .ui-datepicker-group {
+	float: right;
+}
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
+	border-right-width: 0;
+	border-left-width: 1px;
+}
+.ui-dialog {
+	position: absolute;
+	top: 0;
+	left: 0;
+	padding: .2em;
+	outline: 0;
+}
+.ui-dialog .ui-dialog-titlebar {
+	padding: .4em 1em;
+	position: relative;
+}
+.ui-dialog .ui-dialog-title {
+	float: left;
+	margin: .1em 0;
+	white-space: nowrap;
+	width: 90%;
+	overflow: hidden;
+	text-overflow: ellipsis;
+}
+.ui-dialog .ui-dialog-titlebar-close {
+	position: absolute;
+	right: .3em;
+	top: 50%;
+	width: 21px;
+	margin: -10px 0 0 0;
+	padding: 1px;
+	height: 20px;
+}
+.ui-dialog .ui-dialog-content {
+	position: relative;
+	border: 0;
+	padding: .5em 1em;
+	background: none;
+	overflow: auto;
+}
+.ui-dialog .ui-dialog-buttonpane {
+	text-align: left;
+	border-width: 1px 0 0 0;
+	background-image: none;
+	margin-top: .5em;
+	padding: .3em 1em .5em .4em;
+}
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
+	float: right;
+}
+.ui-dialog .ui-dialog-buttonpane button {
+	margin: .5em .4em .5em 0;
+	cursor: pointer;
+}
+.ui-dialog .ui-resizable-se {
+	width: 12px;
+	height: 12px;
+	right: -5px;
+	bottom: -5px;
+	background-position: 16px 16px;
+}
+.ui-draggable .ui-dialog-titlebar {
+	cursor: move;
+}
+.ui-menu {
+	list-style: none;
+	padding: 2px;
+	margin: 0;
+	display: block;
+	outline: none;
+}
+.ui-menu .ui-menu {
+	margin-top: -3px;
+	position: absolute;
+}
+.ui-menu .ui-menu-item {
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	/* support: IE10, see #8844 */
+	list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
+}
+.ui-menu .ui-menu-divider {
+	margin: 5px -2px 5px -2px;
+	height: 0;
+	font-size: 0;
+	line-height: 0;
+	border-width: 1px 0 0 0;
+}
+.ui-menu .ui-menu-item a {
+	text-decoration: none;
+	display: block;
+	padding: 2px .4em;
+	line-height: 1.5;
+	min-height: 0; /* support: IE7 */
+	font-weight: normal;
+}
+.ui-menu .ui-menu-item a.ui-state-focus,
+.ui-menu .ui-menu-item a.ui-state-active {
+	font-weight: normal;
+	margin: -1px;
+}
+
+.ui-menu .ui-state-disabled {
+	font-weight: normal;
+	margin: .4em 0 .2em;
+	line-height: 1.5;
+}
+.ui-menu .ui-state-disabled a {
+	cursor: default;
+}
+
+/* icon support */
+.ui-menu-icons {
+	position: relative;
+}
+.ui-menu-icons .ui-menu-item a {
+	position: relative;
+	padding-left: 2em;
+}
+
+/* left-aligned */
+.ui-menu .ui-icon {
+	position: absolute;
+	top: .2em;
+	left: .2em;
+}
+
+/* right-aligned */
+.ui-menu .ui-menu-icon {
+	position: static;
+	float: right;
+}
+.ui-progressbar {
+	height: 2em;
+	text-align: left;
+	overflow: hidden;
+}
+.ui-progressbar .ui-progressbar-value {
+	margin: -1px;
+	height: 100%;
+}
+.ui-progressbar .ui-progressbar-overlay {
+	background: url("images/animated-overlay.gif");
+	height: 100%;
+	filter: alpha(opacity=25);
+	opacity: 0.25;
+}
+.ui-progressbar-indeterminate .ui-progressbar-value {
+	background-image: none;
+}
+.ui-slider {
+	position: relative;
+	text-align: left;
+}
+.ui-slider .ui-slider-handle {
+	position: absolute;
+	z-index: 2;
+	width: 1.2em;
+	height: 1.2em;
+	cursor: default;
+}
+.ui-slider .ui-slider-range {
+	position: absolute;
+	z-index: 1;
+	font-size: .7em;
+	display: block;
+	border: 0;
+	background-position: 0 0;
+}
+
+/* For IE8 - See #6727 */
+.ui-slider.ui-state-disabled .ui-slider-handle,
+.ui-slider.ui-state-disabled .ui-slider-range {
+	filter: inherit;
+}
+
+.ui-slider-horizontal {
+	height: .8em;
+}
+.ui-slider-horizontal .ui-slider-handle {
+	top: -.3em;
+	margin-left: -.6em;
+}
+.ui-slider-horizontal .ui-slider-range {
+	top: 0;
+	height: 100%;
+}
+.ui-slider-horizontal .ui-slider-range-min {
+	left: 0;
+}
+.ui-slider-horizontal .ui-slider-range-max {
+	right: 0;
+}
+
+.ui-slider-vertical {
+	width: .8em;
+	height: 100px;
+}
+.ui-slider-vertical .ui-slider-handle {
+	left: -.3em;
+	margin-left: 0;
+	margin-bottom: -.6em;
+}
+.ui-slider-vertical .ui-slider-range {
+	left: 0;
+	width: 100%;
+}
+.ui-slider-vertical .ui-slider-range-min {
+	bottom: 0;
+}
+.ui-slider-vertical .ui-slider-range-max {
+	top: 0;
+}
+.ui-spinner {
+	position: relative;
+	display: inline-block;
+	overflow: hidden;
+	padding: 0;
+	vertical-align: middle;
+}
+.ui-spinner-input {
+	border: none;
+	background: none;
+	color: inherit;
+	padding: 0;
+	margin: .2em 0;
+	vertical-align: middle;
+	margin-left: .4em;
+	margin-right: 22px;
+}
+.ui-spinner-button {
+	width: 16px;
+	height: 50%;
+	font-size: .5em;
+	padding: 0;
+	margin: 0;
+	text-align: center;
+	position: absolute;
+	cursor: default;
+	display: block;
+	overflow: hidden;
+	right: 0;
+}
+/* more specificity required here to overide default borders */
+.ui-spinner a.ui-spinner-button {
+	border-top: none;
+	border-bottom: none;
+	border-right: none;
+}
+/* vertical centre icon */
+.ui-spinner .ui-icon {
+	position: absolute;
+	margin-top: -8px;
+	top: 50%;
+	left: 0;
+}
+.ui-spinner-up {
+	top: 0;
+}
+.ui-spinner-down {
+	bottom: 0;
+}
+
+/* TR overrides */
+.ui-spinner .ui-icon-triangle-1-s {
+	/* need to fix icons sprite */
+	background-position: -65px -16px;
+}
+.ui-tabs {
+	position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+	padding: .2em;
+}
+.ui-tabs .ui-tabs-nav {
+	margin: 0;
+	padding: .2em .2em 0;
+}
+.ui-tabs .ui-tabs-nav li {
+	list-style: none;
+	float: left;
+	position: relative;
+	top: 0;
+	margin: 1px .2em 0 0;
+	border-bottom-width: 0;
+	padding: 0;
+	white-space: nowrap;
+}
+.ui-tabs .ui-tabs-nav li a {
+	float: left;
+	padding: .5em 1em;
+	text-decoration: none;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active {
+	margin-bottom: -1px;
+	padding-bottom: 1px;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active a,
+.ui-tabs .ui-tabs-nav li.ui-state-disabled a,
+.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
+	cursor: text;
+}
+.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
+	cursor: pointer;
+}
+.ui-tabs .ui-tabs-panel {
+	display: block;
+	border-width: 0;
+	padding: 1em 1.4em;
+	background: none;
+}
+.ui-tooltip {
+	padding: 8px;
+	position: absolute;
+	z-index: 9999;
+	max-width: 300px;
+	-webkit-box-shadow: 0 0 5px #aaa;
+	box-shadow: 0 0 5px #aaa;
+}
+body .ui-tooltip {
+	border-width: 2px;
+}
+
+/* Component containers
+----------------------------------*/
+.ui-widget {
+	font-family: Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;
+	font-size: 1.1em;
+}
+.ui-widget .ui-widget {
+	font-size: 1em;
+}
+.ui-widget input,
+.ui-widget select,
+.ui-widget textarea,
+.ui-widget button {
+	font-family: Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;
+	font-size: 1em;
+}
+.ui-widget-content {
+	border: 1px solid #dddddd;
+	background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x;
+	color: #333333;
+}
+.ui-widget-content a {
+	color: #333333;
+}
+.ui-widget-header {
+	border: 1px solid #e78f08;
+	background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x;
+	color: #ffffff;
+	font-weight: bold;
+}
+.ui-widget-header a {
+	color: #ffffff;
+}
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default,
+.ui-widget-content .ui-state-default,
+.ui-widget-header .ui-state-default {
+	border: 1px solid #cccccc;
+	background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x;
+	font-weight: bold;
+	color: #1c94c4;
+}
+.ui-state-default a,
+.ui-state-default a:link,
+.ui-state-default a:visited {
+	color: #1c94c4;
+	text-decoration: none;
+}
+.ui-state-hover,
+.ui-widget-content .ui-state-hover,
+.ui-widget-header .ui-state-hover,
+.ui-state-focus,
+.ui-widget-content .ui-state-focus,
+.ui-widget-header .ui-state-focus {
+	border: 1px solid #fbcb09;
+	background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x;
+	font-weight: bold;
+	color: #c77405;
+}
+.ui-state-hover a,
+.ui-state-hover a:hover,
+.ui-state-hover a:link,
+.ui-state-hover a:visited {
+	color: #c77405;
+	text-decoration: none;
+}
+.ui-state-active,
+.ui-widget-content .ui-state-active,
+.ui-widget-header .ui-state-active {
+	border: 1px solid #fbd850;
+	background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;
+	font-weight: bold;
+	color: #eb8f00;
+}
+.ui-state-active a,
+.ui-state-active a:link,
+.ui-state-active a:visited {
+	color: #eb8f00;
+	text-decoration: none;
+}
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight,
+.ui-widget-content .ui-state-highlight,
+.ui-widget-header .ui-state-highlight {
+	border: 1px solid #fed22f;
+	background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x;
+	color: #363636;
+}
+.ui-state-highlight a,
+.ui-widget-content .ui-state-highlight a,
+.ui-widget-header .ui-state-highlight a {
+	color: #363636;
+}
+.ui-state-error,
+.ui-widget-content .ui-state-error,
+.ui-widget-header .ui-state-error {
+	border: 1px solid #cd0a0a;
+	background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat;
+	color: #ffffff;
+}
+.ui-state-error a,
+.ui-widget-content .ui-state-error a,
+.ui-widget-header .ui-state-error a {
+	color: #ffffff;
+}
+.ui-state-error-text,
+.ui-widget-content .ui-state-error-text,
+.ui-widget-header .ui-state-error-text {
+	color: #ffffff;
+}
+.ui-priority-primary,
+.ui-widget-content .ui-priority-primary,
+.ui-widget-header .ui-priority-primary {
+	font-weight: bold;
+}
+.ui-priority-secondary,
+.ui-widget-content .ui-priority-secondary,
+.ui-widget-header .ui-priority-secondary {
+	opacity: .7;
+	filter:Alpha(Opacity=70);
+	font-weight: normal;
+}
+.ui-state-disabled,
+.ui-widget-content .ui-state-disabled,
+.ui-widget-header .ui-state-disabled {
+	opacity: .35;
+	filter:Alpha(Opacity=35);
+	background-image: none;
+}
+.ui-state-disabled .ui-icon {
+	filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
+}
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+	width: 16px;
+	height: 16px;
+}
+.ui-icon,
+.ui-widget-content .ui-icon {
+	background-image: url(images/ui-icons_222222_256x240.png);
+}
+.ui-widget-header .ui-icon {
+	background-image: url(images/ui-icons_ffffff_256x240.png);
+}
+.ui-state-default .ui-icon {
+	background-image: url(images/ui-icons_ef8c08_256x240.png);
+}
+.ui-state-hover .ui-icon,
+.ui-state-focus .ui-icon {
+	background-image: url(images/ui-icons_ef8c08_256x240.png);
+}
+.ui-state-active .ui-icon {
+	background-image: url(images/ui-icons_ef8c08_256x240.png);
+}
+.ui-state-highlight .ui-icon {
+	background-image: url(images/ui-icons_228ef1_256x240.png);
+}
+.ui-state-error .ui-icon,
+.ui-state-error-text .ui-icon {
+	background-image: url(images/ui-icons_ffd27a_256x240.png);
+}
+
+/* positioning */
+.ui-icon-blank { background-position: 16px 16px; }
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-on { background-position: -96px -144px; }
+.ui-icon-radio-off { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-left,
+.ui-corner-tl {
+	border-top-left-radius: 4px;
+}
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-right,
+.ui-corner-tr {
+	border-top-right-radius: 4px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-left,
+.ui-corner-bl {
+	border-bottom-left-radius: 4px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-right,
+.ui-corner-br {
+	border-bottom-right-radius: 4px;
+}
+
+/* Overlays */
+.ui-widget-overlay {
+	background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat;
+	opacity: .5;
+	filter: Alpha(Opacity=50);
+}
+.ui-widget-shadow {
+	margin: -5px 0 0 -5px;
+	padding: 5px;
+	background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x;
+	opacity: .2;
+	filter: Alpha(Opacity=20);
+	border-radius: 5px;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/lib/jquery-ui/css/ui-lightness/jquery-ui.min.css	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,7 @@
+/*! jQuery UI - v1.10.3 - 2013-10-19
+* http://jqueryui.com
+* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css, jquery.ui.theme.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS%2CTahoma%2CVerdana%2CArial%2Csans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=gloss_wave&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=highlight_soft&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=glass&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=glass&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=highlight_soft&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=diagonals_thick&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=diagonals_thick&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=flat&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px
+* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
+
+.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin-top:2px;padding:.5em .5em .5em .7em;min-height:0}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-noicons{padding-left:.7em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month-year{width:100%}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:49%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-dialog{position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:21px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:none}.ui-menu .ui-menu{margin-top:-3px;position:absolute}.ui-menu .ui-menu-item{margin:0;padding:0;width:100%;list-style-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}.ui-menu .ui-menu-divider{margin:5px -2px 5px -2px;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;min-height:0;font-weight:normal}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px}.ui-menu .ui-state-disabled{font-weight:normal;margin:.4em 0 .2em;line-height:1.5}.ui-menu .ui-state-disabled a{cursor:default}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em}.ui-menu .ui-menu-icon{position:static;float:right}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("images/animated-overlay.gif");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav li a{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-tabs-loading a{cursor:text}.ui-tabs .ui-tabs-nav li a,.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #ddd;background:#eee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #e78f08;background:#f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x;color:#fff;font-weight:bold}.ui-widget-header a{color:#fff}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #ccc;background:#f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#1c94c4}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#1c94c4;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #fbcb09;background:#fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#c77405}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited{color:#c77405;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #fbd850;background:#fff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#eb8f00}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#eb8f00;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fed22f;background:#ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat;color:#fff}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#fff}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#fff}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url(images/ui-icons_222222_256x240.png)}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_ffffff_256x240.png)}.ui-state-default .ui-icon{background-image:url(images/ui-icons_ef8c08_256x240.png)}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_ef8c08_256x240.png)}.ui-state-active .ui-icon{background-image:url(images/ui-icons_ef8c08_256x240.png)}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_228ef1_256x240.png)}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_ffd27a_256x240.png)}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:4px}.ui-widget-overlay{background:#666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat;opacity:.5;filter:Alpha(Opacity=50)}.ui-widget-shadow{margin:-5px 0 0 -5px;padding:5px;background:#000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x;opacity:.2;filter:Alpha(Opacity=20);border-radius:5px}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/lib/jquery-ui/i18n/jquery-ui-i18n.min.js	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,6 @@
+/*! jQuery UI - v1.10.3 - 2013-05-03
+* http://jqueryui.com
+* Includes: jquery.ui.datepicker-af.js, jquery.ui.datepicker-ar-DZ.js, jquery.ui.datepicker-ar.js, jquery.ui.datepicker-az.js, jquery.ui.datepicker-be.js, jquery.ui.datepicker-bg.js, jquery.ui.datepicker-bs.js, jquery.ui.datepicker-ca.js, jquery.ui.datepicker-cs.js, jquery.ui.datepicker-cy-GB.js, jquery.ui.datepicker-da.js, jquery.ui.datepicker-de.js, jquery.ui.datepicker-el.js, jquery.ui.datepicker-en-AU.js, jquery.ui.datepicker-en-GB.js, jquery.ui.datepicker-en-NZ.js, jquery.ui.datepicker-eo.js, jquery.ui.datepicker-es.js, jquery.ui.datepicker-et.js, jquery.ui.datepicker-eu.js, jquery.ui.datepicker-fa.js, jquery.ui.datepicker-fi.js, jquery.ui.datepicker-fo.js, jquery.ui.datepicker-fr-CA.js, jquery.ui.datepicker-fr-CH.js, jquery.ui.datepicker-fr.js, jquery.ui.datepicker-gl.js, jquery.ui.datepicker-he.js, jquery.ui.datepicker-hi.js, jquery.ui.datepicker-hr.js, jquery.ui.datepicker-hu.js, jquery.ui.datepicker-hy.js, jquery.ui.datepicker-id.js, jquery.ui.datepicker-is.js, jquery.ui.datepicker-it.js, jquery.ui.datepicker-ja.js, jquery.ui.datepicker-ka.js, jquery.ui.datepicker-kk.js, jquery.ui.datepicker-km.js, jquery.ui.datepicker-ko.js, jquery.ui.datepicker-ky.js, jquery.ui.datepicker-lb.js, jquery.ui.datepicker-lt.js, jquery.ui.datepicker-lv.js, jquery.ui.datepicker-mk.js, jquery.ui.datepicker-ml.js, jquery.ui.datepicker-ms.js, jquery.ui.datepicker-nb.js, jquery.ui.datepicker-nl-BE.js, jquery.ui.datepicker-nl.js, jquery.ui.datepicker-nn.js, jquery.ui.datepicker-no.js, jquery.ui.datepicker-pl.js, jquery.ui.datepicker-pt-BR.js, jquery.ui.datepicker-pt.js, jquery.ui.datepicker-rm.js, jquery.ui.datepicker-ro.js, jquery.ui.datepicker-ru.js, jquery.ui.datepicker-sk.js, jquery.ui.datepicker-sl.js, jquery.ui.datepicker-sq.js, jquery.ui.datepicker-sr-SR.js, jquery.ui.datepicker-sr.js, jquery.ui.datepicker-sv.js, jquery.ui.datepicker-ta.js, jquery.ui.datepicker-th.js, jquery.ui.datepicker-tj.js, jquery.ui.datepicker-tr.js, jquery.ui.datepicker-uk.js, jquery.ui.datepicker-vi.js, jquery.ui.datepicker-zh-CN.js, jquery.ui.datepicker-zh-HK.js, jquery.ui.datepicker-zh-TW.js
+* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
+jQuery(function(e){e.datepicker.regional.af={closeText:"Selekteer",prevText:"Vorige",nextText:"Volgende",currentText:"Vandag",monthNames:["Januarie","Februarie","Maart","April","Mei","Junie","Julie","Augustus","September","Oktober","November","Desember"],monthNamesShort:["Jan","Feb","Mrt","Apr","Mei","Jun","Jul","Aug","Sep","Okt","Nov","Des"],dayNames:["Sondag","Maandag","Dinsdag","Woensdag","Donderdag","Vrydag","Saterdag"],dayNamesShort:["Son","Maa","Din","Woe","Don","Vry","Sat"],dayNamesMin:["So","Ma","Di","Wo","Do","Vr","Sa"],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.af)}),jQuery(function(e){e.datepicker.regional["ar-DZ"]={closeText:"إغلاق",prevText:"&#x3C;السابق",nextText:"التالي&#x3E;",currentText:"اليوم",monthNames:["جانفي","فيفري","مارس","أفريل","ماي","جوان","جويلية","أوت","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesShort:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesMin:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],weekHeader:"أسبوع",dateFormat:"dd/mm/yy",firstDay:6,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional["ar-DZ"])}),jQuery(function(e){e.datepicker.regional.ar={closeText:"إغلاق",prevText:"&#x3C;السابق",nextText:"التالي&#x3E;",currentText:"اليوم",monthNames:["كانون الثاني","شباط","آذار","نيسان","مايو","حزيران","تموز","آب","أيلول","تشرين الأول","تشرين الثاني","كانون الأول"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesShort:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت"],dayNamesMin:["ح","ن","ث","ر","خ","ج","س"],weekHeader:"أسبوع",dateFormat:"dd/mm/yy",firstDay:6,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.ar)}),jQuery(function(e){e.datepicker.regional.az={closeText:"Bağla",prevText:"&#x3C;Geri",nextText:"İrəli&#x3E;",currentText:"Bugün",monthNames:["Yanvar","Fevral","Mart","Aprel","May","İyun","İyul","Avqust","Sentyabr","Oktyabr","Noyabr","Dekabr"],monthNamesShort:["Yan","Fev","Mar","Apr","May","İyun","İyul","Avq","Sen","Okt","Noy","Dek"],dayNames:["Bazar","Bazar ertəsi","Çərşənbə axşamı","Çərşənbə","Cümə axşamı","Cümə","Şənbə"],dayNamesShort:["B","Be","Ça","Ç","Ca","C","Ş"],dayNamesMin:["B","B","Ç","С","Ç","C","Ş"],weekHeader:"Hf",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.az)}),jQuery(function(e){e.datepicker.regional.be={closeText:"Зачыніць",prevText:"&larr;Папяр.",nextText:"Наст.&rarr;",currentText:"Сёньня",monthNames:["Студзень","Люты","Сакавік","Красавік","Травень","Чэрвень","Ліпень","Жнівень","Верасень","Кастрычнік","Лістапад","Сьнежань"],monthNamesShort:["Сту","Лют","Сак","Кра","Тра","Чэр","Ліп","Жні","Вер","Кас","Ліс","Сьн"],dayNames:["нядзеля","панядзелак","аўторак","серада","чацьвер","пятніца","субота"],dayNamesShort:["ндз","пнд","аўт","срд","чцв","птн","сбт"],dayNamesMin:["Нд","Пн","Аў","Ср","Чц","Пт","Сб"],weekHeader:"Тд",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.be)}),jQuery(function(e){e.datepicker.regional.bg={closeText:"затвори",prevText:"&#x3C;назад",nextText:"напред&#x3E;",nextBigText:"&#x3E;&#x3E;",currentText:"днес",monthNames:["Януари","Февруари","Март","Април","Май","Юни","Юли","Август","Септември","Октомври","Ноември","Декември"],monthNamesShort:["Яну","Фев","Мар","Апр","Май","Юни","Юли","Авг","Сеп","Окт","Нов","Дек"],dayNames:["Неделя","Понеделник","Вторник","Сряда","Четвъртък","Петък","Събота"],dayNamesShort:["Нед","Пон","Вто","Сря","Чет","Пет","Съб"],dayNamesMin:["Не","По","Вт","Ср","Че","Пе","Съ"],weekHeader:"Wk",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.bg)}),jQuery(function(e){e.datepicker.regional.bs={closeText:"Zatvori",prevText:"&#x3C;",nextText:"&#x3E;",currentText:"Danas",monthNames:["Januar","Februar","Mart","April","Maj","Juni","Juli","August","Septembar","Oktobar","Novembar","Decembar"],monthNamesShort:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],dayNames:["Nedelja","Ponedeljak","Utorak","Srijeda","Četvrtak","Petak","Subota"],dayNamesShort:["Ned","Pon","Uto","Sri","Čet","Pet","Sub"],dayNamesMin:["Ne","Po","Ut","Sr","Če","Pe","Su"],weekHeader:"Wk",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.bs)}),jQuery(function(e){e.datepicker.regional.ca={closeText:"Tanca",prevText:"Anterior",nextText:"Següent",currentText:"Avui",monthNames:["gener","febrer","març","abril","maig","juny","juliol","agost","setembre","octubre","novembre","desembre"],monthNamesShort:["gen","feb","març","abr","maig","juny","jul","ag","set","oct","nov","des"],dayNames:["diumenge","dilluns","dimarts","dimecres","dijous","divendres","dissabte"],dayNamesShort:["dg","dl","dt","dc","dj","dv","ds"],dayNamesMin:["dg","dl","dt","dc","dj","dv","ds"],weekHeader:"Set",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.ca)}),jQuery(function(e){e.datepicker.regional.cs={closeText:"Zavřít",prevText:"&#x3C;Dříve",nextText:"Později&#x3E;",currentText:"Nyní",monthNames:["leden","únor","březen","duben","květen","červen","červenec","srpen","září","říjen","listopad","prosinec"],monthNamesShort:["led","úno","bře","dub","kvě","čer","čvc","srp","zář","říj","lis","pro"],dayNames:["neděle","pondělí","úterý","středa","čtvrtek","pátek","sobota"],dayNamesShort:["ne","po","út","st","čt","pá","so"],dayNamesMin:["ne","po","út","st","čt","pá","so"],weekHeader:"Týd",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.cs)}),jQuery(function(e){e.datepicker.regional["cy-GB"]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["Ionawr","Chwefror","Mawrth","Ebrill","Mai","Mehefin","Gorffennaf","Awst","Medi","Hydref","Tachwedd","Rhagfyr"],monthNamesShort:["Ion","Chw","Maw","Ebr","Mai","Meh","Gor","Aws","Med","Hyd","Tac","Rha"],dayNames:["Dydd Sul","Dydd Llun","Dydd Mawrth","Dydd Mercher","Dydd Iau","Dydd Gwener","Dydd Sadwrn"],dayNamesShort:["Sul","Llu","Maw","Mer","Iau","Gwe","Sad"],dayNamesMin:["Su","Ll","Ma","Me","Ia","Gw","Sa"],weekHeader:"Wy",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional["cy-GB"])}),jQuery(function(e){e.datepicker.regional.da={closeText:"Luk",prevText:"&#x3C;Forrige",nextText:"Næste&#x3E;",currentText:"Idag",monthNames:["Januar","Februar","Marts","April","Maj","Juni","Juli","August","September","Oktober","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],dayNames:["Søndag","Mandag","Tirsdag","Onsdag","Torsdag","Fredag","Lørdag"],dayNamesShort:["Søn","Man","Tir","Ons","Tor","Fre","Lør"],dayNamesMin:["Sø","Ma","Ti","On","To","Fr","Lø"],weekHeader:"Uge",dateFormat:"dd-mm-yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.da)}),jQuery(function(e){e.datepicker.regional.de={closeText:"Schließen",prevText:"&#x3C;Zurück",nextText:"Vor&#x3E;",currentText:"Heute",monthNames:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthNamesShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],dayNames:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],dayNamesShort:["So","Mo","Di","Mi","Do","Fr","Sa"],dayNamesMin:["So","Mo","Di","Mi","Do","Fr","Sa"],weekHeader:"KW",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.de)}),jQuery(function(e){e.datepicker.regional.el={closeText:"Κλείσιμο",prevText:"Προηγούμενος",nextText:"Επόμενος",currentText:"Τρέχων Μήνας",monthNames:["Ιανουάριος","Φεβρουάριος","Μάρτιος","Απρίλιος","Μάιος","Ιούνιος","Ιούλιος","Αύγουστος","Σεπτέμβριος","Οκτώβριος","Νοέμβριος","Δεκέμβριος"],monthNamesShort:["Ιαν","Φεβ","Μαρ","Απρ","Μαι","Ιουν","Ιουλ","Αυγ","Σεπ","Οκτ","Νοε","Δεκ"],dayNames:["Κυριακή","Δευτέρα","Τρίτη","Τετάρτη","Πέμπτη","Παρασκευή","Σάββατο"],dayNamesShort:["Κυρ","Δευ","Τρι","Τετ","Πεμ","Παρ","Σαβ"],dayNamesMin:["Κυ","Δε","Τρ","Τε","Πε","Πα","Σα"],weekHeader:"Εβδ",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.el)}),jQuery(function(e){e.datepicker.regional["en-AU"]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional["en-AU"])}),jQuery(function(e){e.datepicker.regional["en-GB"]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional["en-GB"])}),jQuery(function(e){e.datepicker.regional["en-NZ"]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional["en-NZ"])}),jQuery(function(e){e.datepicker.regional.eo={closeText:"Fermi",prevText:"&#x3C;Anta",nextText:"Sekv&#x3E;",currentText:"Nuna",monthNames:["Januaro","Februaro","Marto","Aprilo","Majo","Junio","Julio","Aŭgusto","Septembro","Oktobro","Novembro","Decembro"],monthNamesShort:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aŭg","Sep","Okt","Nov","Dec"],dayNames:["Dimanĉo","Lundo","Mardo","Merkredo","Ĵaŭdo","Vendredo","Sabato"],dayNamesShort:["Dim","Lun","Mar","Mer","Ĵaŭ","Ven","Sab"],dayNamesMin:["Di","Lu","Ma","Me","Ĵa","Ve","Sa"],weekHeader:"Sb",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.eo)}),jQuery(function(e){e.datepicker.regional.es={closeText:"Cerrar",prevText:"&#x3C;Ant",nextText:"Sig&#x3E;",currentText:"Hoy",monthNames:["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"],monthNamesShort:["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"],dayNames:["Domingo","Lunes","Martes","Miércoles","Jueves","Viernes","Sábado"],dayNamesShort:["Dom","Lun","Mar","Mié","Juv","Vie","Sáb"],dayNamesMin:["Do","Lu","Ma","Mi","Ju","Vi","Sá"],weekHeader:"Sm",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.es)}),jQuery(function(e){e.datepicker.regional.et={closeText:"Sulge",prevText:"Eelnev",nextText:"Järgnev",currentText:"Täna",monthNames:["Jaanuar","Veebruar","Märts","Aprill","Mai","Juuni","Juuli","August","September","Oktoober","November","Detsember"],monthNamesShort:["Jaan","Veebr","Märts","Apr","Mai","Juuni","Juuli","Aug","Sept","Okt","Nov","Dets"],dayNames:["Pühapäev","Esmaspäev","Teisipäev","Kolmapäev","Neljapäev","Reede","Laupäev"],dayNamesShort:["Pühap","Esmasp","Teisip","Kolmap","Neljap","Reede","Laup"],dayNamesMin:["P","E","T","K","N","R","L"],weekHeader:"näd",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.et)}),jQuery(function(e){e.datepicker.regional.eu={closeText:"Egina",prevText:"&#x3C;Aur",nextText:"Hur&#x3E;",currentText:"Gaur",monthNames:["urtarrila","otsaila","martxoa","apirila","maiatza","ekaina","uztaila","abuztua","iraila","urria","azaroa","abendua"],monthNamesShort:["urt.","ots.","mar.","api.","mai.","eka.","uzt.","abu.","ira.","urr.","aza.","abe."],dayNames:["igandea","astelehena","asteartea","asteazkena","osteguna","ostirala","larunbata"],dayNamesShort:["ig.","al.","ar.","az.","og.","ol.","lr."],dayNamesMin:["ig","al","ar","az","og","ol","lr"],weekHeader:"As",dateFormat:"yy-mm-dd",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.eu)}),jQuery(function(e){e.datepicker.regional.fa={closeText:"بستن",prevText:"&#x3C;قبلی",nextText:"بعدی&#x3E;",currentText:"امروز",monthNames:["فروردين","ارديبهشت","خرداد","تير","مرداد","شهريور","مهر","آبان","آذر","دی","بهمن","اسفند"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["يکشنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنجشنبه","جمعه","شنبه"],dayNamesShort:["ی","د","س","چ","پ","ج","ش"],dayNamesMin:["ی","د","س","چ","پ","ج","ش"],weekHeader:"هف",dateFormat:"yy/mm/dd",firstDay:6,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.fa)}),jQuery(function(e){e.datepicker.regional.fi={closeText:"Sulje",prevText:"&#xAB;Edellinen",nextText:"Seuraava&#xBB;",currentText:"Tänään",monthNames:["Tammikuu","Helmikuu","Maaliskuu","Huhtikuu","Toukokuu","Kesäkuu","Heinäkuu","Elokuu","Syyskuu","Lokakuu","Marraskuu","Joulukuu"],monthNamesShort:["Tammi","Helmi","Maalis","Huhti","Touko","Kesä","Heinä","Elo","Syys","Loka","Marras","Joulu"],dayNamesShort:["Su","Ma","Ti","Ke","To","Pe","La"],dayNames:["Sunnuntai","Maanantai","Tiistai","Keskiviikko","Torstai","Perjantai","Lauantai"],dayNamesMin:["Su","Ma","Ti","Ke","To","Pe","La"],weekHeader:"Vk",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.fi)}),jQuery(function(e){e.datepicker.regional.fo={closeText:"Lat aftur",prevText:"&#x3C;Fyrra",nextText:"Næsta&#x3E;",currentText:"Í dag",monthNames:["Januar","Februar","Mars","Apríl","Mei","Juni","Juli","August","September","Oktober","November","Desember"],monthNamesShort:["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Aug","Sep","Okt","Nov","Des"],dayNames:["Sunnudagur","Mánadagur","Týsdagur","Mikudagur","Hósdagur","Fríggjadagur","Leyardagur"],dayNamesShort:["Sun","Mán","Týs","Mik","Hós","Frí","Ley"],dayNamesMin:["Su","Má","Tý","Mi","Hó","Fr","Le"],weekHeader:"Vk",dateFormat:"dd-mm-yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.fo)}),jQuery(function(e){e.datepicker.regional["fr-CA"]={closeText:"Fermer",prevText:"Précédent",nextText:"Suivant",currentText:"Aujourd'hui",monthNames:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],monthNamesShort:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","déc."],dayNames:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],dayNamesShort:["dim.","lun.","mar.","mer.","jeu.","ven.","sam."],dayNamesMin:["D","L","M","M","J","V","S"],weekHeader:"Sem.",dateFormat:"yy-mm-dd",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional["fr-CA"])}),jQuery(function(e){e.datepicker.regional["fr-CH"]={closeText:"Fermer",prevText:"&#x3C;Préc",nextText:"Suiv&#x3E;",currentText:"Courant",monthNames:["Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Août","Septembre","Octobre","Novembre","Décembre"],monthNamesShort:["Jan","Fév","Mar","Avr","Mai","Jun","Jul","Aoû","Sep","Oct","Nov","Déc"],dayNames:["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"],dayNamesShort:["Dim","Lun","Mar","Mer","Jeu","Ven","Sam"],dayNamesMin:["Di","Lu","Ma","Me","Je","Ve","Sa"],weekHeader:"Sm",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional["fr-CH"])}),jQuery(function(e){e.datepicker.regional.fr={closeText:"Fermer",prevText:"Précédent",nextText:"Suivant",currentText:"Aujourd'hui",monthNames:["Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Août","Septembre","Octobre","Novembre","Décembre"],monthNamesShort:["Janv.","Févr.","Mars","Avril","Mai","Juin","Juil.","Août","Sept.","Oct.","Nov.","Déc."],dayNames:["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"],dayNamesShort:["Dim.","Lun.","Mar.","Mer.","Jeu.","Ven.","Sam."],dayNamesMin:["D","L","M","M","J","V","S"],weekHeader:"Sem.",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.fr)}),jQuery(function(e){e.datepicker.regional.gl={closeText:"Pechar",prevText:"&#x3C;Ant",nextText:"Seg&#x3E;",currentText:"Hoxe",monthNames:["Xaneiro","Febreiro","Marzo","Abril","Maio","Xuño","Xullo","Agosto","Setembro","Outubro","Novembro","Decembro"],monthNamesShort:["Xan","Feb","Mar","Abr","Mai","Xuñ","Xul","Ago","Set","Out","Nov","Dec"],dayNames:["Domingo","Luns","Martes","Mércores","Xoves","Venres","Sábado"],dayNamesShort:["Dom","Lun","Mar","Mér","Xov","Ven","Sáb"],dayNamesMin:["Do","Lu","Ma","Mé","Xo","Ve","Sá"],weekHeader:"Sm",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.gl)}),jQuery(function(e){e.datepicker.regional.he={closeText:"סגור",prevText:"&#x3C;הקודם",nextText:"הבא&#x3E;",currentText:"היום",monthNames:["ינואר","פברואר","מרץ","אפריל","מאי","יוני","יולי","אוגוסט","ספטמבר","אוקטובר","נובמבר","דצמבר"],monthNamesShort:["ינו","פבר","מרץ","אפר","מאי","יוני","יולי","אוג","ספט","אוק","נוב","דצמ"],dayNames:["ראשון","שני","שלישי","רביעי","חמישי","שישי","שבת"],dayNamesShort:["א'","ב'","ג'","ד'","ה'","ו'","שבת"],dayNamesMin:["א'","ב'","ג'","ד'","ה'","ו'","שבת"],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!0,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.he)}),jQuery(function(e){e.datepicker.regional.hi={closeText:"बंद",prevText:"पिछला",nextText:"अगला",currentText:"आज",monthNames:["जनवरी ","फरवरी","मार्च","अप्रेल","मई","जून","जूलाई","अगस्त ","सितम्बर","अक्टूबर","नवम्बर","दिसम्बर"],monthNamesShort:["जन","फर","मार्च","अप्रेल","मई","जून","जूलाई","अग","सित","अक्ट","नव","दि"],dayNames:["रविवार","सोमवार","मंगलवार","बुधवार","गुरुवार","शुक्रवार","शनिवार"],dayNamesShort:["रवि","सोम","मंगल","बुध","गुरु","शुक्र","शनि"],dayNamesMin:["रवि","सोम","मंगल","बुध","गुरु","शुक्र","शनि"],weekHeader:"हफ्ता",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.hi)}),jQuery(function(e){e.datepicker.regional.hr={closeText:"Zatvori",prevText:"&#x3C;",nextText:"&#x3E;",currentText:"Danas",monthNames:["Siječanj","Veljača","Ožujak","Travanj","Svibanj","Lipanj","Srpanj","Kolovoz","Rujan","Listopad","Studeni","Prosinac"],monthNamesShort:["Sij","Velj","Ožu","Tra","Svi","Lip","Srp","Kol","Ruj","Lis","Stu","Pro"],dayNames:["Nedjelja","Ponedjeljak","Utorak","Srijeda","Četvrtak","Petak","Subota"],dayNamesShort:["Ned","Pon","Uto","Sri","Čet","Pet","Sub"],dayNamesMin:["Ne","Po","Ut","Sr","Če","Pe","Su"],weekHeader:"Tje",dateFormat:"dd.mm.yy.",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.hr)}),jQuery(function(e){e.datepicker.regional.hu={closeText:"bezár",prevText:"vissza",nextText:"előre",currentText:"ma",monthNames:["Január","Február","Március","Április","Május","Június","Július","Augusztus","Szeptember","Október","November","December"],monthNamesShort:["Jan","Feb","Már","Ápr","Máj","Jún","Júl","Aug","Szep","Okt","Nov","Dec"],dayNames:["Vasárnap","Hétfő","Kedd","Szerda","Csütörtök","Péntek","Szombat"],dayNamesShort:["Vas","Hét","Ked","Sze","Csü","Pén","Szo"],dayNamesMin:["V","H","K","Sze","Cs","P","Szo"],weekHeader:"Hét",dateFormat:"yy.mm.dd.",firstDay:1,isRTL:!1,showMonthAfterYear:!0,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.hu)}),jQuery(function(e){e.datepicker.regional.hy={closeText:"Փակել",prevText:"&#x3C;Նախ.",nextText:"Հաջ.&#x3E;",currentText:"Այսօր",monthNames:["Հունվար","Փետրվար","Մարտ","Ապրիլ","Մայիս","Հունիս","Հուլիս","Օգոստոս","Սեպտեմբեր","Հոկտեմբեր","Նոյեմբեր","Դեկտեմբեր"],monthNamesShort:["Հունվ","Փետր","Մարտ","Ապր","Մայիս","Հունիս","Հուլ","Օգս","Սեպ","Հոկ","Նոյ","Դեկ"],dayNames:["կիրակի","եկուշաբթի","երեքշաբթի","չորեքշաբթի","հինգշաբթի","ուրբաթ","շաբաթ"],dayNamesShort:["կիր","երկ","երք","չրք","հնգ","ուրբ","շբթ"],dayNamesMin:["կիր","երկ","երք","չրք","հնգ","ուրբ","շբթ"],weekHeader:"ՇԲՏ",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.hy)}),jQuery(function(e){e.datepicker.regional.id={closeText:"Tutup",prevText:"&#x3C;mundur",nextText:"maju&#x3E;",currentText:"hari ini",monthNames:["Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","Nopember","Desember"],monthNamesShort:["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Agus","Sep","Okt","Nop","Des"],dayNames:["Minggu","Senin","Selasa","Rabu","Kamis","Jumat","Sabtu"],dayNamesShort:["Min","Sen","Sel","Rab","kam","Jum","Sab"],dayNamesMin:["Mg","Sn","Sl","Rb","Km","jm","Sb"],weekHeader:"Mg",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.id)}),jQuery(function(e){e.datepicker.regional.is={closeText:"Loka",prevText:"&#x3C; Fyrri",nextText:"Næsti &#x3E;",currentText:"Í dag",monthNames:["Janúar","Febrúar","Mars","Apríl","Maí","Júní","Júlí","Ágúst","September","Október","Nóvember","Desember"],monthNamesShort:["Jan","Feb","Mar","Apr","Maí","Jún","Júl","Ágú","Sep","Okt","Nóv","Des"],dayNames:["Sunnudagur","Mánudagur","Þriðjudagur","Miðvikudagur","Fimmtudagur","Föstudagur","Laugardagur"],dayNamesShort:["Sun","Mán","Þri","Mið","Fim","Fös","Lau"],dayNamesMin:["Su","Má","Þr","Mi","Fi","Fö","La"],weekHeader:"Vika",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.is)}),jQuery(function(e){e.datepicker.regional.it={closeText:"Chiudi",prevText:"&#x3C;Prec",nextText:"Succ&#x3E;",currentText:"Oggi",monthNames:["Gennaio","Febbraio","Marzo","Aprile","Maggio","Giugno","Luglio","Agosto","Settembre","Ottobre","Novembre","Dicembre"],monthNamesShort:["Gen","Feb","Mar","Apr","Mag","Giu","Lug","Ago","Set","Ott","Nov","Dic"],dayNames:["Domenica","Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato"],dayNamesShort:["Dom","Lun","Mar","Mer","Gio","Ven","Sab"],dayNamesMin:["Do","Lu","Ma","Me","Gi","Ve","Sa"],weekHeader:"Sm",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.it)}),jQuery(function(e){e.datepicker.regional.ja={closeText:"閉じる",prevText:"&#x3C;前",nextText:"次&#x3E;",currentText:"今日",monthNames:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],monthNamesShort:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],dayNames:["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],dayNamesShort:["日","月","火","水","木","金","土"],dayNamesMin:["日","月","火","水","木","金","土"],weekHeader:"週",dateFormat:"yy/mm/dd",firstDay:0,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"年"},e.datepicker.setDefaults(e.datepicker.regional.ja)}),jQuery(function(e){e.datepicker.regional.ka={closeText:"დახურვა",prevText:"&#x3c; წინა",nextText:"შემდეგი &#x3e;",currentText:"დღეს",monthNames:["იანვარი","თებერვალი","მარტი","აპრილი","მაისი","ივნისი","ივლისი","აგვისტო","სექტემბერი","ოქტომბერი","ნოემბერი","დეკემბერი"],monthNamesShort:["იან","თებ","მარ","აპრ","მაი","ივნ","ივლ","აგვ","სექ","ოქტ","ნოე","დეკ"],dayNames:["კვირა","ორშაბათი","სამშაბათი","ოთხშაბათი","ხუთშაბათი","პარასკევი","შაბათი"],dayNamesShort:["კვ","ორშ","სამ","ოთხ","ხუთ","პარ","შაბ"],dayNamesMin:["კვ","ორშ","სამ","ოთხ","ხუთ","პარ","შაბ"],weekHeader:"კვირა",dateFormat:"dd-mm-yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.ka)}),jQuery(function(e){e.datepicker.regional.kk={closeText:"Жабу",prevText:"&#x3C;Алдыңғы",nextText:"Келесі&#x3E;",currentText:"Бүгін",monthNames:["Қаңтар","Ақпан","Наурыз","Сәуір","Мамыр","Маусым","Шілде","Тамыз","Қыркүйек","Қазан","Қараша","Желтоқсан"],monthNamesShort:["Қаң","Ақп","Нау","Сәу","Мам","Мау","Шіл","Там","Қыр","Қаз","Қар","Жел"],dayNames:["Жексенбі","Дүйсенбі","Сейсенбі","Сәрсенбі","Бейсенбі","Жұма","Сенбі"],dayNamesShort:["жкс","дсн","ссн","срс","бсн","жма","снб"],dayNamesMin:["Жк","Дс","Сс","Ср","Бс","Жм","Сн"],weekHeader:"Не",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.kk)}),jQuery(function(e){e.datepicker.regional.km={closeText:"ធ្វើ​រួច",prevText:"មុន",nextText:"បន្ទាប់",currentText:"ថ្ងៃ​នេះ",monthNames:["មករា","កុម្ភៈ","មីនា","មេសា","ឧសភា","មិថុនា","កក្កដា","សីហា","កញ្ញា","តុលា","វិច្ឆិកា","ធ្នូ"],monthNamesShort:["មករា","កុម្ភៈ","មីនា","មេសា","ឧសភា","មិថុនា","កក្កដា","សីហា","កញ្ញា","តុលា","វិច្ឆិកា","ធ្នូ"],dayNames:["អាទិត្យ","ចន្ទ","អង្គារ","ពុធ","ព្រហស្បតិ៍","សុក្រ","សៅរ៍"],dayNamesShort:["អា","ច","អ","ពុ","ព្រហ","សុ","សៅ"],dayNamesMin:["អា","ច","អ","ពុ","ព្រហ","សុ","សៅ"],weekHeader:"សប្ដាហ៍",dateFormat:"dd-mm-yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.km)}),jQuery(function(e){e.datepicker.regional.ko={closeText:"닫기",prevText:"이전달",nextText:"다음달",currentText:"오늘",monthNames:["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],monthNamesShort:["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],dayNames:["일요일","월요일","화요일","수요일","목요일","금요일","토요일"],dayNamesShort:["일","월","화","수","목","금","토"],dayNamesMin:["일","월","화","수","목","금","토"],weekHeader:"Wk",dateFormat:"yy-mm-dd",firstDay:0,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"년"},e.datepicker.setDefaults(e.datepicker.regional.ko)}),jQuery(function(e){e.datepicker.regional.ky={closeText:"Жабуу",prevText:"&#x3c;Мур",nextText:"Кий&#x3e;",currentText:"Бүгүн",monthNames:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthNamesShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],dayNames:["жекшемби","дүйшөмбү","шейшемби","шаршемби","бейшемби","жума","ишемби"],dayNamesShort:["жек","дүй","шей","шар","бей","жум","ише"],dayNamesMin:["Жк","Дш","Шш","Шр","Бш","Жм","Иш"],weekHeader:"Жум",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.ky)}),jQuery(function(e){e.datepicker.regional.lb={closeText:"Fäerdeg",prevText:"Zréck",nextText:"Weider",currentText:"Haut",monthNames:["Januar","Februar","Mäerz","Abrëll","Mee","Juni","Juli","August","September","Oktober","November","Dezember"],monthNamesShort:["Jan","Feb","Mäe","Abr","Mee","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],dayNames:["Sonndeg","Méindeg","Dënschdeg","Mëttwoch","Donneschdeg","Freideg","Samschdeg"],dayNamesShort:["Son","Méi","Dën","Mët","Don","Fre","Sam"],dayNamesMin:["So","Mé","Dë","Më","Do","Fr","Sa"],weekHeader:"W",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.lb)}),jQuery(function(e){e.datepicker.regional.lt={closeText:"Uždaryti",prevText:"&#x3C;Atgal",nextText:"Pirmyn&#x3E;",currentText:"Šiandien",monthNames:["Sausis","Vasaris","Kovas","Balandis","Gegužė","Birželis","Liepa","Rugpjūtis","Rugsėjis","Spalis","Lapkritis","Gruodis"],monthNamesShort:["Sau","Vas","Kov","Bal","Geg","Bir","Lie","Rugp","Rugs","Spa","Lap","Gru"],dayNames:["sekmadienis","pirmadienis","antradienis","trečiadienis","ketvirtadienis","penktadienis","šeštadienis"],dayNamesShort:["sek","pir","ant","tre","ket","pen","šeš"],dayNamesMin:["Se","Pr","An","Tr","Ke","Pe","Še"],weekHeader:"Wk",dateFormat:"yy-mm-dd",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.lt)}),jQuery(function(e){e.datepicker.regional.lv={closeText:"Aizvērt",prevText:"Iepr",nextText:"Nāka",currentText:"Šodien",monthNames:["Janvāris","Februāris","Marts","Aprīlis","Maijs","Jūnijs","Jūlijs","Augusts","Septembris","Oktobris","Novembris","Decembris"],monthNamesShort:["Jan","Feb","Mar","Apr","Mai","Jūn","Jūl","Aug","Sep","Okt","Nov","Dec"],dayNames:["svētdiena","pirmdiena","otrdiena","trešdiena","ceturtdiena","piektdiena","sestdiena"],dayNamesShort:["svt","prm","otr","tre","ctr","pkt","sst"],dayNamesMin:["Sv","Pr","Ot","Tr","Ct","Pk","Ss"],weekHeader:"Nav",dateFormat:"dd-mm-yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.lv)}),jQuery(function(e){e.datepicker.regional.mk={closeText:"Затвори",prevText:"&#x3C;",nextText:"&#x3E;",currentText:"Денес",monthNames:["Јануари","Февруари","Март","Април","Мај","Јуни","Јули","Август","Септември","Октомври","Ноември","Декември"],monthNamesShort:["Јан","Фев","Мар","Апр","Мај","Јун","Јул","Авг","Сеп","Окт","Ное","Дек"],dayNames:["Недела","Понеделник","Вторник","Среда","Четврток","Петок","Сабота"],dayNamesShort:["Нед","Пон","Вто","Сре","Чет","Пет","Саб"],dayNamesMin:["Не","По","Вт","Ср","Че","Пе","Са"],weekHeader:"Сед",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.mk)}),jQuery(function(e){e.datepicker.regional.ml={closeText:"ശരി",prevText:"മുന്നത്തെ",nextText:"അടുത്തത് ",currentText:"ഇന്ന്",monthNames:["ജനുവരി","ഫെബ്രുവരി","മാര്‍ച്ച്","ഏപ്രില്‍","മേയ്","ജൂണ്‍","ജൂലൈ","ആഗസ്റ്റ്","സെപ്റ്റംബര്‍","ഒക്ടോബര്‍","നവംബര്‍","ഡിസംബര്‍"],monthNamesShort:["ജനു","ഫെബ്","മാര്‍","ഏപ്രി","മേയ്","ജൂണ്‍","ജൂലാ","ആഗ","സെപ്","ഒക്ടോ","നവം","ഡിസ"],dayNames:["ഞായര്‍","തിങ്കള്‍","ചൊവ്വ","ബുധന്‍","വ്യാഴം","വെള്ളി","ശനി"],dayNamesShort:["ഞായ","തിങ്ക","ചൊവ്വ","ബുധ","വ്യാഴം","വെള്ളി","ശനി"],dayNamesMin:["ഞാ","തി","ചൊ","ബു","വ്യാ","വെ","ശ"],weekHeader:"ആ",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.ml)}),jQuery(function(e){e.datepicker.regional.ms={closeText:"Tutup",prevText:"&#x3C;Sebelum",nextText:"Selepas&#x3E;",currentText:"hari ini",monthNames:["Januari","Februari","Mac","April","Mei","Jun","Julai","Ogos","September","Oktober","November","Disember"],monthNamesShort:["Jan","Feb","Mac","Apr","Mei","Jun","Jul","Ogo","Sep","Okt","Nov","Dis"],dayNames:["Ahad","Isnin","Selasa","Rabu","Khamis","Jumaat","Sabtu"],dayNamesShort:["Aha","Isn","Sel","Rab","kha","Jum","Sab"],dayNamesMin:["Ah","Is","Se","Ra","Kh","Ju","Sa"],weekHeader:"Mg",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.ms)}),jQuery(function(e){e.datepicker.regional.nb={closeText:"Lukk",prevText:"&#xAB;Forrige",nextText:"Neste&#xBB;",currentText:"I dag",monthNames:["januar","februar","mars","april","mai","juni","juli","august","september","oktober","november","desember"],monthNamesShort:["jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des"],dayNamesShort:["søn","man","tir","ons","tor","fre","lør"],dayNames:["søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag"],dayNamesMin:["sø","ma","ti","on","to","fr","lø"],weekHeader:"Uke",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.nb)
+}),jQuery(function(e){e.datepicker.regional["nl-BE"]={closeText:"Sluiten",prevText:"←",nextText:"→",currentText:"Vandaag",monthNames:["januari","februari","maart","april","mei","juni","juli","augustus","september","oktober","november","december"],monthNamesShort:["jan","feb","mrt","apr","mei","jun","jul","aug","sep","okt","nov","dec"],dayNames:["zondag","maandag","dinsdag","woensdag","donderdag","vrijdag","zaterdag"],dayNamesShort:["zon","maa","din","woe","don","vri","zat"],dayNamesMin:["zo","ma","di","wo","do","vr","za"],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional["nl-BE"])}),jQuery(function(e){e.datepicker.regional.nl={closeText:"Sluiten",prevText:"←",nextText:"→",currentText:"Vandaag",monthNames:["januari","februari","maart","april","mei","juni","juli","augustus","september","oktober","november","december"],monthNamesShort:["jan","feb","mrt","apr","mei","jun","jul","aug","sep","okt","nov","dec"],dayNames:["zondag","maandag","dinsdag","woensdag","donderdag","vrijdag","zaterdag"],dayNamesShort:["zon","maa","din","woe","don","vri","zat"],dayNamesMin:["zo","ma","di","wo","do","vr","za"],weekHeader:"Wk",dateFormat:"dd-mm-yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.nl)}),jQuery(function(e){e.datepicker.regional.nn={closeText:"Lukk",prevText:"&#xAB;Førre",nextText:"Neste&#xBB;",currentText:"I dag",monthNames:["januar","februar","mars","april","mai","juni","juli","august","september","oktober","november","desember"],monthNamesShort:["jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des"],dayNamesShort:["sun","mån","tys","ons","tor","fre","lau"],dayNames:["sundag","måndag","tysdag","onsdag","torsdag","fredag","laurdag"],dayNamesMin:["su","må","ty","on","to","fr","la"],weekHeader:"Veke",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.nn)}),jQuery(function(e){e.datepicker.regional.no={closeText:"Lukk",prevText:"&#xAB;Forrige",nextText:"Neste&#xBB;",currentText:"I dag",monthNames:["januar","februar","mars","april","mai","juni","juli","august","september","oktober","november","desember"],monthNamesShort:["jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des"],dayNamesShort:["søn","man","tir","ons","tor","fre","lør"],dayNames:["søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag"],dayNamesMin:["sø","ma","ti","on","to","fr","lø"],weekHeader:"Uke",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.no)}),jQuery(function(e){e.datepicker.regional.pl={closeText:"Zamknij",prevText:"&#x3C;Poprzedni",nextText:"Następny&#x3E;",currentText:"Dziś",monthNames:["Styczeń","Luty","Marzec","Kwiecień","Maj","Czerwiec","Lipiec","Sierpień","Wrzesień","Październik","Listopad","Grudzień"],monthNamesShort:["Sty","Lu","Mar","Kw","Maj","Cze","Lip","Sie","Wrz","Pa","Lis","Gru"],dayNames:["Niedziela","Poniedziałek","Wtorek","Środa","Czwartek","Piątek","Sobota"],dayNamesShort:["Nie","Pn","Wt","Śr","Czw","Pt","So"],dayNamesMin:["N","Pn","Wt","Śr","Cz","Pt","So"],weekHeader:"Tydz",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.pl)}),jQuery(function(e){e.datepicker.regional["pt-BR"]={closeText:"Fechar",prevText:"&#x3C;Anterior",nextText:"Próximo&#x3E;",currentText:"Hoje",monthNames:["Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"],monthNamesShort:["Jan","Fev","Mar","Abr","Mai","Jun","Jul","Ago","Set","Out","Nov","Dez"],dayNames:["Domingo","Segunda-feira","Terça-feira","Quarta-feira","Quinta-feira","Sexta-feira","Sábado"],dayNamesShort:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],dayNamesMin:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],weekHeader:"Sm",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional["pt-BR"])}),jQuery(function(e){e.datepicker.regional.pt={closeText:"Fechar",prevText:"&#x3C;Anterior",nextText:"Seguinte",currentText:"Hoje",monthNames:["Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"],monthNamesShort:["Jan","Fev","Mar","Abr","Mai","Jun","Jul","Ago","Set","Out","Nov","Dez"],dayNames:["Domingo","Segunda-feira","Terça-feira","Quarta-feira","Quinta-feira","Sexta-feira","Sábado"],dayNamesShort:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],dayNamesMin:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],weekHeader:"Sem",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.pt)}),jQuery(function(e){e.datepicker.regional.rm={closeText:"Serrar",prevText:"&#x3C;Suandant",nextText:"Precedent&#x3E;",currentText:"Actual",monthNames:["Schaner","Favrer","Mars","Avrigl","Matg","Zercladur","Fanadur","Avust","Settember","October","November","December"],monthNamesShort:["Scha","Fev","Mar","Avr","Matg","Zer","Fan","Avu","Sett","Oct","Nov","Dec"],dayNames:["Dumengia","Glindesdi","Mardi","Mesemna","Gievgia","Venderdi","Sonda"],dayNamesShort:["Dum","Gli","Mar","Mes","Gie","Ven","Som"],dayNamesMin:["Du","Gl","Ma","Me","Gi","Ve","So"],weekHeader:"emna",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.rm)}),jQuery(function(e){e.datepicker.regional.ro={closeText:"Închide",prevText:"&#xAB; Luna precedentă",nextText:"Luna următoare &#xBB;",currentText:"Azi",monthNames:["Ianuarie","Februarie","Martie","Aprilie","Mai","Iunie","Iulie","August","Septembrie","Octombrie","Noiembrie","Decembrie"],monthNamesShort:["Ian","Feb","Mar","Apr","Mai","Iun","Iul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Duminică","Luni","Marţi","Miercuri","Joi","Vineri","Sâmbătă"],dayNamesShort:["Dum","Lun","Mar","Mie","Joi","Vin","Sâm"],dayNamesMin:["Du","Lu","Ma","Mi","Jo","Vi","Sâ"],weekHeader:"Săpt",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.ro)}),jQuery(function(e){e.datepicker.regional.ru={closeText:"Закрыть",prevText:"&#x3C;Пред",nextText:"След&#x3E;",currentText:"Сегодня",monthNames:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthNamesShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],dayNames:["воскресенье","понедельник","вторник","среда","четверг","пятница","суббота"],dayNamesShort:["вск","пнд","втр","срд","чтв","птн","сбт"],dayNamesMin:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],weekHeader:"Нед",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.ru)}),jQuery(function(e){e.datepicker.regional.sk={closeText:"Zavrieť",prevText:"&#x3C;Predchádzajúci",nextText:"Nasledujúci&#x3E;",currentText:"Dnes",monthNames:["január","február","marec","apríl","máj","jún","júl","august","september","október","november","december"],monthNamesShort:["Jan","Feb","Mar","Apr","Máj","Jún","Júl","Aug","Sep","Okt","Nov","Dec"],dayNames:["nedeľa","pondelok","utorok","streda","štvrtok","piatok","sobota"],dayNamesShort:["Ned","Pon","Uto","Str","Štv","Pia","Sob"],dayNamesMin:["Ne","Po","Ut","St","Št","Pia","So"],weekHeader:"Ty",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.sk)}),jQuery(function(e){e.datepicker.regional.sl={closeText:"Zapri",prevText:"&#x3C;Prejšnji",nextText:"Naslednji&#x3E;",currentText:"Trenutni",monthNames:["Januar","Februar","Marec","April","Maj","Junij","Julij","Avgust","September","Oktober","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Avg","Sep","Okt","Nov","Dec"],dayNames:["Nedelja","Ponedeljek","Torek","Sreda","Četrtek","Petek","Sobota"],dayNamesShort:["Ned","Pon","Tor","Sre","Čet","Pet","Sob"],dayNamesMin:["Ne","Po","To","Sr","Če","Pe","So"],weekHeader:"Teden",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.sl)}),jQuery(function(e){e.datepicker.regional.sq={closeText:"mbylle",prevText:"&#x3C;mbrapa",nextText:"Përpara&#x3E;",currentText:"sot",monthNames:["Janar","Shkurt","Mars","Prill","Maj","Qershor","Korrik","Gusht","Shtator","Tetor","Nëntor","Dhjetor"],monthNamesShort:["Jan","Shk","Mar","Pri","Maj","Qer","Kor","Gus","Sht","Tet","Nën","Dhj"],dayNames:["E Diel","E Hënë","E Martë","E Mërkurë","E Enjte","E Premte","E Shtune"],dayNamesShort:["Di","Hë","Ma","Më","En","Pr","Sh"],dayNamesMin:["Di","Hë","Ma","Më","En","Pr","Sh"],weekHeader:"Ja",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.sq)}),jQuery(function(e){e.datepicker.regional["sr-SR"]={closeText:"Zatvori",prevText:"&#x3C;",nextText:"&#x3E;",currentText:"Danas",monthNames:["Januar","Februar","Mart","April","Maj","Jun","Jul","Avgust","Septembar","Oktobar","Novembar","Decembar"],monthNamesShort:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Avg","Sep","Okt","Nov","Dec"],dayNames:["Nedelja","Ponedeljak","Utorak","Sreda","Četvrtak","Petak","Subota"],dayNamesShort:["Ned","Pon","Uto","Sre","Čet","Pet","Sub"],dayNamesMin:["Ne","Po","Ut","Sr","Če","Pe","Su"],weekHeader:"Sed",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional["sr-SR"])}),jQuery(function(e){e.datepicker.regional.sr={closeText:"Затвори",prevText:"&#x3C;",nextText:"&#x3E;",currentText:"Данас",monthNames:["Јануар","Фебруар","Март","Април","Мај","Јун","Јул","Август","Септембар","Октобар","Новембар","Децембар"],monthNamesShort:["Јан","Феб","Мар","Апр","Мај","Јун","Јул","Авг","Сеп","Окт","Нов","Дец"],dayNames:["Недеља","Понедељак","Уторак","Среда","Четвртак","Петак","Субота"],dayNamesShort:["Нед","Пон","Уто","Сре","Чет","Пет","Суб"],dayNamesMin:["Не","По","Ут","Ср","Че","Пе","Су"],weekHeader:"Сед",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.sr)}),jQuery(function(e){e.datepicker.regional.sv={closeText:"Stäng",prevText:"&#xAB;Förra",nextText:"Nästa&#xBB;",currentText:"Idag",monthNames:["Januari","Februari","Mars","April","Maj","Juni","Juli","Augusti","September","Oktober","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],dayNamesShort:["Sön","Mån","Tis","Ons","Tor","Fre","Lör"],dayNames:["Söndag","Måndag","Tisdag","Onsdag","Torsdag","Fredag","Lördag"],dayNamesMin:["Sö","Må","Ti","On","To","Fr","Lö"],weekHeader:"Ve",dateFormat:"yy-mm-dd",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.sv)}),jQuery(function(e){e.datepicker.regional.ta={closeText:"மூடு",prevText:"முன்னையது",nextText:"அடுத்தது",currentText:"இன்று",monthNames:["தை","மாசி","பங்குனி","சித்திரை","வைகாசி","ஆனி","ஆடி","ஆவணி","புரட்டாசி","ஐப்பசி","கார்த்திகை","மார்கழி"],monthNamesShort:["தை","மாசி","பங்","சித்","வைகா","ஆனி","ஆடி","ஆவ","புர","ஐப்","கார்","மார்"],dayNames:["ஞாயிற்றுக்கிழமை","திங்கட்கிழமை","செவ்வாய்க்கிழமை","புதன்கிழமை","வியாழக்கிழமை","வெள்ளிக்கிழமை","சனிக்கிழமை"],dayNamesShort:["ஞாயிறு","திங்கள்","செவ்வாய்","புதன்","வியாழன்","வெள்ளி","சனி"],dayNamesMin:["ஞா","தி","செ","பு","வி","வெ","ச"],weekHeader:"Не",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.ta)}),jQuery(function(e){e.datepicker.regional.th={closeText:"ปิด",prevText:"&#xAB;&#xA0;ย้อน",nextText:"ถัดไป&#xA0;&#xBB;",currentText:"วันนี้",monthNames:["มกราคม","กุมภาพันธ์","มีนาคม","เมษายน","พฤษภาคม","มิถุนายน","กรกฎาคม","สิงหาคม","กันยายน","ตุลาคม","พฤศจิกายน","ธันวาคม"],monthNamesShort:["ม.ค.","ก.พ.","มี.ค.","เม.ย.","พ.ค.","มิ.ย.","ก.ค.","ส.ค.","ก.ย.","ต.ค.","พ.ย.","ธ.ค."],dayNames:["อาทิตย์","จันทร์","อังคาร","พุธ","พฤหัสบดี","ศุกร์","เสาร์"],dayNamesShort:["อา.","จ.","อ.","พ.","พฤ.","ศ.","ส."],dayNamesMin:["อา.","จ.","อ.","พ.","พฤ.","ศ.","ส."],weekHeader:"Wk",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.th)}),jQuery(function(e){e.datepicker.regional.tj={closeText:"Идома",prevText:"&#x3c;Қафо",nextText:"Пеш&#x3e;",currentText:"Имрӯз",monthNames:["Январ","Феврал","Март","Апрел","Май","Июн","Июл","Август","Сентябр","Октябр","Ноябр","Декабр"],monthNamesShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],dayNames:["якшанбе","душанбе","сешанбе","чоршанбе","панҷшанбе","ҷумъа","шанбе"],dayNamesShort:["якш","душ","сеш","чор","пан","ҷум","шан"],dayNamesMin:["Як","Дш","Сш","Чш","Пш","Ҷм","Шн"],weekHeader:"Хф",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.tj)}),jQuery(function(e){e.datepicker.regional.tr={closeText:"kapat",prevText:"&#x3C;geri",nextText:"ileri&#x3e",currentText:"bugün",monthNames:["Ocak","Şubat","Mart","Nisan","Mayıs","Haziran","Temmuz","Ağustos","Eylül","Ekim","Kasım","Aralık"],monthNamesShort:["Oca","Şub","Mar","Nis","May","Haz","Tem","Ağu","Eyl","Eki","Kas","Ara"],dayNames:["Pazar","Pazartesi","Salı","Çarşamba","Perşembe","Cuma","Cumartesi"],dayNamesShort:["Pz","Pt","Sa","Ça","Pe","Cu","Ct"],dayNamesMin:["Pz","Pt","Sa","Ça","Pe","Cu","Ct"],weekHeader:"Hf",dateFormat:"dd.mm.yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.tr)}),jQuery(function(e){e.datepicker.regional.uk={closeText:"Закрити",prevText:"&#x3C;",nextText:"&#x3E;",currentText:"Сьогодні",monthNames:["Січень","Лютий","Березень","Квітень","Травень","Червень","Липень","Серпень","Вересень","Жовтень","Листопад","Грудень"],monthNamesShort:["Січ","Лют","Бер","Кві","Тра","Чер","Лип","Сер","Вер","Жов","Лис","Гру"],dayNames:["неділя","понеділок","вівторок","середа","четвер","п’ятниця","субота"],dayNamesShort:["нед","пнд","вів","срд","чтв","птн","сбт"],dayNamesMin:["Нд","Пн","Вт","Ср","Чт","Пт","Сб"],weekHeader:"Тиж",dateFormat:"dd/mm/yy",firstDay:1,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.uk)}),jQuery(function(e){e.datepicker.regional.vi={closeText:"Đóng",prevText:"&#x3C;Trước",nextText:"Tiếp&#x3E;",currentText:"Hôm nay",monthNames:["Tháng Một","Tháng Hai","Tháng Ba","Tháng Tư","Tháng Năm","Tháng Sáu","Tháng Bảy","Tháng Tám","Tháng Chín","Tháng Mười","Tháng Mười Một","Tháng Mười Hai"],monthNamesShort:["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"],dayNames:["Chủ Nhật","Thứ Hai","Thứ Ba","Thứ Tư","Thứ Năm","Thứ Sáu","Thứ Bảy"],dayNamesShort:["CN","T2","T3","T4","T5","T6","T7"],dayNamesMin:["CN","T2","T3","T4","T5","T6","T7"],weekHeader:"Tu",dateFormat:"dd/mm/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},e.datepicker.setDefaults(e.datepicker.regional.vi)}),jQuery(function(e){e.datepicker.regional["zh-CN"]={closeText:"关闭",prevText:"&#x3C;上月",nextText:"下月&#x3E;",currentText:"今天",monthNames:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthNamesShort:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],dayNames:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],dayNamesShort:["周日","周一","周二","周三","周四","周五","周六"],dayNamesMin:["日","一","二","三","四","五","六"],weekHeader:"周",dateFormat:"yy-mm-dd",firstDay:1,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"年"},e.datepicker.setDefaults(e.datepicker.regional["zh-CN"])}),jQuery(function(e){e.datepicker.regional["zh-HK"]={closeText:"關閉",prevText:"&#x3C;上月",nextText:"下月&#x3E;",currentText:"今天",monthNames:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthNamesShort:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],dayNames:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],dayNamesShort:["周日","周一","周二","周三","周四","周五","周六"],dayNamesMin:["日","一","二","三","四","五","六"],weekHeader:"周",dateFormat:"dd-mm-yy",firstDay:0,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"年"},e.datepicker.setDefaults(e.datepicker.regional["zh-HK"])}),jQuery(function(e){e.datepicker.regional["zh-TW"]={closeText:"關閉",prevText:"&#x3C;上月",nextText:"下月&#x3E;",currentText:"今天",monthNames:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthNamesShort:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],dayNames:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],dayNamesShort:["周日","周一","周二","周三","周四","周五","周六"],dayNamesMin:["日","一","二","三","四","五","六"],weekHeader:"周",dateFormat:"yy/mm/dd",firstDay:1,isRTL:!1,showMonthAfterYear:!0,yearSuffix:"年"},e.datepicker.setDefaults(e.datepicker.regional["zh-TW"])});
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/webapp/static/lib/jquery-ui/jquery-ui.min.js	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,12 @@
+/*! jQuery UI - v1.10.3 - 2013-05-03
+* http://jqueryui.com
+* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js
+* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */
+(function(t,e){function i(e,i){var n,o,a,r=e.nodeName.toLowerCase();return"area"===r?(n=e.parentNode,o=n.name,e.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap=#"+o+"]")[0],!!a&&s(a)):!1):(/input|select|textarea|button|object/.test(r)?!e.disabled:"a"===r?e.href||i:i)&&s(e)}function s(e){return t.expr.filters.visible(e)&&!t(e).parents().addBack().filter(function(){return"hidden"===t.css(this,"visibility")}).length}var n=0,o=/^ui-id-\d+$/;t.ui=t.ui||{},t.extend(t.ui,{version:"1.10.3",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),t.fn.extend({focus:function(e){return function(i,s){return"number"==typeof i?this.each(function(){var e=this;setTimeout(function(){t(e).focus(),s&&s.call(e)},i)}):e.apply(this,arguments)}}(t.fn.focus),scrollParent:function(){var e;return e=t.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(t.css(this,"position"))&&/(auto|scroll)/.test(t.css(this,"overflow")+t.css(this,"overflow-y")+t.css(this,"overflow-x"))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(t.css(this,"overflow")+t.css(this,"overflow-y")+t.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!e.length?t(document):e},zIndex:function(i){if(i!==e)return this.css("zIndex",i);if(this.length)for(var s,n,o=t(this[0]);o.length&&o[0]!==document;){if(s=o.css("position"),("absolute"===s||"relative"===s||"fixed"===s)&&(n=parseInt(o.css("zIndex"),10),!isNaN(n)&&0!==n))return n;o=o.parent()}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++n)})},removeUniqueId:function(){return this.each(function(){o.test(this.id)&&t(this).removeAttr("id")})}}),t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])},focusable:function(e){return i(e,!isNaN(t.attr(e,"tabindex")))},tabbable:function(e){var s=t.attr(e,"tabindex"),n=isNaN(s);return(n||s>=0)&&i(e,!n)}}),t("<a>").outerWidth(1).jquery||t.each(["Width","Height"],function(i,s){function n(e,i,s,n){return t.each(o,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),n&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var o="Width"===s?["Left","Right"]:["Top","Bottom"],a=s.toLowerCase(),r={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+s]=function(i){return i===e?r["inner"+s].call(this):this.each(function(){t(this).css(a,n(this,i)+"px")})},t.fn["outer"+s]=function(e,i){return"number"!=typeof e?r["outer"+s].call(this,e):this.each(function(){t(this).css(a,n(this,e,!0,i)+"px")})}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(t.fn.removeData=function(e){return function(i){return arguments.length?e.call(this,t.camelCase(i)):e.call(this)}}(t.fn.removeData)),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),t.support.selectstart="onselectstart"in document.createElement("div"),t.fn.extend({disableSelection:function(){return this.bind((t.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(t){t.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),t.extend(t.ui,{plugin:{add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i){var s,n=t.plugins[e];if(n&&t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType)for(s=0;n.length>s;s++)t.options[n[s][0]]&&n[s][1].apply(t.element,i)}},hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)}})})(jQuery),function(t,e){var i=0,s=Array.prototype.slice,n=t.cleanData;t.cleanData=function(e){for(var i,s=0;null!=(i=e[s]);s++)try{t(i).triggerHandler("remove")}catch(o){}n(e)},t.widget=function(i,s,n){var o,a,r,h,l={},c=i.split(".")[0];i=i.split(".")[1],o=c+"-"+i,n||(n=s,s=t.Widget),t.expr[":"][o.toLowerCase()]=function(e){return!!t.data(e,o)},t[c]=t[c]||{},a=t[c][i],r=t[c][i]=function(t,i){return this._createWidget?(arguments.length&&this._createWidget(t,i),e):new r(t,i)},t.extend(r,a,{version:n.version,_proto:t.extend({},n),_childConstructors:[]}),h=new s,h.options=t.widget.extend({},h.options),t.each(n,function(i,n){return t.isFunction(n)?(l[i]=function(){var t=function(){return s.prototype[i].apply(this,arguments)},e=function(t){return s.prototype[i].apply(this,t)};return function(){var i,s=this._super,o=this._superApply;return this._super=t,this._superApply=e,i=n.apply(this,arguments),this._super=s,this._superApply=o,i}}(),e):(l[i]=n,e)}),r.prototype=t.widget.extend(h,{widgetEventPrefix:a?h.widgetEventPrefix:i},l,{constructor:r,namespace:c,widgetName:i,widgetFullName:o}),a?(t.each(a._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,r,i._proto)}),delete a._childConstructors):s._childConstructors.push(r),t.widget.bridge(i,r)},t.widget.extend=function(i){for(var n,o,a=s.call(arguments,1),r=0,h=a.length;h>r;r++)for(n in a[r])o=a[r][n],a[r].hasOwnProperty(n)&&o!==e&&(i[n]=t.isPlainObject(o)?t.isPlainObject(i[n])?t.widget.extend({},i[n],o):t.widget.extend({},o):o);return i},t.widget.bridge=function(i,n){var o=n.prototype.widgetFullName||i;t.fn[i]=function(a){var r="string"==typeof a,h=s.call(arguments,1),l=this;return a=!r&&h.length?t.widget.extend.apply(null,[a].concat(h)):a,r?this.each(function(){var s,n=t.data(this,o);return n?t.isFunction(n[a])&&"_"!==a.charAt(0)?(s=n[a].apply(n,h),s!==n&&s!==e?(l=s&&s.jquery?l.pushStack(s.get()):s,!1):e):t.error("no such method '"+a+"' for "+i+" widget instance"):t.error("cannot call methods on "+i+" prior to initialization; "+"attempted to call method '"+a+"'")}):this.each(function(){var e=t.data(this,o);e?e.option(a||{})._init():t.data(this,o,new n(a,this))}),l}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this.bindings=t(),this.hoverable=t(),this.focusable=t(),s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:t.noop,_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(t.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:t.noop,widget:function(){return this.element},option:function(i,s){var n,o,a,r=i;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof i)if(r={},n=i.split("."),i=n.shift(),n.length){for(o=r[i]=t.widget.extend({},this.options[i]),a=0;n.length-1>a;a++)o[n[a]]=o[n[a]]||{},o=o[n[a]];if(i=n.pop(),s===e)return o[i]===e?null:o[i];o[i]=s}else{if(s===e)return this.options[i]===e?null:this.options[i];r[i]=s}return this._setOptions(r),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return this.options[t]=e,"disabled"===t&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!e).attr("aria-disabled",e),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(i,s,n){var o,a=this;"boolean"!=typeof i&&(n=s,s=i,i=!1),n?(s=o=t(s),this.bindings=this.bindings.add(s)):(n=s,s=this.element,o=this.widget()),t.each(n,function(n,r){function h(){return i||a.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof r?a[r]:r).apply(a,arguments):e}"string"!=typeof r&&(h.guid=r.guid=r.guid||h.guid||t.guid++);var l=n.match(/^(\w+)\s*(.*)$/),c=l[1]+a.eventNamespace,u=l[2];u?o.delegate(u,c,h):s.bind(c,h)})},_off:function(t,e){e=(e||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.unbind(e).undelegate(e)},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){t(e.currentTarget).addClass("ui-state-hover")},mouseleave:function(e){t(e.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){t(e.currentTarget).addClass("ui-state-focus")},focusout:function(e){t(e.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}})}(jQuery),function(t){var e=!1;t(document).mouseup(function(){e=!1}),t.widget("ui.mouse",{version:"1.10.3",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.bind("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).bind("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):undefined}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&t(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(i){if(!e){this._mouseStarted&&this._mouseUp(i),this._mouseDownEvent=i;var s=this,n=1===i.which,o="string"==typeof this.options.cancel&&i.target.nodeName?t(i.target).closest(this.options.cancel).length:!1;return n&&!o&&this._mouseCapture(i)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){s.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(i)&&this._mouseDelayMet(i)&&(this._mouseStarted=this._mouseStart(i)!==!1,!this._mouseStarted)?(i.preventDefault(),!0):(!0===t.data(i.target,this.widgetName+".preventClickEvent")&&t.removeData(i.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return s._mouseMove(t)},this._mouseUpDelegate=function(t){return s._mouseUp(t)},t(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),i.preventDefault(),e=!0,!0)):!0}},_mouseMove:function(e){return t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button?this._mouseUp(e):this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){return t(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),!1},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})}(jQuery),function(t){t.widget("ui.draggable",t.ui.mouse,{version:"1.10.3",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"!==this.options.helper||/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},_destroy:function(){this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy()},_mouseCapture:function(e){var i=this.options;return this.helper||i.disabled||t(e.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(e),this.handle?(t(i.iframeFix===!0?"iframe":i.iframeFix).each(function(){t("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>").css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(t(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(e){var i=this.options;return this.helper=this._createHelper(e),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),t.ui.ddmanager&&(t.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offsetParent=this.helper.offsetParent(),this.offsetParentCssPosition=this.offsetParent.css("position"),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},this.offset.scroll=!1,t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",e)===!1?(this._clear(),!1):(this._cacheHelperProportions(),t.ui.ddmanager&&!i.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this._mouseDrag(e,!0),t.ui.ddmanager&&t.ui.ddmanager.dragStart(this,e),!0)},_mouseDrag:function(e,i){if("fixed"===this.offsetParentCssPosition&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",e,s)===!1)return this._mouseUp({}),!1;this.position=s.position}return this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),!1},_mouseStop:function(e){var i=this,s=!1;return t.ui.ddmanager&&!this.options.dropBehaviour&&(s=t.ui.ddmanager.drop(this,e)),this.dropped&&(s=this.dropped,this.dropped=!1),"original"!==this.options.helper||t.contains(this.element[0].ownerDocument,this.element[0])?("invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||t.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?t(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",e)!==!1&&i._clear()}):this._trigger("stop",e)!==!1&&this._clear(),!1):!1},_mouseUp:function(e){return t("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),t.ui.ddmanager&&t.ui.ddmanager.dragStop(this,e),t.ui.mouse.prototype._mouseUp.call(this,e)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(e){return this.options.handle?!!t(e.target).closest(this.element.find(this.options.handle)).length:!0},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return s.parents("body").length||s.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s[0]===this.element[0]||/(fixed|absolute)/.test(s.css("position"))||s.css("position","absolute"),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.element.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;return n.containment?"window"===n.containment?(this.containment=[t(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,t(window).scrollLeft()+t(window).width()-this.helperProportions.width-this.margins.left,t(window).scrollTop()+(t(window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],undefined):"document"===n.containment?(this.containment=[0,0,t(document).width()-this.helperProportions.width-this.margins.left,(t(document).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],undefined):n.containment.constructor===Array?(this.containment=n.containment,undefined):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=t(n.containment),s=i[0],s&&(e="hidden"!==i.css("overflow"),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(e?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(e?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=i),undefined):(this.containment=null,undefined)},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent;return this.offset.scroll||(this.offset.scroll={top:n.scrollTop(),left:n.scrollLeft()}),{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():this.offset.scroll.top)*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():this.offset.scroll.left)*s}},_generatePosition:function(e){var i,s,n,o,a=this.options,r="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=e.pageX,l=e.pageY;return this.offset.scroll||(this.offset.scroll={top:r.scrollTop(),left:r.scrollLeft()}),this.originalPosition&&(this.containment&&(this.relative_container?(s=this.relative_container.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,e.pageX-this.offset.click.left<i[0]&&(h=i[0]+this.offset.click.left),e.pageY-this.offset.click.top<i[1]&&(l=i[1]+this.offset.click.top),e.pageX-this.offset.click.left>i[2]&&(h=i[2]+this.offset.click.left),e.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),a.grid&&(n=a.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/a.grid[1])*a.grid[1]:this.originalPageY,l=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-a.grid[1]:n+a.grid[1]:n,o=a.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/a.grid[0])*a.grid[0]:this.originalPageX,h=i?o-this.offset.click.left>=i[0]||o-this.offset.click.left>i[2]?o:o-this.offset.click.left>=i[0]?o-a.grid[0]:o+a.grid[0]:o)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():this.offset.scroll.left)}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(e,i,s){return s=s||this._uiHash(),t.ui.plugin.call(this,e,[i,s]),"drag"===e&&(this.positionAbs=this._convertPositionTo("absolute")),t.Widget.prototype._trigger.call(this,e,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),t.ui.plugin.add("draggable","connectToSortable",{start:function(e,i){var s=t(this).data("ui-draggable"),n=s.options,o=t.extend({},i,{item:s.element});s.sortables=[],t(n.connectToSortable).each(function(){var i=t.data(this,"ui-sortable");i&&!i.options.disabled&&(s.sortables.push({instance:i,shouldRevert:i.options.revert}),i.refreshPositions(),i._trigger("activate",e,o))})},stop:function(e,i){var s=t(this).data("ui-draggable"),n=t.extend({},i,{item:s.element});t.each(s.sortables,function(){this.instance.isOver?(this.instance.isOver=0,s.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=this.shouldRevert),this.instance._mouseStop(e),this.instance.options.helper=this.instance.options._helper,"original"===s.options.helper&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",e,n))})},drag:function(e,i){var s=t(this).data("ui-draggable"),n=this;t.each(s.sortables,function(){var o=!1,a=this;this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this.instance._intersectsWith(this.instance.containerCache)&&(o=!0,t.each(s.sortables,function(){return this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this!==a&&this.instance._intersectsWith(this.instance.containerCache)&&t.contains(a.instance.element[0],this.instance.element[0])&&(o=!1),o})),o?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=t(n).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return i.helper[0]},e.target=this.instance.currentItem[0],this.instance._mouseCapture(e,!0),this.instance._mouseStart(e,!0,!0),this.instance.offset.click.top=s.offset.click.top,this.instance.offset.click.left=s.offset.click.left,this.instance.offset.parent.left-=s.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=s.offset.parent.top-this.instance.offset.parent.top,s._trigger("toSortable",e),s.dropped=this.instance.element,s.currentItem=s.element,this.instance.fromOutside=s),this.instance.currentItem&&this.instance._mouseDrag(e)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",e,this.instance._uiHash(this.instance)),this.instance._mouseStop(e,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),s._trigger("fromSortable",e),s.dropped=!1)})}}),t.ui.plugin.add("draggable","cursor",{start:function(){var e=t("body"),i=t(this).data("ui-draggable").options;e.css("cursor")&&(i._cursor=e.css("cursor")),e.css("cursor",i.cursor)},stop:function(){var e=t(this).data("ui-draggable").options;e._cursor&&t("body").css("cursor",e._cursor)}}),t.ui.plugin.add("draggable","opacity",{start:function(e,i){var s=t(i.helper),n=t(this).data("ui-draggable").options;s.css("opacity")&&(n._opacity=s.css("opacity")),s.css("opacity",n.opacity)},stop:function(e,i){var s=t(this).data("ui-draggable").options;s._opacity&&t(i.helper).css("opacity",s._opacity)}}),t.ui.plugin.add("draggable","scroll",{start:function(){var e=t(this).data("ui-draggable");e.scrollParent[0]!==document&&"HTML"!==e.scrollParent[0].tagName&&(e.overflowOffset=e.scrollParent.offset())},drag:function(e){var i=t(this).data("ui-draggable"),s=i.options,n=!1;i.scrollParent[0]!==document&&"HTML"!==i.scrollParent[0].tagName?(s.axis&&"x"===s.axis||(i.overflowOffset.top+i.scrollParent[0].offsetHeight-e.pageY<s.scrollSensitivity?i.scrollParent[0].scrollTop=n=i.scrollParent[0].scrollTop+s.scrollSpeed:e.pageY-i.overflowOffset.top<s.scrollSensitivity&&(i.scrollParent[0].scrollTop=n=i.scrollParent[0].scrollTop-s.scrollSpeed)),s.axis&&"y"===s.axis||(i.overflowOffset.left+i.scrollParent[0].offsetWidth-e.pageX<s.scrollSensitivity?i.scrollParent[0].scrollLeft=n=i.scrollParent[0].scrollLeft+s.scrollSpeed:e.pageX-i.overflowOffset.left<s.scrollSensitivity&&(i.scrollParent[0].scrollLeft=n=i.scrollParent[0].scrollLeft-s.scrollSpeed))):(s.axis&&"x"===s.axis||(e.pageY-t(document).scrollTop()<s.scrollSensitivity?n=t(document).scrollTop(t(document).scrollTop()-s.scrollSpeed):t(window).height()-(e.pageY-t(document).scrollTop())<s.scrollSensitivity&&(n=t(document).scrollTop(t(document).scrollTop()+s.scrollSpeed))),s.axis&&"y"===s.axis||(e.pageX-t(document).scrollLeft()<s.scrollSensitivity?n=t(document).scrollLeft(t(document).scrollLeft()-s.scrollSpeed):t(window).width()-(e.pageX-t(document).scrollLeft())<s.scrollSensitivity&&(n=t(document).scrollLeft(t(document).scrollLeft()+s.scrollSpeed)))),n!==!1&&t.ui.ddmanager&&!s.dropBehaviour&&t.ui.ddmanager.prepareOffsets(i,e)}}),t.ui.plugin.add("draggable","snap",{start:function(){var e=t(this).data("ui-draggable"),i=e.options;e.snapElements=[],t(i.snap.constructor!==String?i.snap.items||":data(ui-draggable)":i.snap).each(function(){var i=t(this),s=i.offset();this!==e.element[0]&&e.snapElements.push({item:this,width:i.outerWidth(),height:i.outerHeight(),top:s.top,left:s.left})})},drag:function(e,i){var s,n,o,a,r,h,l,c,u,d,p=t(this).data("ui-draggable"),f=p.options,g=f.snapTolerance,m=i.offset.left,v=m+p.helperProportions.width,_=i.offset.top,b=_+p.helperProportions.height;for(u=p.snapElements.length-1;u>=0;u--)r=p.snapElements[u].left,h=r+p.snapElements[u].width,l=p.snapElements[u].top,c=l+p.snapElements[u].height,r-g>v||m>h+g||l-g>b||_>c+g||!t.contains(p.snapElements[u].item.ownerDocument,p.snapElements[u].item)?(p.snapElements[u].snapping&&p.options.snap.release&&p.options.snap.release.call(p.element,e,t.extend(p._uiHash(),{snapItem:p.snapElements[u].item})),p.snapElements[u].snapping=!1):("inner"!==f.snapMode&&(s=g>=Math.abs(l-b),n=g>=Math.abs(c-_),o=g>=Math.abs(r-v),a=g>=Math.abs(h-m),s&&(i.position.top=p._convertPositionTo("relative",{top:l-p.helperProportions.height,left:0}).top-p.margins.top),n&&(i.position.top=p._convertPositionTo("relative",{top:c,left:0}).top-p.margins.top),o&&(i.position.left=p._convertPositionTo("relative",{top:0,left:r-p.helperProportions.width}).left-p.margins.left),a&&(i.position.left=p._convertPositionTo("relative",{top:0,left:h}).left-p.margins.left)),d=s||n||o||a,"outer"!==f.snapMode&&(s=g>=Math.abs(l-_),n=g>=Math.abs(c-b),o=g>=Math.abs(r-m),a=g>=Math.abs(h-v),s&&(i.position.top=p._convertPositionTo("relative",{top:l,left:0}).top-p.margins.top),n&&(i.position.top=p._convertPositionTo("relative",{top:c-p.helperProportions.height,left:0}).top-p.margins.top),o&&(i.position.left=p._convertPositionTo("relative",{top:0,left:r}).left-p.margins.left),a&&(i.position.left=p._convertPositionTo("relative",{top:0,left:h-p.helperProportions.width}).left-p.margins.left)),!p.snapElements[u].snapping&&(s||n||o||a||d)&&p.options.snap.snap&&p.options.snap.snap.call(p.element,e,t.extend(p._uiHash(),{snapItem:p.snapElements[u].item})),p.snapElements[u].snapping=s||n||o||a||d)}}),t.ui.plugin.add("draggable","stack",{start:function(){var e,i=this.data("ui-draggable").options,s=t.makeArray(t(i.stack)).sort(function(e,i){return(parseInt(t(e).css("zIndex"),10)||0)-(parseInt(t(i).css("zIndex"),10)||0)});s.length&&(e=parseInt(t(s[0]).css("zIndex"),10)||0,t(s).each(function(i){t(this).css("zIndex",e+i)}),this.css("zIndex",e+s.length))}}),t.ui.plugin.add("draggable","zIndex",{start:function(e,i){var s=t(i.helper),n=t(this).data("ui-draggable").options;s.css("zIndex")&&(n._zIndex=s.css("zIndex")),s.css("zIndex",n.zIndex)},stop:function(e,i){var s=t(this).data("ui-draggable").options;s._zIndex&&t(i.helper).css("zIndex",s._zIndex)}})}(jQuery),function(t){function e(t,e,i){return t>e&&e+i>t}t.widget("ui.droppable",{version:"1.10.3",widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var e=this.options,i=e.accept;this.isover=!1,this.isout=!0,this.accept=t.isFunction(i)?i:function(t){return t.is(i)
+},this.proportions={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight},t.ui.ddmanager.droppables[e.scope]=t.ui.ddmanager.droppables[e.scope]||[],t.ui.ddmanager.droppables[e.scope].push(this),e.addClasses&&this.element.addClass("ui-droppable")},_destroy:function(){for(var e=0,i=t.ui.ddmanager.droppables[this.options.scope];i.length>e;e++)i[e]===this&&i.splice(e,1);this.element.removeClass("ui-droppable ui-droppable-disabled")},_setOption:function(e,i){"accept"===e&&(this.accept=t.isFunction(i)?i:function(t){return t.is(i)}),t.Widget.prototype._setOption.apply(this,arguments)},_activate:function(e){var i=t.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),i&&this._trigger("activate",e,this.ui(i))},_deactivate:function(e){var i=t.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),i&&this._trigger("deactivate",e,this.ui(i))},_over:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",e,this.ui(i)))},_out:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",e,this.ui(i)))},_drop:function(e,i){var s=i||t.ui.ddmanager.current,n=!1;return s&&(s.currentItem||s.element)[0]!==this.element[0]?(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var e=t.data(this,"ui-droppable");return e.options.greedy&&!e.options.disabled&&e.options.scope===s.options.scope&&e.accept.call(e.element[0],s.currentItem||s.element)&&t.ui.intersect(s,t.extend(e,{offset:e.element.offset()}),e.options.tolerance)?(n=!0,!1):undefined}),n?!1:this.accept.call(this.element[0],s.currentItem||s.element)?(this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",e,this.ui(s)),this.element):!1):!1},ui:function(t){return{draggable:t.currentItem||t.element,helper:t.helper,position:t.position,offset:t.positionAbs}}}),t.ui.intersect=function(t,i,s){if(!i.offset)return!1;var n,o,a=(t.positionAbs||t.position.absolute).left,r=a+t.helperProportions.width,h=(t.positionAbs||t.position.absolute).top,l=h+t.helperProportions.height,c=i.offset.left,u=c+i.proportions.width,d=i.offset.top,p=d+i.proportions.height;switch(s){case"fit":return a>=c&&u>=r&&h>=d&&p>=l;case"intersect":return a+t.helperProportions.width/2>c&&u>r-t.helperProportions.width/2&&h+t.helperProportions.height/2>d&&p>l-t.helperProportions.height/2;case"pointer":return n=(t.positionAbs||t.position.absolute).left+(t.clickOffset||t.offset.click).left,o=(t.positionAbs||t.position.absolute).top+(t.clickOffset||t.offset.click).top,e(o,d,i.proportions.height)&&e(n,c,i.proportions.width);case"touch":return(h>=d&&p>=h||l>=d&&p>=l||d>h&&l>p)&&(a>=c&&u>=a||r>=c&&u>=r||c>a&&r>u);default:return!1}},t.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(e,i){var s,n,o=t.ui.ddmanager.droppables[e.options.scope]||[],a=i?i.type:null,r=(e.currentItem||e.element).find(":data(ui-droppable)").addBack();t:for(s=0;o.length>s;s++)if(!(o[s].options.disabled||e&&!o[s].accept.call(o[s].element[0],e.currentItem||e.element))){for(n=0;r.length>n;n++)if(r[n]===o[s].element[0]){o[s].proportions.height=0;continue t}o[s].visible="none"!==o[s].element.css("display"),o[s].visible&&("mousedown"===a&&o[s]._activate.call(o[s],i),o[s].offset=o[s].element.offset(),o[s].proportions={width:o[s].element[0].offsetWidth,height:o[s].element[0].offsetHeight})}},drop:function(e,i){var s=!1;return t.each((t.ui.ddmanager.droppables[e.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&t.ui.intersect(e,this,this.options.tolerance)&&(s=this._drop.call(this,i)||s),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],e.currentItem||e.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,i)))}),s},dragStart:function(e,i){e.element.parentsUntil("body").bind("scroll.droppable",function(){e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)})},drag:function(e,i){e.options.refreshPositions&&t.ui.ddmanager.prepareOffsets(e,i),t.each(t.ui.ddmanager.droppables[e.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var s,n,o,a=t.ui.intersect(e,this,this.options.tolerance),r=!a&&this.isover?"isout":a&&!this.isover?"isover":null;r&&(this.options.greedy&&(n=this.options.scope,o=this.element.parents(":data(ui-droppable)").filter(function(){return t.data(this,"ui-droppable").options.scope===n}),o.length&&(s=t.data(o[0],"ui-droppable"),s.greedyChild="isover"===r)),s&&"isover"===r&&(s.isover=!1,s.isout=!0,s._out.call(s,i)),this[r]=!0,this["isout"===r?"isover":"isout"]=!1,this["isover"===r?"_over":"_out"].call(this,i),s&&"isout"===r&&(s.isout=!1,s.isover=!0,s._over.call(s,i)))}})},dragStop:function(e,i){e.element.parentsUntil("body").unbind("scroll.droppable"),e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)}}}(jQuery),function(t){function e(t){return parseInt(t,10)||0}function i(t){return!isNaN(parseInt(t,10))}t.widget("ui.resizable",t.ui.mouse,{version:"1.10.3",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_create:function(){var e,i,s,n,o,a=this,r=this.options;if(this.element.addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!r.aspectRatio,aspectRatio:r.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:r.helper||r.ghost||r.animate?r.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(t("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.data("ui-resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=r.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),e=this.handles.split(","),this.handles={},i=0;e.length>i;i++)s=t.trim(e[i]),o="ui-resizable-"+s,n=t("<div class='ui-resizable-handle "+o+"'></div>"),n.css({zIndex:r.zIndex}),"se"===s&&n.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(n);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String&&(this.handles[i]=t(this.handles[i],this.element).show()),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),t(this.handles[i]).length},this._renderAxis(this.element),this._handles=t(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){a.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),a.axis=n&&n[1]?n[1]:"se")}),r.autoHide&&(this._handles.hide(),t(this.element).addClass("ui-resizable-autohide").mouseenter(function(){r.disabled||(t(this).removeClass("ui-resizable-autohide"),a._handles.show())}).mouseleave(function(){r.disabled||a.resizing||(t(this).addClass("ui-resizable-autohide"),a._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(i){var s,n,o,a=this.options,r=this.element.position(),h=this.element;return this.resizing=!0,/absolute/.test(h.css("position"))?h.css({position:"absolute",top:h.css("top"),left:h.css("left")}):h.is(".ui-draggable")&&h.css({position:"absolute",top:r.top,left:r.left}),this._renderProxy(),s=e(this.helper.css("left")),n=e(this.helper.css("top")),a.containment&&(s+=t(a.containment).scrollLeft()||0,n+=t(a.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:s,top:n},this.size=this._helper?{width:h.outerWidth(),height:h.outerHeight()}:{width:h.width(),height:h.height()},this.originalSize=this._helper?{width:h.outerWidth(),height:h.outerHeight()}:{width:h.width(),height:h.height()},this.originalPosition={left:s,top:n},this.sizeDiff={width:h.outerWidth()-h.width(),height:h.outerHeight()-h.height()},this.originalMousePosition={left:i.pageX,top:i.pageY},this.aspectRatio="number"==typeof a.aspectRatio?a.aspectRatio:this.originalSize.width/this.originalSize.height||1,o=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===o?this.axis+"-resize":o),h.addClass("ui-resizable-resizing"),this._propagate("start",i),!0},_mouseDrag:function(e){var i,s=this.helper,n={},o=this.originalMousePosition,a=this.axis,r=this.position.top,h=this.position.left,l=this.size.width,c=this.size.height,u=e.pageX-o.left||0,d=e.pageY-o.top||0,p=this._change[a];return p?(i=p.apply(this,[e,u,d]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),this.position.top!==r&&(n.top=this.position.top+"px"),this.position.left!==h&&(n.left=this.position.left+"px"),this.size.width!==l&&(n.width=this.size.width+"px"),this.size.height!==c&&(n.height=this.size.height+"px"),s.css(n),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(n)||this._trigger("resize",e,this.ui()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&t.ui.hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null,h=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(t){var e,s,n,o,a,r=this.options;a={minWidth:i(r.minWidth)?r.minWidth:0,maxWidth:i(r.maxWidth)?r.maxWidth:1/0,minHeight:i(r.minHeight)?r.minHeight:0,maxHeight:i(r.maxHeight)?r.maxHeight:1/0},(this._aspectRatio||t)&&(e=a.minHeight*this.aspectRatio,n=a.minWidth/this.aspectRatio,s=a.maxHeight*this.aspectRatio,o=a.maxWidth/this.aspectRatio,e>a.minWidth&&(a.minWidth=e),n>a.minHeight&&(a.minHeight=n),a.maxWidth>s&&(a.maxWidth=s),a.maxHeight>o&&(a.maxHeight=o)),this._vBoundaries=a},_updateCache:function(t){this.offset=this.helper.offset(),i(t.left)&&(this.position.left=t.left),i(t.top)&&(this.position.top=t.top),i(t.height)&&(this.size.height=t.height),i(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,s=this.size,n=this.axis;return i(t.height)?t.width=t.height*this.aspectRatio:i(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===n&&(t.left=e.left+(s.width-t.width),t.top=null),"nw"===n&&(t.top=e.top+(s.height-t.height),t.left=e.left+(s.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,s=this.axis,n=i(t.width)&&e.maxWidth&&e.maxWidth<t.width,o=i(t.height)&&e.maxHeight&&e.maxHeight<t.height,a=i(t.width)&&e.minWidth&&e.minWidth>t.width,r=i(t.height)&&e.minHeight&&e.minHeight>t.height,h=this.originalPosition.left+this.originalSize.width,l=this.position.top+this.size.height,c=/sw|nw|w/.test(s),u=/nw|ne|n/.test(s);return a&&(t.width=e.minWidth),r&&(t.height=e.minHeight),n&&(t.width=e.maxWidth),o&&(t.height=e.maxHeight),a&&c&&(t.left=h-e.minWidth),n&&c&&(t.left=h-e.maxWidth),r&&u&&(t.top=l-e.minHeight),o&&u&&(t.top=l-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_proportionallyResize:function(){if(this._proportionallyResizeElements.length){var t,e,i,s,n,o=this.helper||this.element;for(t=0;this._proportionallyResizeElements.length>t;t++){if(n=this._proportionallyResizeElements[t],!this.borderDif)for(this.borderDif=[],i=[n.css("borderTopWidth"),n.css("borderRightWidth"),n.css("borderBottomWidth"),n.css("borderLeftWidth")],s=[n.css("paddingTop"),n.css("paddingRight"),n.css("paddingBottom"),n.css("paddingLeft")],e=0;i.length>e;e++)this.borderDif[e]=(parseInt(i[e],10)||0)+(parseInt(s[e],10)||0);n.css({height:o.height()-this.borderDif[0]-this.borderDif[2]||0,width:o.width()-this.borderDif[1]-this.borderDif[3]||0})}}},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("<div style='overflow:hidden;'></div>"),this.helper.addClass(this._helper).css({width:this.element.outerWidth()-1,height:this.element.outerHeight()-1,position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).data("ui-resizable"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&t.ui.hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseInt(i.element.css("left"),10)+(i.position.left-i.originalPosition.left)||null,c=parseInt(i.element.css("top"),10)+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseInt(i.element.css("width"),10),height:parseInt(i.element.css("height"),10),top:parseInt(i.element.css("top"),10),left:parseInt(i.element.css("left"),10)};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var i,s,n,o,a,r,h,l=t(this).data("ui-resizable"),c=l.options,u=l.element,d=c.containment,p=d instanceof t?d.get(0):/parent/.test(d)?u.parent().get(0):d;p&&(l.containerElement=t(p),/document/.test(d)||d===document?(l.containerOffset={left:0,top:0},l.containerPosition={left:0,top:0},l.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(i=t(p),s=[],t(["Top","Right","Left","Bottom"]).each(function(t,n){s[t]=e(i.css("padding"+n))}),l.containerOffset=i.offset(),l.containerPosition=i.position(),l.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},n=l.containerOffset,o=l.containerSize.height,a=l.containerSize.width,r=t.ui.hasScroll(p,"left")?p.scrollWidth:a,h=t.ui.hasScroll(p)?p.scrollHeight:o,l.parentData={element:p,left:n.left,top:n.top,width:r,height:h}))},resize:function(e){var i,s,n,o,a=t(this).data("ui-resizable"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio),a.position.top=a._helper?h.top:0),a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top,i=Math.abs((a._helper?a.offset.left-u.left:a.offset.left-u.left)+a.sizeDiff.width),s=Math.abs((a._helper?a.offset.top-u.top:a.offset.top-h.top)+a.sizeDiff.height),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o&&(i-=a.parentData.left),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio))},stop:function(){var e=t(this).data("ui-resizable"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).data("ui-resizable"),i=e.options,s=function(e){t(e).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseInt(e.width(),10),height:parseInt(e.height(),10),left:parseInt(e.css("left"),10),top:parseInt(e.css("top"),10)})})};"object"!=typeof i.alsoResize||i.alsoResize.parentNode?s(i.alsoResize):i.alsoResize.length?(i.alsoResize=i.alsoResize[0],s(i.alsoResize)):t.each(i.alsoResize,function(t){s(t)})},resize:function(e,i){var s=t(this).data("ui-resizable"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0},h=function(e,s){t(e).each(function(){var e=t(this),n=t(this).data("ui-resizable-alsoresize"),o={},a=s&&s.length?s:e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(a,function(t,e){var i=(n[e]||0)+(r[e]||0);i&&i>=0&&(o[e]=i||null)}),e.css(o)})};"object"!=typeof n.alsoResize||n.alsoResize.nodeType?h(n.alsoResize):t.each(n.alsoResize,function(t,e){h(t,e)})},stop:function(){t(this).removeData("resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).data("ui-resizable"),i=e.options,s=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof i.ghost?i.ghost:""),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).data("ui-resizable");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).data("ui-resizable");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e=t(this).data("ui-resizable"),i=e.options,s=e.size,n=e.originalSize,o=e.originalPosition,a=e.axis,r="number"==typeof i.grid?[i.grid,i.grid]:i.grid,h=r[0]||1,l=r[1]||1,c=Math.round((s.width-n.width)/h)*h,u=Math.round((s.height-n.height)/l)*l,d=n.width+c,p=n.height+u,f=i.maxWidth&&d>i.maxWidth,g=i.maxHeight&&p>i.maxHeight,m=i.minWidth&&i.minWidth>d,v=i.minHeight&&i.minHeight>p;i.grid=r,m&&(d+=h),v&&(p+=l),f&&(d-=h),g&&(p-=l),/^(se|s|e)$/.test(a)?(e.size.width=d,e.size.height=p):/^(ne)$/.test(a)?(e.size.width=d,e.size.height=p,e.position.top=o.top-u):/^(sw)$/.test(a)?(e.size.width=d,e.size.height=p,e.position.left=o.left-c):(e.size.width=d,e.size.height=p,e.position.top=o.top-u,e.position.left=o.left-c)}})}(jQuery),function(t){t.widget("ui.selectable",t.ui.mouse,{version:"1.10.3",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var e,i=this;this.element.addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){e=t(i.options.filter,i.element[0]),e.addClass("ui-selectee"),e.each(function(){var e=t(this),i=e.offset();t.data(this,"selectable-item",{element:this,$element:e,left:i.left,top:i.top,right:i.left+e.outerWidth(),bottom:i.top+e.outerHeight(),startselected:!1,selected:e.hasClass("ui-selected"),selecting:e.hasClass("ui-selecting"),unselecting:e.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=e.addClass("ui-selectee"),this._mouseInit(),this.helper=t("<div class='ui-selectable-helper'></div>")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(e){var i=this,s=this.options;this.opos=[e.pageX,e.pageY],this.options.disabled||(this.selectees=t(s.filter,this.element[0]),this._trigger("start",e),t(s.appendTo).append(this.helper),this.helper.css({left:e.pageX,top:e.pageY,width:0,height:0}),s.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var s=t.data(this,"selectable-item");s.startselected=!0,e.metaKey||e.ctrlKey||(s.$element.removeClass("ui-selected"),s.selected=!1,s.$element.addClass("ui-unselecting"),s.unselecting=!0,i._trigger("unselecting",e,{unselecting:s.element}))}),t(e.target).parents().addBack().each(function(){var s,n=t.data(this,"selectable-item");return n?(s=!e.metaKey&&!e.ctrlKey||!n.$element.hasClass("ui-selected"),n.$element.removeClass(s?"ui-unselecting":"ui-selected").addClass(s?"ui-selecting":"ui-unselecting"),n.unselecting=!s,n.selecting=s,n.selected=s,s?i._trigger("selecting",e,{selecting:n.element}):i._trigger("unselecting",e,{unselecting:n.element}),!1):undefined}))},_mouseDrag:function(e){if(this.dragged=!0,!this.options.disabled){var i,s=this,n=this.options,o=this.opos[0],a=this.opos[1],r=e.pageX,h=e.pageY;return o>r&&(i=r,r=o,o=i),a>h&&(i=h,h=a,a=i),this.helper.css({left:o,top:a,width:r-o,height:h-a}),this.selectees.each(function(){var i=t.data(this,"selectable-item"),l=!1;i&&i.element!==s.element[0]&&("touch"===n.tolerance?l=!(i.left>r||o>i.right||i.top>h||a>i.bottom):"fit"===n.tolerance&&(l=i.left>o&&r>i.right&&i.top>a&&h>i.bottom),l?(i.selected&&(i.$element.removeClass("ui-selected"),i.selected=!1),i.unselecting&&(i.$element.removeClass("ui-unselecting"),i.unselecting=!1),i.selecting||(i.$element.addClass("ui-selecting"),i.selecting=!0,s._trigger("selecting",e,{selecting:i.element}))):(i.selecting&&((e.metaKey||e.ctrlKey)&&i.startselected?(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.$element.addClass("ui-selected"),i.selected=!0):(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.startselected&&(i.$element.addClass("ui-unselecting"),i.unselecting=!0),s._trigger("unselecting",e,{unselecting:i.element}))),i.selected&&(e.metaKey||e.ctrlKey||i.startselected||(i.$element.removeClass("ui-selected"),i.selected=!1,i.$element.addClass("ui-unselecting"),i.unselecting=!0,s._trigger("unselecting",e,{unselecting:i.element})))))}),!1}},_mouseStop:function(e){var i=this;return this.dragged=!1,t(".ui-unselecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");s.$element.removeClass("ui-unselecting"),s.unselecting=!1,s.startselected=!1,i._trigger("unselected",e,{unselected:s.element})}),t(".ui-selecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");s.$element.removeClass("ui-selecting").addClass("ui-selected"),s.selecting=!1,s.selected=!0,s.startselected=!0,i._trigger("selected",e,{selected:s.element})}),this._trigger("stop",e),this.helper.remove(),!1}})}(jQuery),function(t){function e(t,e,i){return t>e&&e+i>t}function i(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))}t.widget("ui.sortable",t.ui.mouse,{version:"1.10.3",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_create:function(){var t=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?"x"===t.axis||i(this.items[0].item):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var t=this.items.length-1;t>=0;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_setOption:function(e,i){"disabled"===e?(this.options[e]=i,this.widget().toggleClass("ui-sortable-disabled",!!i)):t.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(e,i){var s=null,n=!1,o=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(e),t(e.target).parents().each(function(){return t.data(this,o.widgetName+"-item")===o?(s=t(this),!1):undefined}),t.data(e.target,o.widgetName+"-item")===o&&(s=t(e.target)),s?!this.options.handle||i||(t(this.options.handle,s).find("*").addBack().each(function(){this===e.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(e,i,s){var n,o,a=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(e),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,a.cursorAt&&this._adjustOffsetFromHelper(a.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),a.containment&&this._setContainment(),a.cursor&&"auto"!==a.cursor&&(o=this.document.find("body"),this.storedCursor=o.css("cursor"),o.css("cursor",a.cursor),this.storedStylesheet=t("<style>*{ cursor: "+a.cursor+" !important; }</style>").appendTo(o)),a.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",a.opacity)),a.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",a.zIndex)),this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,n,o,a=this.options,r=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY<a.scrollSensitivity?this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop+a.scrollSpeed:e.pageY-this.overflowOffset.top<a.scrollSensitivity&&(this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop-a.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-e.pageX<a.scrollSensitivity?this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft+a.scrollSpeed:e.pageX-this.overflowOffset.left<a.scrollSensitivity&&(this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft-a.scrollSpeed)):(e.pageY-t(document).scrollTop()<a.scrollSensitivity?r=t(document).scrollTop(t(document).scrollTop()-a.scrollSpeed):t(window).height()-(e.pageY-t(document).scrollTop())<a.scrollSensitivity&&(r=t(document).scrollTop(t(document).scrollTop()+a.scrollSpeed)),e.pageX-t(document).scrollLeft()<a.scrollSensitivity?r=t(document).scrollLeft(t(document).scrollLeft()-a.scrollSpeed):t(window).width()-(e.pageX-t(document).scrollLeft())<a.scrollSensitivity&&(r=t(document).scrollLeft(t(document).scrollLeft()+a.scrollSpeed))),r!==!1&&t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e)),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),i=this.items.length-1;i>=0;i--)if(s=this.items[i],n=s.item[0],o=this._intersectsWithPointer(s),o&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===o?"next":"prev"]()[0]!==n&&!t.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!t.contains(this.element[0],n):!0)){if(this.direction=1===o?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;
+this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,n=this.placeholder.offset(),o=this.options.axis,a={};o&&"x"!==o||(a.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollLeft)),o&&"y"!==o||(a.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(a,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,o=t.left,a=o+t.width,r=t.top,h=r+t.height,l=this.offset.click.top,c=this.offset.click.left,u="x"===this.options.axis||s+l>r&&h>s+l,d="y"===this.options.axis||e+c>o&&a>e+c,p=u&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?p:e+this.helperProportions.width/2>o&&a>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(t){var i="x"===this.options.axis||e(this.positionAbs.top+this.offset.click.top,t.top,t.height),s="y"===this.options.axis||e(this.positionAbs.left+this.offset.click.left,t.left,t.width),n=i&&s,o=this._getDragVerticalDirection(),a=this._getDragHorizontalDirection();return n?this.floating?a&&"right"===a||"down"===o?2:1:o&&("down"===o?2:1):!1},_intersectsWithSides:function(t){var i=e(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),s=e(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),n=this._getDragVerticalDirection(),o=this._getDragHorizontalDirection();return this.floating&&o?"right"===o&&s||"left"===o&&!s:n&&("down"===n&&i||"up"===n&&!i)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){var i,s,n,o,a=[],r=[],h=this._connectWith();if(h&&e)for(i=h.length-1;i>=0;i--)for(n=t(h[i]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&r.push([t.isFunction(o.options.items)?o.options.items.call(o.element):t(o.options.items,o.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),o]);for(r.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),i=r.length-1;i>=0;i--)r[i][0].each(function(){a.push(this)});return t(a)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;e.length>i;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,n,o,a,r,h,l,c=this.items,u=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=t(d[i]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&(u.push([t.isFunction(o.options.items)?o.options.items.call(o.element[0],e,{item:this.currentItem}):t(o.options.items,o.element),o]),this.containers.push(o));for(i=u.length-1;i>=0;i--)for(a=u[i][1],r=u[i][0],s=0,l=r.length;l>s;s++)h=t(r[s]),h.data(this.widgetName+"-item",a),c.push({item:h,instance:a,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,o;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=n.outerWidth(),s.height=n.outerHeight()),o=n.offset(),s.left=o.left,s.top=o.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)o=this.containers[i].element.offset(),this.containers[i].containerCache.left=o.left,this.containers[i].containerCache.top=o.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),n=t("<"+s+">",e.document[0]).addClass(i||e.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper");return"tr"===s?e.currentItem.children().each(function(){t("<td>&#160;</td>",e.document[0]).attr("colspan",t(this).attr("colspan")||1).appendTo(n)}):"img"===s&&n.attr("src",e.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(t,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_contactContainers:function(s){var n,o,a,r,h,l,c,u,d,p,f=null,g=null;for(n=this.containers.length-1;n>=0;n--)if(!t.contains(this.currentItem[0],this.containers[n].element[0]))if(this._intersectsWith(this.containers[n].containerCache)){if(f&&t.contains(this.containers[n].element[0],f.element[0]))continue;f=this.containers[n],g=n}else this.containers[n].containerCache.over&&(this.containers[n]._trigger("out",s,this._uiHash(this)),this.containers[n].containerCache.over=0);if(f)if(1===this.containers.length)this.containers[g].containerCache.over||(this.containers[g]._trigger("over",s,this._uiHash(this)),this.containers[g].containerCache.over=1);else{for(a=1e4,r=null,p=f.floating||i(this.currentItem),h=p?"left":"top",l=p?"width":"height",c=this.positionAbs[h]+this.offset.click[h],o=this.items.length-1;o>=0;o--)t.contains(this.containers[g].element[0],this.items[o].item[0])&&this.items[o].item[0]!==this.currentItem[0]&&(!p||e(this.positionAbs.top+this.offset.click.top,this.items[o].top,this.items[o].height))&&(u=this.items[o].item.offset()[h],d=!1,Math.abs(u-c)>Math.abs(u+this.items[o][l]-c)&&(d=!0,u+=this.items[o][l]),a>Math.abs(u-c)&&(a=Math.abs(u-c),r=this.items[o],this.direction=d?"up":"down"));if(!r&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[g])return;r?this._rearrange(s,r,null,!0):this._rearrange(s,null,this.containers[g].element,!0),this._trigger("change",s,this._uiHash()),this.containers[g]._trigger("change",s,this._uiHash(this)),this.currentContainer=this.containers[g],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[g]._trigger("over",s,this._uiHash(this)),this.containers[g].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,t("document"===n.containment?document:window).width()-this.helperProportions.width-this.margins.left,(t("document"===n.containment?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(e=t(n.containment)[0],i=t(n.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())*s}},_generatePosition:function(e){var i,s,n=this.options,o=e.pageX,a=e.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==document&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.left<this.containment[0]&&(o=this.containment[0]+this.offset.click.left),e.pageY-this.offset.click.top<this.containment[1]&&(a=this.containment[1]+this.offset.click.top),e.pageX-this.offset.click.left>this.containment[2]&&(o=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(a=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((a-this.originalPageY)/n.grid[1])*n.grid[1],a=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((o-this.originalPageX)/n.grid[0])*n.grid[0],o=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:a-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){this.reverting=!1;var i,s=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(i in this._storedCSS)("auto"===this._storedCSS[i]||"static"===this._storedCSS[i])&&(this._storedCSS[i]="");this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&s.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||s.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(s.push(function(t){this._trigger("remove",t,this._uiHash())}),s.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),s.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),i=this.containers.length-1;i>=0;i--)e||s.push(function(t){return function(e){t._trigger("deactivate",e,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over&&(s.push(function(t){return function(e){t._trigger("out",e,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,this.cancelHelperRemoval){if(!e){for(this._trigger("beforeStop",t,this._uiHash()),i=0;s.length>i;i++)s[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!1}if(e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null,!e){for(i=0;s.length>i;i++)s[i].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!0},_trigger:function(){t.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}})}(jQuery),function(t,e){var i="ui-effects-";t.effects={effect:{}},function(t,e){function i(t,e,i){var s=u[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:0>t?0:t>s.max?s.max:t)}function s(i){var s=l(),n=s._rgba=[];return i=i.toLowerCase(),f(h,function(t,o){var a,r=o.re.exec(i),h=r&&o.parse(r),l=o.space||"rgba";return h?(a=s[l](h),s[c[l].cache]=a[c[l].cache],n=s._rgba=a._rgba,!1):e}),n.length?("0,0,0,0"===n.join()&&t.extend(n,o.transparent),s):o[i]}function n(t,e,i){return i=(i+1)%1,1>6*i?t+6*(e-t)*i:1>2*i?e:2>3*i?t+6*(e-t)*(2/3-i):t}var o,a="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",r=/^([\-+])=\s*(\d+\.?\d*)/,h=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],l=t.Color=function(e,i,s,n){return new t.Color.fn.parse(e,i,s,n)},c={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},u={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},d=l.support={},p=t("<p>")[0],f=t.each;p.style.cssText="background-color:rgba(1,1,1,.5)",d.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(c,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),l.fn=t.extend(l.prototype,{parse:function(n,a,r,h){if(n===e)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=t(n).css(a),a=e);var u=this,d=t.type(n),p=this._rgba=[];return a!==e&&(n=[n,a,r,h],d="array"),"string"===d?this.parse(s(n)||o._default):"array"===d?(f(c.rgba.props,function(t,e){p[e.idx]=i(n[e.idx],e)}),this):"object"===d?(n instanceof l?f(c,function(t,e){n[e.cache]&&(u[e.cache]=n[e.cache].slice())}):f(c,function(e,s){var o=s.cache;f(s.props,function(t,e){if(!u[o]&&s.to){if("alpha"===t||null==n[t])return;u[o]=s.to(u._rgba)}u[o][e.idx]=i(n[t],e,!0)}),u[o]&&0>t.inArray(null,u[o].slice(0,3))&&(u[o][3]=1,s.from&&(u._rgba=s.from(u[o])))}),this):e},is:function(t){var i=l(t),s=!0,n=this;return f(c,function(t,o){var a,r=i[o.cache];return r&&(a=n[o.cache]||o.to&&o.to(n._rgba)||[],f(o.props,function(t,i){return null!=r[i.idx]?s=r[i.idx]===a[i.idx]:e})),s}),s},_space:function(){var t=[],e=this;return f(c,function(i,s){e[s.cache]&&t.push(i)}),t.pop()},transition:function(t,e){var s=l(t),n=s._space(),o=c[n],a=0===this.alpha()?l("transparent"):this,r=a[o.cache]||o.to(a._rgba),h=r.slice();return s=s[o.cache],f(o.props,function(t,n){var o=n.idx,a=r[o],l=s[o],c=u[n.type]||{};null!==l&&(null===a?h[o]=l:(c.mod&&(l-a>c.mod/2?a+=c.mod:a-l>c.mod/2&&(a-=c.mod)),h[o]=i((l-a)*e+a,n)))}),this[n](h)},blend:function(e){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),n=l(e)._rgba;return l(t.map(i,function(t,e){return(1-s)*n[e]+s*t}))},toRgbaString:function(){var e="rgba(",i=t.map(this._rgba,function(t,e){return null==t?e>2?1:0:t});return 1===i[3]&&(i.pop(),e="rgb("),e+i.join()+")"},toHslaString:function(){var e="hsla(",i=t.map(this.hsla(),function(t,e){return null==t&&(t=e>2?1:0),e&&3>e&&(t=Math.round(100*t)+"%"),t});return 1===i[3]&&(i.pop(),e="hsl("),e+i.join()+")"},toHexString:function(e){var i=this._rgba.slice(),s=i.pop();return e&&i.push(~~(255*s)),"#"+t.map(i,function(t){return t=(t||0).toString(16),1===t.length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),l.fn.parse.prototype=l.fn,c.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e,i,s=t[0]/255,n=t[1]/255,o=t[2]/255,a=t[3],r=Math.max(s,n,o),h=Math.min(s,n,o),l=r-h,c=r+h,u=.5*c;return e=h===r?0:s===r?60*(n-o)/l+360:n===r?60*(o-s)/l+120:60*(s-n)/l+240,i=0===l?0:.5>=u?l/c:l/(2-c),[Math.round(e)%360,i,u,null==a?1:a]},c.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],o=t[3],a=.5>=s?s*(1+i):s+i-s*i,r=2*s-a;return[Math.round(255*n(r,a,e+1/3)),Math.round(255*n(r,a,e)),Math.round(255*n(r,a,e-1/3)),o]},f(c,function(s,n){var o=n.props,a=n.cache,h=n.to,c=n.from;l.fn[s]=function(s){if(h&&!this[a]&&(this[a]=h(this._rgba)),s===e)return this[a].slice();var n,r=t.type(s),u="array"===r||"object"===r?s:arguments,d=this[a].slice();return f(o,function(t,e){var s=u["object"===r?t:e.idx];null==s&&(s=d[e.idx]),d[e.idx]=i(s,e)}),c?(n=l(c(d)),n[a]=d,n):l(d)},f(o,function(e,i){l.fn[e]||(l.fn[e]=function(n){var o,a=t.type(n),h="alpha"===e?this._hsla?"hsla":"rgba":s,l=this[h](),c=l[i.idx];return"undefined"===a?c:("function"===a&&(n=n.call(this,c),a=t.type(n)),null==n&&i.empty?this:("string"===a&&(o=r.exec(n),o&&(n=c+parseFloat(o[2])*("+"===o[1]?1:-1))),l[i.idx]=n,this[h](l)))})})}),l.hook=function(e){var i=e.split(" ");f(i,function(e,i){t.cssHooks[i]={set:function(e,n){var o,a,r="";if("transparent"!==n&&("string"!==t.type(n)||(o=s(n)))){if(n=l(o||n),!d.rgba&&1!==n._rgba[3]){for(a="backgroundColor"===i?e.parentNode:e;(""===r||"transparent"===r)&&a&&a.style;)try{r=t.css(a,"backgroundColor"),a=a.parentNode}catch(h){}n=n.blend(r&&"transparent"!==r?r:"_default")}n=n.toRgbaString()}try{e.style[i]=n}catch(h){}}},t.fx.step[i]=function(e){e.colorInit||(e.start=l(e.elem,i),e.end=l(e.end),e.colorInit=!0),t.cssHooks[i].set(e.elem,e.start.transition(e.end,e.pos))}})},l.hook(a),t.cssHooks.borderColor={expand:function(t){var e={};return f(["Top","Right","Bottom","Left"],function(i,s){e["border"+s+"Color"]=t}),e}},o=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function i(e){var i,s,n=e.ownerDocument.defaultView?e.ownerDocument.defaultView.getComputedStyle(e,null):e.currentStyle,o={};if(n&&n.length&&n[0]&&n[n[0]])for(s=n.length;s--;)i=n[s],"string"==typeof n[i]&&(o[t.camelCase(i)]=n[i]);else for(i in n)"string"==typeof n[i]&&(o[i]=n[i]);return o}function s(e,i){var s,n,a={};for(s in i)n=i[s],e[s]!==n&&(o[s]||(t.fx.step[s]||!isNaN(parseFloat(n)))&&(a[s]=n));return a}var n=["add","remove","toggle"],o={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};t.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(e,i){t.fx.step[i]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(jQuery.style(t.elem,i,t.end),t.setAttr=!0)}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.effects.animateClass=function(e,o,a,r){var h=t.speed(o,a,r);return this.queue(function(){var o,a=t(this),r=a.attr("class")||"",l=h.children?a.find("*").addBack():a;l=l.map(function(){var e=t(this);return{el:e,start:i(this)}}),o=function(){t.each(n,function(t,i){e[i]&&a[i+"Class"](e[i])})},o(),l=l.map(function(){return this.end=i(this.el[0]),this.diff=s(this.start,this.end),this}),a.attr("class",r),l=l.map(function(){var e=this,i=t.Deferred(),s=t.extend({},h,{queue:!1,complete:function(){i.resolve(e)}});return this.el.animate(this.diff,s),i.promise()}),t.when.apply(t,l.get()).done(function(){o(),t.each(arguments,function(){var e=this.el;t.each(this.diff,function(t){e.css(t,"")})}),h.complete.call(a[0])})})},t.fn.extend({addClass:function(e){return function(i,s,n,o){return s?t.effects.animateClass.call(this,{add:i},s,n,o):e.apply(this,arguments)}}(t.fn.addClass),removeClass:function(e){return function(i,s,n,o){return arguments.length>1?t.effects.animateClass.call(this,{remove:i},s,n,o):e.apply(this,arguments)}}(t.fn.removeClass),toggleClass:function(i){return function(s,n,o,a,r){return"boolean"==typeof n||n===e?o?t.effects.animateClass.call(this,n?{add:s}:{remove:s},o,a,r):i.apply(this,arguments):t.effects.animateClass.call(this,{toggle:s},n,o,a)}}(t.fn.toggleClass),switchClass:function(e,i,s,n,o){return t.effects.animateClass.call(this,{add:i,remove:e},s,n,o)}})}(),function(){function s(e,i,s,n){return t.isPlainObject(e)&&(i=e,e=e.effect),e={effect:e},null==i&&(i={}),t.isFunction(i)&&(n=i,s=null,i={}),("number"==typeof i||t.fx.speeds[i])&&(n=s,s=i,i={}),t.isFunction(s)&&(n=s,s=null),i&&t.extend(e,i),s=s||i.duration,e.duration=t.fx.off?0:"number"==typeof s?s:s in t.fx.speeds?t.fx.speeds[s]:t.fx.speeds._default,e.complete=n||i.complete,e}function n(e){return!e||"number"==typeof e||t.fx.speeds[e]?!0:"string"!=typeof e||t.effects.effect[e]?t.isFunction(e)?!0:"object"!=typeof e||e.effect?!1:!0:!0}t.extend(t.effects,{version:"1.10.3",save:function(t,e){for(var s=0;e.length>s;s++)null!==e[s]&&t.data(i+e[s],t[0].style[e[s]])},restore:function(t,s){var n,o;for(o=0;s.length>o;o++)null!==s[o]&&(n=t.data(i+s[o]),n===e&&(n=""),t.css(s[o],n))},setMode:function(t,e){return"toggle"===e&&(e=t.is(":hidden")?"show":"hide"),e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createWrapper:function(e){if(e.parent().is(".ui-effects-wrapper"))return e.parent();var i={width:e.outerWidth(!0),height:e.outerHeight(!0),"float":e.css("float")},s=t("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),n={width:e.width(),height:e.height()},o=document.activeElement;try{o.id}catch(a){o=document.body}return e.wrap(s),(e[0]===o||t.contains(e[0],o))&&t(o).focus(),s=e.parent(),"static"===e.css("position")?(s.css({position:"relative"}),e.css({position:"relative"})):(t.extend(i,{position:e.css("position"),zIndex:e.css("z-index")}),t.each(["top","left","bottom","right"],function(t,s){i[s]=e.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),e.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),e.css(n),s.css(i).show()},removeWrapper:function(e){var i=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),(e[0]===i||t.contains(e[0],i))&&t(i).focus()),e},setTransition:function(e,i,s,n){return n=n||{},t.each(i,function(t,i){var o=e.cssUnit(i);o[0]>0&&(n[i]=o[0]*s+o[1])}),n}}),t.fn.extend({effect:function(){function e(e){function s(){t.isFunction(o)&&o.call(n[0]),t.isFunction(e)&&e()}var n=t(this),o=i.complete,r=i.mode;(n.is(":hidden")?"hide"===r:"show"===r)?(n[r](),s()):a.call(n[0],i,s)}var i=s.apply(this,arguments),n=i.mode,o=i.queue,a=t.effects.effect[i.effect];return t.fx.off||!a?n?this[n](i.duration,i.complete):this.each(function(){i.complete&&i.complete.call(this)}):o===!1?this.each(e):this.queue(o||"fx",e)},show:function(t){return function(e){if(n(e))return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="show",this.effect.call(this,i)}}(t.fn.show),hide:function(t){return function(e){if(n(e))return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="hide",this.effect.call(this,i)}}(t.fn.hide),toggle:function(t){return function(e){if(n(e)||"boolean"==typeof e)return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="toggle",this.effect.call(this,i)}}(t.fn.toggle),cssUnit:function(e){var i=this.css(e),s=[];return t.each(["em","px","%","pt"],function(t,e){i.indexOf(e)>0&&(s=[parseFloat(i),e])}),s}})}(),function(){var e={};t.each(["Quad","Cubic","Quart","Quint","Expo"],function(t,i){e[i]=function(e){return Math.pow(e,t+2)}}),t.extend(e,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;((e=Math.pow(2,--i))-1)/11>t;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),t.each(e,function(e,i){t.easing["easeIn"+e]=i,t.easing["easeOut"+e]=function(t){return 1-i(1-t)},t.easing["easeInOut"+e]=function(t){return.5>t?i(2*t)/2:1-i(-2*t+2)/2}})}()}(jQuery),function(t){var e=0,i={},s={};i.height=i.paddingTop=i.paddingBottom=i.borderTopWidth=i.borderBottomWidth="hide",s.height=s.paddingTop=s.paddingBottom=s.borderTopWidth=s.borderBottomWidth="show",t.widget("ui.accordion",{version:"1.10.3",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},_create:function(){var e=this.options;this.prevShow=this.prevHide=t(),this.element.addClass("ui-accordion ui-widget ui-helper-reset").attr("role","tablist"),e.collapsible||e.active!==!1&&null!=e.active||(e.active=0),this._processPanels(),0>e.active&&(e.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():t(),content:this.active.length?this.active.next():t()}},_createIcons:function(){var e=this.options.icons;e&&(t("<span>").addClass("ui-accordion-header-icon ui-icon "+e.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(e.header).addClass(e.activeHeader),this.headers.addClass("ui-accordion-icons"))
+},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var t;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this._destroyIcons(),t=this.headers.next().css("display","").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),"content"!==this.options.heightStyle&&t.css("height","")},_setOption:function(t,e){return"active"===t?(this._activate(e),undefined):("event"===t&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(e)),this._super(t,e),"collapsible"!==t||e||this.options.active!==!1||this._activate(0),"icons"===t&&(this._destroyIcons(),e&&this._createIcons()),"disabled"===t&&this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!e),undefined)},_keydown:function(e){if(!e.altKey&&!e.ctrlKey){var i=t.ui.keyCode,s=this.headers.length,n=this.headers.index(e.target),o=!1;switch(e.keyCode){case i.RIGHT:case i.DOWN:o=this.headers[(n+1)%s];break;case i.LEFT:case i.UP:o=this.headers[(n-1+s)%s];break;case i.SPACE:case i.ENTER:this._eventHandler(e);break;case i.HOME:o=this.headers[0];break;case i.END:o=this.headers[s-1]}o&&(t(e.target).attr("tabIndex",-1),t(o).attr("tabIndex",0),o.focus(),e.preventDefault())}},_panelKeyDown:function(e){e.keyCode===t.ui.keyCode.UP&&e.ctrlKey&&t(e.currentTarget).prev().focus()},refresh:function(){var e=this.options;this._processPanels(),e.active===!1&&e.collapsible===!0||!this.headers.length?(e.active=!1,this.active=t()):e.active===!1?this._activate(0):this.active.length&&!t.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(e.active=!1,this.active=t()):this._activate(Math.max(0,e.active-1)):e.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){this.headers=this.element.find(this.options.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all"),this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").filter(":not(.ui-accordion-content-active)").hide()},_refresh:function(){var i,s=this.options,n=s.heightStyle,o=this.element.parent(),a=this.accordionId="ui-accordion-"+(this.element.attr("id")||++e);this.active=this._findActive(s.active).addClass("ui-accordion-header-active ui-state-active ui-corner-top").removeClass("ui-corner-all"),this.active.next().addClass("ui-accordion-content-active").show(),this.headers.attr("role","tab").each(function(e){var i=t(this),s=i.attr("id"),n=i.next(),o=n.attr("id");s||(s=a+"-header-"+e,i.attr("id",s)),o||(o=a+"-panel-"+e,n.attr("id",o)),i.attr("aria-controls",o),n.attr("aria-labelledby",s)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false",tabIndex:-1}).next().attr({"aria-expanded":"false","aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true",tabIndex:0}).next().attr({"aria-expanded":"true","aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(s.event),"fill"===n?(i=o.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.headers.each(function(){i-=t(this).outerHeight(!0)}),this.headers.next().each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===n&&(i=0,this.headers.next().each(function(){i=Math.max(i,t(this).css("height","").height())}).height(i))},_activate:function(e){var i=this._findActive(e)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return"number"==typeof e?this.headers.eq(e):t()},_setupEvents:function(e){var i={keydown:"_keydown"};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),o=n[0]===s[0],a=o&&i.collapsible,r=a?t():n.next(),h=s.next(),l={oldHeader:s,oldPanel:h,newHeader:a?t():n,newPanel:r};e.preventDefault(),o&&!i.collapsible||this._trigger("beforeActivate",e,l)===!1||(i.active=a?!1:this.headers.index(n),this.active=o?t():n,this._toggle(l),s.removeClass("ui-accordion-header-active ui-state-active"),i.icons&&s.children(".ui-accordion-header-icon").removeClass(i.icons.activeHeader).addClass(i.icons.header),o||(n.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),i.icons&&n.children(".ui-accordion-header-icon").removeClass(i.icons.header).addClass(i.icons.activeHeader),n.next().addClass("ui-accordion-content-active")))},_toggle:function(e){var i=e.newPanel,s=this.prevShow.length?this.prevShow:e.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=s,this.options.animate?this._animate(i,s,e):(s.hide(),i.show(),this._toggleComplete(e)),s.attr({"aria-expanded":"false","aria-hidden":"true"}),s.prev().attr("aria-selected","false"),i.length&&s.length?s.prev().attr("tabIndex",-1):i.length&&this.headers.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),i.attr({"aria-expanded":"true","aria-hidden":"false"}).prev().attr({"aria-selected":"true",tabIndex:0})},_animate:function(t,e,n){var o,a,r,h=this,l=0,c=t.length&&(!e.length||t.index()<e.index()),u=this.options.animate||{},d=c&&u.down||u,p=function(){h._toggleComplete(n)};return"number"==typeof d&&(r=d),"string"==typeof d&&(a=d),a=a||d.easing||u.easing,r=r||d.duration||u.duration,e.length?t.length?(o=t.show().outerHeight(),e.animate(i,{duration:r,easing:a,step:function(t,e){e.now=Math.round(t)}}),t.hide().animate(s,{duration:r,easing:a,complete:p,step:function(t,i){i.now=Math.round(t),"height"!==i.prop?l+=i.now:"content"!==h.options.heightStyle&&(i.now=Math.round(o-e.outerHeight()-l),l=0)}}),undefined):e.animate(i,r,a,p):t.animate(s,r,a,p)},_toggleComplete:function(t){var e=t.oldPanel;e.removeClass("ui-accordion-content-active").prev().removeClass("ui-corner-top").addClass("ui-corner-all"),e.length&&(e.parent()[0].className=e.parent()[0].className),this._trigger("activate",null,t)}})}(jQuery),function(t){var e=0;t.widget("ui.autocomplete",{version:"1.10.3",defaultElement:"<input>",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},pending:0,_create:function(){var e,i,s,n=this.element[0].nodeName.toLowerCase(),o="textarea"===n,a="input"===n;this.isMultiLine=o?!0:a?!1:this.element.prop("isContentEditable"),this.valueMethod=this.element[o||a?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))return e=!0,s=!0,i=!0,undefined;e=!1,s=!1,i=!1;var o=t.ui.keyCode;switch(n.keyCode){case o.PAGE_UP:e=!0,this._move("previousPage",n);break;case o.PAGE_DOWN:e=!0,this._move("nextPage",n);break;case o.UP:e=!0,this._keyEvent("previous",n);break;case o.DOWN:e=!0,this._keyEvent("next",n);break;case o.ENTER:case o.NUMPAD_ENTER:this.menu.active&&(e=!0,n.preventDefault(),this.menu.select(n));break;case o.TAB:this.menu.active&&this.menu.select(n);break;case o.ESCAPE:this.menu.element.is(":visible")&&(this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}},keypress:function(s){if(e)return e=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault(),undefined;if(!i){var n=t.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(t){return s?(s=!1,t.preventDefault(),undefined):(this._searchTimeout(t),undefined)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,undefined):(clearTimeout(this.searching),this.close(t),this._change(t),undefined)}}),this._initSource(),this.menu=t("<ul>").addClass("ui-autocomplete ui-front").appendTo(this._appendTo()).menu({role:null}).hide().data("ui-menu"),this._on(this.menu.element,{mousedown:function(e){e.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur});var i=this.menu.element[0];t(e.target).closest(".ui-menu-item").length||this._delay(function(){var e=this;this.document.one("mousedown",function(s){s.target===e.element[0]||s.target===i||t.contains(i,s.target)||e.close()})})},menufocus:function(e,i){if(this.isNewMenu&&(this.isNewMenu=!1,e.originalEvent&&/^mouse/.test(e.originalEvent.type)))return this.menu.blur(),this.document.one("mousemove",function(){t(e.target).trigger(e.originalEvent)}),undefined;var s=i.item.data("ui-autocomplete-item");!1!==this._trigger("focus",e,{item:s})?e.originalEvent&&/^key/.test(e.originalEvent.type)&&this._value(s.value):this.liveRegion.text(s.value)},menuselect:function(t,e){var i=e.item.data("ui-autocomplete-item"),s=this.previous;this.element[0]!==this.document[0].activeElement&&(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s,this.selectedItem=i})),!1!==this._trigger("select",t,{item:i})&&this._value(i.value),this.term=this._value(),this.close(t),this.selectedItem=i}}),this.liveRegion=t("<span>",{role:"status","aria-live":"polite"}).addClass("ui-helper-hidden-accessible").insertBefore(this.element),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_appendTo:function(){var e=this.options.appendTo;return e&&(e=e.jquery||e.nodeType?t(e):this.document.find(e).eq(0)),e||(e=this.element.closest(".ui-front")),e.length||(e=this.document[0].body),e},_initSource:function(){var e,i,s=this;t.isArray(this.options.source)?(e=this.options.source,this.source=function(i,s){s(t.ui.autocomplete.filter(e,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(e,n){s.xhr&&s.xhr.abort(),s.xhr=t.ajax({url:i,data:e,dataType:"json",success:function(t){n(t)},error:function(){n([])}})}):this.source=this.options.source},_searchTimeout:function(t){clearTimeout(this.searching),this.searching=this._delay(function(){this.term!==this._value()&&(this.selectedItem=null,this.search(null,t))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length<this.options.minLength?this.close(e):this._trigger("search",e)!==!1?this._search(t):undefined},_search:function(t){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:t},this._response())},_response:function(){var t=this,i=++e;return function(s){i===e&&t.__response(s),t.pending--,t.pending||t.element.removeClass("ui-autocomplete-loading")}},__response:function(t){t&&(t=this._normalize(t)),this._trigger("response",null,{content:t}),!this.options.disabled&&t&&t.length&&!this.cancelSearch?(this._suggest(t),this._trigger("open")):this._close()},close:function(t){this.cancelSearch=!0,this._close(t)},_close:function(t){this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",t))},_change:function(t){this.previous!==this._value()&&this._trigger("change",t,{item:this.selectedItem})},_normalize:function(e){return e.length&&e[0].label&&e[0].value?e:t.map(e,function(e){return"string"==typeof e?{label:e,value:e}:t.extend({label:e.label||e.value,value:e.value||e.label},e)})},_suggest:function(e){var i=this.menu.element.empty();this._renderMenu(i,e),this.isNewMenu=!0,this.menu.refresh(),i.show(),this._resizeMenu(),i.position(t.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next()},_resizeMenu:function(){var t=this.menu.element;t.outerWidth(Math.max(t.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(e,i){var s=this;t.each(i,function(t,i){s._renderItemData(e,i)})},_renderItemData:function(t,e){return this._renderItem(t,e).data("ui-autocomplete-item",e)},_renderItem:function(e,i){return t("<li>").append(t("<a>").text(i.label)).appendTo(e)},_move:function(t,e){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this._value(this.term),this.menu.blur(),undefined):(this.menu[t](e),undefined):(this.search(null,e),undefined)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(t,e),e.preventDefault())}}),t.extend(t.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(e,i){var s=RegExp(t.ui.autocomplete.escapeRegex(i),"i");return t.grep(e,function(t){return s.test(t.label||t.value||t)})}}),t.widget("ui.autocomplete",t.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(t>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(t){var e;this._superApply(arguments),this.options.disabled||this.cancelSearch||(e=t&&t.length?this.options.messages.results(t.length):this.options.messages.noResults,this.liveRegion.text(e))}})}(jQuery),function(t){var e,i,s,n,o="ui-button ui-widget ui-state-default ui-corner-all",a="ui-state-hover ui-state-active ",r="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",h=function(){var e=t(this);setTimeout(function(){e.find(":ui-button").button("refresh")},1)},l=function(e){var i=e.name,s=e.form,n=t([]);return i&&(i=i.replace(/'/g,"\\'"),n=s?t(s).find("[name='"+i+"']"):t("[name='"+i+"']",e.ownerDocument).filter(function(){return!this.form})),n};t.widget("ui.button",{version:"1.10.3",defaultElement:"<button>",options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset"+this.eventNamespace).bind("reset"+this.eventNamespace,h),"boolean"!=typeof this.options.disabled?this.options.disabled=!!this.element.prop("disabled"):this.element.prop("disabled",this.options.disabled),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var a=this,r=this.options,c="checkbox"===this.type||"radio"===this.type,u=c?"":"ui-state-active",d="ui-state-focus";null===r.label&&(r.label="input"===this.type?this.buttonElement.val():this.buttonElement.html()),this._hoverable(this.buttonElement),this.buttonElement.addClass(o).attr("role","button").bind("mouseenter"+this.eventNamespace,function(){r.disabled||this===e&&t(this).addClass("ui-state-active")}).bind("mouseleave"+this.eventNamespace,function(){r.disabled||t(this).removeClass(u)}).bind("click"+this.eventNamespace,function(t){r.disabled&&(t.preventDefault(),t.stopImmediatePropagation())}),this.element.bind("focus"+this.eventNamespace,function(){a.buttonElement.addClass(d)}).bind("blur"+this.eventNamespace,function(){a.buttonElement.removeClass(d)}),c&&(this.element.bind("change"+this.eventNamespace,function(){n||a.refresh()}),this.buttonElement.bind("mousedown"+this.eventNamespace,function(t){r.disabled||(n=!1,i=t.pageX,s=t.pageY)}).bind("mouseup"+this.eventNamespace,function(t){r.disabled||(i!==t.pageX||s!==t.pageY)&&(n=!0)})),"checkbox"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){return r.disabled||n?!1:undefined}):"radio"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){if(r.disabled||n)return!1;t(this).addClass("ui-state-active"),a.buttonElement.attr("aria-pressed","true");var e=a.element[0];l(e).not(e).map(function(){return t(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown"+this.eventNamespace,function(){return r.disabled?!1:(t(this).addClass("ui-state-active"),e=this,a.document.one("mouseup",function(){e=null}),undefined)}).bind("mouseup"+this.eventNamespace,function(){return r.disabled?!1:(t(this).removeClass("ui-state-active"),undefined)}).bind("keydown"+this.eventNamespace,function(e){return r.disabled?!1:((e.keyCode===t.ui.keyCode.SPACE||e.keyCode===t.ui.keyCode.ENTER)&&t(this).addClass("ui-state-active"),undefined)}).bind("keyup"+this.eventNamespace+" blur"+this.eventNamespace,function(){t(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(e){e.keyCode===t.ui.keyCode.SPACE&&t(this).click()})),this._setOption("disabled",r.disabled),this._resetButton()},_determineButtonType:function(){var t,e,i;this.type=this.element.is("[type=checkbox]")?"checkbox":this.element.is("[type=radio]")?"radio":this.element.is("input")?"input":"button","checkbox"===this.type||"radio"===this.type?(t=this.element.parents().last(),e="label[for='"+this.element.attr("id")+"']",this.buttonElement=t.find(e),this.buttonElement.length||(t=t.length?t.siblings():this.element.siblings(),this.buttonElement=t.filter(e),this.buttonElement.length||(this.buttonElement=t.find(e))),this.element.addClass("ui-helper-hidden-accessible"),i=this.element.is(":checked"),i&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.prop("aria-pressed",i)):this.buttonElement=this.element},widget:function(){return this.buttonElement},_destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(o+" "+a+" "+r).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title")},_setOption:function(t,e){return this._super(t,e),"disabled"===t?(e?this.element.prop("disabled",!0):this.element.prop("disabled",!1),undefined):(this._resetButton(),undefined)},refresh:function(){var e=this.element.is("input, button")?this.element.is(":disabled"):this.element.hasClass("ui-button-disabled");e!==this.options.disabled&&this._setOption("disabled",e),"radio"===this.type?l(this.element[0]).each(function(){t(this).is(":checked")?t(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):t(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):"checkbox"===this.type&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if("input"===this.type)return this.options.label&&this.element.val(this.options.label),undefined;var e=this.buttonElement.removeClass(r),i=t("<span></span>",this.document[0]).addClass("ui-button-text").html(this.options.label).appendTo(e.empty()).text(),s=this.options.icons,n=s.primary&&s.secondary,o=[];s.primary||s.secondary?(this.options.text&&o.push("ui-button-text-icon"+(n?"s":s.primary?"-primary":"-secondary")),s.primary&&e.prepend("<span class='ui-button-icon-primary ui-icon "+s.primary+"'></span>"),s.secondary&&e.append("<span class='ui-button-icon-secondary ui-icon "+s.secondary+"'></span>"),this.options.text||(o.push(n?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||e.attr("title",t.trim(i)))):o.push("ui-button-text-only"),e.addClass(o.join(" "))}}),t.widget("ui.buttonset",{version:"1.10.3",options:{items:"button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(t,e){"disabled"===t&&this.buttons.button("option",t,e),this._super(t,e)},refresh:function(){var e="rtl"===this.element.css("direction");this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return t(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(e?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(e?"ui-corner-left":"ui-corner-right").end().end()},_destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return t(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy")}})}(jQuery),function(t,e){function i(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},t.extend(this._defaults,this.regional[""]),this.dpDiv=s(t("<div id='"+this._mainDivId+"' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"))}function s(e){var i="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return e.delegate(i,"mouseout",function(){t(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).removeClass("ui-datepicker-next-hover")}).delegate(i,"mouseover",function(){t.datepicker._isDisabledDatepicker(o.inline?e.parent()[0]:o.input[0])||(t(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),t(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).addClass("ui-datepicker-next-hover"))})}function n(e,i){t.extend(e,i);for(var s in i)null==i[s]&&(e[s]=i[s]);return e}t.extend(t.ui,{datepicker:{version:"1.10.3"}});var o,a="datepicker";t.extend(i.prototype,{markerClassName:"hasDatepicker",maxRows:4,_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(t){return n(this._defaults,t||{}),this},_attachDatepicker:function(e,i){var s,n,o;s=e.nodeName.toLowerCase(),n="div"===s||"span"===s,e.id||(this.uuid+=1,e.id="dp"+this.uuid),o=this._newInst(t(e),n),o.settings=t.extend({},i||{}),"input"===s?this._connectDatepicker(e,o):n&&this._inlineDatepicker(e,o)},_newInst:function(e,i){var n=e[0].id.replace(/([^A-Za-z0-9_\-])/g,"\\\\$1");return{id:n,input:e,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:i,dpDiv:i?s(t("<div class='"+this._inlineClass+" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")):this.dpDiv}},_connectDatepicker:function(e,i){var s=t(e);i.append=t([]),i.trigger=t([]),s.hasClass(this.markerClassName)||(this._attachments(s,i),s.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp),this._autoSize(i),t.data(e,a,i),i.settings.disabled&&this._disableDatepicker(e))},_attachments:function(e,i){var s,n,o,a=this._get(i,"appendText"),r=this._get(i,"isRTL");i.append&&i.append.remove(),a&&(i.append=t("<span class='"+this._appendClass+"'>"+a+"</span>"),e[r?"before":"after"](i.append)),e.unbind("focus",this._showDatepicker),i.trigger&&i.trigger.remove(),s=this._get(i,"showOn"),("focus"===s||"both"===s)&&e.focus(this._showDatepicker),("button"===s||"both"===s)&&(n=this._get(i,"buttonText"),o=this._get(i,"buttonImage"),i.trigger=t(this._get(i,"buttonImageOnly")?t("<img/>").addClass(this._triggerClass).attr({src:o,alt:n,title:n}):t("<button type='button'></button>").addClass(this._triggerClass).html(o?t("<img/>").attr({src:o,alt:n,title:n}):n)),e[r?"before":"after"](i.trigger),i.trigger.click(function(){return t.datepicker._datepickerShowing&&t.datepicker._lastInput===e[0]?t.datepicker._hideDatepicker():t.datepicker._datepickerShowing&&t.datepicker._lastInput!==e[0]?(t.datepicker._hideDatepicker(),t.datepicker._showDatepicker(e[0])):t.datepicker._showDatepicker(e[0]),!1}))},_autoSize:function(t){if(this._get(t,"autoSize")&&!t.inline){var e,i,s,n,o=new Date(2009,11,20),a=this._get(t,"dateFormat");a.match(/[DM]/)&&(e=function(t){for(i=0,s=0,n=0;t.length>n;n++)t[n].length>i&&(i=t[n].length,s=n);return s},o.setMonth(e(this._get(t,a.match(/MM/)?"monthNames":"monthNamesShort"))),o.setDate(e(this._get(t,a.match(/DD/)?"dayNames":"dayNamesShort"))+20-o.getDay())),t.input.attr("size",this._formatDate(t,o).length)}},_inlineDatepicker:function(e,i){var s=t(e);s.hasClass(this.markerClassName)||(s.addClass(this.markerClassName).append(i.dpDiv),t.data(e,a,i),this._setDate(i,this._getDefaultDate(i),!0),this._updateDatepicker(i),this._updateAlternate(i),i.settings.disabled&&this._disableDatepicker(e),i.dpDiv.css("display","block"))},_dialogDatepicker:function(e,i,s,o,r){var h,l,c,u,d,p=this._dialogInst;return p||(this.uuid+=1,h="dp"+this.uuid,this._dialogInput=t("<input type='text' id='"+h+"' style='position: absolute; top: -100px; width: 0px;'/>"),this._dialogInput.keydown(this._doKeyDown),t("body").append(this._dialogInput),p=this._dialogInst=this._newInst(this._dialogInput,!1),p.settings={},t.data(this._dialogInput[0],a,p)),n(p.settings,o||{}),i=i&&i.constructor===Date?this._formatDate(p,i):i,this._dialogInput.val(i),this._pos=r?r.length?r:[r.pageX,r.pageY]:null,this._pos||(l=document.documentElement.clientWidth,c=document.documentElement.clientHeight,u=document.documentElement.scrollLeft||document.body.scrollLeft,d=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[l/2-100+u,c/2-150+d]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),p.settings.onSelect=s,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),t.blockUI&&t.blockUI(this.dpDiv),t.data(this._dialogInput[0],a,p),this},_destroyDatepicker:function(e){var i,s=t(e),n=t.data(e,a);s.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),t.removeData(e,a),"input"===i?(n.append.remove(),n.trigger.remove(),s.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):("div"===i||"span"===i)&&s.removeClass(this.markerClassName).empty())},_enableDatepicker:function(e){var i,s,n=t(e),o=t.data(e,a);n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!1,o.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().removeClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}))},_disableDatepicker:function(e){var i,s,n=t(e),o=t.data(e,a);n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!0,o.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().addClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}),this._disabledInputs[this._disabledInputs.length]=e)},_isDisabledDatepicker:function(t){if(!t)return!1;for(var e=0;this._disabledInputs.length>e;e++)if(this._disabledInputs[e]===t)return!0;return!1},_getInst:function(e){try{return t.data(e,a)}catch(i){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(i,s,o){var a,r,h,l,c=this._getInst(i);return 2===arguments.length&&"string"==typeof s?"defaults"===s?t.extend({},t.datepicker._defaults):c?"all"===s?t.extend({},c.settings):this._get(c,s):null:(a=s||{},"string"==typeof s&&(a={},a[s]=o),c&&(this._curInst===c&&this._hideDatepicker(),r=this._getDateDatepicker(i,!0),h=this._getMinMaxDate(c,"min"),l=this._getMinMaxDate(c,"max"),n(c.settings,a),null!==h&&a.dateFormat!==e&&a.minDate===e&&(c.settings.minDate=this._formatDate(c,h)),null!==l&&a.dateFormat!==e&&a.maxDate===e&&(c.settings.maxDate=this._formatDate(c,l)),"disabled"in a&&(a.disabled?this._disableDatepicker(i):this._enableDatepicker(i)),this._attachments(t(i),c),this._autoSize(c),this._setDate(c,r),this._updateAlternate(c),this._updateDatepicker(c)),e)},_changeDatepicker:function(t,e,i){this._optionDatepicker(t,e,i)},_refreshDatepicker:function(t){var e=this._getInst(t);e&&this._updateDatepicker(e)},_setDateDatepicker:function(t,e){var i=this._getInst(t);i&&(this._setDate(i,e),this._updateDatepicker(i),this._updateAlternate(i))},_getDateDatepicker:function(t,e){var i=this._getInst(t);return i&&!i.inline&&this._setDateFromField(i,e),i?this._getDate(i):null},_doKeyDown:function(e){var i,s,n,o=t.datepicker._getInst(e.target),a=!0,r=o.dpDiv.is(".ui-datepicker-rtl");if(o._keyEvent=!0,t.datepicker._datepickerShowing)switch(e.keyCode){case 9:t.datepicker._hideDatepicker(),a=!1;break;case 13:return n=t("td."+t.datepicker._dayOverClass+":not(."+t.datepicker._currentClass+")",o.dpDiv),n[0]&&t.datepicker._selectDay(e.target,o.selectedMonth,o.selectedYear,n[0]),i=t.datepicker._get(o,"onSelect"),i?(s=t.datepicker._formatDate(o),i.apply(o.input?o.input[0]:null,[s,o])):t.datepicker._hideDatepicker(),!1;
+case 27:t.datepicker._hideDatepicker();break;case 33:t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(o,"stepBigMonths"):-t.datepicker._get(o,"stepMonths"),"M");break;case 34:t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(o,"stepBigMonths"):+t.datepicker._get(o,"stepMonths"),"M");break;case 35:(e.ctrlKey||e.metaKey)&&t.datepicker._clearDate(e.target),a=e.ctrlKey||e.metaKey;break;case 36:(e.ctrlKey||e.metaKey)&&t.datepicker._gotoToday(e.target),a=e.ctrlKey||e.metaKey;break;case 37:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,r?1:-1,"D"),a=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(o,"stepBigMonths"):-t.datepicker._get(o,"stepMonths"),"M");break;case 38:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,-7,"D"),a=e.ctrlKey||e.metaKey;break;case 39:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,r?-1:1,"D"),a=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(o,"stepBigMonths"):+t.datepicker._get(o,"stepMonths"),"M");break;case 40:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,7,"D"),a=e.ctrlKey||e.metaKey;break;default:a=!1}else 36===e.keyCode&&e.ctrlKey?t.datepicker._showDatepicker(this):a=!1;a&&(e.preventDefault(),e.stopPropagation())},_doKeyPress:function(i){var s,n,o=t.datepicker._getInst(i.target);return t.datepicker._get(o,"constrainInput")?(s=t.datepicker._possibleChars(t.datepicker._get(o,"dateFormat")),n=String.fromCharCode(null==i.charCode?i.keyCode:i.charCode),i.ctrlKey||i.metaKey||" ">n||!s||s.indexOf(n)>-1):e},_doKeyUp:function(e){var i,s=t.datepicker._getInst(e.target);if(s.input.val()!==s.lastVal)try{i=t.datepicker.parseDate(t.datepicker._get(s,"dateFormat"),s.input?s.input.val():null,t.datepicker._getFormatConfig(s)),i&&(t.datepicker._setDateFromField(s),t.datepicker._updateAlternate(s),t.datepicker._updateDatepicker(s))}catch(n){}return!0},_showDatepicker:function(e){if(e=e.target||e,"input"!==e.nodeName.toLowerCase()&&(e=t("input",e.parentNode)[0]),!t.datepicker._isDisabledDatepicker(e)&&t.datepicker._lastInput!==e){var i,s,o,a,r,h,l;i=t.datepicker._getInst(e),t.datepicker._curInst&&t.datepicker._curInst!==i&&(t.datepicker._curInst.dpDiv.stop(!0,!0),i&&t.datepicker._datepickerShowing&&t.datepicker._hideDatepicker(t.datepicker._curInst.input[0])),s=t.datepicker._get(i,"beforeShow"),o=s?s.apply(e,[e,i]):{},o!==!1&&(n(i.settings,o),i.lastVal=null,t.datepicker._lastInput=e,t.datepicker._setDateFromField(i),t.datepicker._inDialog&&(e.value=""),t.datepicker._pos||(t.datepicker._pos=t.datepicker._findPos(e),t.datepicker._pos[1]+=e.offsetHeight),a=!1,t(e).parents().each(function(){return a|="fixed"===t(this).css("position"),!a}),r={left:t.datepicker._pos[0],top:t.datepicker._pos[1]},t.datepicker._pos=null,i.dpDiv.empty(),i.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),t.datepicker._updateDatepicker(i),r=t.datepicker._checkOffset(i,r,a),i.dpDiv.css({position:t.datepicker._inDialog&&t.blockUI?"static":a?"fixed":"absolute",display:"none",left:r.left+"px",top:r.top+"px"}),i.inline||(h=t.datepicker._get(i,"showAnim"),l=t.datepicker._get(i,"duration"),i.dpDiv.zIndex(t(e).zIndex()+1),t.datepicker._datepickerShowing=!0,t.effects&&t.effects.effect[h]?i.dpDiv.show(h,t.datepicker._get(i,"showOptions"),l):i.dpDiv[h||"show"](h?l:null),t.datepicker._shouldFocusInput(i)&&i.input.focus(),t.datepicker._curInst=i))}},_updateDatepicker:function(e){this.maxRows=4,o=e,e.dpDiv.empty().append(this._generateHTML(e)),this._attachHandlers(e),e.dpDiv.find("."+this._dayOverClass+" a").mouseover();var i,s=this._getNumberOfMonths(e),n=s[1],a=17;e.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),n>1&&e.dpDiv.addClass("ui-datepicker-multi-"+n).css("width",a*n+"em"),e.dpDiv[(1!==s[0]||1!==s[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),e.dpDiv[(this._get(e,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),e===t.datepicker._curInst&&t.datepicker._datepickerShowing&&t.datepicker._shouldFocusInput(e)&&e.input.focus(),e.yearshtml&&(i=e.yearshtml,setTimeout(function(){i===e.yearshtml&&e.yearshtml&&e.dpDiv.find("select.ui-datepicker-year:first").replaceWith(e.yearshtml),i=e.yearshtml=null},0))},_shouldFocusInput:function(t){return t.input&&t.input.is(":visible")&&!t.input.is(":disabled")&&!t.input.is(":focus")},_checkOffset:function(e,i,s){var n=e.dpDiv.outerWidth(),o=e.dpDiv.outerHeight(),a=e.input?e.input.outerWidth():0,r=e.input?e.input.outerHeight():0,h=document.documentElement.clientWidth+(s?0:t(document).scrollLeft()),l=document.documentElement.clientHeight+(s?0:t(document).scrollTop());return i.left-=this._get(e,"isRTL")?n-a:0,i.left-=s&&i.left===e.input.offset().left?t(document).scrollLeft():0,i.top-=s&&i.top===e.input.offset().top+r?t(document).scrollTop():0,i.left-=Math.min(i.left,i.left+n>h&&h>n?Math.abs(i.left+n-h):0),i.top-=Math.min(i.top,i.top+o>l&&l>o?Math.abs(o+r):0),i},_findPos:function(e){for(var i,s=this._getInst(e),n=this._get(s,"isRTL");e&&("hidden"===e.type||1!==e.nodeType||t.expr.filters.hidden(e));)e=e[n?"previousSibling":"nextSibling"];return i=t(e).offset(),[i.left,i.top]},_hideDatepicker:function(e){var i,s,n,o,r=this._curInst;!r||e&&r!==t.data(e,a)||this._datepickerShowing&&(i=this._get(r,"showAnim"),s=this._get(r,"duration"),n=function(){t.datepicker._tidyDialog(r)},t.effects&&(t.effects.effect[i]||t.effects[i])?r.dpDiv.hide(i,t.datepicker._get(r,"showOptions"),s,n):r.dpDiv["slideDown"===i?"slideUp":"fadeIn"===i?"fadeOut":"hide"](i?s:null,n),i||n(),this._datepickerShowing=!1,o=this._get(r,"onClose"),o&&o.apply(r.input?r.input[0]:null,[r.input?r.input.val():"",r]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),t.blockUI&&(t.unblockUI(),t("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(t){t.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(e){if(t.datepicker._curInst){var i=t(e.target),s=t.datepicker._getInst(i[0]);(i[0].id!==t.datepicker._mainDivId&&0===i.parents("#"+t.datepicker._mainDivId).length&&!i.hasClass(t.datepicker.markerClassName)&&!i.closest("."+t.datepicker._triggerClass).length&&t.datepicker._datepickerShowing&&(!t.datepicker._inDialog||!t.blockUI)||i.hasClass(t.datepicker.markerClassName)&&t.datepicker._curInst!==s)&&t.datepicker._hideDatepicker()}},_adjustDate:function(e,i,s){var n=t(e),o=this._getInst(n[0]);this._isDisabledDatepicker(n[0])||(this._adjustInstDate(o,i+("M"===s?this._get(o,"showCurrentAtPos"):0),s),this._updateDatepicker(o))},_gotoToday:function(e){var i,s=t(e),n=this._getInst(s[0]);this._get(n,"gotoCurrent")&&n.currentDay?(n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear):(i=new Date,n.selectedDay=i.getDate(),n.drawMonth=n.selectedMonth=i.getMonth(),n.drawYear=n.selectedYear=i.getFullYear()),this._notifyChange(n),this._adjustDate(s)},_selectMonthYear:function(e,i,s){var n=t(e),o=this._getInst(n[0]);o["selected"+("M"===s?"Month":"Year")]=o["draw"+("M"===s?"Month":"Year")]=parseInt(i.options[i.selectedIndex].value,10),this._notifyChange(o),this._adjustDate(n)},_selectDay:function(e,i,s,n){var o,a=t(e);t(n).hasClass(this._unselectableClass)||this._isDisabledDatepicker(a[0])||(o=this._getInst(a[0]),o.selectedDay=o.currentDay=t("a",n).html(),o.selectedMonth=o.currentMonth=i,o.selectedYear=o.currentYear=s,this._selectDate(e,this._formatDate(o,o.currentDay,o.currentMonth,o.currentYear)))},_clearDate:function(e){var i=t(e);this._selectDate(i,"")},_selectDate:function(e,i){var s,n=t(e),o=this._getInst(n[0]);i=null!=i?i:this._formatDate(o),o.input&&o.input.val(i),this._updateAlternate(o),s=this._get(o,"onSelect"),s?s.apply(o.input?o.input[0]:null,[i,o]):o.input&&o.input.trigger("change"),o.inline?this._updateDatepicker(o):(this._hideDatepicker(),this._lastInput=o.input[0],"object"!=typeof o.input[0]&&o.input.focus(),this._lastInput=null)},_updateAlternate:function(e){var i,s,n,o=this._get(e,"altField");o&&(i=this._get(e,"altFormat")||this._get(e,"dateFormat"),s=this._getDate(e),n=this.formatDate(i,s,this._getFormatConfig(e)),t(o).each(function(){t(this).val(n)}))},noWeekends:function(t){var e=t.getDay();return[e>0&&6>e,""]},iso8601Week:function(t){var e,i=new Date(t.getTime());return i.setDate(i.getDate()+4-(i.getDay()||7)),e=i.getTime(),i.setMonth(0),i.setDate(1),Math.floor(Math.round((e-i)/864e5)/7)+1},parseDate:function(i,s,n){if(null==i||null==s)throw"Invalid arguments";if(s="object"==typeof s?""+s:s+"",""===s)return null;var o,a,r,h,l=0,c=(n?n.shortYearCutoff:null)||this._defaults.shortYearCutoff,u="string"!=typeof c?c:(new Date).getFullYear()%100+parseInt(c,10),d=(n?n.dayNamesShort:null)||this._defaults.dayNamesShort,p=(n?n.dayNames:null)||this._defaults.dayNames,f=(n?n.monthNamesShort:null)||this._defaults.monthNamesShort,g=(n?n.monthNames:null)||this._defaults.monthNames,m=-1,v=-1,_=-1,b=-1,y=!1,w=function(t){var e=i.length>o+1&&i.charAt(o+1)===t;return e&&o++,e},k=function(t){var e=w(t),i="@"===t?14:"!"===t?20:"y"===t&&e?4:"o"===t?3:2,n=RegExp("^\\d{1,"+i+"}"),o=s.substring(l).match(n);if(!o)throw"Missing number at position "+l;return l+=o[0].length,parseInt(o[0],10)},x=function(i,n,o){var a=-1,r=t.map(w(i)?o:n,function(t,e){return[[e,t]]}).sort(function(t,e){return-(t[1].length-e[1].length)});if(t.each(r,function(t,i){var n=i[1];return s.substr(l,n.length).toLowerCase()===n.toLowerCase()?(a=i[0],l+=n.length,!1):e}),-1!==a)return a+1;throw"Unknown name at position "+l},D=function(){if(s.charAt(l)!==i.charAt(o))throw"Unexpected literal at position "+l;l++};for(o=0;i.length>o;o++)if(y)"'"!==i.charAt(o)||w("'")?D():y=!1;else switch(i.charAt(o)){case"d":_=k("d");break;case"D":x("D",d,p);break;case"o":b=k("o");break;case"m":v=k("m");break;case"M":v=x("M",f,g);break;case"y":m=k("y");break;case"@":h=new Date(k("@")),m=h.getFullYear(),v=h.getMonth()+1,_=h.getDate();break;case"!":h=new Date((k("!")-this._ticksTo1970)/1e4),m=h.getFullYear(),v=h.getMonth()+1,_=h.getDate();break;case"'":w("'")?D():y=!0;break;default:D()}if(s.length>l&&(r=s.substr(l),!/^\s+/.test(r)))throw"Extra/unparsed characters found in date: "+r;if(-1===m?m=(new Date).getFullYear():100>m&&(m+=(new Date).getFullYear()-(new Date).getFullYear()%100+(u>=m?0:-100)),b>-1)for(v=1,_=b;;){if(a=this._getDaysInMonth(m,v-1),a>=_)break;v++,_-=a}if(h=this._daylightSavingAdjust(new Date(m,v-1,_)),h.getFullYear()!==m||h.getMonth()+1!==v||h.getDate()!==_)throw"Invalid date";return h},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:1e7*60*60*24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925)),formatDate:function(t,e,i){if(!e)return"";var s,n=(i?i.dayNamesShort:null)||this._defaults.dayNamesShort,o=(i?i.dayNames:null)||this._defaults.dayNames,a=(i?i.monthNamesShort:null)||this._defaults.monthNamesShort,r=(i?i.monthNames:null)||this._defaults.monthNames,h=function(e){var i=t.length>s+1&&t.charAt(s+1)===e;return i&&s++,i},l=function(t,e,i){var s=""+e;if(h(t))for(;i>s.length;)s="0"+s;return s},c=function(t,e,i,s){return h(t)?s[e]:i[e]},u="",d=!1;if(e)for(s=0;t.length>s;s++)if(d)"'"!==t.charAt(s)||h("'")?u+=t.charAt(s):d=!1;else switch(t.charAt(s)){case"d":u+=l("d",e.getDate(),2);break;case"D":u+=c("D",e.getDay(),n,o);break;case"o":u+=l("o",Math.round((new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime()-new Date(e.getFullYear(),0,0).getTime())/864e5),3);break;case"m":u+=l("m",e.getMonth()+1,2);break;case"M":u+=c("M",e.getMonth(),a,r);break;case"y":u+=h("y")?e.getFullYear():(10>e.getYear()%100?"0":"")+e.getYear()%100;break;case"@":u+=e.getTime();break;case"!":u+=1e4*e.getTime()+this._ticksTo1970;break;case"'":h("'")?u+="'":d=!0;break;default:u+=t.charAt(s)}return u},_possibleChars:function(t){var e,i="",s=!1,n=function(i){var s=t.length>e+1&&t.charAt(e+1)===i;return s&&e++,s};for(e=0;t.length>e;e++)if(s)"'"!==t.charAt(e)||n("'")?i+=t.charAt(e):s=!1;else switch(t.charAt(e)){case"d":case"m":case"y":case"@":i+="0123456789";break;case"D":case"M":return null;case"'":n("'")?i+="'":s=!0;break;default:i+=t.charAt(e)}return i},_get:function(t,i){return t.settings[i]!==e?t.settings[i]:this._defaults[i]},_setDateFromField:function(t,e){if(t.input.val()!==t.lastVal){var i=this._get(t,"dateFormat"),s=t.lastVal=t.input?t.input.val():null,n=this._getDefaultDate(t),o=n,a=this._getFormatConfig(t);try{o=this.parseDate(i,s,a)||n}catch(r){s=e?"":s}t.selectedDay=o.getDate(),t.drawMonth=t.selectedMonth=o.getMonth(),t.drawYear=t.selectedYear=o.getFullYear(),t.currentDay=s?o.getDate():0,t.currentMonth=s?o.getMonth():0,t.currentYear=s?o.getFullYear():0,this._adjustInstDate(t)}},_getDefaultDate:function(t){return this._restrictMinMax(t,this._determineDate(t,this._get(t,"defaultDate"),new Date))},_determineDate:function(e,i,s){var n=function(t){var e=new Date;return e.setDate(e.getDate()+t),e},o=function(i){try{return t.datepicker.parseDate(t.datepicker._get(e,"dateFormat"),i,t.datepicker._getFormatConfig(e))}catch(s){}for(var n=(i.toLowerCase().match(/^c/)?t.datepicker._getDate(e):null)||new Date,o=n.getFullYear(),a=n.getMonth(),r=n.getDate(),h=/([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,l=h.exec(i);l;){switch(l[2]||"d"){case"d":case"D":r+=parseInt(l[1],10);break;case"w":case"W":r+=7*parseInt(l[1],10);break;case"m":case"M":a+=parseInt(l[1],10),r=Math.min(r,t.datepicker._getDaysInMonth(o,a));break;case"y":case"Y":o+=parseInt(l[1],10),r=Math.min(r,t.datepicker._getDaysInMonth(o,a))}l=h.exec(i)}return new Date(o,a,r)},a=null==i||""===i?s:"string"==typeof i?o(i):"number"==typeof i?isNaN(i)?s:n(i):new Date(i.getTime());return a=a&&"Invalid Date"==""+a?s:a,a&&(a.setHours(0),a.setMinutes(0),a.setSeconds(0),a.setMilliseconds(0)),this._daylightSavingAdjust(a)},_daylightSavingAdjust:function(t){return t?(t.setHours(t.getHours()>12?t.getHours()+2:0),t):null},_setDate:function(t,e,i){var s=!e,n=t.selectedMonth,o=t.selectedYear,a=this._restrictMinMax(t,this._determineDate(t,e,new Date));t.selectedDay=t.currentDay=a.getDate(),t.drawMonth=t.selectedMonth=t.currentMonth=a.getMonth(),t.drawYear=t.selectedYear=t.currentYear=a.getFullYear(),n===t.selectedMonth&&o===t.selectedYear||i||this._notifyChange(t),this._adjustInstDate(t),t.input&&t.input.val(s?"":this._formatDate(t))},_getDate:function(t){var e=!t.currentYear||t.input&&""===t.input.val()?null:this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return e},_attachHandlers:function(e){var i=this._get(e,"stepMonths"),s="#"+e.id.replace(/\\\\/g,"\\");e.dpDiv.find("[data-handler]").map(function(){var e={prev:function(){t.datepicker._adjustDate(s,-i,"M")},next:function(){t.datepicker._adjustDate(s,+i,"M")},hide:function(){t.datepicker._hideDatepicker()},today:function(){t.datepicker._gotoToday(s)},selectDay:function(){return t.datepicker._selectDay(s,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return t.datepicker._selectMonthYear(s,this,"M"),!1},selectYear:function(){return t.datepicker._selectMonthYear(s,this,"Y"),!1}};t(this).bind(this.getAttribute("data-event"),e[this.getAttribute("data-handler")])})},_generateHTML:function(t){var e,i,s,n,o,a,r,h,l,c,u,d,p,f,g,m,v,_,b,y,w,k,x,D,C,I,P,T,M,S,z,A,H,E,N,W,O,F,R,L=new Date,j=this._daylightSavingAdjust(new Date(L.getFullYear(),L.getMonth(),L.getDate())),Y=this._get(t,"isRTL"),B=this._get(t,"showButtonPanel"),V=this._get(t,"hideIfNoPrevNext"),K=this._get(t,"navigationAsDateFormat"),U=this._getNumberOfMonths(t),q=this._get(t,"showCurrentAtPos"),Q=this._get(t,"stepMonths"),X=1!==U[0]||1!==U[1],$=this._daylightSavingAdjust(t.currentDay?new Date(t.currentYear,t.currentMonth,t.currentDay):new Date(9999,9,9)),G=this._getMinMaxDate(t,"min"),J=this._getMinMaxDate(t,"max"),Z=t.drawMonth-q,te=t.drawYear;if(0>Z&&(Z+=12,te--),J)for(e=this._daylightSavingAdjust(new Date(J.getFullYear(),J.getMonth()-U[0]*U[1]+1,J.getDate())),e=G&&G>e?G:e;this._daylightSavingAdjust(new Date(te,Z,1))>e;)Z--,0>Z&&(Z=11,te--);for(t.drawMonth=Z,t.drawYear=te,i=this._get(t,"prevText"),i=K?this.formatDate(i,this._daylightSavingAdjust(new Date(te,Z-Q,1)),this._getFormatConfig(t)):i,s=this._canAdjustMonth(t,-1,te,Z)?"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>":V?"":"<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>",n=this._get(t,"nextText"),n=K?this.formatDate(n,this._daylightSavingAdjust(new Date(te,Z+Q,1)),this._getFormatConfig(t)):n,o=this._canAdjustMonth(t,1,te,Z)?"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>":V?"":"<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>",a=this._get(t,"currentText"),r=this._get(t,"gotoCurrent")&&t.currentDay?$:j,a=K?this.formatDate(a,r,this._getFormatConfig(t)):a,h=t.inline?"":"<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>"+this._get(t,"closeText")+"</button>",l=B?"<div class='ui-datepicker-buttonpane ui-widget-content'>"+(Y?h:"")+(this._isInRange(t,r)?"<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'>"+a+"</button>":"")+(Y?"":h)+"</div>":"",c=parseInt(this._get(t,"firstDay"),10),c=isNaN(c)?0:c,u=this._get(t,"showWeek"),d=this._get(t,"dayNames"),p=this._get(t,"dayNamesMin"),f=this._get(t,"monthNames"),g=this._get(t,"monthNamesShort"),m=this._get(t,"beforeShowDay"),v=this._get(t,"showOtherMonths"),_=this._get(t,"selectOtherMonths"),b=this._getDefaultDate(t),y="",k=0;U[0]>k;k++){for(x="",this.maxRows=4,D=0;U[1]>D;D++){if(C=this._daylightSavingAdjust(new Date(te,Z,t.selectedDay)),I=" ui-corner-all",P="",X){if(P+="<div class='ui-datepicker-group",U[1]>1)switch(D){case 0:P+=" ui-datepicker-group-first",I=" ui-corner-"+(Y?"right":"left");break;case U[1]-1:P+=" ui-datepicker-group-last",I=" ui-corner-"+(Y?"left":"right");break;default:P+=" ui-datepicker-group-middle",I=""}P+="'>"}for(P+="<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix"+I+"'>"+(/all|left/.test(I)&&0===k?Y?o:s:"")+(/all|right/.test(I)&&0===k?Y?s:o:"")+this._generateMonthYearHeader(t,Z,te,G,J,k>0||D>0,f,g)+"</div><table class='ui-datepicker-calendar'><thead>"+"<tr>",T=u?"<th class='ui-datepicker-week-col'>"+this._get(t,"weekHeader")+"</th>":"",w=0;7>w;w++)M=(w+c)%7,T+="<th"+((w+c+6)%7>=5?" class='ui-datepicker-week-end'":"")+">"+"<span title='"+d[M]+"'>"+p[M]+"</span></th>";for(P+=T+"</tr></thead><tbody>",S=this._getDaysInMonth(te,Z),te===t.selectedYear&&Z===t.selectedMonth&&(t.selectedDay=Math.min(t.selectedDay,S)),z=(this._getFirstDayOfMonth(te,Z)-c+7)%7,A=Math.ceil((z+S)/7),H=X?this.maxRows>A?this.maxRows:A:A,this.maxRows=H,E=this._daylightSavingAdjust(new Date(te,Z,1-z)),N=0;H>N;N++){for(P+="<tr>",W=u?"<td class='ui-datepicker-week-col'>"+this._get(t,"calculateWeek")(E)+"</td>":"",w=0;7>w;w++)O=m?m.apply(t.input?t.input[0]:null,[E]):[!0,""],F=E.getMonth()!==Z,R=F&&!_||!O[0]||G&&G>E||J&&E>J,W+="<td class='"+((w+c+6)%7>=5?" ui-datepicker-week-end":"")+(F?" ui-datepicker-other-month":"")+(E.getTime()===C.getTime()&&Z===t.selectedMonth&&t._keyEvent||b.getTime()===E.getTime()&&b.getTime()===C.getTime()?" "+this._dayOverClass:"")+(R?" "+this._unselectableClass+" ui-state-disabled":"")+(F&&!v?"":" "+O[1]+(E.getTime()===$.getTime()?" "+this._currentClass:"")+(E.getTime()===j.getTime()?" ui-datepicker-today":""))+"'"+(F&&!v||!O[2]?"":" title='"+O[2].replace(/'/g,"&#39;")+"'")+(R?"":" data-handler='selectDay' data-event='click' data-month='"+E.getMonth()+"' data-year='"+E.getFullYear()+"'")+">"+(F&&!v?"&#xa0;":R?"<span class='ui-state-default'>"+E.getDate()+"</span>":"<a class='ui-state-default"+(E.getTime()===j.getTime()?" ui-state-highlight":"")+(E.getTime()===$.getTime()?" ui-state-active":"")+(F?" ui-priority-secondary":"")+"' href='#'>"+E.getDate()+"</a>")+"</td>",E.setDate(E.getDate()+1),E=this._daylightSavingAdjust(E);P+=W+"</tr>"}Z++,Z>11&&(Z=0,te++),P+="</tbody></table>"+(X?"</div>"+(U[0]>0&&D===U[1]-1?"<div class='ui-datepicker-row-break'></div>":""):""),x+=P}y+=x}return y+=l,t._keyEvent=!1,y},_generateMonthYearHeader:function(t,e,i,s,n,o,a,r){var h,l,c,u,d,p,f,g,m=this._get(t,"changeMonth"),v=this._get(t,"changeYear"),_=this._get(t,"showMonthAfterYear"),b="<div class='ui-datepicker-title'>",y="";if(o||!m)y+="<span class='ui-datepicker-month'>"+a[e]+"</span>";else{for(h=s&&s.getFullYear()===i,l=n&&n.getFullYear()===i,y+="<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>",c=0;12>c;c++)(!h||c>=s.getMonth())&&(!l||n.getMonth()>=c)&&(y+="<option value='"+c+"'"+(c===e?" selected='selected'":"")+">"+r[c]+"</option>");y+="</select>"}if(_||(b+=y+(!o&&m&&v?"":"&#xa0;")),!t.yearshtml)if(t.yearshtml="",o||!v)b+="<span class='ui-datepicker-year'>"+i+"</span>";else{for(u=this._get(t,"yearRange").split(":"),d=(new Date).getFullYear(),p=function(t){var e=t.match(/c[+\-].*/)?i+parseInt(t.substring(1),10):t.match(/[+\-].*/)?d+parseInt(t,10):parseInt(t,10);return isNaN(e)?d:e},f=p(u[0]),g=Math.max(f,p(u[1]||"")),f=s?Math.max(f,s.getFullYear()):f,g=n?Math.min(g,n.getFullYear()):g,t.yearshtml+="<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";g>=f;f++)t.yearshtml+="<option value='"+f+"'"+(f===i?" selected='selected'":"")+">"+f+"</option>";t.yearshtml+="</select>",b+=t.yearshtml,t.yearshtml=null}return b+=this._get(t,"yearSuffix"),_&&(b+=(!o&&m&&v?"":"&#xa0;")+y),b+="</div>"},_adjustInstDate:function(t,e,i){var s=t.drawYear+("Y"===i?e:0),n=t.drawMonth+("M"===i?e:0),o=Math.min(t.selectedDay,this._getDaysInMonth(s,n))+("D"===i?e:0),a=this._restrictMinMax(t,this._daylightSavingAdjust(new Date(s,n,o)));t.selectedDay=a.getDate(),t.drawMonth=t.selectedMonth=a.getMonth(),t.drawYear=t.selectedYear=a.getFullYear(),("M"===i||"Y"===i)&&this._notifyChange(t)},_restrictMinMax:function(t,e){var i=this._getMinMaxDate(t,"min"),s=this._getMinMaxDate(t,"max"),n=i&&i>e?i:e;return s&&n>s?s:n},_notifyChange:function(t){var e=this._get(t,"onChangeMonthYear");e&&e.apply(t.input?t.input[0]:null,[t.selectedYear,t.selectedMonth+1,t])},_getNumberOfMonths:function(t){var e=this._get(t,"numberOfMonths");return null==e?[1,1]:"number"==typeof e?[1,e]:e},_getMinMaxDate:function(t,e){return this._determineDate(t,this._get(t,e+"Date"),null)},_getDaysInMonth:function(t,e){return 32-this._daylightSavingAdjust(new Date(t,e,32)).getDate()},_getFirstDayOfMonth:function(t,e){return new Date(t,e,1).getDay()},_canAdjustMonth:function(t,e,i,s){var n=this._getNumberOfMonths(t),o=this._daylightSavingAdjust(new Date(i,s+(0>e?e:n[0]*n[1]),1));return 0>e&&o.setDate(this._getDaysInMonth(o.getFullYear(),o.getMonth())),this._isInRange(t,o)},_isInRange:function(t,e){var i,s,n=this._getMinMaxDate(t,"min"),o=this._getMinMaxDate(t,"max"),a=null,r=null,h=this._get(t,"yearRange");return h&&(i=h.split(":"),s=(new Date).getFullYear(),a=parseInt(i[0],10),r=parseInt(i[1],10),i[0].match(/[+\-].*/)&&(a+=s),i[1].match(/[+\-].*/)&&(r+=s)),(!n||e.getTime()>=n.getTime())&&(!o||e.getTime()<=o.getTime())&&(!a||e.getFullYear()>=a)&&(!r||r>=e.getFullYear())},_getFormatConfig:function(t){var e=this._get(t,"shortYearCutoff");return e="string"!=typeof e?e:(new Date).getFullYear()%100+parseInt(e,10),{shortYearCutoff:e,dayNamesShort:this._get(t,"dayNamesShort"),dayNames:this._get(t,"dayNames"),monthNamesShort:this._get(t,"monthNamesShort"),monthNames:this._get(t,"monthNames")}},_formatDate:function(t,e,i,s){e||(t.currentDay=t.selectedDay,t.currentMonth=t.selectedMonth,t.currentYear=t.selectedYear);var n=e?"object"==typeof e?e:this._daylightSavingAdjust(new Date(s,i,e)):this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return this.formatDate(this._get(t,"dateFormat"),n,this._getFormatConfig(t))}}),t.fn.datepicker=function(e){if(!this.length)return this;t.datepicker.initialized||(t(document).mousedown(t.datepicker._checkExternalClick),t.datepicker.initialized=!0),0===t("#"+t.datepicker._mainDivId).length&&t("body").append(t.datepicker.dpDiv);var i=Array.prototype.slice.call(arguments,1);return"string"!=typeof e||"isDisabled"!==e&&"getDate"!==e&&"widget"!==e?"option"===e&&2===arguments.length&&"string"==typeof arguments[1]?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i)):this.each(function(){"string"==typeof e?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this].concat(i)):t.datepicker._attachDatepicker(this,e)}):t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i))},t.datepicker=new i,t.datepicker.initialized=!1,t.datepicker.uuid=(new Date).getTime(),t.datepicker.version="1.10.3"}(jQuery),function(t){var e={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},i={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0};t.widget("ui.dialog",{version:"1.10.3",options:{appendTo:"body",autoOpen:!0,buttons:[],closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(e){var i=t(this).css(e).offset().top;0>i&&t(this).css("top",e.top-i)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),this.options.title=this.options.title||this.originalTitle,this._createWrapper(),this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(this.uiDialog),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&t.fn.draggable&&this._makeDraggable(),this.options.resizable&&t.fn.resizable&&this._makeResizable(),this._isOpen=!1},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var e=this.options.appendTo;return e&&(e.jquery||e.nodeType)?t(e):this.document.find(e||"body").eq(0)},_destroy:function(){var t,e=this.originalPosition;this._destroyOverlay(),this.element.removeUniqueId().removeClass("ui-dialog-content ui-widget-content").css(this.originalCss).detach(),this.uiDialog.stop(!0,!0).remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),t=e.parent.children().eq(e.index),t.length&&t[0]!==this.element[0]?t.before(this.element):e.parent.append(this.element)},widget:function(){return this.uiDialog},disable:t.noop,enable:t.noop,close:function(e){var i=this;this._isOpen&&this._trigger("beforeClose",e)!==!1&&(this._isOpen=!1,this._destroyOverlay(),this.opener.filter(":focusable").focus().length||t(this.document[0].activeElement).blur(),this._hide(this.uiDialog,this.options.hide,function(){i._trigger("close",e)}))},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(t,e){var i=!!this.uiDialog.nextAll(":visible").insertBefore(this.uiDialog).length;return i&&!e&&this._trigger("focus",t),i},open:function(){var e=this;return this._isOpen?(this._moveToTop()&&this._focusTabbable(),undefined):(this._isOpen=!0,this.opener=t(this.document[0].activeElement),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this._show(this.uiDialog,this.options.show,function(){e._focusTabbable(),e._trigger("focus")}),this._trigger("open"),undefined)},_focusTabbable:function(){var t=this.element.find("[autofocus]");t.length||(t=this.element.find(":tabbable")),t.length||(t=this.uiDialogButtonPane.find(":tabbable")),t.length||(t=this.uiDialogTitlebarClose.filter(":tabbable")),t.length||(t=this.uiDialog),t.eq(0).focus()},_keepFocus:function(e){function i(){var e=this.document[0].activeElement,i=this.uiDialog[0]===e||t.contains(this.uiDialog[0],e);i||this._focusTabbable()}e.preventDefault(),i.call(this),this._delay(i)},_createWrapper:function(){this.uiDialog=t("<div>").addClass("ui-dialog ui-widget ui-widget-content ui-corner-all ui-front "+this.options.dialogClass).hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._on(this.uiDialog,{keydown:function(e){if(this.options.closeOnEscape&&!e.isDefaultPrevented()&&e.keyCode&&e.keyCode===t.ui.keyCode.ESCAPE)return e.preventDefault(),this.close(e),undefined;if(e.keyCode===t.ui.keyCode.TAB){var i=this.uiDialog.find(":tabbable"),s=i.filter(":first"),n=i.filter(":last");e.target!==n[0]&&e.target!==this.uiDialog[0]||e.shiftKey?e.target!==s[0]&&e.target!==this.uiDialog[0]||!e.shiftKey||(n.focus(1),e.preventDefault()):(s.focus(1),e.preventDefault())}},mousedown:function(t){this._moveToTop(t)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var e;this.uiDialogTitlebar=t("<div>").addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(this.uiDialog),this._on(this.uiDialogTitlebar,{mousedown:function(e){t(e.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.focus()}}),this.uiDialogTitlebarClose=t("<button></button>").button({label:this.options.closeText,icons:{primary:"ui-icon-closethick"},text:!1}).addClass("ui-dialog-titlebar-close").appendTo(this.uiDialogTitlebar),this._on(this.uiDialogTitlebarClose,{click:function(t){t.preventDefault(),this.close(t)}}),e=t("<span>").uniqueId().addClass("ui-dialog-title").prependTo(this.uiDialogTitlebar),this._title(e),this.uiDialog.attr({"aria-labelledby":e.attr("id")})},_title:function(t){this.options.title||t.html("&#160;"),t.text(this.options.title)},_createButtonPane:function(){this.uiDialogButtonPane=t("<div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),this.uiButtonSet=t("<div>").addClass("ui-dialog-buttonset").appendTo(this.uiDialogButtonPane),this._createButtons()},_createButtons:function(){var e=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),t.isEmptyObject(i)||t.isArray(i)&&!i.length?(this.uiDialog.removeClass("ui-dialog-buttons"),undefined):(t.each(i,function(i,s){var n,o;s=t.isFunction(s)?{click:s,text:i}:s,s=t.extend({type:"button"},s),n=s.click,s.click=function(){n.apply(e.element[0],arguments)},o={icons:s.icons,text:s.showText},delete s.icons,delete s.showText,t("<button></button>",s).button(o).appendTo(e.uiButtonSet)}),this.uiDialog.addClass("ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),undefined)},_makeDraggable:function(){function e(t){return{position:t.position,offset:t.offset}}var i=this,s=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(s,n){t(this).addClass("ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",s,e(n))},drag:function(t,s){i._trigger("drag",t,e(s))},stop:function(n,o){s.position=[o.position.left-i.document.scrollLeft(),o.position.top-i.document.scrollTop()],t(this).removeClass("ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",n,e(o))}})},_makeResizable:function(){function e(t){return{originalPosition:t.originalPosition,originalSize:t.originalSize,position:t.position,size:t.size}
+}var i=this,s=this.options,n=s.resizable,o=this.uiDialog.css("position"),a="string"==typeof n?n:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:s.maxWidth,maxHeight:s.maxHeight,minWidth:s.minWidth,minHeight:this._minHeight(),handles:a,start:function(s,n){t(this).addClass("ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",s,e(n))},resize:function(t,s){i._trigger("resize",t,e(s))},stop:function(n,o){s.height=t(this).height(),s.width=t(this).width(),t(this).removeClass("ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",n,e(o))}}).css("position",o)},_minHeight:function(){var t=this.options;return"auto"===t.height?t.minHeight:Math.min(t.minHeight,t.height)},_position:function(){var t=this.uiDialog.is(":visible");t||this.uiDialog.show(),this.uiDialog.position(this.options.position),t||this.uiDialog.hide()},_setOptions:function(s){var n=this,o=!1,a={};t.each(s,function(t,s){n._setOption(t,s),t in e&&(o=!0),t in i&&(a[t]=s)}),o&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",a)},_setOption:function(t,e){var i,s,n=this.uiDialog;"dialogClass"===t&&n.removeClass(this.options.dialogClass).addClass(e),"disabled"!==t&&(this._super(t,e),"appendTo"===t&&this.uiDialog.appendTo(this._appendTo()),"buttons"===t&&this._createButtons(),"closeText"===t&&this.uiDialogTitlebarClose.button({label:""+e}),"draggable"===t&&(i=n.is(":data(ui-draggable)"),i&&!e&&n.draggable("destroy"),!i&&e&&this._makeDraggable()),"position"===t&&this._position(),"resizable"===t&&(s=n.is(":data(ui-resizable)"),s&&!e&&n.resizable("destroy"),s&&"string"==typeof e&&n.resizable("option","handles",e),s||e===!1||this._makeResizable()),"title"===t&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var t,e,i,s=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),s.minWidth>s.width&&(s.width=s.minWidth),t=this.uiDialog.css({height:"auto",width:s.width}).outerHeight(),e=Math.max(0,s.minHeight-t),i="number"==typeof s.maxHeight?Math.max(0,s.maxHeight-t):"none","auto"===s.height?this.element.css({minHeight:e,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,s.height-t)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var e=t(this);return t("<div>").css({position:"absolute",width:e.outerWidth(),height:e.outerHeight()}).appendTo(e.parent()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(e){return t(e.target).closest(".ui-dialog").length?!0:!!t(e.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var e=this,i=this.widgetFullName;t.ui.dialog.overlayInstances||this._delay(function(){t.ui.dialog.overlayInstances&&this.document.bind("focusin.dialog",function(s){e._allowInteraction(s)||(s.preventDefault(),t(".ui-dialog:visible:last .ui-dialog-content").data(i)._focusTabbable())})}),this.overlay=t("<div>").addClass("ui-widget-overlay ui-front").appendTo(this._appendTo()),this._on(this.overlay,{mousedown:"_keepFocus"}),t.ui.dialog.overlayInstances++}},_destroyOverlay:function(){this.options.modal&&this.overlay&&(t.ui.dialog.overlayInstances--,t.ui.dialog.overlayInstances||this.document.unbind("focusin.dialog"),this.overlay.remove(),this.overlay=null)}}),t.ui.dialog.overlayInstances=0,t.uiBackCompat!==!1&&t.widget("ui.dialog",t.ui.dialog,{_position:function(){var e,i=this.options.position,s=[],n=[0,0];i?(("string"==typeof i||"object"==typeof i&&"0"in i)&&(s=i.split?i.split(" "):[i[0],i[1]],1===s.length&&(s[1]=s[0]),t.each(["left","top"],function(t,e){+s[t]===s[t]&&(n[t]=s[t],s[t]=e)}),i={my:s[0]+(0>n[0]?n[0]:"+"+n[0])+" "+s[1]+(0>n[1]?n[1]:"+"+n[1]),at:s.join(" ")}),i=t.extend({},t.ui.dialog.prototype.options.position,i)):i=t.ui.dialog.prototype.options.position,e=this.uiDialog.is(":visible"),e||this.uiDialog.show(),this.uiDialog.position(i),e||this.uiDialog.hide()}})}(jQuery),function(t){var e=/up|down|vertical/,i=/up|left|vertical|horizontal/;t.effects.effect.blind=function(s,n){var o,a,r,h=t(this),l=["position","top","bottom","left","right","height","width"],c=t.effects.setMode(h,s.mode||"hide"),u=s.direction||"up",d=e.test(u),p=d?"height":"width",f=d?"top":"left",g=i.test(u),m={},v="show"===c;h.parent().is(".ui-effects-wrapper")?t.effects.save(h.parent(),l):t.effects.save(h,l),h.show(),o=t.effects.createWrapper(h).css({overflow:"hidden"}),a=o[p](),r=parseFloat(o.css(f))||0,m[p]=v?a:0,g||(h.css(d?"bottom":"right",0).css(d?"top":"left","auto").css({position:"absolute"}),m[f]=v?r:a+r),v&&(o.css(p,0),g||o.css(f,r+a)),o.animate(m,{duration:s.duration,easing:s.easing,queue:!1,complete:function(){"hide"===c&&h.hide(),t.effects.restore(h,l),t.effects.removeWrapper(h),n()}})}}(jQuery),function(t){t.effects.effect.bounce=function(e,i){var s,n,o,a=t(this),r=["position","top","bottom","left","right","height","width"],h=t.effects.setMode(a,e.mode||"effect"),l="hide"===h,c="show"===h,u=e.direction||"up",d=e.distance,p=e.times||5,f=2*p+(c||l?1:0),g=e.duration/f,m=e.easing,v="up"===u||"down"===u?"top":"left",_="up"===u||"left"===u,b=a.queue(),y=b.length;for((c||l)&&r.push("opacity"),t.effects.save(a,r),a.show(),t.effects.createWrapper(a),d||(d=a["top"===v?"outerHeight":"outerWidth"]()/3),c&&(o={opacity:1},o[v]=0,a.css("opacity",0).css(v,_?2*-d:2*d).animate(o,g,m)),l&&(d/=Math.pow(2,p-1)),o={},o[v]=0,s=0;p>s;s++)n={},n[v]=(_?"-=":"+=")+d,a.animate(n,g,m).animate(o,g,m),d=l?2*d:d/2;l&&(n={opacity:0},n[v]=(_?"-=":"+=")+d,a.animate(n,g,m)),a.queue(function(){l&&a.hide(),t.effects.restore(a,r),t.effects.removeWrapper(a),i()}),y>1&&b.splice.apply(b,[1,0].concat(b.splice(y,f+1))),a.dequeue()}}(jQuery),function(t){t.effects.effect.clip=function(e,i){var s,n,o,a=t(this),r=["position","top","bottom","left","right","height","width"],h=t.effects.setMode(a,e.mode||"hide"),l="show"===h,c=e.direction||"vertical",u="vertical"===c,d=u?"height":"width",p=u?"top":"left",f={};t.effects.save(a,r),a.show(),s=t.effects.createWrapper(a).css({overflow:"hidden"}),n="IMG"===a[0].tagName?s:a,o=n[d](),l&&(n.css(d,0),n.css(p,o/2)),f[d]=l?o:0,f[p]=l?0:o/2,n.animate(f,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){l||a.hide(),t.effects.restore(a,r),t.effects.removeWrapper(a),i()}})}}(jQuery),function(t){t.effects.effect.drop=function(e,i){var s,n=t(this),o=["position","top","bottom","left","right","opacity","height","width"],a=t.effects.setMode(n,e.mode||"hide"),r="show"===a,h=e.direction||"left",l="up"===h||"down"===h?"top":"left",c="up"===h||"left"===h?"pos":"neg",u={opacity:r?1:0};t.effects.save(n,o),n.show(),t.effects.createWrapper(n),s=e.distance||n["top"===l?"outerHeight":"outerWidth"](!0)/2,r&&n.css("opacity",0).css(l,"pos"===c?-s:s),u[l]=(r?"pos"===c?"+=":"-=":"pos"===c?"-=":"+=")+s,n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===a&&n.hide(),t.effects.restore(n,o),t.effects.removeWrapper(n),i()}})}}(jQuery),function(t){t.effects.effect.explode=function(e,i){function s(){b.push(this),b.length===u*d&&n()}function n(){p.css({visibility:"visible"}),t(b).remove(),g||p.hide(),i()}var o,a,r,h,l,c,u=e.pieces?Math.round(Math.sqrt(e.pieces)):3,d=u,p=t(this),f=t.effects.setMode(p,e.mode||"hide"),g="show"===f,m=p.show().css("visibility","hidden").offset(),v=Math.ceil(p.outerWidth()/d),_=Math.ceil(p.outerHeight()/u),b=[];for(o=0;u>o;o++)for(h=m.top+o*_,c=o-(u-1)/2,a=0;d>a;a++)r=m.left+a*v,l=a-(d-1)/2,p.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-a*v,top:-o*_}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:v,height:_,left:r+(g?l*v:0),top:h+(g?c*_:0),opacity:g?0:1}).animate({left:r+(g?0:l*v),top:h+(g?0:c*_),opacity:g?1:0},e.duration||500,e.easing,s)}}(jQuery),function(t){t.effects.effect.fade=function(e,i){var s=t(this),n=t.effects.setMode(s,e.mode||"toggle");s.animate({opacity:n},{queue:!1,duration:e.duration,easing:e.easing,complete:i})}}(jQuery),function(t){t.effects.effect.fold=function(e,i){var s,n,o=t(this),a=["position","top","bottom","left","right","height","width"],r=t.effects.setMode(o,e.mode||"hide"),h="show"===r,l="hide"===r,c=e.size||15,u=/([0-9]+)%/.exec(c),d=!!e.horizFirst,p=h!==d,f=p?["width","height"]:["height","width"],g=e.duration/2,m={},v={};t.effects.save(o,a),o.show(),s=t.effects.createWrapper(o).css({overflow:"hidden"}),n=p?[s.width(),s.height()]:[s.height(),s.width()],u&&(c=parseInt(u[1],10)/100*n[l?0:1]),h&&s.css(d?{height:0,width:c}:{height:c,width:0}),m[f[0]]=h?n[0]:c,v[f[1]]=h?n[1]:0,s.animate(m,g,e.easing).animate(v,g,e.easing,function(){l&&o.hide(),t.effects.restore(o,a),t.effects.removeWrapper(o),i()})}}(jQuery),function(t){t.effects.effect.highlight=function(e,i){var s=t(this),n=["backgroundImage","backgroundColor","opacity"],o=t.effects.setMode(s,e.mode||"show"),a={backgroundColor:s.css("backgroundColor")};"hide"===o&&(a.opacity=0),t.effects.save(s,n),s.show().css({backgroundImage:"none",backgroundColor:e.color||"#ffff99"}).animate(a,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===o&&s.hide(),t.effects.restore(s,n),i()}})}}(jQuery),function(t){t.effects.effect.pulsate=function(e,i){var s,n=t(this),o=t.effects.setMode(n,e.mode||"show"),a="show"===o,r="hide"===o,h=a||"hide"===o,l=2*(e.times||5)+(h?1:0),c=e.duration/l,u=0,d=n.queue(),p=d.length;for((a||!n.is(":visible"))&&(n.css("opacity",0).show(),u=1),s=1;l>s;s++)n.animate({opacity:u},c,e.easing),u=1-u;n.animate({opacity:u},c,e.easing),n.queue(function(){r&&n.hide(),i()}),p>1&&d.splice.apply(d,[1,0].concat(d.splice(p,l+1))),n.dequeue()}}(jQuery),function(t){t.effects.effect.puff=function(e,i){var s=t(this),n=t.effects.setMode(s,e.mode||"hide"),o="hide"===n,a=parseInt(e.percent,10)||150,r=a/100,h={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()};t.extend(e,{effect:"scale",queue:!1,fade:!0,mode:n,complete:i,percent:o?a:100,from:o?h:{height:h.height*r,width:h.width*r,outerHeight:h.outerHeight*r,outerWidth:h.outerWidth*r}}),s.effect(e)},t.effects.effect.scale=function(e,i){var s=t(this),n=t.extend(!0,{},e),o=t.effects.setMode(s,e.mode||"effect"),a=parseInt(e.percent,10)||(0===parseInt(e.percent,10)?0:"hide"===o?0:100),r=e.direction||"both",h=e.origin,l={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()},c={y:"horizontal"!==r?a/100:1,x:"vertical"!==r?a/100:1};n.effect="size",n.queue=!1,n.complete=i,"effect"!==o&&(n.origin=h||["middle","center"],n.restore=!0),n.from=e.from||("show"===o?{height:0,width:0,outerHeight:0,outerWidth:0}:l),n.to={height:l.height*c.y,width:l.width*c.x,outerHeight:l.outerHeight*c.y,outerWidth:l.outerWidth*c.x},n.fade&&("show"===o&&(n.from.opacity=0,n.to.opacity=1),"hide"===o&&(n.from.opacity=1,n.to.opacity=0)),s.effect(n)},t.effects.effect.size=function(e,i){var s,n,o,a=t(this),r=["position","top","bottom","left","right","width","height","overflow","opacity"],h=["position","top","bottom","left","right","overflow","opacity"],l=["width","height","overflow"],c=["fontSize"],u=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],d=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=t.effects.setMode(a,e.mode||"effect"),f=e.restore||"effect"!==p,g=e.scale||"both",m=e.origin||["middle","center"],v=a.css("position"),_=f?r:h,b={height:0,width:0,outerHeight:0,outerWidth:0};"show"===p&&a.show(),s={height:a.height(),width:a.width(),outerHeight:a.outerHeight(),outerWidth:a.outerWidth()},"toggle"===e.mode&&"show"===p?(a.from=e.to||b,a.to=e.from||s):(a.from=e.from||("show"===p?b:s),a.to=e.to||("hide"===p?b:s)),o={from:{y:a.from.height/s.height,x:a.from.width/s.width},to:{y:a.to.height/s.height,x:a.to.width/s.width}},("box"===g||"both"===g)&&(o.from.y!==o.to.y&&(_=_.concat(u),a.from=t.effects.setTransition(a,u,o.from.y,a.from),a.to=t.effects.setTransition(a,u,o.to.y,a.to)),o.from.x!==o.to.x&&(_=_.concat(d),a.from=t.effects.setTransition(a,d,o.from.x,a.from),a.to=t.effects.setTransition(a,d,o.to.x,a.to))),("content"===g||"both"===g)&&o.from.y!==o.to.y&&(_=_.concat(c).concat(l),a.from=t.effects.setTransition(a,c,o.from.y,a.from),a.to=t.effects.setTransition(a,c,o.to.y,a.to)),t.effects.save(a,_),a.show(),t.effects.createWrapper(a),a.css("overflow","hidden").css(a.from),m&&(n=t.effects.getBaseline(m,s),a.from.top=(s.outerHeight-a.outerHeight())*n.y,a.from.left=(s.outerWidth-a.outerWidth())*n.x,a.to.top=(s.outerHeight-a.to.outerHeight)*n.y,a.to.left=(s.outerWidth-a.to.outerWidth)*n.x),a.css(a.from),("content"===g||"both"===g)&&(u=u.concat(["marginTop","marginBottom"]).concat(c),d=d.concat(["marginLeft","marginRight"]),l=r.concat(u).concat(d),a.find("*[width]").each(function(){var i=t(this),s={height:i.height(),width:i.width(),outerHeight:i.outerHeight(),outerWidth:i.outerWidth()};f&&t.effects.save(i,l),i.from={height:s.height*o.from.y,width:s.width*o.from.x,outerHeight:s.outerHeight*o.from.y,outerWidth:s.outerWidth*o.from.x},i.to={height:s.height*o.to.y,width:s.width*o.to.x,outerHeight:s.height*o.to.y,outerWidth:s.width*o.to.x},o.from.y!==o.to.y&&(i.from=t.effects.setTransition(i,u,o.from.y,i.from),i.to=t.effects.setTransition(i,u,o.to.y,i.to)),o.from.x!==o.to.x&&(i.from=t.effects.setTransition(i,d,o.from.x,i.from),i.to=t.effects.setTransition(i,d,o.to.x,i.to)),i.css(i.from),i.animate(i.to,e.duration,e.easing,function(){f&&t.effects.restore(i,l)})})),a.animate(a.to,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){0===a.to.opacity&&a.css("opacity",a.from.opacity),"hide"===p&&a.hide(),t.effects.restore(a,_),f||("static"===v?a.css({position:"relative",top:a.to.top,left:a.to.left}):t.each(["top","left"],function(t,e){a.css(e,function(e,i){var s=parseInt(i,10),n=t?a.to.left:a.to.top;return"auto"===i?n+"px":s+n+"px"})})),t.effects.removeWrapper(a),i()}})}}(jQuery),function(t){t.effects.effect.shake=function(e,i){var s,n=t(this),o=["position","top","bottom","left","right","height","width"],a=t.effects.setMode(n,e.mode||"effect"),r=e.direction||"left",h=e.distance||20,l=e.times||3,c=2*l+1,u=Math.round(e.duration/c),d="up"===r||"down"===r?"top":"left",p="up"===r||"left"===r,f={},g={},m={},v=n.queue(),_=v.length;for(t.effects.save(n,o),n.show(),t.effects.createWrapper(n),f[d]=(p?"-=":"+=")+h,g[d]=(p?"+=":"-=")+2*h,m[d]=(p?"-=":"+=")+2*h,n.animate(f,u,e.easing),s=1;l>s;s++)n.animate(g,u,e.easing).animate(m,u,e.easing);n.animate(g,u,e.easing).animate(f,u/2,e.easing).queue(function(){"hide"===a&&n.hide(),t.effects.restore(n,o),t.effects.removeWrapper(n),i()}),_>1&&v.splice.apply(v,[1,0].concat(v.splice(_,c+1))),n.dequeue()}}(jQuery),function(t){t.effects.effect.slide=function(e,i){var s,n=t(this),o=["position","top","bottom","left","right","width","height"],a=t.effects.setMode(n,e.mode||"show"),r="show"===a,h=e.direction||"left",l="up"===h||"down"===h?"top":"left",c="up"===h||"left"===h,u={};t.effects.save(n,o),n.show(),s=e.distance||n["top"===l?"outerHeight":"outerWidth"](!0),t.effects.createWrapper(n).css({overflow:"hidden"}),r&&n.css(l,c?isNaN(s)?"-"+s:-s:s),u[l]=(r?c?"+=":"-=":c?"-=":"+=")+s,n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===a&&n.hide(),t.effects.restore(n,o),t.effects.removeWrapper(n),i()}})}}(jQuery),function(t){t.effects.effect.transfer=function(e,i){var s=t(this),n=t(e.to),o="fixed"===n.css("position"),a=t("body"),r=o?a.scrollTop():0,h=o?a.scrollLeft():0,l=n.offset(),c={top:l.top-r,left:l.left-h,height:n.innerHeight(),width:n.innerWidth()},u=s.offset(),d=t("<div class='ui-effects-transfer'></div>").appendTo(document.body).addClass(e.className).css({top:u.top-r,left:u.left-h,height:s.innerHeight(),width:s.innerWidth(),position:o?"fixed":"absolute"}).animate(c,e.duration,e.easing,function(){d.remove(),i()})}}(jQuery),function(t){t.widget("ui.menu",{version:"1.10.3",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content ui-corner-all").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}).bind("click"+this.eventNamespace,t.proxy(function(t){this.options.disabled&&t.preventDefault()},this)),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({"mousedown .ui-menu-item > a":function(t){t.preventDefault()},"click .ui-state-disabled > a":function(t){t.preventDefault()},"click .ui-menu-item:has(a)":function(e){var i=t(e.target).closest(".ui-menu-item");!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.mouseHandled=!0,this.select(e),i.has(".ui-menu").length?this.expand(e):this.element.is(":focus")||(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(e){var i=t(e.currentTarget);i.siblings().children(".ui-state-active").removeClass("ui-state-active"),this.focus(e,i)},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this.element.children(".ui-menu-item").eq(0);e||this.focus(t,i)},blur:function(e){this._delay(function(){t.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(e)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(e){t(e.target).closest(".ui-menu").length||this.collapseAll(e),this.mouseHandled=!1}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeClass("ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").children("a").removeUniqueId().removeClass("ui-corner-all ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var e=t(this);e.data("ui-menu-submenu-carat")&&e.remove()}),this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(e){function i(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}var s,n,o,a,r,h=!0;switch(e.keyCode){case t.ui.keyCode.PAGE_UP:this.previousPage(e);break;case t.ui.keyCode.PAGE_DOWN:this.nextPage(e);break;case t.ui.keyCode.HOME:this._move("first","first",e);break;case t.ui.keyCode.END:this._move("last","last",e);break;case t.ui.keyCode.UP:this.previous(e);break;case t.ui.keyCode.DOWN:this.next(e);break;case t.ui.keyCode.LEFT:this.collapse(e);break;case t.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(e);break;case t.ui.keyCode.ENTER:case t.ui.keyCode.SPACE:this._activate(e);break;case t.ui.keyCode.ESCAPE:this.collapse(e);break;default:h=!1,n=this.previousFilter||"",o=String.fromCharCode(e.keyCode),a=!1,clearTimeout(this.filterTimer),o===n?a=!0:o=n+o,r=RegExp("^"+i(o),"i"),s=this.activeMenu.children(".ui-menu-item").filter(function(){return r.test(t(this).children("a").text())}),s=a&&-1!==s.index(this.active.next())?this.active.nextAll(".ui-menu-item"):s,s.length||(o=String.fromCharCode(e.keyCode),r=RegExp("^"+i(o),"i"),s=this.activeMenu.children(".ui-menu-item").filter(function(){return r.test(t(this).children("a").text())})),s.length?(this.focus(e,s),s.length>1?(this.previousFilter=o,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter):delete this.previousFilter}h&&e.preventDefault()},_activate:function(t){this.active.is(".ui-state-disabled")||(this.active.children("a[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var e,i=this.options.icons.submenu,s=this.element.find(this.options.menus);s.filter(":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-corner-all").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var e=t(this),s=e.prev("a"),n=t("<span>").addClass("ui-menu-icon ui-icon "+i).data("ui-menu-submenu-carat",!0);s.attr("aria-haspopup","true").prepend(n),e.attr("aria-labelledby",s.attr("id"))}),e=s.add(this.element),e.children(":not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","presentation").children("a").uniqueId().addClass("ui-corner-all").attr({tabIndex:-1,role:this._itemRole()}),e.children(":not(.ui-menu-item)").each(function(){var e=t(this);/[^\-\u2014\u2013\s]/.test(e.text())||e.addClass("ui-widget-content ui-menu-divider")}),e.children(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!t.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){"icons"===t&&this.element.find(".ui-menu-icon").removeClass(this.options.icons.submenu).addClass(e.submenu),this._super(t,e)},focus:function(t,e){var i,s;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),s=this.active.children("a").addClass("ui-state-focus"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),this.active.parent().closest(".ui-menu-item").children("a:first").addClass("ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=e.children(".ui-menu"),i.length&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(e){var i,s,n,o,a,r;this._hasScroll()&&(i=parseFloat(t.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(t.css(this.activeMenu[0],"paddingTop"))||0,n=e.offset().top-this.activeMenu.offset().top-i-s,o=this.activeMenu.scrollTop(),a=this.activeMenu.height(),r=e.height(),0>n?this.activeMenu.scrollTop(o+n):n+r>a&&this.activeMenu.scrollTop(o+n-a+r))},blur:function(t,e){e||clearTimeout(this.timer),this.active&&(this.active.children("a").removeClass("ui-state-focus"),this.active=null,this._trigger("blur",t,{item:this.active}))},_startOpening:function(t){clearTimeout(this.timer),"true"===t.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(t)},this.delay))},_open:function(e){var i=t.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(e.parents(".ui-menu")).hide().attr("aria-hidden","true"),e.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(e,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:t(e&&e.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(e),this.activeMenu=s},this.delay)},_close:function(t){t||(t=this.active?this.active.parent():this.element),t.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find("a.ui-state-active").removeClass("ui-state-active")},collapse:function(t){var e=this.active&&this.active.parent().closest(".ui-menu-item",this.element);e&&e.length&&(this._close(),this.focus(t,e))},expand:function(t){var e=this.active&&this.active.children(".ui-menu ").children(".ui-menu-item").first();e&&e.length&&(this._open(e.parent()),this._delay(function(){this.focus(t,e)}))},next:function(t){this._move("next","first",t)},previous:function(t){this._move("prev","last",t)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(t,e,i){var s;this.active&&(s="first"===t||"last"===t?this.active["first"===t?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[t+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.children(".ui-menu-item")[e]()),this.focus(i,s)},nextPage:function(e){var i,s,n;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=t(this),0>i.offset().top-s-n}),this.focus(e,i)):this.focus(e,this.activeMenu.children(".ui-menu-item")[this.active?"last":"first"]())),undefined):(this.next(e),undefined)},previousPage:function(e){var i,s,n;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=t(this),i.offset().top-s+n>0}),this.focus(e,i)):this.focus(e,this.activeMenu.children(".ui-menu-item").first())),undefined):(this.next(e),undefined)},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(e){this.active=this.active||t(e.target).closest(".ui-menu-item");var i={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(e,!0),this._trigger("select",e,i)}})}(jQuery),function(t,e){function i(t,e,i){return[parseFloat(t[0])*(p.test(t[0])?e/100:1),parseFloat(t[1])*(p.test(t[1])?i/100:1)]}function s(e,i){return parseInt(t.css(e,i),10)||0}function n(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}t.ui=t.ui||{};var o,a=Math.max,r=Math.abs,h=Math.round,l=/left|center|right/,c=/top|center|bottom/,u=/[\+\-]\d+(\.[\d]+)?%?/,d=/^\w+/,p=/%$/,f=t.fn.position;t.position={scrollbarWidth:function(){if(o!==e)return o;var i,s,n=t("<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),a=n.children()[0];return t("body").append(n),i=a.offsetWidth,n.css("overflow","scroll"),s=a.offsetWidth,i===s&&(s=n[0].clientWidth),n.remove(),o=i-s},getScrollInfo:function(e){var i=e.isWindow?"":e.element.css("overflow-x"),s=e.isWindow?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.width<e.element[0].scrollWidth,o="scroll"===s||"auto"===s&&e.height<e.element[0].scrollHeight;return{width:o?t.position.scrollbarWidth():0,height:n?t.position.scrollbarWidth():0}},getWithinInfo:function(e){var i=t(e||window),s=t.isWindow(i[0]);return{element:i,isWindow:s,offset:i.offset()||{left:0,top:0},scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:s?i.width():i.outerWidth(),height:s?i.height():i.outerHeight()}}},t.fn.position=function(e){if(!e||!e.of)return f.apply(this,arguments);e=t.extend({},e);var o,p,g,m,v,_,b=t(e.of),y=t.position.getWithinInfo(e.within),w=t.position.getScrollInfo(y),k=(e.collision||"flip").split(" "),x={};return _=n(b),b[0].preventDefault&&(e.at="left top"),p=_.width,g=_.height,m=_.offset,v=t.extend({},m),t.each(["my","at"],function(){var t,i,s=(e[this]||"").split(" ");1===s.length&&(s=l.test(s[0])?s.concat(["center"]):c.test(s[0])?["center"].concat(s):["center","center"]),s[0]=l.test(s[0])?s[0]:"center",s[1]=c.test(s[1])?s[1]:"center",t=u.exec(s[0]),i=u.exec(s[1]),x[this]=[t?t[0]:0,i?i[0]:0],e[this]=[d.exec(s[0])[0],d.exec(s[1])[0]]}),1===k.length&&(k[1]=k[0]),"right"===e.at[0]?v.left+=p:"center"===e.at[0]&&(v.left+=p/2),"bottom"===e.at[1]?v.top+=g:"center"===e.at[1]&&(v.top+=g/2),o=i(x.at,p,g),v.left+=o[0],v.top+=o[1],this.each(function(){var n,l,c=t(this),u=c.outerWidth(),d=c.outerHeight(),f=s(this,"marginLeft"),_=s(this,"marginTop"),D=u+f+s(this,"marginRight")+w.width,C=d+_+s(this,"marginBottom")+w.height,I=t.extend({},v),P=i(x.my,c.outerWidth(),c.outerHeight());"right"===e.my[0]?I.left-=u:"center"===e.my[0]&&(I.left-=u/2),"bottom"===e.my[1]?I.top-=d:"center"===e.my[1]&&(I.top-=d/2),I.left+=P[0],I.top+=P[1],t.support.offsetFractions||(I.left=h(I.left),I.top=h(I.top)),n={marginLeft:f,marginTop:_},t.each(["left","top"],function(i,s){t.ui.position[k[i]]&&t.ui.position[k[i]][s](I,{targetWidth:p,targetHeight:g,elemWidth:u,elemHeight:d,collisionPosition:n,collisionWidth:D,collisionHeight:C,offset:[o[0]+P[0],o[1]+P[1]],my:e.my,at:e.at,within:y,elem:c})}),e.using&&(l=function(t){var i=m.left-I.left,s=i+p-u,n=m.top-I.top,o=n+g-d,h={target:{element:b,left:m.left,top:m.top,width:p,height:g},element:{element:c,left:I.left,top:I.top,width:u,height:d},horizontal:0>s?"left":i>0?"right":"center",vertical:0>o?"top":n>0?"bottom":"middle"};u>p&&p>r(i+s)&&(h.horizontal="center"),d>g&&g>r(n+o)&&(h.vertical="middle"),h.important=a(r(i),r(s))>a(r(n),r(o))?"horizontal":"vertical",e.using.call(this,t,h)}),c.offset(t.extend(I,{using:l}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,o=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-o-n;e.collisionWidth>o?h>0&&0>=l?(i=t.left+h+e.collisionWidth-o-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+o-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=a(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,o=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-o-n;e.collisionHeight>o?h>0&&0>=l?(i=t.top+h+e.collisionHeight-o-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+o-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=a(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,a=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-a-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-a-o,(0>i||r(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>r(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,a=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-a-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];0>c?(s=t.top+p+f+g+e.collisionHeight-a-o,t.top+p+f+g>c&&(0>s||r(c)>s)&&(t.top+=p+f+g)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+g-h,t.top+p+f+g>u&&(i>0||u>r(i))&&(t.top+=p+f+g))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}},function(){var e,i,s,n,o,a=document.getElementsByTagName("body")[0],r=document.createElement("div");e=document.createElement(a?"div":"body"),s={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},a&&t.extend(s,{position:"absolute",left:"-1000px",top:"-1000px"});for(o in s)e.style[o]=s[o];e.appendChild(r),i=a||document.documentElement,i.insertBefore(e,i.firstChild),r.style.cssText="position: absolute; left: 10.7432222px;",n=t(r).offset().left,t.support.offsetFractions=n>10&&11>n,e.innerHTML="",i.removeChild(e)}()}(jQuery),function(t,e){t.widget("ui.progressbar",{version:"1.10.3",options:{max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min}),this.valueDiv=t("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element),this._refreshValue()},_destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove()
+},value:function(t){return t===e?this.options.value:(this.options.value=this._constrainedValue(t),this._refreshValue(),e)},_constrainedValue:function(t){return t===e&&(t=this.options.value),this.indeterminate=t===!1,"number"!=typeof t&&(t=0),this.indeterminate?!1:Math.min(this.options.max,Math.max(this.min,t))},_setOptions:function(t){var e=t.value;delete t.value,this._super(t),this.options.value=this._constrainedValue(e),this._refreshValue()},_setOption:function(t,e){"max"===t&&(e=Math.max(this.min,e)),this._super(t,e)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var e=this.options.value,i=this._percentage();this.valueDiv.toggle(this.indeterminate||e>this.min).toggleClass("ui-corner-right",e===this.options.max).width(i.toFixed(0)+"%"),this.element.toggleClass("ui-progressbar-indeterminate",this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=t("<div class='ui-progressbar-overlay'></div>").appendTo(this.valueDiv))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":e}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==e&&(this.oldValue=e,this._trigger("change")),e===this.options.max&&this._trigger("complete")}})}(jQuery),function(t){var e=5;t.widget("ui.slider",t.ui.mouse,{version:"1.10.3",widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"),this._refresh(),this._setOption("disabled",this.options.disabled),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var e,i,s=this.options,n=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),o="<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",a=[];for(i=s.values&&s.values.length||1,n.length>i&&(n.slice(i).remove(),n=n.slice(0,i)),e=n.length;i>e;e++)a.push(o);this.handles=n.add(t(a.join("")).appendTo(this.element)),this.handle=this.handles.eq(0),this.handles.each(function(e){t(this).data("ui-slider-handle-index",e)})},_createRange:function(){var e=this.options,i="";e.range?(e.range===!0&&(e.values?e.values.length&&2!==e.values.length?e.values=[e.values[0],e.values[0]]:t.isArray(e.values)&&(e.values=e.values.slice(0)):e.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?this.range.removeClass("ui-slider-range-min ui-slider-range-max").css({left:"",bottom:""}):(this.range=t("<div></div>").appendTo(this.element),i="ui-slider-range ui-widget-header ui-corner-all"),this.range.addClass(i+("min"===e.range||"max"===e.range?" ui-slider-range-"+e.range:""))):this.range=t([])},_setupEvents:function(){var t=this.handles.add(this.range).filter("a");this._off(t),this._on(t,this._handleEvents),this._hoverable(t),this._focusable(t)},_destroy:function(){this.handles.remove(),this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-widget ui-widget-content ui-corner-all"),this._mouseDestroy()},_mouseCapture:function(e){var i,s,n,o,a,r,h,l,c=this,u=this.options;return u.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),i={x:e.pageX,y:e.pageY},s=this._normValueFromMouse(i),n=this._valueMax()-this._valueMin()+1,this.handles.each(function(e){var i=Math.abs(s-c.values(e));(n>i||n===i&&(e===c._lastChangedValue||c.values(e)===u.min))&&(n=i,o=t(this),a=e)}),r=this._start(e,a),r===!1?!1:(this._mouseSliding=!0,this._handleIndex=a,o.addClass("ui-state-active").focus(),h=o.offset(),l=!t(e.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:e.pageX-h.left-o.width()/2,top:e.pageY-h.top-o.height()/2-(parseInt(o.css("borderTopWidth"),10)||0)-(parseInt(o.css("borderBottomWidth"),10)||0)+(parseInt(o.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(e,a,s),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(t){var e={x:t.pageX,y:t.pageY},i=this._normValueFromMouse(e);return this._slide(t,this._handleIndex,i),!1},_mouseStop:function(t){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(t,this._handleIndex),this._change(t,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(t){var e,i,s,n,o;return"horizontal"===this.orientation?(e=this.elementSize.width,i=t.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(e=this.elementSize.height,i=t.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),s=i/e,s>1&&(s=1),0>s&&(s=0),"vertical"===this.orientation&&(s=1-s),n=this._valueMax()-this._valueMin(),o=this._valueMin()+s*n,this._trimAlignValue(o)},_start:function(t,e){var i={handle:this.handles[e],value:this.value()};return this.options.values&&this.options.values.length&&(i.value=this.values(e),i.values=this.values()),this._trigger("start",t,i)},_slide:function(t,e,i){var s,n,o;this.options.values&&this.options.values.length?(s=this.values(e?0:1),2===this.options.values.length&&this.options.range===!0&&(0===e&&i>s||1===e&&s>i)&&(i=s),i!==this.values(e)&&(n=this.values(),n[e]=i,o=this._trigger("slide",t,{handle:this.handles[e],value:i,values:n}),s=this.values(e?0:1),o!==!1&&this.values(e,i,!0))):i!==this.value()&&(o=this._trigger("slide",t,{handle:this.handles[e],value:i}),o!==!1&&this.value(i))},_stop:function(t,e){var i={handle:this.handles[e],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(e),i.values=this.values()),this._trigger("stop",t,i)},_change:function(t,e){if(!this._keySliding&&!this._mouseSliding){var i={handle:this.handles[e],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(e),i.values=this.values()),this._lastChangedValue=e,this._trigger("change",t,i)}},value:function(t){return arguments.length?(this.options.value=this._trimAlignValue(t),this._refreshValue(),this._change(null,0),undefined):this._value()},values:function(e,i){var s,n,o;if(arguments.length>1)return this.options.values[e]=this._trimAlignValue(i),this._refreshValue(),this._change(null,e),undefined;if(!arguments.length)return this._values();if(!t.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(e):this.value();for(s=this.options.values,n=arguments[0],o=0;s.length>o;o+=1)s[o]=this._trimAlignValue(n[o]),this._change(null,o);this._refreshValue()},_setOption:function(e,i){var s,n=0;switch("range"===e&&this.options.range===!0&&("min"===i?(this.options.value=this._values(0),this.options.values=null):"max"===i&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),t.isArray(this.options.values)&&(n=this.options.values.length),t.Widget.prototype._setOption.apply(this,arguments),e){case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue();break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),s=0;n>s;s+=1)this._change(null,s);this._animateOff=!1;break;case"min":case"max":this._animateOff=!0,this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_value:function(){var t=this.options.value;return t=this._trimAlignValue(t)},_values:function(t){var e,i,s;if(arguments.length)return e=this.options.values[t],e=this._trimAlignValue(e);if(this.options.values&&this.options.values.length){for(i=this.options.values.slice(),s=0;i.length>s;s+=1)i[s]=this._trimAlignValue(i[s]);return i}return[]},_trimAlignValue:function(t){if(this._valueMin()>=t)return this._valueMin();if(t>=this._valueMax())return this._valueMax();var e=this.options.step>0?this.options.step:1,i=(t-this._valueMin())%e,s=t-i;return 2*Math.abs(i)>=e&&(s+=i>0?e:-e),parseFloat(s.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var e,i,s,n,o,a=this.options.range,r=this.options,h=this,l=this._animateOff?!1:r.animate,c={};this.options.values&&this.options.values.length?this.handles.each(function(s){i=100*((h.values(s)-h._valueMin())/(h._valueMax()-h._valueMin())),c["horizontal"===h.orientation?"left":"bottom"]=i+"%",t(this).stop(1,1)[l?"animate":"css"](c,r.animate),h.options.range===!0&&("horizontal"===h.orientation?(0===s&&h.range.stop(1,1)[l?"animate":"css"]({left:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({width:i-e+"%"},{queue:!1,duration:r.animate})):(0===s&&h.range.stop(1,1)[l?"animate":"css"]({bottom:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({height:i-e+"%"},{queue:!1,duration:r.animate}))),e=i}):(s=this.value(),n=this._valueMin(),o=this._valueMax(),i=o!==n?100*((s-n)/(o-n)):0,c["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[l?"animate":"css"](c,r.animate),"min"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:i+"%"},r.animate),"max"===a&&"horizontal"===this.orientation&&this.range[l?"animate":"css"]({width:100-i+"%"},{queue:!1,duration:r.animate}),"min"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:i+"%"},r.animate),"max"===a&&"vertical"===this.orientation&&this.range[l?"animate":"css"]({height:100-i+"%"},{queue:!1,duration:r.animate}))},_handleEvents:{keydown:function(i){var s,n,o,a,r=t(i.target).data("ui-slider-handle-index");switch(i.keyCode){case t.ui.keyCode.HOME:case t.ui.keyCode.END:case t.ui.keyCode.PAGE_UP:case t.ui.keyCode.PAGE_DOWN:case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(i.preventDefault(),!this._keySliding&&(this._keySliding=!0,t(i.target).addClass("ui-state-active"),s=this._start(i,r),s===!1))return}switch(a=this.options.step,n=o=this.options.values&&this.options.values.length?this.values(r):this.value(),i.keyCode){case t.ui.keyCode.HOME:o=this._valueMin();break;case t.ui.keyCode.END:o=this._valueMax();break;case t.ui.keyCode.PAGE_UP:o=this._trimAlignValue(n+(this._valueMax()-this._valueMin())/e);break;case t.ui.keyCode.PAGE_DOWN:o=this._trimAlignValue(n-(this._valueMax()-this._valueMin())/e);break;case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:if(n===this._valueMax())return;o=this._trimAlignValue(n+a);break;case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(n===this._valueMin())return;o=this._trimAlignValue(n-a)}this._slide(i,r,o)},click:function(t){t.preventDefault()},keyup:function(e){var i=t(e.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(e,i),this._change(e,i),t(e.target).removeClass("ui-state-active"))}}})}(jQuery),function(t){function e(t){return function(){var e=this.element.val();t.apply(this,arguments),this._refresh(),e!==this.element.val()&&this._trigger("change")}}t.widget("ui.spinner",{version:"1.10.3",defaultElement:"<input>",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var e={},i=this.element;return t.each(["min","max","step"],function(t,s){var n=i.attr(s);void 0!==n&&n.length&&(e[s]=n)}),e},_events:{keydown:function(t){this._start(t)&&this._keydown(t)&&t.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",t),void 0)},mousewheel:function(t,e){if(e){if(!this.spinning&&!this._start(t))return!1;this._spin((e>0?1:-1)*this.options.step,t),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(t)},100),t.preventDefault()}},"mousedown .ui-spinner-button":function(e){function i(){var t=this.element[0]===this.document[0].activeElement;t||(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s}))}var s;s=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),e.preventDefault(),i.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,i.call(this)}),this._start(e)!==!1&&this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(e){return t(e.currentTarget).hasClass("ui-state-active")?this._start(e)===!1?!1:(this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e),void 0):void 0},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var t=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this.element.attr("role","spinbutton"),this.buttons=t.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(.5*t.height())&&t.height()>0&&t.height(t.height()),this.options.disabled&&this.disable()},_keydown:function(e){var i=this.options,s=t.ui.keyCode;switch(e.keyCode){case s.UP:return this._repeat(null,1,e),!0;case s.DOWN:return this._repeat(null,-1,e),!0;case s.PAGE_UP:return this._repeat(null,i.page,e),!0;case s.PAGE_DOWN:return this._repeat(null,-i.page,e),!0}return!1},_uiSpinnerHtml:function(){return"<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"},_buttonHtml:function(){return"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'><span class='ui-icon "+this.options.icons.up+"'>&#9650;</span>"+"</a>"+"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>"+"<span class='ui-icon "+this.options.icons.down+"'>&#9660;</span>"+"</a>"},_start:function(t){return this.spinning||this._trigger("start",t)!==!1?(this.counter||(this.counter=1),this.spinning=!0,!0):!1},_repeat:function(t,e,i){t=t||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,e,i)},t),this._spin(e*this.options.step,i)},_spin:function(t,e){var i=this.value()||0;this.counter||(this.counter=1),i=this._adjustValue(i+t*this._increment(this.counter)),this.spinning&&this._trigger("spin",e,{value:i})===!1||(this._value(i),this.counter++)},_increment:function(e){var i=this.options.incremental;return i?t.isFunction(i)?i(e):Math.floor(e*e*e/5e4-e*e/500+17*e/200+1):1},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_adjustValue:function(t){var e,i,s=this.options;return e=null!==s.min?s.min:0,i=t-e,i=Math.round(i/s.step)*s.step,t=e+i,t=parseFloat(t.toFixed(this._precision())),null!==s.max&&t>s.max?s.max:null!==s.min&&s.min>t?s.min:t},_stop:function(t){this.spinning&&(clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",t))},_setOption:function(t,e){if("culture"===t||"numberFormat"===t){var i=this._parse(this.element.val());return this.options[t]=e,this.element.val(this._format(i)),void 0}("max"===t||"min"===t||"step"===t)&&"string"==typeof e&&(e=this._parse(e)),"icons"===t&&(this.buttons.first().find(".ui-icon").removeClass(this.options.icons.up).addClass(e.up),this.buttons.last().find(".ui-icon").removeClass(this.options.icons.down).addClass(e.down)),this._super(t,e),"disabled"===t&&(e?(this.element.prop("disabled",!0),this.buttons.button("disable")):(this.element.prop("disabled",!1),this.buttons.button("enable")))},_setOptions:e(function(t){this._super(t),this._value(this.element.val())}),_parse:function(t){return"string"==typeof t&&""!==t&&(t=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(t,10,this.options.culture):+t),""===t||isNaN(t)?null:t},_format:function(t){return""===t?"":window.Globalize&&this.options.numberFormat?Globalize.format(t,this.options.numberFormat,this.options.culture):t},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},_value:function(t,e){var i;""!==t&&(i=this._parse(t),null!==i&&(e||(i=this._adjustValue(i)),t=this._format(i))),this.element.val(t),this._refresh()},_destroy:function(){this.element.removeClass("ui-spinner-input").prop("disabled",!1).removeAttr("autocomplete").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:e(function(t){this._stepUp(t)}),_stepUp:function(t){this._start()&&(this._spin((t||1)*this.options.step),this._stop())},stepDown:e(function(t){this._stepDown(t)}),_stepDown:function(t){this._start()&&(this._spin((t||1)*-this.options.step),this._stop())},pageUp:e(function(t){this._stepUp((t||1)*this.options.page)}),pageDown:e(function(t){this._stepDown((t||1)*this.options.page)}),value:function(t){return arguments.length?(e(this._value).call(this,t),void 0):this._parse(this.element.val())},widget:function(){return this.uiSpinner}})}(jQuery),function(t,e){function i(){return++n}function s(t){return t.hash.length>1&&decodeURIComponent(t.href.replace(o,""))===decodeURIComponent(location.href.replace(o,""))}var n=0,o=/#.*$/;t.widget("ui.tabs",{version:"1.10.3",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var e=this,i=this.options;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",i.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(e){t(this).is(".ui-state-disabled")&&e.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){t(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs(),i.active=this._initialActive(),t.isArray(i.disabled)&&(i.disabled=t.unique(i.disabled.concat(t.map(this.tabs.filter(".ui-state-disabled"),function(t){return e.tabs.index(t)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):t(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var i=this.options.active,s=this.options.collapsible,n=location.hash.substring(1);return null===i&&(n&&this.tabs.each(function(s,o){return t(o).attr("aria-controls")===n?(i=s,!1):e}),null===i&&(i=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===i||-1===i)&&(i=this.tabs.length?0:!1)),i!==!1&&(i=this.tabs.index(this.tabs.eq(i)),-1===i&&(i=s?!1:0)),!s&&i===!1&&this.anchors.length&&(i=0),i},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):t()}},_tabKeydown:function(i){var s=t(this.document[0].activeElement).closest("li"),n=this.tabs.index(s),o=!0;if(!this._handlePageNav(i)){switch(i.keyCode){case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:n++;break;case t.ui.keyCode.UP:case t.ui.keyCode.LEFT:o=!1,n--;break;case t.ui.keyCode.END:n=this.anchors.length-1;break;case t.ui.keyCode.HOME:n=0;break;case t.ui.keyCode.SPACE:return i.preventDefault(),clearTimeout(this.activating),this._activate(n),e;case t.ui.keyCode.ENTER:return i.preventDefault(),clearTimeout(this.activating),this._activate(n===this.options.active?!1:n),e;default:return}i.preventDefault(),clearTimeout(this.activating),n=this._focusNextTab(n,o),i.ctrlKey||(s.attr("aria-selected","false"),this.tabs.eq(n).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",n)},this.delay))}},_panelKeydown:function(e){this._handlePageNav(e)||e.ctrlKey&&e.keyCode===t.ui.keyCode.UP&&(e.preventDefault(),this.active.focus())},_handlePageNav:function(i){return i.altKey&&i.keyCode===t.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):i.altKey&&i.keyCode===t.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):e},_findNextTab:function(e,i){function s(){return e>n&&(e=0),0>e&&(e=n),e}for(var n=this.tabs.length-1;-1!==t.inArray(s(),this.options.disabled);)e=i?e+1:e-1;return e},_focusNextTab:function(t,e){return t=this._findNextTab(t,e),this.tabs.eq(t).focus(),t},_setOption:function(t,i){return"active"===t?(this._activate(i),e):"disabled"===t?(this._setupDisabled(i),e):(this._super(t,i),"collapsible"===t&&(this.element.toggleClass("ui-tabs-collapsible",i),i||this.options.active!==!1||this._activate(0)),"event"===t&&this._setupEvents(i),"heightStyle"===t&&this._setupHeightStyle(i),e)},_tabId:function(t){return t.attr("aria-controls")||"ui-tabs-"+i()},_sanitizeSelector:function(t){return t?t.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var e=this.options,i=this.tablist.children(":has(a[href])");e.disabled=t.map(i.filter(".ui-state-disabled"),function(t){return i.index(t)}),this._processTabs(),e.active!==!1&&this.anchors.length?this.active.length&&!t.contains(this.tablist[0],this.active[0])?this.tabs.length===e.disabled.length?(e.active=!1,this.active=t()):this._activate(this._findNextTab(Math.max(0,e.active-1),!1)):e.active=this.tabs.index(this.active):(e.active=!1,this.active=t()),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var e=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return t("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=t(),this.anchors.each(function(i,n){var o,a,r,h=t(n).uniqueId().attr("id"),l=t(n).closest("li"),c=l.attr("aria-controls");s(n)?(o=n.hash,a=e.element.find(e._sanitizeSelector(o))):(r=e._tabId(l),o="#"+r,a=e.element.find(o),a.length||(a=e._createPanel(r),a.insertAfter(e.panels[i-1]||e.tablist)),a.attr("aria-live","polite")),a.length&&(e.panels=e.panels.add(a)),c&&l.data("ui-tabs-aria-controls",c),l.attr({"aria-controls":o.substring(1),"aria-labelledby":h}),a.attr("aria-labelledby",h)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.element.find("ol,ul").eq(0)},_createPanel:function(e){return t("<div>").attr("id",e).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(e){t.isArray(e)&&(e.length?e.length===this.anchors.length&&(e=!0):e=!1);for(var i,s=0;i=this.tabs[s];s++)e===!0||-1!==t.inArray(s,e)?t(i).addClass("ui-state-disabled").attr("aria-disabled","true"):t(i).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=e},_setupEvents:function(e){var i={click:function(t){t.preventDefault()}};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(e){var i,s=this.element.parent();"fill"===e?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=t(this).outerHeight(!0)}),this.panels.each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.panels.each(function(){i=Math.max(i,t(this).height("").height())}).height(i))},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),o=n.closest("li"),a=o[0]===s[0],r=a&&i.collapsible,h=r?t():this._getPanelForTab(o),l=s.length?this._getPanelForTab(s):t(),c={oldTab:s,oldPanel:l,newTab:r?t():o,newPanel:h};e.preventDefault(),o.hasClass("ui-state-disabled")||o.hasClass("ui-tabs-loading")||this.running||a&&!i.collapsible||this._trigger("beforeActivate",e,c)===!1||(i.active=r?!1:this.tabs.index(o),this.active=a?t():o,this.xhr&&this.xhr.abort(),l.length||h.length||t.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(o),e),this._toggle(e,c))},_toggle:function(e,i){function s(){o.running=!1,o._trigger("activate",e,i)}function n(){i.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),a.length&&o.options.show?o._show(a,o.options.show,s):(a.show(),s())}var o=this,a=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),n()}):(i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),r.hide(),n()),r.attr({"aria-expanded":"false","aria-hidden":"true"}),i.oldTab.attr("aria-selected","false"),a.length&&r.length?i.oldTab.attr("tabIndex",-1):a.length&&this.tabs.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),a.attr({"aria-expanded":"true","aria-hidden":"false"}),i.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(e){var i,s=this._findActive(e);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return e===!1?t():this.tabs.eq(e)},_getIndex:function(t){return"string"==typeof t&&(t=this.anchors.index(this.anchors.filter("[href$='"+t+"']"))),t},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){t.data(this,"ui-tabs-destroy")?t(this).remove():t(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var e=t(this),i=e.data("ui-tabs-aria-controls");i?e.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):e.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(i){var s=this.options.disabled;s!==!1&&(i===e?s=!1:(i=this._getIndex(i),s=t.isArray(s)?t.map(s,function(t){return t!==i?t:null}):t.map(this.tabs,function(t,e){return e!==i?e:null})),this._setupDisabled(s))},disable:function(i){var s=this.options.disabled;if(s!==!0){if(i===e)s=!0;else{if(i=this._getIndex(i),-1!==t.inArray(i,s))return;s=t.isArray(s)?t.merge([i],s).sort():[i]}this._setupDisabled(s)}},load:function(e,i){e=this._getIndex(e);var n=this,o=this.tabs.eq(e),a=o.find(".ui-tabs-anchor"),r=this._getPanelForTab(o),h={tab:o,panel:r};s(a[0])||(this.xhr=t.ajax(this._ajaxSettings(a,i,h)),this.xhr&&"canceled"!==this.xhr.statusText&&(o.addClass("ui-tabs-loading"),r.attr("aria-busy","true"),this.xhr.success(function(t){setTimeout(function(){r.html(t),n._trigger("load",i,h)},1)}).complete(function(t,e){setTimeout(function(){"abort"===e&&n.panels.stop(!1,!0),o.removeClass("ui-tabs-loading"),r.removeAttr("aria-busy"),t===n.xhr&&delete n.xhr},1)})))},_ajaxSettings:function(e,i,s){var n=this;return{url:e.attr("href"),beforeSend:function(e,o){return n._trigger("beforeLoad",i,t.extend({jqXHR:e,ajaxSettings:o},s))}}},_getPanelForTab:function(e){var i=t(e).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}})}(jQuery),function(t){function e(e,i){var s=(e.attr("aria-describedby")||"").split(/\s+/);s.push(i),e.data("ui-tooltip-id",i).attr("aria-describedby",t.trim(s.join(" ")))}function i(e){var i=e.data("ui-tooltip-id"),s=(e.attr("aria-describedby")||"").split(/\s+/),n=t.inArray(i,s);-1!==n&&s.splice(n,1),e.removeData("ui-tooltip-id"),s=t.trim(s.join(" ")),s?e.attr("aria-describedby",s):e.removeAttr("aria-describedby")}var s=0;t.widget("ui.tooltip",{version:"1.10.3",options:{content:function(){var e=t(this).attr("title")||"";return t("<a>").text(e).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.options.disabled&&this._disable()},_setOption:function(e,i){var s=this;return"disabled"===e?(this[i?"_disable":"_enable"](),this.options[e]=i,void 0):(this._super(e,i),"content"===e&&t.each(this.tooltips,function(t,e){s._updateContent(e)}),void 0)},_disable:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s[0],e.close(n,!0)}),this.element.find(this.options.items).addBack().each(function(){var e=t(this);e.is("[title]")&&e.data("ui-tooltip-title",e.attr("title")).attr("title","")})},_enable:function(){this.element.find(this.options.items).addBack().each(function(){var e=t(this);e.data("ui-tooltip-title")&&e.attr("title",e.data("ui-tooltip-title"))})},open:function(e){var i=this,s=t(e?e.target:this.element).closest(this.options.items);s.length&&!s.data("ui-tooltip-id")&&(s.attr("title")&&s.data("ui-tooltip-title",s.attr("title")),s.data("ui-tooltip-open",!0),e&&"mouseover"===e.type&&s.parents().each(function(){var e,s=t(this);s.data("ui-tooltip-open")&&(e=t.Event("blur"),e.target=e.currentTarget=this,i.close(e,!0)),s.attr("title")&&(s.uniqueId(),i.parents[this.id]={element:this,title:s.attr("title")},s.attr("title",""))}),this._updateContent(s,e))},_updateContent:function(t,e){var i,s=this.options.content,n=this,o=e?e.type:null;return"string"==typeof s?this._open(e,t,s):(i=s.call(t[0],function(i){t.data("ui-tooltip-open")&&n._delay(function(){e&&(e.type=o),this._open(e,t,i)})}),i&&this._open(e,t,i),void 0)},_open:function(i,s,n){function o(t){l.of=t,a.is(":hidden")||a.position(l)}var a,r,h,l=t.extend({},this.options.position);
+if(n){if(a=this._find(s),a.length)return a.find(".ui-tooltip-content").html(n),void 0;s.is("[title]")&&(i&&"mouseover"===i.type?s.attr("title",""):s.removeAttr("title")),a=this._tooltip(s),e(s,a.attr("id")),a.find(".ui-tooltip-content").html(n),this.options.track&&i&&/^mouse/.test(i.type)?(this._on(this.document,{mousemove:o}),o(i)):a.position(t.extend({of:s},this.options.position)),a.hide(),this._show(a,this.options.show),this.options.show&&this.options.show.delay&&(h=this.delayedShow=setInterval(function(){a.is(":visible")&&(o(l.of),clearInterval(h))},t.fx.interval)),this._trigger("open",i,{tooltip:a}),r={keyup:function(e){if(e.keyCode===t.ui.keyCode.ESCAPE){var i=t.Event(e);i.currentTarget=s[0],this.close(i,!0)}},remove:function(){this._removeTooltip(a)}},i&&"mouseover"!==i.type||(r.mouseleave="close"),i&&"focusin"!==i.type||(r.focusout="close"),this._on(!0,s,r)}},close:function(e){var s=this,n=t(e?e.currentTarget:this.element),o=this._find(n);this.closing||(clearInterval(this.delayedShow),n.data("ui-tooltip-title")&&n.attr("title",n.data("ui-tooltip-title")),i(n),o.stop(!0),this._hide(o,this.options.hide,function(){s._removeTooltip(t(this))}),n.removeData("ui-tooltip-open"),this._off(n,"mouseleave focusout keyup"),n[0]!==this.element[0]&&this._off(n,"remove"),this._off(this.document,"mousemove"),e&&"mouseleave"===e.type&&t.each(this.parents,function(e,i){t(i.element).attr("title",i.title),delete s.parents[e]}),this.closing=!0,this._trigger("close",e,{tooltip:o}),this.closing=!1)},_tooltip:function(e){var i="ui-tooltip-"+s++,n=t("<div>").attr({id:i,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));return t("<div>").addClass("ui-tooltip-content").appendTo(n),n.appendTo(this.document[0].body),this.tooltips[i]=e,n},_find:function(e){var i=e.data("ui-tooltip-id");return i?t("#"+i):t()},_removeTooltip:function(t){t.remove(),delete this.tooltips[t.attr("id")]},_destroy:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s[0],e.close(n,!0),t("#"+i).remove(),s.data("ui-tooltip-title")&&(s.attr("title",s.data("ui-tooltip-title")),s.removeData("ui-tooltip-title"))})}})}(jQuery);
\ No newline at end of file
--- a/server/src/test/java/org/iri_research/renkan/test/controller/AdminControllerTest.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/test/java/org/iri_research/renkan/test/controller/AdminControllerTest.java	Wed Jan 15 18:36:27 2014 +0100
@@ -1,27 +1,24 @@
 package org.iri_research.renkan.test.controller;
 
-import java.security.SecureRandom;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.TimeZone;
 import java.util.UUID;
 
-import org.apache.commons.codec.binary.Hex;
 import org.iri_research.renkan.models.Project;
 import org.iri_research.renkan.models.Space;
 import org.iri_research.renkan.repositories.ProjectsRepository;
 import org.iri_research.renkan.repositories.SpacesRepository;
+import org.joda.time.DateTime;
 import org.junit.After;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 import org.springframework.test.context.web.WebAppConfiguration;
@@ -31,449 +28,87 @@
 import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
 import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
 import org.springframework.test.web.servlet.setup.MockMvcBuilders;
-import org.springframework.web.client.HttpClientErrorException;
 import org.springframework.web.context.WebApplicationContext;
-import org.springframework.web.util.NestedServletException;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @WebAppConfiguration
-@ContextConfiguration(locations={"controller-context.xml", "file:src/main/webapp/WEB-INF/spring-servlet.xml"})
+@ContextConfiguration(locations = { "controller-context.xml",
+        "file:src/main/webapp/WEB-INF/spring-servlet.xml" })
 public class AdminControllerTest {
-	
-	private final static int SPACE_NB = 3;
-	
-	private Logger logger = LoggerFactory.getLogger(AdminControllerTest.class);
-	
-	@Autowired
-	private SpacesRepository spacesRepository;
-	@Autowired
-	private ProjectsRepository projectsRepository;
-	
-	private Map<String, Space> spacesList = new HashMap<String, Space>(SPACE_NB);
-	private List<String> spacesUuids = new ArrayList<>(SPACE_NB);
-	
-	private ArrayList<Project> testProjects = new ArrayList<Project>();
-	
-	@Autowired
-	private WebApplicationContext context;
-	private MockMvc mvc;
-	
-	
-	@Before
-	public void setup() {
-		
-		logger.debug("Setup");
-		spacesRepository.deleteAll();
-		projectsRepository.deleteAll();
-		
-		ArrayList<Project> pl = new ArrayList<Project>();
-		for(int i=0;i<SPACE_NB;i++) {
-			Date creationDate = new Date();
-			String uuid = UUID.randomUUID().toString();
-			spacesUuids.add(uuid);
-			Space testSpace = new Space(uuid, "test " + i, "Test space " + 1, "{}", "http://ldt.iri.centrepompidou.fr", "#ababab", "test_user", "http://ldt.iri.centrepompidou.fr", creationDate);
-			testSpace = spacesRepository.save(testSpace);
-			this.spacesList.put(uuid, testSpace);
-			for(int j=0; j<SPACE_NB-1-i; j++) {
-				pl.add(new Project(testSpace.getId(), UUID.randomUUID().toString(), "test"+((SPACE_NB-1)*i+j+1), "desc"+((SPACE_NB-1)*i+j+1), "http://localhost:8080/rest/projects/id"+((SPACE_NB-1)*i+j+1), creationDate));
-			}
-			try {
-				Thread.sleep(1);
-			} catch (InterruptedException e) {
-				e.printStackTrace();
-			}
-		}
-		
-		for(Project p: projectsRepository.save(pl)) {
-			this.testProjects.add(p);
-		}
-		
-		this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
-	}
-	
-	@After
-	public void teardown() {
-		spacesRepository.deleteAll();
-		projectsRepository.deleteAll();
-	}
+
+    private final static int SPACE_NB = 3;
+
+    private Logger logger = LoggerFactory.getLogger(AdminControllerTest.class);
+
+    @Autowired
+    private SpacesRepository spacesRepository;
+    @Autowired
+    private ProjectsRepository projectsRepository;
 
-	
-	@Test
-	public void testContext() throws Exception {
-		MockHttpServletRequestBuilder get = MockMvcRequestBuilders.get("/");
-		MvcResult res = this.mvc.perform(get)
-				.andExpect(MockMvcResultMatchers.status().isOk())
-				.andReturn();
-		
-		logger.debug("testContext resp : " + res.getResponse().getContentAsString());
-		
-	}
-	
-	@Test
-	public void testSpacePostUpdate() throws Exception {
-		
-		MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post("/admin/spaces/save");
-		post = post.param("id", this.spacesUuids.get(0));
-		post = post.param("title", "New title");
-		post = post.param("description", "New description");
-		post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
-		post = post.param("color", "#ffffff");
-		post = post.param("binConfig", "{}");
-		
-		this.mvc.perform(post)
-				.andExpect(MockMvcResultMatchers.status().isSeeOther())
-				.andExpect(MockMvcResultMatchers.redirectedUrl("/admin/spaces"));
-		
-		Space sp = this.spacesRepository.findOne(this.spacesUuids.get(0));
-		
-		Assert.assertNotNull("Should find space", sp);
-		Assert.assertEquals("Title equals", "New title", sp.getTitle());
-		Assert.assertEquals("Description equals", "New description", sp.getDescription());
-		Assert.assertEquals("Uri equals", "http://ldt.iri.centrepompidou.fr/new/uri", sp.getUri());
-		Assert.assertEquals("Color equals", "#ffffff", sp.getColor());
-		Assert.assertEquals("BinConfig equals", "{}", sp.getBinConfig());
-		
-	}
+    private Map<String, Space> spacesList = new HashMap<String, Space>(SPACE_NB);
+    private List<String> spacesUuids = new ArrayList<>(SPACE_NB);
+
+    private ArrayList<Project> testProjects = new ArrayList<Project>();
 
-	@Test
-	public void testSpacePostCreate() throws Exception {
-		
-		MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post("/admin/spaces/save");
-		post = post.param("title", "New title");
-		post = post.param("description", "New description");
-		post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
-		post = post.param("color", "#ffffff");
-		post = post.param("binConfig", "{}");
-		
-		this.mvc.perform(post)
-				.andExpect(MockMvcResultMatchers.status().isSeeOther())
-				.andExpect(MockMvcResultMatchers.redirectedUrl("/admin/spaces"));
-		
-		
-		Assert.assertEquals("Must have one more space", SPACE_NB + 1, this.spacesRepository.count());
-		
-		for (Space sp : this.spacesRepository.findAll()) {
-			if(this.spacesList.containsKey(sp.getId())) {
-				continue;
-			}
-			else {
-				Assert.assertNotNull("Should find space", sp);
-				Assert.assertEquals("Title equals", "New title", sp.getTitle());
-				Assert.assertEquals("Description equals", "New description", sp.getDescription());
-				Assert.assertEquals("Uri equals", "http://ldt.iri.centrepompidou.fr/new/uri", sp.getUri());
-				Assert.assertEquals("Color equals", "#ffffff", sp.getColor());
-				Assert.assertEquals("BinConfig equals", "{}", sp.getBinConfig());
-				Assert.assertTrue("id sould match uuid regex", sp.getId().matches("[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}"));
-				Assert.assertNotNull("Date created should be not null", sp.getCreated());
-			}
-		}
-	}
-	
-	@Test
-	public void testSpacePostUpdateEmptyTitle() throws Exception {
-		
-		MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post("/admin/spaces/save");
-		post = post.param("id", this.spacesUuids.get(0));
-		post = post.param("title", "");
-		post = post.param("description", "New description");
-		post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
-		post = post.param("color", "#ffffff");
-		post = post.param("binConfig", "{}");
-		
-		this.mvc.perform(post)
-				.andExpect(MockMvcResultMatchers.status().isOk())
-				.andExpect(MockMvcResultMatchers.view().name("admin/spaceEdit"))
-				.andExpect(MockMvcResultMatchers.model().hasErrors())
-				.andExpect(MockMvcResultMatchers.model().errorCount(1))
-				.andExpect(MockMvcResultMatchers.model().attributeHasErrors("space"))
-				.andExpect(MockMvcResultMatchers.model().attributeHasFieldErrors("space", "title"));
-		
-		Space sp = this.spacesRepository.findOne(this.spacesUuids.get(0));
-		
-		Assert.assertNotNull("Should find space", sp);
-		Assert.assertEquals("Title equals", "test 0", sp.getTitle());
-		
-	}
-	
-	@Test
-	public void testSpacePostCreateEmptyTitle() throws Exception {
-		
-		MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post("/admin/spaces/save");
-		post = post.param("title", "");
-		post = post.param("description", "New description");
-		post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
-		post = post.param("color", "#ffffff");
-		post = post.param("binConfig", "{}");
-		
-		this.mvc.perform(post)
-				.andExpect(MockMvcResultMatchers.status().isOk())
-				.andExpect(MockMvcResultMatchers.view().name("admin/spaceEdit"))
-				.andExpect(MockMvcResultMatchers.model().hasErrors())
-				.andExpect(MockMvcResultMatchers.model().errorCount(1))
-				.andExpect(MockMvcResultMatchers.model().attributeHasErrors("space"))
-				.andExpect(MockMvcResultMatchers.model().attributeHasFieldErrors("space", "title"));
-				
-		Assert.assertEquals("Must not have one more space", SPACE_NB, this.spacesRepository.count());
-		
-	}
+    @Autowired
+    private WebApplicationContext context;
+    private MockMvc mvc;
+
+    @Before
+    public void setup() {
+
+        logger.debug("Setup");
+        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+        spacesRepository.deleteAll();
+        projectsRepository.deleteAll();
 
-	@Test
-	public void testSpacePostUpdateBadJson() throws Exception {
-		
-		MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post("/admin/spaces/save");
-		post = post.param("id", this.spacesUuids.get(0));
-		post = post.param("title", "New Title");
-		post = post.param("description", "New description");
-		post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
-		post = post.param("color", "#ffffff");
-		post = post.param("binConfig", "{");
-		
-		this.mvc.perform(post)
-				.andExpect(MockMvcResultMatchers.status().isOk())
-				.andExpect(MockMvcResultMatchers.view().name("admin/spaceEdit"))
-				.andExpect(MockMvcResultMatchers.model().hasErrors())
-				.andExpect(MockMvcResultMatchers.model().errorCount(1))
-				.andExpect(MockMvcResultMatchers.model().attributeHasErrors("space"))
-				.andExpect(MockMvcResultMatchers.model().attributeHasFieldErrors("space", "binConfig"));
-		
-		Space sp = this.spacesRepository.findOne(this.spacesUuids.get(0));
-		
-		Assert.assertNotNull("Should find space", sp);
-		Assert.assertEquals("Bin config equals", "{}", sp.getBinConfig());
-		
-	}
-	
-	@Test
-	public void testSpacePostCreateBadJson() throws Exception {
-		
-		MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post("/admin/spaces/save");
-		post = post.param("title", "New Title");
-		post = post.param("description", "New description");
-		post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
-		post = post.param("color", "#ffffff");
-		post = post.param("binConfig", "}");
-		
-		this.mvc.perform(post)
-				.andExpect(MockMvcResultMatchers.status().isOk())
-				.andExpect(MockMvcResultMatchers.view().name("admin/spaceEdit"))
-				.andExpect(MockMvcResultMatchers.model().hasErrors())
-				.andExpect(MockMvcResultMatchers.model().errorCount(1))
-				.andExpect(MockMvcResultMatchers.model().attributeHasErrors("space"))
-				.andExpect(MockMvcResultMatchers.model().attributeHasFieldErrors("space", "binConfig"));
-				
-		Assert.assertEquals("Must not have one more space", SPACE_NB, this.spacesRepository.count());
-		
-	}
-
-	@Test
-	public void testSpacePostUpdateAllErrors() throws Exception {
-		
-		MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post("/admin/spaces/save");
-		post = post.param("id", this.spacesUuids.get(0));
-		post = post.param("title", "");
-		post = post.param("description", "New description");
-		post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
-		post = post.param("color", "#ffffff");
-		post = post.param("binConfig", "{");
-		
-		this.mvc.perform(post)
-				.andExpect(MockMvcResultMatchers.status().isOk())
-				.andExpect(MockMvcResultMatchers.view().name("admin/spaceEdit"))
-				.andExpect(MockMvcResultMatchers.model().hasErrors())
-				.andExpect(MockMvcResultMatchers.model().errorCount(2))
-				.andExpect(MockMvcResultMatchers.model().attributeHasErrors("space"))
-				.andExpect(MockMvcResultMatchers.model().attributeHasFieldErrors("space", "title"))
-				.andExpect(MockMvcResultMatchers.model().attributeHasFieldErrors("space", "binConfig"));
-		
-		Space sp = this.spacesRepository.findOne(this.spacesUuids.get(0));
-		
-		Assert.assertNotNull("Should find space", sp);
-		Assert.assertEquals("Bin config equals", "{}", sp.getBinConfig());
-		Assert.assertEquals("title equals", "test 0", sp.getTitle());
-		
-	}
-	
-	@Test
-	public void testSpacePostCreateAllErrors() throws Exception {
-		
-		MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post("/admin/spaces/save");
-		post = post.param("title", "");
-		post = post.param("description", "New description");
-		post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
-		post = post.param("color", "#ffffff");
-		post = post.param("binConfig", "}");
-		
-		this.mvc.perform(post)
-				.andExpect(MockMvcResultMatchers.status().isOk())
-				.andExpect(MockMvcResultMatchers.view().name("admin/spaceEdit"))
-				.andExpect(MockMvcResultMatchers.model().hasErrors())
-				.andExpect(MockMvcResultMatchers.model().errorCount(2))
-				.andExpect(MockMvcResultMatchers.model().attributeHasErrors("space"))
-				.andExpect(MockMvcResultMatchers.model().attributeHasFieldErrors("space", "title"))
-				.andExpect(MockMvcResultMatchers.model().attributeHasFieldErrors("space", "binConfig"));
-				
-		Assert.assertEquals("Must not have one more space", SPACE_NB, this.spacesRepository.count());
-		
-	}
-	
-	@Test
-	public void testDeleteSpace() throws Exception {
-		
-		MockHttpServletRequestBuilder get = MockMvcRequestBuilders.get("/admin/spaces/delete/"+this.spacesUuids.get(SPACE_NB-1));
-		
-		MvcResult res = this.mvc.perform(get)
-			.andExpect(MockMvcResultMatchers.status().isOk())			
-			.andExpect(MockMvcResultMatchers.view().name("admin/spaceDeleteConfirm"))
-			.andExpect(MockMvcResultMatchers.model().attributeExists("spaceObj", "key", "salt"))
-			.andReturn();
-		
-		Map<String, Object> model = res.getModelAndView().getModel();
-		
-		Space space = (Space)model.get("spaceObj");
-		Assert.assertNotNull("Space is not null", space);
-		Assert.assertEquals("Must be first space id", this.spacesUuids.get(SPACE_NB-1), space.getId());
-		
-		String key = (String)model.get("key");
-		Assert.assertNotNull("key is not null", key);
-
-		String salt = (String)model.get("salt");
-		Assert.assertNotNull("salt is not null", salt);
-		
-		Assert.assertTrue("Key must be checked", space.checkKey(key, salt));
-		
-	}
+        ArrayList<Project> pl = new ArrayList<Project>();
+        for (int i = 0; i < SPACE_NB; i++) {
+            DateTime creationDate = new DateTime();
+            String uuid = UUID.randomUUID().toString();
+            spacesUuids.add(uuid);
+            Space testSpace = new Space(uuid, "test " + i, "Test space " + 1,
+                    "{}", "http://ldt.iri.centrepompidou.fr", "#ababab",
+                    "test_user", "http://ldt.iri.centrepompidou.fr",
+                    creationDate);
+            testSpace = spacesRepository.save(testSpace);
+            this.spacesList.put(uuid, testSpace);
+            for (int j = 0; j < SPACE_NB - 1 - i; j++) {
+                pl.add(new Project(testSpace.getId(), UUID.randomUUID()
+                        .toString(), "test" + ((SPACE_NB - 1) * i + j + 1),
+                        "desc" + ((SPACE_NB - 1) * i + j + 1),
+                        "http://localhost:8080/rest/projects/id"
+                                + ((SPACE_NB - 1) * i + j + 1), creationDate));
+            }
+            try {
+                Thread.sleep(1);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
 
-	@Test
-	public void testDeleteFakeSpace() throws Exception {
-		
-		MockHttpServletRequestBuilder get = MockMvcRequestBuilders.get("/admin/spaces/delete/" + UUID.randomUUID().toString());
-		
-		try {
-			this.mvc.perform(get)
-				.andExpect(MockMvcResultMatchers.status().isNotFound());
-		}
-		catch(NestedServletException e) {
-			Assert.assertNotNull("Nested exception must not be null", e.getCause());
-			Assert.assertEquals("Inner exception must be a HttpClientErrorException", HttpClientErrorException.class, e.getCause().getClass());
-			Assert.assertEquals("Exception error status must be not found", HttpStatus.NOT_FOUND, ((HttpClientErrorException)e.getCause()).getStatusCode());
-		}
-		
-	}
-	
-	@Test
-	public void testDeleteSpaceProject() throws Exception {
-		
-		MockHttpServletRequestBuilder get = MockMvcRequestBuilders.get("/admin/spaces/delete/" + this.spacesUuids.get(0));
-		
-		try {
-			this.mvc.perform(get)
-				.andExpect(MockMvcResultMatchers.status().isBadRequest());
-		}
-		catch(NestedServletException e) {
-			Assert.assertNotNull("Nested exception must not be null", e.getCause());
-			Assert.assertEquals("Inner exception must be a HttpClientErrorException", HttpClientErrorException.class, e.getCause().getClass());
-			Assert.assertEquals("Exception error status must be not found", HttpStatus.BAD_REQUEST, ((HttpClientErrorException)e.getCause()).getStatusCode());
-		}
-		
-	}
-	
-	@Test
-	public void testDoDeleteSpaceNoKey() throws Exception {
-		MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post("/admin/spaces/delete/"+this.spacesUuids.get(SPACE_NB-1));
-		
-		try {
-			this.mvc.perform(post)
-				.andExpect(MockMvcResultMatchers.status().isBadRequest());
-		}
-		catch(NestedServletException e) {
-			Assert.assertNotNull("Nested exception must not be null", e.getCause());
-			Assert.assertEquals("Inner exception must be a HttpClientErrorException", HttpClientErrorException.class, e.getCause().getClass());
-			Assert.assertEquals("Exception error status must be not found", HttpStatus.BAD_REQUEST, ((HttpClientErrorException)e.getCause()).getStatusCode());
-		}
+        for (Project p : projectsRepository.save(pl)) {
+            this.testProjects.add(p);
+        }
+
+        this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
+    }
 
-		
-		Assert.assertEquals("Must have same nb of space", SPACE_NB, this.spacesRepository.count());
-		
-	}
-	
-	@Test
-	public void testDoDeleteSpace() throws Exception {
-		
-		Space space = this.spacesList.get(this.spacesUuids.get(SPACE_NB-1));
-		
-		SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
-		rand.setSeed(System.currentTimeMillis());
-		byte[] rawSalt = new byte[50];
-		rand.nextBytes(rawSalt);
-		String salt = Hex.encodeHexString(rawSalt);
-		String key = space.getKey(salt);
-		
-		
-		MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post(String.format("/admin/spaces/delete/%s?key=%s&salt=%s",this.spacesUuids.get(SPACE_NB-1), key, salt));
-		
-		this.mvc.perform(post)
-			.andExpect(MockMvcResultMatchers.status().isSeeOther())
-			.andExpect(MockMvcResultMatchers.redirectedUrl("/admin/spaces"));
-		
-		Assert.assertEquals("Must have one less space", SPACE_NB-1, this.spacesRepository.count());
-		
-		space = this.spacesRepository.findOne(this.spacesUuids.get(SPACE_NB-1));
-		
-		Assert.assertNull("Space " + this.spacesUuids.get(SPACE_NB-1) + " deleted", space);
-		
-	}
+    @After
+    public void teardown() {
+        spacesRepository.deleteAll();
+        projectsRepository.deleteAll();
+    }
 
-	
-	@Test
-	public void testDoDeleteSpaceFake() throws Exception {
-		
-		Space space = this.spacesList.get(this.spacesUuids.get(SPACE_NB-1));
-		
-		SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
-		rand.setSeed(System.currentTimeMillis());
-		byte[] rawSalt = new byte[50];
-		rand.nextBytes(rawSalt);
-		String salt = Hex.encodeHexString(rawSalt);
-		String key = space.getKey(salt);
-		
-		
-		MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post(String.format("/admin/spaces/delete/%s?key=%s&salt=%s",UUID.randomUUID(), key, salt));
-		
-		this.mvc.perform(post)
-			.andExpect(MockMvcResultMatchers.status().isSeeOther())
-			.andExpect(MockMvcResultMatchers.redirectedUrl("/admin/spaces"));			
-		
-		Assert.assertEquals("Must have the same nb of space", SPACE_NB, this.spacesRepository.count());
-				
-	}
+    @Test
+    public void testContext() throws Exception {
+        MockHttpServletRequestBuilder get = MockMvcRequestBuilders.get("/");
+        MvcResult res = this.mvc.perform(get)
+                .andExpect(MockMvcResultMatchers.status().isOk()).andReturn();
 
-	@Test
-	public void testDoDeleteSpaceProject() throws Exception {
-		
-		Space space = this.spacesList.get(this.spacesUuids.get(0));
-		
-		SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
-		rand.setSeed(System.currentTimeMillis());
-		byte[] rawSalt = new byte[50];
-		rand.nextBytes(rawSalt);
-		String salt = Hex.encodeHexString(rawSalt);
-		String key = space.getKey(salt);
-		
-		
-		MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post(String.format("/admin/spaces/delete/%s?key=%s&salt=%s",this.spacesUuids.get(0), key, salt));
-		
-		try {
-			this.mvc.perform(post)
-				.andExpect(MockMvcResultMatchers.status().isBadRequest());
-		}
-		catch(NestedServletException e) {
-			Assert.assertNotNull("Nested exception must not be null", e.getCause());
-			Assert.assertEquals("Inner exception must be a HttpClientErrorException", HttpClientErrorException.class, e.getCause().getClass());
-			Assert.assertEquals("Exception error status must be not found", HttpStatus.BAD_REQUEST, ((HttpClientErrorException)e.getCause()).getStatusCode());
-		}
-		
-		Assert.assertEquals("Must have the same nb of space", SPACE_NB, this.spacesRepository.count());
-				
-	}
+        logger.debug("testContext resp : "
+                + res.getResponse().getContentAsString());
+
+    }
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/test/java/org/iri_research/renkan/test/controller/GroupsAdminControllerTest.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,484 @@
+package org.iri_research.renkan.test.controller;
+
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.UUID;
+
+import org.apache.commons.codec.binary.Hex;
+import org.iri_research.renkan.models.Group;
+import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.models.Space;
+import org.iri_research.renkan.models.User;
+import org.iri_research.renkan.repositories.GroupsRepository;
+import org.iri_research.renkan.repositories.ProjectsRepository;
+import org.iri_research.renkan.repositories.SpacesRepository;
+import org.iri_research.renkan.repositories.UsersRepository;
+import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.util.NestedServletException;
+
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@WebAppConfiguration
+@ContextConfiguration(locations = { "controller-context.xml",
+        "file:src/main/webapp/WEB-INF/spring-servlet.xml" })
+public class GroupsAdminControllerTest {
+
+    private final static int SPACE_NB = 3;
+    private final static int USER_NB = 3;
+    private final static int GROUP_NB = 3;
+
+    private Logger logger = LoggerFactory.getLogger(GroupsAdminControllerTest.class);
+
+    @Autowired
+    private SpacesRepository spacesRepository;
+    @Autowired
+    private ProjectsRepository projectsRepository;
+    @Autowired
+    private UsersRepository usersRepository;
+    @Autowired
+    private GroupsRepository groupsRepository;
+
+    
+    
+    @Autowired
+    private PasswordEncoder renkanPasswordEncoder;
+
+    private Map<String, Space> spacesList = new HashMap<String, Space>(SPACE_NB);
+    private List<String> spacesUuids = new ArrayList<>(SPACE_NB);
+
+    private ArrayList<Project> testProjects = new ArrayList<Project>();
+    
+    private Map<String, User> usersList = new HashMap<String, User>(USER_NB);
+    private List<String> usersUuids = new ArrayList<>(USER_NB);
+
+    private Map<String, Group> groupsList = new HashMap<String, Group>(GROUP_NB);
+    private List<String> groupsUuids = new ArrayList<>(GROUP_NB);
+    
+    
+
+    @Autowired
+    private WebApplicationContext context;
+    private MockMvc mvc;
+
+    @Before
+    public void setup() {
+
+        logger.debug("Setup");
+        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+        spacesRepository.deleteAll();
+        projectsRepository.deleteAll();
+        usersRepository.deleteAll();
+        groupsRepository.deleteAll();
+
+        for(int i=0; i < USER_NB; i++) {
+            String uuid = UUID.randomUUID().toString();
+            User user = new User(uuid, "user" + i, "User nb " + i, "http://www.iri.centrepompidou.fr", "#ababab");
+            user.setLocked(false);
+            user.setEnabled(true);
+            user.setAvatar("A pretty picture");
+            user.setExpirationDate(new LocalDate());
+            user.setCredentialsExpirationDate(new LocalDate());
+            user.setEmail(String.format("user%d@mail.com", i));
+            user = usersRepository.save(user);
+            this.usersUuids.add(uuid);
+            this.usersList.put(uuid, user);
+        }
+        
+        
+        for(int i=0; i < GROUP_NB; i++) {
+            String uuid = UUID.randomUUID().toString();
+            Group group = new Group(uuid, "group" + i, "Group nb " + i, "http://www.iri.centrepompidou.fr/group/"+uuid, "#ababab");
+            group.setAvatar("A pretty group picture " + i);
+            group = groupsRepository.save(group);
+            this.groupsUuids.add(uuid);
+            this.groupsList.put(uuid, group);
+        }
+        
+        ArrayList<Project> pl = new ArrayList<Project>();
+        for (int i = 0; i < SPACE_NB; i++) {
+            DateTime creationDate = new DateTime();
+            String uuid = UUID.randomUUID().toString();
+            spacesUuids.add(uuid);
+            Space testSpace = new Space(uuid, "test " + i, "Test space " + 1,
+                    "{}", "http://ldt.iri.centrepompidou.fr", "#ababab",
+                    "test_user", "http://ldt.iri.centrepompidou.fr",
+                    creationDate);
+            testSpace = spacesRepository.save(testSpace);
+            this.spacesList.put(uuid, testSpace);
+            for (int j = 0; j < SPACE_NB - 1 - i; j++) {
+                Project p = new Project(testSpace.getId(), UUID.randomUUID()
+                        .toString(), "test" + ((SPACE_NB - 1) * i + j + 1),
+                        "desc" + ((SPACE_NB - 1) * i + j + 1),
+                        "http://localhost:8080/rest/projects/id"
+                                + ((SPACE_NB - 1) * i + j + 1), creationDate);
+                p.addUser(this.usersList.get(this.usersUuids.get(0)));
+                pl.add(p);
+            }
+            try {
+                Thread.sleep(1);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+
+        for (Project p : projectsRepository.save(pl)) {
+            this.testProjects.add(p);
+        }
+        
+        
+
+        this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
+    }
+
+    @After
+    public void teardown() {
+        spacesRepository.deleteAll();
+        projectsRepository.deleteAll();
+        usersRepository.deleteAll();
+        groupsRepository.deleteAll();
+
+    }
+
+    @Test
+    public void testGroupPostUpdate() throws Exception {
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/groups/save");
+        post = post.param("id", this.groupsUuids.get(0));
+        post = post.param("title", "New name");
+        post = post.param("description", "New description");
+        post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
+        post = post.param("color", "#ffffff");
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isSeeOther())
+                .andExpect(MockMvcResultMatchers.redirectedUrl("/admin/groups"));
+
+        Group group = this.groupsRepository.findOne(this.groupsUuids.get(0));
+
+        Assert.assertNotNull("Should find space", group);
+        Assert.assertEquals("Title equals", "New name", group.getTitle());
+        Assert.assertEquals("Description equals", "New description",
+                group.getDescription());
+        Assert.assertEquals("Uri equals",
+                "http://ldt.iri.centrepompidou.fr/new/uri", group.getUri());
+        Assert.assertEquals("Color equals", "#ffffff", group.getColor());
+    }
+
+    @Test
+    public void testGroupPostCreate() throws Exception {
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/groups/save")
+                    .param("title", "New name")
+                    .param("description", "New description")
+                    .param("uri", "http://ldt.iri.centrepompidou.fr/new/uri")
+                    .param("color", "#ffffff")
+                    .param("avatar", "A pretty avatar");
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isSeeOther())
+                .andExpect(MockMvcResultMatchers.redirectedUrl("/admin/groups"));
+
+        Assert.assertEquals("Must have one more group", GROUP_NB + 1,
+                this.groupsRepository.count());
+
+        for (Group group : this.groupsRepository.findAll()) {
+            if (this.groupsList.containsKey(group.getId())) {
+                continue;
+            }
+            else {
+                Assert.assertNotNull("Should find group", group);
+                Assert.assertEquals("Title equals", "New name", group.getTitle());
+                Assert.assertEquals("Description equals", "New description",
+                        group.getDescription());
+                Assert.assertEquals("Uri equals",
+                        "http://ldt.iri.centrepompidou.fr/new/uri", group.getUri());
+                Assert.assertEquals("Color equals", "#ffffff", group.getColor());
+                Assert.assertEquals("Avatar equals", "A pretty avatar", group.getAvatar());
+                Assert.assertTrue(
+                        "id sould match uuid regex",
+                        group.getId()
+                                .matches(
+                                        "[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}"));
+            }
+        }
+    }
+
+    @Test
+    public void testGroupPostUpdateEmptyTitle() throws Exception {
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/groups/save")
+                .param("id", this.groupsUuids.get(0))
+                .param("title", "")
+                .param("description", "New description")
+                .param("uri", "http://ldt.iri.centrepompidou.fr/new/uri")
+                .param("color", "#ffffff")
+                .param("avatar", "A pretty avatar");
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isOk())
+                .andExpect(MockMvcResultMatchers.view().name("admin/groupEdit"))
+                .andExpect(MockMvcResultMatchers.model().hasErrors())
+                .andExpect(MockMvcResultMatchers.model().errorCount(1))
+                .andExpect(MockMvcResultMatchers.model().attributeHasErrors("group"))
+                .andExpect(MockMvcResultMatchers.model().attributeHasFieldErrors("group", "title"));
+
+        Group group = this.groupsRepository.findOne(this.groupsUuids.get(0));
+
+        Assert.assertNotNull("Should find group", group);
+        Assert.assertEquals("name equals", "group0", group.getTitle());
+        
+        Assert.assertEquals("name equals", "Group nb 0", group.getDescription());
+
+    }
+
+    @Test
+    public void testGroupPostCreateEmptyName() throws Exception {
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/groups/save")
+                .param("title", "")
+                .param("description", "New description")
+                .param("uri", "http://ldt.iri.centrepompidou.fr/new/uri")
+                .param("color", "#ffffff")
+                .param("avatar", "A pretty avatar");
+                
+        
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isOk())
+                .andExpect(MockMvcResultMatchers.view().name("admin/groupEdit"))
+                .andExpect(MockMvcResultMatchers.model().hasErrors())
+                .andExpect(MockMvcResultMatchers.model().errorCount(1))
+                .andExpect(MockMvcResultMatchers.model().attributeHasErrors("group"))
+                .andExpect(MockMvcResultMatchers.model().attributeHasFieldErrors("group", "title"));
+
+        Assert.assertEquals("Must not have one more group", GROUP_NB,this.groupsRepository.count());
+
+    }
+
+    @Test
+    public void testUserPostCreateBadPassword() throws Exception {
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/users/save")
+                .param("title", "user")
+                .param("description", "New description")
+                .param("uri", "http://ldt.iri.centrepompidou.fr/new/uri")
+                .param("color", "#ffffff")
+                .param("expirationDate","2007-11-24")
+                .param("credentialsExpirationDate","2009-11-29")
+                .param("password", "test")
+                .param("passwordConfirm", "test2");
+
+        this.mvc.perform(post)
+            .andExpect(MockMvcResultMatchers.status().isOk())
+            .andExpect(MockMvcResultMatchers.view().name("admin/userEdit"))
+            .andExpect(MockMvcResultMatchers.model().hasErrors())
+            .andExpect(MockMvcResultMatchers.model().errorCount(1))
+            .andExpect(MockMvcResultMatchers.model().attributeHasErrors("user"))
+            .andExpect(MockMvcResultMatchers.model().attributeHasFieldErrors("user", "password"));
+        
+        Assert.assertEquals("Must not have one more user", USER_NB,this.usersRepository.count());
+
+    }
+
+
+    @Test
+    public void testDeleteGroup() throws Exception {
+
+        MockHttpServletRequestBuilder get = MockMvcRequestBuilders
+                .get("/admin/groups/delete/"
+                        + this.groupsUuids.get(GROUP_NB - 1));
+
+        MvcResult res = this.mvc
+                .perform(get)
+                .andExpect(MockMvcResultMatchers.status().isOk())
+                .andExpect(
+                        MockMvcResultMatchers.view().name(
+                                "admin/groupDeleteConfirm"))
+                .andExpect(
+                        MockMvcResultMatchers.model().attributeExists(
+                                "groupObj", "key", "salt")).andReturn();
+
+        Map<String, Object> model = res.getModelAndView().getModel();
+
+        Group group = (Group) model.get("groupObj");
+        Assert.assertNotNull("Group is not null", group);
+        Assert.assertEquals("Must be first group id",
+                this.groupsUuids.get(GROUP_NB - 1), group.getId());
+
+        String key = (String) model.get("key");
+        Assert.assertNotNull("key is not null", key);
+
+        String salt = (String) model.get("salt");
+        Assert.assertNotNull("salt is not null", salt);
+
+        Assert.assertTrue("Key must be checked", group.checkKey(key, salt));
+
+    }
+
+    @Test
+    public void testDeleteFakeGroup() throws Exception {
+
+        MockHttpServletRequestBuilder get = MockMvcRequestBuilders
+                .get("/admin/groups/delete/" + UUID.randomUUID().toString());
+
+        try {
+            this.mvc.perform(get).andExpect(
+                    MockMvcResultMatchers.status().isNotFound());
+        } catch (NestedServletException e) {
+            Assert.assertNotNull("Nested exception must not be null",
+                    e.getCause());
+            Assert.assertEquals(
+                    "Inner exception must be a HttpClientErrorException",
+                    HttpClientErrorException.class, e.getCause().getClass());
+            Assert.assertEquals("Exception error status must be not found",
+                    HttpStatus.NOT_FOUND,
+                    ((HttpClientErrorException) e.getCause()).getStatusCode());
+        }
+
+    }
+
+    @Test
+    public void testDoDeleteGroupNoKey() throws Exception {
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/groups/delete/"
+                        + this.spacesUuids.get(GROUP_NB - 1));
+
+        try {
+            this.mvc.perform(post).andExpect(
+                    MockMvcResultMatchers.status().isBadRequest());
+        } catch (NestedServletException e) {
+            Assert.assertNotNull("Nested exception must not be null",
+                    e.getCause());
+            Assert.assertEquals(
+                    "Inner exception must be a HttpClientErrorException",
+                    HttpClientErrorException.class, e.getCause().getClass());
+            Assert.assertEquals("Exception error status must be not found",
+                    HttpStatus.BAD_REQUEST,
+                    ((HttpClientErrorException) e.getCause()).getStatusCode());
+        }
+
+        Assert.assertEquals("Must have same nb of group", GROUP_NB,
+                this.groupsRepository.count());
+
+    }
+
+    @Test
+    public void testDoDeleteGroup() throws Exception {
+
+        Group group = this.groupsList.get(this.groupsUuids.get(GROUP_NB - 1));
+
+        SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
+        rand.setSeed(System.currentTimeMillis());
+        byte[] rawSalt = new byte[50];
+        rand.nextBytes(rawSalt);
+        String salt = Hex.encodeHexString(rawSalt);
+        String key = group.getKey(salt);
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post(String
+                .format("/admin/groups/delete/%s?key=%s&salt=%s",
+                        this.groupsUuids.get(GROUP_NB - 1), key, salt));
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isSeeOther())
+                .andExpect(MockMvcResultMatchers.redirectedUrl("/admin/groups"));
+
+        Assert.assertEquals("Must have one less space", GROUP_NB - 1,
+                this.groupsRepository.count());
+
+        group = this.groupsRepository.findOne(this.groupsUuids
+                .get(GROUP_NB - 1));
+
+        Assert.assertNull("Group " + this.groupsUuids.get(GROUP_NB - 1)
+                + " deleted", group);
+
+    }
+
+    @Test
+    public void testDoDeleteGroupFake() throws Exception {
+
+        Group group = this.groupsList.get(this.groupsUuids.get(GROUP_NB - 1));
+
+        SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
+        rand.setSeed(System.currentTimeMillis());
+        byte[] rawSalt = new byte[50];
+        rand.nextBytes(rawSalt);
+        String salt = Hex.encodeHexString(rawSalt);
+        String key = group.getKey(salt);
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post(String
+                .format("/admin/groups/delete/%s?key=%s&salt=%s",
+                        UUID.randomUUID(), key, salt));
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isSeeOther())
+                .andExpect(MockMvcResultMatchers.redirectedUrl("/admin/groups"));
+
+        Assert.assertEquals("Must have the same nb of group", GROUP_NB,
+                this.groupsRepository.count());
+
+    }
+    
+    @Test
+    public void testUpdateUserGroups() throws Exception {
+        
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/groups/save");
+        post = post.param("id", this.groupsUuids.get(0));
+        post = post.param("title", "New name");
+        post = post.param("description", "New description");
+        post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
+        post = post.param("color", "#ffffff");
+        post = post.param("users", this.usersUuids.toArray(new String[GroupsAdminControllerTest.GROUP_NB]));
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isSeeOther())
+                .andExpect(MockMvcResultMatchers.redirectedUrl("/admin/groups"));
+
+        Group group = this.groupsRepository.findOne(this.groupsUuids.get(0));
+
+        Assert.assertNotNull("Should find group", group);
+        Assert.assertEquals("Title equals", "New name", group.getTitle());
+        Assert.assertEquals("Description equals", "New description",
+                group.getDescription());
+        Assert.assertEquals("Uri equals",
+                "http://ldt.iri.centrepompidou.fr/new/uri", group.getUri());
+        Assert.assertEquals("Color equals", "#ffffff", group.getColor());
+
+        Assert.assertNotNull("Users must be set", group.getUsers());
+        Assert.assertEquals("all users must be set", USER_NB, group.getUsers().size());
+        Assert.assertTrue("users list must contains all users", this.usersUuids.containsAll(group.getUsers()));
+        
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/test/java/org/iri_research/renkan/test/controller/SpacesAdminControllerTest.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,557 @@
+package org.iri_research.renkan.test.controller;
+
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.UUID;
+
+import org.apache.commons.codec.binary.Hex;
+import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.models.Space;
+import org.iri_research.renkan.repositories.ProjectsRepository;
+import org.iri_research.renkan.repositories.SpacesRepository;
+import org.joda.time.DateTime;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.util.NestedServletException;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@WebAppConfiguration
+@ContextConfiguration(locations = { "controller-context.xml",
+        "file:src/main/webapp/WEB-INF/spring-servlet.xml" })
+public class SpacesAdminControllerTest {
+
+    private final static int SPACE_NB = 3;
+
+    private Logger logger = LoggerFactory.getLogger(SpacesAdminControllerTest.class);
+
+    @Autowired
+    private SpacesRepository spacesRepository;
+    @Autowired
+    private ProjectsRepository projectsRepository;
+
+    private Map<String, Space> spacesList = new HashMap<String, Space>(SPACE_NB);
+    private List<String> spacesUuids = new ArrayList<>(SPACE_NB);
+
+    private ArrayList<Project> testProjects = new ArrayList<Project>();
+
+    @Autowired
+    private WebApplicationContext context;
+    private MockMvc mvc;
+
+    @Before
+    public void setup() {
+
+        logger.debug("Setup");
+        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+        spacesRepository.deleteAll();
+        projectsRepository.deleteAll();
+
+        ArrayList<Project> pl = new ArrayList<Project>();
+        for (int i = 0; i < SPACE_NB; i++) {
+            DateTime creationDate = new DateTime();
+            String uuid = UUID.randomUUID().toString();
+            spacesUuids.add(uuid);
+            Space testSpace = new Space(uuid, "test " + i, "Test space " + 1,
+                    "{}", "http://ldt.iri.centrepompidou.fr", "#ababab",
+                    "test_user", "http://ldt.iri.centrepompidou.fr",
+                    creationDate);
+            testSpace = spacesRepository.save(testSpace);
+            this.spacesList.put(uuid, testSpace);
+            for (int j = 0; j < SPACE_NB - 1 - i; j++) {
+                pl.add(new Project(testSpace.getId(), UUID.randomUUID()
+                        .toString(), "test" + ((SPACE_NB - 1) * i + j + 1),
+                        "desc" + ((SPACE_NB - 1) * i + j + 1),
+                        "http://localhost:8080/rest/projects/id"
+                                + ((SPACE_NB - 1) * i + j + 1), creationDate));
+            }
+            try {
+                Thread.sleep(1);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+
+        for (Project p : projectsRepository.save(pl)) {
+            this.testProjects.add(p);
+        }
+
+        this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
+    }
+
+    @After
+    public void teardown() {
+        spacesRepository.deleteAll();
+        projectsRepository.deleteAll();
+    }
+
+    @Test
+    public void testSpacePostUpdate() throws Exception {
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/spaces/save");
+        post = post.param("id", this.spacesUuids.get(0));
+        post = post.param("title", "New title");
+        post = post.param("description", "New description");
+        post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
+        post = post.param("color", "#ffffff");
+        post = post.param("binConfig", "{}");
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isSeeOther())
+                .andExpect(MockMvcResultMatchers.redirectedUrl("/admin/spaces"));
+
+        Space sp = this.spacesRepository.findOne(this.spacesUuids.get(0));
+
+        Assert.assertNotNull("Should find space", sp);
+        Assert.assertEquals("Title equals", "New title", sp.getTitle());
+        Assert.assertEquals("Description equals", "New description",
+                sp.getDescription());
+        Assert.assertEquals("Uri equals",
+                "http://ldt.iri.centrepompidou.fr/new/uri", sp.getUri());
+        Assert.assertEquals("Color equals", "#ffffff", sp.getColor());
+        Assert.assertEquals("BinConfig equals", "{}", sp.getBinConfig());
+
+    }
+
+    @Test
+    public void testSpacePostCreate() throws Exception {
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/spaces/save");
+        post = post.param("title", "New title");
+        post = post.param("description", "New description");
+        post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
+        post = post.param("color", "#ffffff");
+        post = post.param("binConfig", "{}");
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isSeeOther())
+                .andExpect(MockMvcResultMatchers.redirectedUrl("/admin/spaces"));
+
+        Assert.assertEquals("Must have one more space", SPACE_NB + 1,
+                this.spacesRepository.count());
+
+        for (Space sp : this.spacesRepository.findAll()) {
+            if (this.spacesList.containsKey(sp.getId())) {
+                continue;
+            } else {
+                Assert.assertNotNull("Should find space", sp);
+                Assert.assertEquals("Title equals", "New title", sp.getTitle());
+                Assert.assertEquals("Description equals", "New description",
+                        sp.getDescription());
+                Assert.assertEquals("Uri equals",
+                        "http://ldt.iri.centrepompidou.fr/new/uri", sp.getUri());
+                Assert.assertEquals("Color equals", "#ffffff", sp.getColor());
+                Assert.assertEquals("BinConfig equals", "{}", sp.getBinConfig());
+                Assert.assertTrue(
+                        "id sould match uuid regex",
+                        sp.getId()
+                                .matches(
+                                        "[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}"));
+                Assert.assertNotNull("Date created should be not null",
+                        sp.getCreated());
+            }
+        }
+    }
+
+    @Test
+    public void testSpacePostUpdateEmptyTitle() throws Exception {
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/spaces/save");
+        post = post.param("id", this.spacesUuids.get(0));
+        post = post.param("title", "");
+        post = post.param("description", "New description");
+        post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
+        post = post.param("color", "#ffffff");
+        post = post.param("binConfig", "{}");
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isOk())
+                .andExpect(MockMvcResultMatchers.view().name("admin/spaceEdit"))
+                .andExpect(MockMvcResultMatchers.model().hasErrors())
+                .andExpect(MockMvcResultMatchers.model().errorCount(1))
+                .andExpect(
+                        MockMvcResultMatchers.model().attributeHasErrors(
+                                "space"))
+                .andExpect(
+                        MockMvcResultMatchers.model().attributeHasFieldErrors(
+                                "space", "title"));
+
+        Space sp = this.spacesRepository.findOne(this.spacesUuids.get(0));
+
+        Assert.assertNotNull("Should find space", sp);
+        Assert.assertEquals("Title equals", "test 0", sp.getTitle());
+
+    }
+
+    @Test
+    public void testSpacePostCreateEmptyTitle() throws Exception {
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/spaces/save");
+        post = post.param("title", "");
+        post = post.param("description", "New description");
+        post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
+        post = post.param("color", "#ffffff");
+        post = post.param("binConfig", "{}");
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isOk())
+                .andExpect(MockMvcResultMatchers.view().name("admin/spaceEdit"))
+                .andExpect(MockMvcResultMatchers.model().hasErrors())
+                .andExpect(MockMvcResultMatchers.model().errorCount(1))
+                .andExpect(
+                        MockMvcResultMatchers.model().attributeHasErrors(
+                                "space"))
+                .andExpect(
+                        MockMvcResultMatchers.model().attributeHasFieldErrors(
+                                "space", "title"));
+
+        Assert.assertEquals("Must not have one more space", SPACE_NB,
+                this.spacesRepository.count());
+
+    }
+
+    @Test
+    public void testSpacePostUpdateBadJson() throws Exception {
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/spaces/save");
+        post = post.param("id", this.spacesUuids.get(0));
+        post = post.param("title", "New Title");
+        post = post.param("description", "New description");
+        post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
+        post = post.param("color", "#ffffff");
+        post = post.param("binConfig", "{");
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isOk())
+                .andExpect(MockMvcResultMatchers.view().name("admin/spaceEdit"))
+                .andExpect(MockMvcResultMatchers.model().hasErrors())
+                .andExpect(MockMvcResultMatchers.model().errorCount(1))
+                .andExpect(
+                        MockMvcResultMatchers.model().attributeHasErrors(
+                                "space"))
+                .andExpect(
+                        MockMvcResultMatchers.model().attributeHasFieldErrors(
+                                "space", "binConfig"));
+
+        Space sp = this.spacesRepository.findOne(this.spacesUuids.get(0));
+
+        Assert.assertNotNull("Should find space", sp);
+        Assert.assertEquals("Bin config equals", "{}", sp.getBinConfig());
+
+    }
+
+    @Test
+    public void testSpacePostCreateBadJson() throws Exception {
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/spaces/save");
+        post = post.param("title", "New Title");
+        post = post.param("description", "New description");
+        post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
+        post = post.param("color", "#ffffff");
+        post = post.param("binConfig", "}");
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isOk())
+                .andExpect(MockMvcResultMatchers.view().name("admin/spaceEdit"))
+                .andExpect(MockMvcResultMatchers.model().hasErrors())
+                .andExpect(MockMvcResultMatchers.model().errorCount(1))
+                .andExpect(
+                        MockMvcResultMatchers.model().attributeHasErrors(
+                                "space"))
+                .andExpect(
+                        MockMvcResultMatchers.model().attributeHasFieldErrors(
+                                "space", "binConfig"));
+
+        Assert.assertEquals("Must not have one more space", SPACE_NB,
+                this.spacesRepository.count());
+
+    }
+
+    @Test
+    public void testSpacePostUpdateAllErrors() throws Exception {
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/spaces/save");
+        post = post.param("id", this.spacesUuids.get(0));
+        post = post.param("title", "");
+        post = post.param("description", "New description");
+        post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
+        post = post.param("color", "#ffffff");
+        post = post.param("binConfig", "{");
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isOk())
+                .andExpect(MockMvcResultMatchers.view().name("admin/spaceEdit"))
+                .andExpect(MockMvcResultMatchers.model().hasErrors())
+                .andExpect(MockMvcResultMatchers.model().errorCount(2))
+                .andExpect(
+                        MockMvcResultMatchers.model().attributeHasErrors(
+                                "space"))
+                .andExpect(
+                        MockMvcResultMatchers.model().attributeHasFieldErrors(
+                                "space", "title"))
+                .andExpect(
+                        MockMvcResultMatchers.model().attributeHasFieldErrors(
+                                "space", "binConfig"));
+
+        Space sp = this.spacesRepository.findOne(this.spacesUuids.get(0));
+
+        Assert.assertNotNull("Should find space", sp);
+        Assert.assertEquals("Bin config equals", "{}", sp.getBinConfig());
+        Assert.assertEquals("title equals", "test 0", sp.getTitle());
+
+    }
+
+    @Test
+    public void testSpacePostCreateAllErrors() throws Exception {
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/spaces/save");
+        post = post.param("title", "");
+        post = post.param("description", "New description");
+        post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
+        post = post.param("color", "#ffffff");
+        post = post.param("binConfig", "}");
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isOk())
+                .andExpect(MockMvcResultMatchers.view().name("admin/spaceEdit"))
+                .andExpect(MockMvcResultMatchers.model().hasErrors())
+                .andExpect(MockMvcResultMatchers.model().errorCount(2))
+                .andExpect(
+                        MockMvcResultMatchers.model().attributeHasErrors(
+                                "space"))
+                .andExpect(
+                        MockMvcResultMatchers.model().attributeHasFieldErrors(
+                                "space", "title"))
+                .andExpect(
+                        MockMvcResultMatchers.model().attributeHasFieldErrors(
+                                "space", "binConfig"));
+
+        Assert.assertEquals("Must not have one more space", SPACE_NB,
+                this.spacesRepository.count());
+
+    }
+
+    @Test
+    public void testDeleteSpace() throws Exception {
+
+        MockHttpServletRequestBuilder get = MockMvcRequestBuilders
+                .get("/admin/spaces/delete/"
+                        + this.spacesUuids.get(SPACE_NB - 1));
+
+        MvcResult res = this.mvc
+                .perform(get)
+                .andExpect(MockMvcResultMatchers.status().isOk())
+                .andExpect(
+                        MockMvcResultMatchers.view().name(
+                                "admin/spaceDeleteConfirm"))
+                .andExpect(
+                        MockMvcResultMatchers.model().attributeExists(
+                                "spaceObj", "key", "salt")).andReturn();
+
+        Map<String, Object> model = res.getModelAndView().getModel();
+
+        Space space = (Space) model.get("spaceObj");
+        Assert.assertNotNull("Space is not null", space);
+        Assert.assertEquals("Must be first space id",
+                this.spacesUuids.get(SPACE_NB - 1), space.getId());
+
+        String key = (String) model.get("key");
+        Assert.assertNotNull("key is not null", key);
+
+        String salt = (String) model.get("salt");
+        Assert.assertNotNull("salt is not null", salt);
+
+        Assert.assertTrue("Key must be checked", space.checkKey(key, salt));
+
+    }
+
+    @Test
+    public void testDeleteFakeSpace() throws Exception {
+
+        MockHttpServletRequestBuilder get = MockMvcRequestBuilders
+                .get("/admin/spaces/delete/" + UUID.randomUUID().toString());
+
+        try {
+            this.mvc.perform(get).andExpect(
+                    MockMvcResultMatchers.status().isNotFound());
+        } catch (NestedServletException e) {
+            Assert.assertNotNull("Nested exception must not be null",
+                    e.getCause());
+            Assert.assertEquals(
+                    "Inner exception must be a HttpClientErrorException",
+                    HttpClientErrorException.class, e.getCause().getClass());
+            Assert.assertEquals("Exception error status must be not found",
+                    HttpStatus.NOT_FOUND,
+                    ((HttpClientErrorException) e.getCause()).getStatusCode());
+        }
+
+    }
+
+    @Test
+    public void testDeleteSpaceProject() throws Exception {
+
+        MockHttpServletRequestBuilder get = MockMvcRequestBuilders
+                .get("/admin/spaces/delete/" + this.spacesUuids.get(0));
+
+        try {
+            this.mvc.perform(get).andExpect(
+                    MockMvcResultMatchers.status().isBadRequest());
+        } catch (NestedServletException e) {
+            Assert.assertNotNull("Nested exception must not be null",
+                    e.getCause());
+            Assert.assertEquals(
+                    "Inner exception must be a HttpClientErrorException",
+                    HttpClientErrorException.class, e.getCause().getClass());
+            Assert.assertEquals("Exception error status must be not found",
+                    HttpStatus.BAD_REQUEST,
+                    ((HttpClientErrorException) e.getCause()).getStatusCode());
+        }
+
+    }
+
+    @Test
+    public void testDoDeleteSpaceNoKey() throws Exception {
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/spaces/delete/"
+                        + this.spacesUuids.get(SPACE_NB - 1));
+
+        try {
+            this.mvc.perform(post).andExpect(
+                    MockMvcResultMatchers.status().isBadRequest());
+        } catch (NestedServletException e) {
+            Assert.assertNotNull("Nested exception must not be null",
+                    e.getCause());
+            Assert.assertEquals(
+                    "Inner exception must be a HttpClientErrorException",
+                    HttpClientErrorException.class, e.getCause().getClass());
+            Assert.assertEquals("Exception error status must be not found",
+                    HttpStatus.BAD_REQUEST,
+                    ((HttpClientErrorException) e.getCause()).getStatusCode());
+        }
+
+        Assert.assertEquals("Must have same nb of space", SPACE_NB,
+                this.spacesRepository.count());
+
+    }
+
+    @Test
+    public void testDoDeleteSpace() throws Exception {
+
+        Space space = this.spacesList.get(this.spacesUuids.get(SPACE_NB - 1));
+
+        SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
+        rand.setSeed(System.currentTimeMillis());
+        byte[] rawSalt = new byte[50];
+        rand.nextBytes(rawSalt);
+        String salt = Hex.encodeHexString(rawSalt);
+        String key = space.getKey(salt);
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post(String
+                .format("/admin/spaces/delete/%s?key=%s&salt=%s",
+                        this.spacesUuids.get(SPACE_NB - 1), key, salt));
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isSeeOther())
+                .andExpect(MockMvcResultMatchers.redirectedUrl("/admin/spaces"));
+
+        Assert.assertEquals("Must have one less space", SPACE_NB - 1,
+                this.spacesRepository.count());
+
+        space = this.spacesRepository.findOne(this.spacesUuids
+                .get(SPACE_NB - 1));
+
+        Assert.assertNull("Space " + this.spacesUuids.get(SPACE_NB - 1)
+                + " deleted", space);
+
+    }
+
+    @Test
+    public void testDoDeleteSpaceFake() throws Exception {
+
+        Space space = this.spacesList.get(this.spacesUuids.get(SPACE_NB - 1));
+
+        SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
+        rand.setSeed(System.currentTimeMillis());
+        byte[] rawSalt = new byte[50];
+        rand.nextBytes(rawSalt);
+        String salt = Hex.encodeHexString(rawSalt);
+        String key = space.getKey(salt);
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post(String
+                .format("/admin/spaces/delete/%s?key=%s&salt=%s",
+                        UUID.randomUUID(), key, salt));
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isSeeOther())
+                .andExpect(MockMvcResultMatchers.redirectedUrl("/admin/spaces"));
+
+        Assert.assertEquals("Must have the same nb of space", SPACE_NB,
+                this.spacesRepository.count());
+
+    }
+
+    @Test
+    public void testDoDeleteSpaceProject() throws Exception {
+
+        Space space = this.spacesList.get(this.spacesUuids.get(0));
+
+        SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
+        rand.setSeed(System.currentTimeMillis());
+        byte[] rawSalt = new byte[50];
+        rand.nextBytes(rawSalt);
+        String salt = Hex.encodeHexString(rawSalt);
+        String key = space.getKey(salt);
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post(String
+                .format("/admin/spaces/delete/%s?key=%s&salt=%s",
+                        this.spacesUuids.get(0), key, salt));
+
+        try {
+            this.mvc.perform(post).andExpect(
+                    MockMvcResultMatchers.status().isBadRequest());
+        } catch (NestedServletException e) {
+            Assert.assertNotNull("Nested exception must not be null",
+                    e.getCause());
+            Assert.assertEquals(
+                    "Inner exception must be a HttpClientErrorException",
+                    HttpClientErrorException.class, e.getCause().getClass());
+            Assert.assertEquals("Exception error status must be not found",
+                    HttpStatus.BAD_REQUEST,
+                    ((HttpClientErrorException) e.getCause()).getStatusCode());
+        }
+
+        Assert.assertEquals("Must have the same nb of space", SPACE_NB,
+                this.spacesRepository.count());
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/test/java/org/iri_research/renkan/test/controller/UsersAdminControllerTest.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,549 @@
+package org.iri_research.renkan.test.controller;
+
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.UUID;
+
+import org.apache.commons.codec.binary.Hex;
+import org.iri_research.renkan.models.Group;
+import org.iri_research.renkan.models.Project;
+import org.iri_research.renkan.models.Space;
+import org.iri_research.renkan.models.User;
+import org.iri_research.renkan.repositories.GroupsRepository;
+import org.iri_research.renkan.repositories.ProjectsRepository;
+import org.iri_research.renkan.repositories.SpacesRepository;
+import org.iri_research.renkan.repositories.UsersRepository;
+import org.joda.time.DateTime;
+import org.joda.time.LocalDate;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.util.NestedServletException;
+
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@WebAppConfiguration
+@ContextConfiguration(locations = { "controller-context.xml",
+        "file:src/main/webapp/WEB-INF/spring-servlet.xml" })
+public class UsersAdminControllerTest {
+
+    private final static int SPACE_NB = 3;
+    private final static int USER_NB = 3;
+    private final static int GROUP_NB = 4;
+
+    private Logger logger = LoggerFactory.getLogger(UsersAdminControllerTest.class);
+
+    @Autowired
+    private SpacesRepository spacesRepository;
+    @Autowired
+    private ProjectsRepository projectsRepository;
+    @Autowired
+    private UsersRepository usersRepository;
+    @Autowired
+    private GroupsRepository groupsRepository;
+
+
+    @Autowired
+    private PasswordEncoder renkanPasswordEncoder;
+
+    private Map<String, Space> spacesList = new HashMap<String, Space>(SPACE_NB);
+    private List<String> spacesUuids = new ArrayList<>(SPACE_NB);
+
+    private ArrayList<Project> testProjects = new ArrayList<Project>();
+    
+    private Map<String, User> usersList = new HashMap<String, User>(USER_NB);
+    private List<String> usersUuids = new ArrayList<>(USER_NB);
+    
+    private Map<String, Group> groupsList = new HashMap<String, Group>(GROUP_NB);
+    private List<String> groupsUuids = new ArrayList<>(GROUP_NB);
+
+    @Autowired
+    private WebApplicationContext context;
+    private MockMvc mvc;
+
+    @Before
+    public void setup() {
+
+        logger.debug("Setup");
+        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+        spacesRepository.deleteAll();
+        projectsRepository.deleteAll();
+        usersRepository.deleteAll();
+
+        for(int i=0; i < USER_NB; i++) {
+            String uuid = UUID.randomUUID().toString();
+            User user = new User(uuid, "user" + i, "User nb " + i, "http://www.iri.centrepompidou.fr", "#ababab");
+            user.setLocked(false);
+            user.setEnabled(true);
+            user.setAvatar("A pretty picture");
+            user.setExpirationDate(new LocalDate());
+            user.setCredentialsExpirationDate(new LocalDate());
+            user.setEmail(String.format("user%d@mail.com", i));
+            user = usersRepository.save(user);
+            this.usersUuids.add(uuid);
+            this.usersList.put(uuid, user);
+        }
+        
+        for(int i=0; i < GROUP_NB; i++) {
+            String uuid = UUID.randomUUID().toString();
+            Group group = new Group(uuid, "group" + i, "Group nb " + i, "http://www.iri.centrepompidou.fr/group/"+uuid, "#ababab");
+            group.setAvatar("A pretty group picture " + i);
+            group = groupsRepository.save(group);
+            this.groupsUuids.add(uuid);
+            this.groupsList.put(uuid, group);
+            try {
+                Thread.sleep(1);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+
+        }
+        
+        ArrayList<Project> pl = new ArrayList<Project>();
+        for (int i = 0; i < SPACE_NB; i++) {
+            DateTime creationDate = new DateTime();
+            String uuid = UUID.randomUUID().toString();
+            spacesUuids.add(uuid);
+            Space testSpace = new Space(uuid, "test " + i, "Test space " + 1,
+                    "{}", "http://ldt.iri.centrepompidou.fr", "#ababab",
+                    "test_user", "http://ldt.iri.centrepompidou.fr",
+                    creationDate);
+            testSpace = spacesRepository.save(testSpace);
+            this.spacesList.put(uuid, testSpace);
+            for (int j = 0; j < SPACE_NB - 1 - i; j++) {
+                Project p = new Project(testSpace.getId(), UUID.randomUUID()
+                        .toString(), "test" + ((SPACE_NB - 1) * i + j + 1),
+                        "desc" + ((SPACE_NB - 1) * i + j + 1),
+                        "http://localhost:8080/rest/projects/id"
+                                + ((SPACE_NB - 1) * i + j + 1), creationDate);
+                p.addUser(this.usersList.get(this.usersUuids.get(0)));
+                pl.add(p);
+            }
+            try {
+                Thread.sleep(1);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+
+        for (Project p : projectsRepository.save(pl)) {
+            this.testProjects.add(p);
+        }
+        
+        
+
+        this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
+    }
+
+    @After
+    public void teardown() {
+        spacesRepository.deleteAll();
+        projectsRepository.deleteAll();
+        usersRepository.deleteAll();
+    }
+
+    @Test
+    public void testUserPostUpdate() throws Exception {
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/users/save");
+        post = post.param("id", this.usersUuids.get(0));
+        post = post.param("title", "New name");
+        post = post.param("description", "New description");
+        post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
+        post = post.param("color", "#ffffff");
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isSeeOther())
+                .andExpect(MockMvcResultMatchers.redirectedUrl("/admin/users"));
+
+        User user = this.usersRepository.findOne(this.usersUuids.get(0));
+
+        Assert.assertNotNull("Should find user", user);
+        Assert.assertEquals("Title equals", "New name", user.getTitle());
+        Assert.assertEquals("Description equals", "New description",
+                user.getDescription());
+        Assert.assertEquals("Uri equals",
+                "http://ldt.iri.centrepompidou.fr/new/uri", user.getUri());
+        Assert.assertEquals("Color equals", "#ffffff", user.getColor());
+    }
+
+    @Test
+    public void testUserPostCreate() throws Exception {
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/users/save")
+                    .param("title", "New name")
+                    .param("description", "New description")
+                    .param("uri", "http://ldt.iri.centrepompidou.fr/new/uri")
+                    .param("color", "#ffffff")
+                    .param("expirationDate","2007-11-24")
+                    .param("credentialsExpirationDate","2009-11-29")
+                    .param("password", "test")
+                    .param("passwordConfirm", "test");
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isSeeOther())
+                .andExpect(MockMvcResultMatchers.redirectedUrl("/admin/users"));
+
+        Assert.assertEquals("Must have one more space", USER_NB + 1,
+                this.usersRepository.count());
+
+        for (User user : this.usersRepository.findAll()) {
+            if (this.usersList.containsKey(user.getId())) {
+                continue;
+            }
+            else {
+                Assert.assertNotNull("Should find user", user);
+                Assert.assertEquals("Title equals", "New name", user.getTitle());
+                Assert.assertEquals("Description equals", "New description",
+                        user.getDescription());
+                Assert.assertEquals("Uri equals",
+                        "http://ldt.iri.centrepompidou.fr/new/uri", user.getUri());
+                Assert.assertEquals("Color equals", "#ffffff", user.getColor());
+                Assert.assertTrue(
+                        "id sould match uuid regex",
+                        user.getId()
+                                .matches(
+                                        "[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}"));
+                Assert.assertTrue("password must match \"test\"", renkanPasswordEncoder.matches("test", user.getPassword()));
+                Assert.assertEquals(new LocalDate(2007, 11, 24), user.getExpirationDate());
+            }
+        }
+    }
+
+    @Test
+    public void testUserPostUpdateEmptyTitle() throws Exception {
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/users/save")
+                .param("id", this.usersUuids.get(0))
+                .param("title", "")
+                .param("description", "New description")
+                .param("uri", "http://ldt.iri.centrepompidou.fr/new/uri")
+                .param("color", "#ffffff")
+                .param("expirationDate","2007-11-24")
+                .param("credentialsExpirationDate","2009-11-29")
+                .param("password", "test")
+                .param("passwordConfirm", "test");
+
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isOk())
+                .andExpect(MockMvcResultMatchers.view().name("admin/userEdit"))
+                .andExpect(MockMvcResultMatchers.model().hasErrors())
+                .andExpect(MockMvcResultMatchers.model().errorCount(1))
+                .andExpect(MockMvcResultMatchers.model().attributeHasErrors("user"))
+                .andExpect(MockMvcResultMatchers.model().attributeHasFieldErrors("user", "title"));
+
+        User user = this.usersRepository.findOne(this.usersUuids.get(0));
+
+        Assert.assertNotNull("Should find user", user);
+        Assert.assertEquals("name equals", "user0", user.getTitle());
+        
+        Assert.assertEquals("name equals", "User nb 0", user.getDescription());
+
+    }
+
+    @Test
+    public void testUserPostCreateEmptyName() throws Exception {
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/users/save")
+                .param("title", "")
+                .param("description", "New description")
+                .param("uri", "http://ldt.iri.centrepompidou.fr/new/uri")
+                .param("color", "#ffffff")
+                .param("expirationDate","2007-11-24")
+                .param("credentialsExpirationDate","2009-11-29")
+                .param("password", "test")
+                .param("passwordConfirm", "test");
+
+        
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isOk())
+                .andExpect(MockMvcResultMatchers.view().name("admin/userEdit"))
+                .andExpect(MockMvcResultMatchers.model().hasErrors())
+                .andExpect(MockMvcResultMatchers.model().errorCount(1))
+                .andExpect(MockMvcResultMatchers.model().attributeHasErrors("user"))
+                .andExpect(MockMvcResultMatchers.model().attributeHasFieldErrors("user", "title"));
+
+        Assert.assertEquals("Must not have one more user", USER_NB,this.usersRepository.count());
+
+    }
+
+    @Test
+    public void testUserPostCreateBadPassword() throws Exception {
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/users/save")
+                .param("title", "user")
+                .param("description", "New description")
+                .param("uri", "http://ldt.iri.centrepompidou.fr/new/uri")
+                .param("color", "#ffffff")
+                .param("expirationDate","2007-11-24")
+                .param("credentialsExpirationDate","2009-11-29")
+                .param("password", "test")
+                .param("passwordConfirm", "test2");
+
+        this.mvc.perform(post)
+            .andExpect(MockMvcResultMatchers.status().isOk())
+            .andExpect(MockMvcResultMatchers.view().name("admin/userEdit"))
+            .andExpect(MockMvcResultMatchers.model().hasErrors())
+            .andExpect(MockMvcResultMatchers.model().errorCount(1))
+            .andExpect(MockMvcResultMatchers.model().attributeHasErrors("user"))
+            .andExpect(MockMvcResultMatchers.model().attributeHasFieldErrors("user", "password"));
+        
+        Assert.assertEquals("Must not have one more user", USER_NB,this.usersRepository.count());
+
+    }
+
+    @Test
+    public void testDeleteUser() throws Exception {
+
+        MockHttpServletRequestBuilder get = MockMvcRequestBuilders
+                .get("/admin/users/delete/"
+                        + this.usersUuids.get(USER_NB - 1));
+
+        MvcResult res = this.mvc
+                .perform(get)
+                .andExpect(MockMvcResultMatchers.status().isOk())
+                .andExpect(
+                        MockMvcResultMatchers.view().name(
+                                "admin/userDeleteConfirm"))
+                .andExpect(
+                        MockMvcResultMatchers.model().attributeExists(
+                                "userObj", "key", "salt")).andReturn();
+
+        Map<String, Object> model = res.getModelAndView().getModel();
+
+        User user = (User) model.get("userObj");
+        Assert.assertNotNull("User is not null", user);
+        Assert.assertEquals("Must be first user id",
+                this.usersUuids.get(USER_NB - 1), user.getId());
+
+        String key = (String) model.get("key");
+        Assert.assertNotNull("key is not null", key);
+
+        String salt = (String) model.get("salt");
+        Assert.assertNotNull("salt is not null", salt);
+
+        Assert.assertTrue("Key must be checked", user.checkKey(key, salt));
+
+    }
+
+    @Test
+    public void testDeleteFakeUser() throws Exception {
+
+        MockHttpServletRequestBuilder get = MockMvcRequestBuilders
+                .get("/admin/users/delete/" + UUID.randomUUID().toString());
+
+        try {
+            this.mvc.perform(get).andExpect(
+                    MockMvcResultMatchers.status().isNotFound());
+        } catch (NestedServletException e) {
+            Assert.assertNotNull("Nested exception must not be null",
+                    e.getCause());
+            Assert.assertEquals(
+                    "Inner exception must be a HttpClientErrorException",
+                    HttpClientErrorException.class, e.getCause().getClass());
+            Assert.assertEquals("Exception error status must be not found",
+                    HttpStatus.NOT_FOUND,
+                    ((HttpClientErrorException) e.getCause()).getStatusCode());
+        }
+
+    }
+
+    @Test
+    public void testDeleteUserProject() throws Exception {
+
+        MockHttpServletRequestBuilder get = MockMvcRequestBuilders
+                .get("/admin/users/delete/" + this.usersUuids.get(0));
+
+        try {
+            this.mvc.perform(get).andExpect(
+                    MockMvcResultMatchers.status().isBadRequest());
+        } catch (NestedServletException e) {
+            Assert.assertNotNull("Nested exception must not be null",
+                    e.getCause());
+            Assert.assertEquals(
+                    "Inner exception must be a HttpClientErrorException",
+                    HttpClientErrorException.class, e.getCause().getClass());
+            Assert.assertEquals("Exception error status must be not found",
+                    HttpStatus.BAD_REQUEST,
+                    ((HttpClientErrorException) e.getCause()).getStatusCode());
+        }
+
+    }
+
+    @Test
+    public void testDoDeleteUserNoKey() throws Exception {
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/users/delete/"
+                        + this.usersUuids.get(USER_NB - 1));
+
+        try {
+            this.mvc.perform(post).andExpect(
+                    MockMvcResultMatchers.status().isBadRequest());
+        } catch (NestedServletException e) {
+            Assert.assertNotNull("Nested exception must not be null",
+                    e.getCause());
+            Assert.assertEquals(
+                    "Inner exception must be a HttpClientErrorException",
+                    HttpClientErrorException.class, e.getCause().getClass());
+            Assert.assertEquals("Exception error status must be not found",
+                    HttpStatus.BAD_REQUEST,
+                    ((HttpClientErrorException) e.getCause()).getStatusCode());
+        }
+
+        Assert.assertEquals("Must have same nb of user", USER_NB,
+                this.usersRepository.count());
+
+    }
+
+    @Test
+    public void testDoDeleteUser() throws Exception {
+
+        User user = this.usersList.get(this.usersUuids.get(USER_NB - 1));
+
+        SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
+        rand.setSeed(System.currentTimeMillis());
+        byte[] rawSalt = new byte[50];
+        rand.nextBytes(rawSalt);
+        String salt = Hex.encodeHexString(rawSalt);
+        String key = user.getKey(salt);
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post(String
+                .format("/admin/users/delete/%s?key=%s&salt=%s",
+                        this.usersUuids.get(USER_NB - 1), key, salt));
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isSeeOther())
+                .andExpect(MockMvcResultMatchers.redirectedUrl("/admin/users"));
+
+        Assert.assertEquals("Must have one less user", USER_NB - 1,
+                this.usersRepository.count());
+
+        user = this.usersRepository.findOne(this.usersUuids
+                .get(USER_NB - 1));
+
+        Assert.assertNull("User " + this.usersUuids.get(USER_NB - 1)
+                + " deleted", user);
+
+    }
+
+    @Test
+    public void testDoDeleteSpaceFake() throws Exception {
+
+        User user = this.usersList.get(this.usersUuids.get(USER_NB - 1));
+
+        SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
+        rand.setSeed(System.currentTimeMillis());
+        byte[] rawSalt = new byte[50];
+        rand.nextBytes(rawSalt);
+        String salt = Hex.encodeHexString(rawSalt);
+        String key = user.getKey(salt);
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post(String
+                .format("/admin/users/delete/%s?key=%s&salt=%s",
+                        UUID.randomUUID(), key, salt));
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isSeeOther())
+                .andExpect(MockMvcResultMatchers.redirectedUrl("/admin/users"));
+
+        Assert.assertEquals("Must have the same nb of user", USER_NB,
+                this.usersRepository.count());
+
+    }
+
+    @Test
+    public void testDoDeleteUserProject() throws Exception {
+
+        User user = this.usersList.get(this.usersUuids.get(0));
+
+        SecureRandom rand = SecureRandom.getInstance("SHA1PRNG");
+        rand.setSeed(System.currentTimeMillis());
+        byte[] rawSalt = new byte[50];
+        rand.nextBytes(rawSalt);
+        String salt = Hex.encodeHexString(rawSalt);
+        String key = user.getKey(salt);
+
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders.post(String
+                .format("/admin/users/delete/%s?key=%s&salt=%s",
+                        this.usersUuids.get(0), key, salt));
+
+        try {
+            this.mvc.perform(post).andExpect(
+                    MockMvcResultMatchers.status().isBadRequest());
+        } catch (NestedServletException e) {
+            Assert.assertNotNull("Nested exception must not be null",
+                    e.getCause());
+            Assert.assertEquals(
+                    "Inner exception must be a HttpClientErrorException",
+                    HttpClientErrorException.class, e.getCause().getClass());
+            Assert.assertEquals("Exception error status must be not found",
+                    HttpStatus.BAD_REQUEST,
+                    ((HttpClientErrorException) e.getCause()).getStatusCode());
+        }
+
+        Assert.assertEquals("Must have the same nb of user", USER_NB,
+                this.usersRepository.count());
+
+    }
+    
+    @Test
+    public void testUpdateUserGroups() throws Exception {
+        
+        MockHttpServletRequestBuilder post = MockMvcRequestBuilders
+                .post("/admin/users/save");
+        post = post.param("id", this.usersUuids.get(0));
+        post = post.param("title", "New name");
+        post = post.param("description", "New description");
+        post = post.param("uri", "http://ldt.iri.centrepompidou.fr/new/uri");
+        post = post.param("color", "#ffffff");
+        post = post.param("groups", this.groupsUuids.toArray(new String[UsersAdminControllerTest.GROUP_NB]));
+
+        this.mvc.perform(post)
+                .andExpect(MockMvcResultMatchers.status().isSeeOther())
+                .andExpect(MockMvcResultMatchers.redirectedUrl("/admin/users"));
+
+        User user = this.usersRepository.findOne(this.usersUuids.get(0));
+
+        Assert.assertNotNull("Should find user", user);
+        Assert.assertEquals("Title equals", "New name", user.getTitle());
+        Assert.assertEquals("Description equals", "New description",
+                user.getDescription());
+        Assert.assertEquals("Uri equals",
+                "http://ldt.iri.centrepompidou.fr/new/uri", user.getUri());
+        Assert.assertEquals("Color equals", "#ffffff", user.getColor());
+
+        Assert.assertNotNull("Groups must be set", user.getGroups());
+        Assert.assertEquals("all users must be set", GROUP_NB, user.getGroups().size());
+        Assert.assertTrue("users list must contains all users", this.groupsUuids.containsAll(user.getGroups()));
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/test/java/org/iri_research/renkan/test/repositories/GroupsRepositoryTest.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,391 @@
+package org.iri_research.renkan.test.repositories;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TimeZone;
+import java.util.UUID;
+
+import org.iri_research.renkan.models.Group;
+import org.iri_research.renkan.models.User;
+import org.iri_research.renkan.repositories.GroupsRepository;
+import org.iri_research.renkan.repositories.UsersRepository;
+import org.joda.time.LocalDate;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.mongodb.DBCollection;
+import com.mongodb.DBObject;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration("repositories-context.xml")
+public class GroupsRepositoryTest {
+
+    private final static int USER_NB = 3;
+    private final static int GROUP_NB = 3;
+
+    private Logger logger = LoggerFactory.getLogger(GroupsRepositoryTest.class);
+
+    @Autowired
+    private UsersRepository usersRepository;
+    @Autowired
+    private GroupsRepository groupsRepository;
+
+    
+    @Autowired
+    private MongoTemplate mongoTemplate;
+
+    private Map<String, User> usersList = new HashMap<String, User>(USER_NB);
+    private List<String> usersUuids = new ArrayList<>(USER_NB);
+
+    private Map<String, Group> groupsList = new HashMap<String, Group>(GROUP_NB);
+    private List<String> groupsUuids = new ArrayList<>(GROUP_NB);
+
+    
+    @Before
+    public void setup() {
+
+        logger.debug("Setup");
+        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+        usersRepository.deleteAll();
+        for(int i=0; i < USER_NB; i++) {
+            String uuid = UUID.randomUUID().toString();
+            User user = new User(uuid, "user" + i, "User nb " + i, "http://www.iri.centrepompidou.fr", "#ababab");
+            user.setLocked(false);
+            user.setEnabled(true);
+            user.setAvatar("A pretty picture");
+            user.setExpirationDate(new LocalDate());
+            user.setCredentialsExpirationDate(new LocalDate());
+            user.setEmail(String.format("user%d@mail.com", i));
+            user = usersRepository.save(user);
+            this.usersUuids.add(uuid);
+            this.usersList.put(uuid, user);
+            try {
+                Thread.sleep(1);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+        
+        for(int i=0; i < GROUP_NB; i++) {
+            String uuid = UUID.randomUUID().toString();
+            Group group = new Group(uuid, "group" + i, "Group nb " + i, "http://www.iri.centrepompidou.fr/group/"+uuid, "#ababab");
+            group.setAvatar("A pretty group picture " + i);
+            group = groupsRepository.save(group);
+            this.groupsUuids.add(uuid);
+            this.groupsList.put(uuid, group);
+            try {
+                Thread.sleep(1);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+
+        }
+
+
+    }
+
+    @Test
+    public void testGroupFieldMapping() {
+        // query json directly with mongodb driver
+        // check field values
+        DBCollection coll = mongoTemplate.getCollection(mongoTemplate
+                .getCollectionName(Group.class));
+
+        for (DBObject obj : coll.find()) {
+            Assert.assertTrue("mongo object must have _id field",
+                    obj.containsField("_id"));
+
+            String id = obj.get("_id").toString();
+
+            Group group = this.groupsList.get(id);
+
+            Assert.assertTrue("mongo object must have title field",
+                    obj.containsField("title"));
+            Assert.assertEquals("Titles must be the same",
+                    group.getTitle(), obj.get("title"));
+
+            Assert.assertTrue("mongo object must have description field",
+                    obj.containsField("description"));
+            Assert.assertEquals("description must be the same",
+                    group.getDescription(), obj.get("description"));
+
+            Assert.assertTrue("mongo object must have color field",
+                    obj.containsField("color"));
+            Assert.assertEquals("Color must be the same", group.getColor(), obj.get("color"));
+
+            Assert.assertTrue("mongo object must have uri field",
+                    obj.containsField("uri"));
+            Assert.assertEquals("Uri must be the same", group.getUri(), obj.get("uri"));
+            
+            Assert.assertTrue("mongo object must have avatar field",
+                    obj.containsField("avatar"));
+            Assert.assertEquals("Avater must be the same", group.getAvatar(), obj.get("avatar"));
+
+        }
+    }
+    
+    @Test
+    public void testSetUsersList() {
+
+        Group group = this.groupsList.get(this.groupsUuids.get(0));
+        
+        List<String> userIds = this.usersUuids;
+        
+        this.groupsRepository.setUsersList(group, userIds);
+        
+        //reload user
+        group = this.groupsRepository.findOne(group.getId());
+        
+        Assert.assertEquals("group user list is big enough", userIds.size(), group.getUsers().size());
+        Assert.assertTrue("Group user list contains all users", group.getUsers().containsAll(userIds));
+
+        for (User u : this.usersRepository.findAll(userIds)) {
+            Assert.assertEquals(String.format("user list for user %s must be size 1", u.getId()), 1, u.getGroups().size());
+            Assert.assertTrue(String.format("user list for group %s must contains user %s", u.getId(), group.getId()), u.getGroups().contains(group.getId()));
+        }
+    }
+    
+
+    @Test
+    public void testAddUsersList() {
+        Group group = this.groupsList.get(this.groupsUuids.get(1));
+        
+        List<String> userIds = this.usersUuids.subList(0, 1);
+        this.groupsRepository.setUsersList(group, userIds);
+        
+        group = this.groupsRepository.findOne(group.getId());
+        
+        Assert.assertEquals("group users is big enough", userIds.size(), group.getUsers().size());
+        Assert.assertTrue("User list contains all user", group.getUsers().containsAll(userIds));
+        
+        User user = this.usersRepository.findOne(userIds.get(0));
+        Assert.assertEquals(String.format("group list for user %s must be size 1", user.getId()), 1, user.getGroups().size());
+        Assert.assertTrue(String.format("group list for user %s must contains group %s", user.getId(), group.getId()), user.getGroups().contains(group.getId()));
+        
+        this.groupsRepository.setUsersList(group, this.usersUuids);
+        
+        //reload group
+        group = this.groupsRepository.findOne(group.getId());
+        
+        Assert.assertEquals("group user list is big enough", this.usersUuids.size(), group.getUsers().size());
+        Assert.assertTrue("User list contains all user", group.getUsers().containsAll(this.usersUuids));
+
+        for (User u : this.usersRepository.findAll(this.usersUuids)) {
+            Assert.assertEquals(String.format("group list for user %s must be size 1", u.getId()), 1, u.getGroups().size());
+            Assert.assertTrue(String.format("group list for user %s must contains group %s", u.getId(), group.getId()), u.getGroups().contains(group.getId()));
+        }
+
+    }
+    
+    @Test
+    public void testRemoveUsersList() {
+        Group group = this.groupsList.get(this.groupsUuids.get(2));
+        
+        this.groupsRepository.setUsersList(group, this.usersUuids);
+        
+        //reload group
+        group = this.groupsRepository.findOne(group.getId());
+        
+        Assert.assertEquals("Group user list is big enough", this.usersUuids.size(), group.getUsers().size());
+        Assert.assertTrue("User list contains all user", group.getUsers().containsAll(this.usersUuids));
+        
+        for(User user : this.usersRepository.findAll(this.usersUuids)) {
+            Assert.assertEquals(String.format("group list for user %s must be size 1", user.getId()), 1, user.getGroups().size());
+            Assert.assertTrue(String.format("group list for user %s must contains group %s", user.getId(), group.getId()), user.getGroups().contains(group.getId()));
+        }
+        
+        this.groupsRepository.setUsersList(group, this.usersUuids.subList(USER_NB-1, USER_NB));
+        
+        //reload group
+        group = this.groupsRepository.findOne(group.getId());
+        
+        Assert.assertEquals("group user list is big enough", 1, group.getUsers().size());
+        Assert.assertTrue("User list contains all user", group.getUsers().contains(this.usersUuids.get(USER_NB-1)));
+
+        User u = this.usersRepository.findOne(this.usersUuids.get(USER_NB-1));
+        Assert.assertEquals(String.format("group list for user %s must be size 1", u.getId()), 1, u.getGroups().size());
+        Assert.assertTrue(String.format("group list for user %s must contains group %s", u.getId(), group.getId()), u.getGroups().contains(group.getId()));
+        
+        for(User otherUser: this.usersRepository.findAll(this.usersUuids.subList(0, USER_NB-2))) {
+            Assert.assertEquals(String.format("group list for user %s must be size 0", otherUser.getId()), 0, otherUser.getGroups().size());
+        }
+
+    }
+
+
+    @Test
+    public void testAddUsersListExisting() {
+        
+       // get first group
+        Group group = this.groupsList.get(this.groupsUuids.get(0));
+        
+        List<String> userIds = this.usersUuids;
+        
+        // set all users for first group
+        this.groupsRepository.setUsersList(group, userIds);
+        
+        //reload group
+        group = this.groupsRepository.findOne(group.getId());
+        
+        //check that group has all users
+        Assert.assertEquals("Group user list is big enough", userIds.size(), group.getUsers().size());
+        Assert.assertTrue("User list contains all user", group.getUsers().containsAll(userIds));
+
+        // and that users have all new group
+        for (User u : this.usersRepository.findAll(userIds)) {
+            Assert.assertEquals(String.format("Group list for user %s must be size 1", u.getId()), 1, u.getGroups().size());
+            Assert.assertTrue(String.format("Group list for user %s must contains group %s", u.getId(), group.getId()), u.getGroups().contains(group.getId()));
+        }
+
+        
+        // get second group
+        group = this.groupsList.get(this.groupsUuids.get(1));
+        
+        //first set one user
+        List<String> secondUserIds = this.usersUuids.subList(0, 1);
+        this.groupsRepository.setUsersList(group, secondUserIds);
+        
+        // reload group
+        group = this.groupsRepository.findOne(group.getId());
+        
+        // check that second group has all users
+        Assert.assertEquals("Group user list is big enough", secondUserIds.size(), group.getUsers().size());
+        Assert.assertTrue("User list contains all users", group.getUsers().containsAll(secondUserIds));
+        
+        // check that group has new and old user
+        User user = this.usersRepository.findOne(secondUserIds.get(0));
+        Assert.assertEquals(String.format("Group list for user %s must be size 2", user.getId()), 2, user.getGroups().size());
+        Assert.assertTrue(String.format("Group list for user %s must contains group %s", user.getId(), group.getId()), user.getGroups().contains(group.getId()));
+        Assert.assertTrue(String.format("Group list for user %s must contains group %s", user.getId(), groupsUuids.get(0)), user.getGroups().contains(groupsUuids.get(0)));
+        
+        // set all new users list for second group
+        this.groupsRepository.setUsersList(group, this.usersUuids);
+        
+        //reload group
+        group = this.groupsRepository.findOne(group.getId());
+        
+        //check that group 2 has all users 
+        Assert.assertEquals("Group user list is big enough", this.usersUuids.size(), group.getUsers().size());
+        Assert.assertTrue("User list contains all user", group.getUsers().containsAll(this.usersUuids));
+
+        // check that all users had group 1 and group 2
+        for (User u : this.usersRepository.findAll(this.usersUuids)) {
+            Assert.assertEquals(String.format("Group list for user %s must be size 1", u.getId()), 2, u.getGroups().size());
+            Assert.assertTrue(String.format("Group list for user %s must contains group %s", u.getId(), group.getId()), u.getGroups().contains(group.getId()));
+            Assert.assertTrue(String.format("Group list for user %s must contains group %s", u.getId(), groupsUuids.get(0)), u.getGroups().contains(groupsUuids.get(0)));
+        }
+
+    }
+
+    
+    @Test
+    public void testRemoveGroupListExisting() {
+        
+        // get first group
+        Group group = this.groupsList.get(this.groupsUuids.get(0));
+        
+        List<String> userIds = this.usersUuids;
+        
+        // set all users for first group
+        this.groupsRepository.setUsersList(group, userIds);
+        
+        //reload group
+        group = this.groupsRepository.findOne(group.getId());
+        
+        //check that group has all users
+        Assert.assertEquals("Group users list is big enough", userIds.size(), group.getUsers().size());
+        Assert.assertTrue("User list contains all user", group.getUsers().containsAll(userIds));
+
+        // and that users have all new group
+        for (User u : this.usersRepository.findAll(userIds)) {
+            Assert.assertEquals(String.format("Group list for user %s must be size 1", u.getId()), 1, u.getGroups().size());
+            Assert.assertTrue(String.format("Group list for user %s must contains group %s", u.getId(), group.getId()), u.getGroups().contains(group.getId()));
+        }
+
+        // get 3rd group
+        group = this.groupsList.get(this.groupsUuids.get(2));
+        
+        // set all users for 3rd group
+        this.groupsRepository.setUsersList(group, this.usersUuids);
+        
+        //reload 3rd group
+        group = this.groupsRepository.findOne(group.getId());
+        
+        //check that all users are set for 3rd group
+        Assert.assertEquals("Group users list is big enough", this.usersUuids.size(), group.getUsers().size());
+        Assert.assertTrue("User list contains all users", group.getUsers().containsAll(this.usersUuids));
+        
+        //check that all users has 3rd group and 1st group
+        for(User user : this.usersRepository.findAll(this.usersUuids)) {
+            Assert.assertEquals(String.format("Group list for user %s must be size 2", user.getId()), 2, user.getGroups().size());
+            Assert.assertTrue(String.format("Group list for user %s must contains group %s", user.getId(), group.getId()), user.getGroups().contains(group.getId()));
+            Assert.assertTrue(String.format("Group list for user %s must contains group %s", user.getId(), this.groupsUuids.get(0)), user.getGroups().contains(this.groupsUuids.get(0)));
+        }
+        
+        //set new user list for 3rd group
+        this.groupsRepository.setUsersList(group, this.usersUuids.subList(USER_NB-1, USER_NB));
+        
+        //reload 3rd group
+        group = this.groupsRepository.findOne(group.getId());
+        
+        //check that 3rd group has only one user (last user)
+        Assert.assertEquals("Group users list is big enough", 1, group.getUsers().size());
+        Assert.assertTrue("User list contains all users", group.getUsers().contains(this.usersUuids.get(USER_NB-1)));
+
+        // check that last user has 3rd and 1rst group
+        User u = this.usersRepository.findOne(this.usersUuids.get(USER_NB-1));
+        Assert.assertEquals(String.format("Group list for user %s must be size 1", u.getId()), 2, u.getGroups().size());
+        Assert.assertTrue(String.format("Group list for user %s must contains group %s", u.getId(), group.getId()), u.getGroups().contains(group.getId()));
+        Assert.assertTrue(String.format("Group list for user %s must contains group %s", u.getId(), this.groupsUuids.get(0)), u.getGroups().contains(this.groupsUuids.get(0)));
+        
+        // check that other users has only 1rst group 
+        for(User otherUser: this.usersRepository.findAll(this.usersUuids.subList(0, USER_NB-2))) {
+            Assert.assertEquals(String.format("Group list for user %s must be size 0", otherUser.getId()), 1, otherUser.getGroups().size());
+            Assert.assertTrue(String.format("Group list for user %s must contains group %s", otherUser.getId(), this.groupsUuids.get(0)), otherUser.getGroups().contains(this.groupsUuids.get(0)));
+        }
+
+    }
+
+    @Test
+    public void testGetUsersMap() {
+        
+        Group group = this.groupsList.get(this.groupsUuids.get(0));
+        
+        List<String> userIds = this.usersUuids;
+        
+        this.groupsRepository.setUsersList(group, userIds);
+        
+        
+        Map<String, User> usersMap = this.groupsRepository.getUsersMap(group);
+        
+        Assert.assertEquals ("user map should have same length than users list", this.usersUuids.size(), usersMap.size());
+        Assert.assertTrue("user map should contains all uuids", this.usersUuids.containsAll(usersMap.keySet()));
+        for (Entry<String, User> entry : usersMap.entrySet()) {
+            User user = entry.getValue();
+            String userId = entry.getKey();
+            Assert.assertTrue("user id in user uuid", this.usersUuids.contains(userId));
+            Assert.assertEquals("key id and value user id must be the same", userId, user.getId());
+        }
+
+    }
+    
+
+    @After
+    public void teardown() {
+        this.usersRepository.deleteAll();
+        this.groupsRepository.deleteAll();
+    }
+
+}
--- a/server/src/test/java/org/iri_research/renkan/test/repositories/ProjectSyncsRepositoryTest.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/test/java/org/iri_research/renkan/test/repositories/ProjectSyncsRepositoryTest.java	Wed Jan 15 18:36:27 2014 +0100
@@ -1,8 +1,7 @@
 package org.iri_research.renkan.test.repositories;
 
-
 import java.util.ArrayList;
-import java.util.Date;
+import java.util.TimeZone;
 import java.util.UUID;
 
 import org.iri_research.renkan.RenkanException;
@@ -12,6 +11,7 @@
 import org.iri_research.renkan.repositories.ProjectSyncsRepository;
 import org.iri_research.renkan.repositories.ProjectsRepository;
 import org.iri_research.renkan.repositories.SpacesRepository;
+import org.joda.time.DateTime;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -23,143 +23,155 @@
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
-
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration("repositories-context.xml")
 public class ProjectSyncsRepositoryTest {
 
-	private Logger logger = LoggerFactory.getLogger(ProjectSyncsRepositoryTest.class);
-	
-	@Autowired
-	private ProjectsRepository projectRepository;
+    private Logger logger = LoggerFactory
+            .getLogger(ProjectSyncsRepositoryTest.class);
+
+    @Autowired
+    private ProjectsRepository projectRepository;
+
+    @Autowired
+    private ProjectSyncsRepository projectSyncsRepository;
+
+    @Autowired
+    private SpacesRepository spacesRepository;
+
+    private ArrayList<Project> testProjects = new ArrayList<Project>();
+
+    public ProjectSyncsRepositoryTest() {
+    }
+
+    @Before
+    public void setup() {
+
+        logger.debug("Setup");
+        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+        Space testSpace = new Space(UUID.randomUUID().toString(), "test",
+                "Test space", null, null, null, "test_user", null, null);
+        testSpace = spacesRepository.save(testSpace);
+        ArrayList<Project> pl = new ArrayList<Project>();
+        pl.add(new Project(testSpace.getId(), null, "test1", "desc1",
+                "http://localhost:8080/rest/projects/id1", new DateTime()));
+        pl.add(new Project(testSpace.getId(), null, "test2", "desc2",
+                "http://localhost:8080/rest/projects/id2", new DateTime()));
+        logger.debug("Setup : new Project ");
+        for (Project p : projectRepository.save(pl)) {
+            this.testProjects.add(p);
+        }
+    }
 
-	@Autowired
-	private ProjectSyncsRepository projectSyncsRepository;
-	
-	@Autowired
-	private SpacesRepository spacesRepository;
-	
-	
-	private ArrayList<Project> testProjects = new ArrayList<Project>();
-	
-	public ProjectSyncsRepositoryTest() {
-	}
-	
-	@Before
-	public void setup() {
-		
-		logger.debug("Setup");
-		Space testSpace = new Space(UUID.randomUUID().toString(), "test", "Test space", null, null, null, "test_user", null, null);
-		testSpace = spacesRepository.save(testSpace);
-		ArrayList<Project> pl = new ArrayList<Project>();
-		pl.add(new Project(testSpace.getId(), null, "test1", "desc1", "http://localhost:8080/rest/projects/id1", new Date()));
-		pl.add(new Project(testSpace.getId(), null, "test2", "desc2", "http://localhost:8080/rest/projects/id2", new Date()));
-		logger.debug("Setup : new Project ");
-		for(Project p: projectRepository.save(pl)) {
-			this.testProjects.add(p);
-		}
-	}
-	
-	@After
-	public void teardown() {
-		logger.debug("Teardown");
-		projectRepository.deleteAll();
-		projectSyncsRepository.deleteAll();
-	}
-	
+    @After
+    public void teardown() {
+        logger.debug("Teardown");
+        projectRepository.deleteAll();
+        projectSyncsRepository.deleteAll();
+    }
+
+    @Test
+    public void testGetCollection() {
+        String collectionName = this.projectSyncsRepository.getCollection()
+                .getName();
+
+        Assert.assertEquals("The collection name should be projectSyncs",
+                "projectSyncs", collectionName);
+
+    }
+
+    @Test
+    public void testGetProjectSync() throws RenkanException {
+
+        Project p = projectRepository.findOne(this.testProjects.get(0).getId());
+
+        String data = "{\"example\":\"this is an example\"}";
+
+        ProjectSync ps = projectSyncsRepository
+                .getProjectSync(data, p, "user1");
+
+        ps = this.projectSyncsRepository.save(ps);
+
+        ps = this.projectSyncsRepository.findOne(ps.getId());
+
+        Assert.assertNotNull(ps);
+        Assert.assertEquals(data, ps.getData());
+
+    }
 
-	@Test
-	public void testGetCollection() {
-		String collectionName = this.projectSyncsRepository.getCollection().getName();
-		
-		Assert.assertEquals("The collection name should be projectSyncs", "projectSyncs", collectionName);
-		
-	}
-	
-	@Test
-	public void testGetProjectSync() throws RenkanException {
-		
-		Project p = projectRepository.findOne(this.testProjects.get(0).getId());
-		
-		String data = "{\"example\":\"this is an example\"}";
-		
-		ProjectSync ps = projectSyncsRepository.getProjectSync(data, p, "user1");
-		
-		ps = this.projectSyncsRepository.save(ps);
-				
-		
-		ps = this.projectSyncsRepository.findOne(ps.getId());
-		
-		Assert.assertNotNull(ps);
-		Assert.assertEquals(data, ps.getData());
-				
-	}
-	
-	
-	@Test
-	public void testGetProjectSyncRevision() throws RenkanException {
-		
-		Project p = projectRepository.findOne(this.testProjects.get(0).getId());
-		
-		String data = "{\"example\":\"this is an example\"}";
-		
-		ProjectSync ps = projectSyncsRepository.getProjectSync(data, p, "user1");
-		
-		ps = this.projectSyncsRepository.save(ps);
-		ps = this.projectSyncsRepository.findOne(ps.getId());
-				
-		p = projectRepository.findOne(this.testProjects.get(0).getId());
-		
-		Assert.assertNotNull(ps.getProject());
-		Assert.assertEquals(p.getId(), ps.getProject().getId());
-		Assert.assertEquals("Revision of the project sync mustbe one less tha the rev counter pf the project", p.getRevCounter()-1, ps.getRevision());
-		
-		Assert.assertEquals("Revision of the project sync mustbe one less tha the rev counter of its project", ps.getProject().getRevCounter()-1, ps.getRevision());
-		
-	}
-	
-	@Test(expected=RenkanException.class)
-	public void testGetProjectSyncExceptionNullProject() throws RenkanException {
-		
-		String data = "{\"example\":\"this is an example\"}";
-		Project p = null;
-		ProjectSync ps = projectSyncsRepository.getProjectSync(data, p, "user1");
-		
-		// should never be executed.
-		Assert.assertNull(ps);
-	}
-	
-	@Test(expected=RenkanException.class)
-	public void testGetProjectSyncExceptionNullId() throws RenkanException {
-		
-		String data = "{\"example\":\"this is an example\"}";
-		String project_id = null;
-		ProjectSync ps = projectSyncsRepository.getProjectSync(data, project_id, "user1");
-		
-		// should never be executed.
-		Assert.assertNull(ps);
-	}
-	
-	@Test(expected=RenkanException.class)
-	public void testGetProjectSyncExceptionEmptyId() throws RenkanException {
-		
-		String data = "{\"example\":\"this is an example\"}";
-		String project_id = "";
-		ProjectSync ps = projectSyncsRepository.getProjectSync(data, project_id, "user1");
-		
-		// should never be executed.
-		Assert.assertNull(ps);
-	}
-	
-	@Test(expected=RenkanException.class)
-	public void testGetProjectSyncExceptionBadId() throws RenkanException {
-		
-		String data = "{\"example\":\"this is an example\"}";
-		String project_id = "BAD_ID";
-		ProjectSync ps = projectSyncsRepository.getProjectSync(data, project_id, "user1");
-		
-		// should never be executed.
-		Assert.assertNull(ps);
-	}
-	
+    @Test
+    public void testGetProjectSyncRevision() throws RenkanException {
+
+        Project p = projectRepository.findOne(this.testProjects.get(0).getId());
+
+        String data = "{\"example\":\"this is an example\"}";
+
+        ProjectSync ps = projectSyncsRepository
+                .getProjectSync(data, p, "user1");
+
+        ps = this.projectSyncsRepository.save(ps);
+        ps = this.projectSyncsRepository.findOne(ps.getId());
+
+        p = projectRepository.findOne(this.testProjects.get(0).getId());
+
+        Assert.assertNotNull(ps.getProject());
+        Assert.assertEquals(p.getId(), ps.getProject().getId());
+        Assert.assertEquals(
+                "Revision of the project sync mustbe one less tha the rev counter pf the project",
+                p.getRevCounter() - 1, ps.getRevision());
+
+        Assert.assertEquals(
+                "Revision of the project sync mustbe one less tha the rev counter of its project",
+                ps.getProject().getRevCounter() - 1, ps.getRevision());
+
+    }
+
+    @Test(expected = RenkanException.class)
+    public void testGetProjectSyncExceptionNullProject() throws RenkanException {
+
+        String data = "{\"example\":\"this is an example\"}";
+        Project p = null;
+        ProjectSync ps = projectSyncsRepository
+                .getProjectSync(data, p, "user1");
+
+        // should never be executed.
+        Assert.assertNull(ps);
+    }
+
+    @Test(expected = RenkanException.class)
+    public void testGetProjectSyncExceptionNullId() throws RenkanException {
+
+        String data = "{\"example\":\"this is an example\"}";
+        String project_id = null;
+        ProjectSync ps = projectSyncsRepository.getProjectSync(data,
+                project_id, "user1");
+
+        // should never be executed.
+        Assert.assertNull(ps);
+    }
+
+    @Test(expected = RenkanException.class)
+    public void testGetProjectSyncExceptionEmptyId() throws RenkanException {
+
+        String data = "{\"example\":\"this is an example\"}";
+        String project_id = "";
+        ProjectSync ps = projectSyncsRepository.getProjectSync(data,
+                project_id, "user1");
+
+        // should never be executed.
+        Assert.assertNull(ps);
+    }
+
+    @Test(expected = RenkanException.class)
+    public void testGetProjectSyncExceptionBadId() throws RenkanException {
+
+        String data = "{\"example\":\"this is an example\"}";
+        String project_id = "BAD_ID";
+        ProjectSync ps = projectSyncsRepository.getProjectSync(data,
+                project_id, "user1");
+
+        // should never be executed.
+        Assert.assertNull(ps);
+    }
+
 }
--- a/server/src/test/java/org/iri_research/renkan/test/repositories/ProjectsRepositoryTest.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/test/java/org/iri_research/renkan/test/repositories/ProjectsRepositoryTest.java	Wed Jan 15 18:36:27 2014 +0100
@@ -1,11 +1,10 @@
 package org.iri_research.renkan.test.repositories;
 
-
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.TimeZone;
 import java.util.UUID;
 
 import org.iri_research.renkan.models.Edge;
@@ -13,11 +12,15 @@
 import org.iri_research.renkan.models.Project;
 import org.iri_research.renkan.models.ProjectRevision;
 import org.iri_research.renkan.models.Space;
+import org.iri_research.renkan.models.User;
 import org.iri_research.renkan.repositories.EdgesRepository;
 import org.iri_research.renkan.repositories.NodesRepository;
 import org.iri_research.renkan.repositories.ProjectRevisionsRepository;
 import org.iri_research.renkan.repositories.ProjectsRepository;
 import org.iri_research.renkan.repositories.SpacesRepository;
+import org.iri_research.renkan.repositories.UsersRepository;
+import org.iri_research.renkan.utils.ColorGenerator;
+import org.joda.time.DateTime;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -39,452 +42,655 @@
 import com.mongodb.DBObject;
 import com.mongodb.DBRef;
 
-
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration("repositories-context.xml")
 public class ProjectsRepositoryTest {
 
-	private final static int SPACE_NB = 3;
-	
-	private Logger logger = LoggerFactory.getLogger(ProjectsRepositoryTest.class);
-	
-	@Autowired
-	private ProjectsRepository projectsRepository;
-	
-	@Autowired
-	private SpacesRepository spacesRepository;
-		
-	@Autowired
-	private NodesRepository nodesRepository;
-	
-	@Autowired
-	private EdgesRepository edgesRepository;
-	
-	@Autowired
-	private ProjectRevisionsRepository projectRevisionsRepository;
-	
-	@Autowired
-	private MongoTemplate mongoTemplate;
-	
-	private ArrayList<Project> testProjects = new ArrayList<Project>();
-	private List<Node> testNodes = new ArrayList<Node>();
-	private List<Edge> testEdges = new ArrayList<>();
-	
-	private Date creationDate = new Date();
-	
-	private List<String> spaceIds = new ArrayList<>(); 
-	
-	private Project copyProject;
-	
-	public ProjectsRepositoryTest() {
-	}
-	
-	@Before
-	public void setup() {
+    private final static int SPACE_NB = 3;
+
+    private Logger logger = LoggerFactory
+            .getLogger(ProjectsRepositoryTest.class);
+
+    @Autowired
+    private ProjectsRepository projectsRepository;
+
+    @Autowired
+    private SpacesRepository spacesRepository;
+
+    @Autowired
+    private NodesRepository nodesRepository;
+
+    @Autowired
+    private EdgesRepository edgesRepository;
+
+    @Autowired
+    private UsersRepository usersRepository;
+
+    @Autowired
+    private ProjectRevisionsRepository projectRevisionsRepository;
+
+    @Autowired
+    private MongoTemplate mongoTemplate;
+
+    private ArrayList<Project> testProjects = new ArrayList<Project>();
+    private List<Node> testNodes = new ArrayList<>();
+    private List<Edge> testEdges = new ArrayList<>();
+    private List<User> testUsers = new ArrayList<>();
+
+    private DateTime creationDate = new DateTime();
+
+    private List<String> spaceIds = new ArrayList<>();
+
+    private Project copyProject;
+
+    public ProjectsRepositoryTest() {
+    }
+
+    @Before
+    public void setup() {
+
+        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+        logger.debug("Setup");
+
+        // CREATE USERS
+        for (int i = 0; i < SPACE_NB + 1; i++) {
+            this.testUsers.add(new User(UUID.randomUUID().toString(),
+                    "test_user" + (i + 1), "Test user " + (i + 1),
+                    "http://www.iri.centrepompidou.fr/users/test_user"
+                            + (i + 1), "#" + ColorGenerator.randomColorHex()));
+        }
+        usersRepository.save(this.testUsers);
+
+        ArrayList<Project> pl = new ArrayList<Project>();
+        Space testSpace = null;
+        for (int i = 0; i < SPACE_NB; i++) {
+            spaceIds.add(UUID.randomUUID().toString());
+            testSpace = new Space(this.spaceIds.get(i), "test space " + i,
+                    "Test space " + i, null, null, null, "test_user", null,
+                    this.creationDate);
+            testSpace = spacesRepository.save(testSpace);
+            for (int j = 0; j < SPACE_NB - 1 - i; j++) {
+                final Project project = new Project(testSpace.getId(), UUID
+                        .randomUUID().toString(), "test project "
+                        + ((SPACE_NB - 1) * i + j + 1), "desc"
+                        + ((SPACE_NB - 1) * i + j + 1),
+                        "http://localhost:8080/rest/projects/id"
+                                + ((SPACE_NB - 1) * i + j + 1),
+                        this.creationDate);
+                pl.add(project);
+            }
+        }
+
+        for (int i = 0; i < testUsers.size() - 1; i++) {
+            User u = this.testUsers.get(i);
+            for (int j = 0; j < pl.size(); j++) {
+                Project p = pl.get(j);
+                if (j < pl.size() - i) {
+                    p.addUser(u);
+                } else {
+                    p.addUser(null, null);
+                }
+
+            }
+        }
+
+        for (Project p : projectsRepository.save(pl)) {
+            this.testProjects.add(p);
+        }
+
+        copyProject = this.testProjects.get(0);
+
+        for (int i = 0; i < 3; i++) {
+            Node node = new Node("Node" + i, "Node" + i, "Node " + i,
+                    "http://renkan.org/nodes/node" + i, "#ffff0" + i,
+                    "test_user", new Point(0, i),
+                    "http://renkan.org/images/node" + i, i, copyProject.getId());
+            node = this.nodesRepository.save(node);
+            copyProject.getNodes().add(node);
+            this.testNodes.add(node);
+        }
+        for (int i = 0; i < 3; i++) {
+            Edge edge = new Edge("Node" + i, "Node" + i, "Node " + i,
+                    "http://renkan.org/edges/edge" + i, "#ffff0" + i,
+                    this.testNodes.get((i + 2) % 3), this.testNodes.get(i),
+                    "test_user", copyProject.getId());
+            edge = this.edgesRepository.save(edge);
+            copyProject.getEdges().add(edge);
+            this.testEdges.add(edge);
+        }
+
+        this.projectsRepository.save(copyProject);
+
+    }
+
+    @After
+    public void teardown() {
+        logger.debug("Teardown");
+        edgesRepository.deleteAll();
+        nodesRepository.deleteAll();
+        projectRevisionsRepository.deleteAll();
+        projectsRepository.deleteAll();
+        spacesRepository.deleteAll();
+        usersRepository.deleteAll();
+    }
+
+    @Test
+    public void testInitialRevCounter() {
+
+        Project p = projectsRepository
+                .findOne(this.testProjects.get(0).getId());
+
+        Assert.assertEquals("Initial rev counter should be 1", 1,
+                p.getRevCounter());
+    }
+
+    @Test
+    public void testIncrementRevCounter() {
+
+        int revCounter = projectsRepository.getRevCounter(this.testProjects
+                .get(0).getId());
+        Assert.assertEquals("After 1 call rev counter should be 1", 1,
+                revCounter);
+        revCounter = projectsRepository.getRevCounter(this.testProjects.get(0)
+                .getId());
+        Assert.assertEquals("After 2 calls rev counter should be 2", 2,
+                revCounter);
+
+        for (int i = 0; i < 10; i++) {
+            revCounter = projectsRepository.getRevCounter(this.testProjects
+                    .get(0).getId());
+        }
+
+        Assert.assertEquals("After 10 more calls rev counter should be 12", 12,
+                revCounter);
+
+        Project p = projectsRepository
+                .findOne(this.testProjects.get(0).getId());
 
-		logger.debug("Setup");
-		ArrayList<Project> pl = new ArrayList<Project>();
-		Space testSpace = null;
-		for(int i=0; i<SPACE_NB; i++) {
-			spaceIds.add(UUID.randomUUID().toString());
-			testSpace = new Space(this.spaceIds.get(i), "test space " + i, "Test space " + i, null, null, null, "test_user", null, this.creationDate);
-			testSpace = spacesRepository.save(testSpace);
-			for(int j=0; j<SPACE_NB-1-i; j++) {
-				pl.add(new Project(testSpace.getId(), UUID.randomUUID().toString(), "test project "+((SPACE_NB-1)*i+j+1), "desc"+((SPACE_NB-1)*i+j+1), "http://localhost:8080/rest/projects/id"+((SPACE_NB-1)*i+j+1), this.creationDate));
-			}
-		}
-		for(Project p: projectsRepository.save(pl)) {
-			this.testProjects.add(p);
-		}
-		copyProject = this.testProjects.get(0);
-		
-		for(int i=0;i<3;i++) {
-			Node node = new Node("Node"+i, "Node"+i, "Node "+i, "http://renkan.org/nodes/node"+i, "#ffff0"+i, "test_user", new Point(0, i), "http://renkan.org/images/node"+i, i, copyProject.getId());
-			node = this.nodesRepository.save(node);
-			copyProject.getNodes().add(node);
-			this.testNodes.add(node);
-		}
-		
-		for(int i=0;i<3;i++) {
-			Edge edge = new Edge("Node"+i, "Node"+i, "Node "+i, "http://renkan.org/edges/edge"+i, "#ffff0"+i, this.testNodes.get((i+2)%3), this.testNodes.get(i), "test_user", copyProject.getId());
-			edge = this.edgesRepository.save(edge);
-			copyProject.getEdges().add(edge);
-			this.testEdges.add(edge);
-		}
-		
-		this.projectsRepository.save(copyProject);
+        Assert.assertEquals("next rev counter should be 13", 13,
+                p.getRevCounter());
+
+        p = projectsRepository.findOne(this.testProjects.get(1).getId());
+
+        Assert.assertEquals("other project next rev counter should be 1", 1,
+                p.getRevCounter());
+
+    }
+
+    @Test
+    public void testIncrementNonExisting() {
+
+        int revCounter = projectsRepository.getRevCounter("aaaa");
+        Assert.assertEquals("Rev counter non existing == -1", -1, revCounter);
+
+    }
+
+    @Test
+    public void testIncrementNull() {
+
+        int revCounter = projectsRepository.getRevCounter(null);
+        Assert.assertEquals("Rev counter null == -1", -1, revCounter);
+
+    }
+
+    @Test
+    public void testIncrementEmpty() {
+
+        int revCounter = projectsRepository.getRevCounter("");
+        Assert.assertEquals("Rev counter empty == -1", -1, revCounter);
+
+    }
+
+    @Test
+    public void testDateCreation() {
+
+        for (Project p : projectsRepository.findAll()) {
+            Assert.assertEquals(this.creationDate, p.getCreated());
+        }
+    }
+
+    @Test
+    public void testGetCountBySpace() {
+
+        Map<String, Integer> groupRes = projectsRepository.getCountBySpace();
+
+        Assert.assertNotNull("GroupRes not null", groupRes);
+        Assert.assertEquals("Group res size", SPACE_NB - 1, groupRes.size());
+
+        for (int i = 0; i < (SPACE_NB - 1); i++) {
+            Integer count = groupRes.get(this.spaceIds.get(i));
+            Assert.assertNotNull("count not null", count);
+            Assert.assertEquals("Nb of project/space", 2 - i, count.intValue());
+        }
+
+        Assert.assertNull("Last space id has no project i.e count is null",
+                groupRes.get(this.spaceIds.get(SPACE_NB - 1)));
+    }
+
+    @Test
+    public void testGetCountBySpaceFilter() {
+
+        List<String> spacesIdsFilter = Arrays.asList(this.spaceIds.get(0));
+
+        Map<String, Integer> groupRes = projectsRepository
+                .getCountBySpace(spacesIdsFilter);
+
+        Assert.assertNotNull("GroupRes not null", groupRes);
+        Assert.assertEquals("Group res size", 1, groupRes.size());
+
+        Integer count = groupRes.get(this.spaceIds.get(0));
+        Assert.assertNotNull("count not null", count);
+        Assert.assertEquals("Nb of project/space", 2, count.intValue());
 
-	}
-	
-	@After
-	public void teardown() {
-		logger.debug("Teardown");
-		edgesRepository.deleteAll();
-		nodesRepository.deleteAll();
-		projectRevisionsRepository.deleteAll();
-		projectsRepository.deleteAll();
-		spacesRepository.deleteAll();
-	}
-	
-	@Test
-	public void testInitialRevCounter() {
-		
-		Project p = projectsRepository.findOne(this.testProjects.get(0).getId());
-		
-		Assert.assertEquals("Initial rev counter should be 1", 1, p.getRevCounter());
-	}
-	
-	@Test
-	public void testIncrementRevCounter() {
-		
-		int revCounter = projectsRepository.getRevCounter(this.testProjects.get(0).getId());
-		Assert.assertEquals("After 1 call rev counter should be 1", 1, revCounter);
-		revCounter = projectsRepository.getRevCounter(this.testProjects.get(0).getId());
-		Assert.assertEquals("After 2 calls rev counter should be 2", 2, revCounter);
+        for (int i = 1; i < SPACE_NB; i++) {
+            Assert.assertNull(
+                    "other space id has no project i.e count is null",
+                    groupRes.get(this.spaceIds.get(i)));
+        }
+    }
+
+    @Test
+    public void testGetCountByUser() {
+
+        Map<String, Integer> groupRes = projectsRepository.getCountByUser();
+        int nu = this.testUsers.size();
+
+        Assert.assertNotNull("GroupRes not null", groupRes);
+        Assert.assertEquals("Group res size", nu, groupRes.size());
+
+        for (int i = 0; i < nu - 1; i++) {
+            Integer count = groupRes.get(this.testUsers.get(i).getId());
+            Assert.assertNotNull("count not null", count);
+            Assert.assertEquals("Nb of user/project", testProjects.size() - i,
+                    count.intValue());
+        }
+        Assert.assertNull("Last user id has no project i.e count is null",
+                groupRes.get(this.testUsers.get(nu - 1).getId()));
+
+        Integer count = groupRes.get(null);
+        Assert.assertNotNull("count not null", count);
+        Assert.assertEquals("Nb of anonymous user/project", (nu - 1) * (nu - 2)
+                / 2, count.intValue());
+    }
+
+    @Test
+    public void testGetCountByUserFilter() {
+
+        List<String> userIdsFilter = Arrays.asList(this.testUsers.get(0)
+                .getId());
+
+        Map<String, Integer> groupRes = projectsRepository
+                .getCountByUser(userIdsFilter);
+
+        Assert.assertNotNull("GroupRes not null", groupRes);
+        Assert.assertEquals("Group res size", 1, groupRes.size());
 
-		for(int i=0; i<10; i++) {
-			revCounter = projectsRepository.getRevCounter(this.testProjects.get(0).getId());
-		}
-		
-		Assert.assertEquals("After 10 more calls rev counter should be 12", 12, revCounter);
-		
-		Project p = projectsRepository.findOne(this.testProjects.get(0).getId());
-		
-		Assert.assertEquals("next rev counter should be 13", 13, p.getRevCounter());
-		
-		p = projectsRepository.findOne(this.testProjects.get(1).getId());
-		
-		Assert.assertEquals("other project next rev counter should be 1", 1, p.getRevCounter());
-		
-	}
-	
-	
-	@Test
-	public void testIncrementNonExisting() {
-		
-		int revCounter = projectsRepository.getRevCounter("aaaa");
-		Assert.assertEquals("Rev counter non existing == -1", -1, revCounter);
-		
-	}
-	
-	@Test
-	public void testIncrementNull() {
-		
-		int revCounter = projectsRepository.getRevCounter(null);
-		Assert.assertEquals("Rev counter null == -1", -1, revCounter);
-		
-	}
+        Integer count = groupRes.get(this.testUsers.get(0).getId());
+        Assert.assertNotNull("count not null", count);
+        Assert.assertEquals("Nb of user/project", testProjects.size(),
+                count.intValue());
+
+    }
+
+    @Test
+    public void testGetCountByUsername() {
+
+        Map<String, Integer> groupRes = projectsRepository.getCountByUsername();
+        int nu = this.testUsers.size() - 1;
+        int nb_username = this.testUsers.size() + (SPACE_NB - 1) * SPACE_NB / 2
+                - 2;
+
+        Assert.assertNotNull("GroupRes not null", groupRes);
+        Assert.assertEquals("Group res size", nb_username, groupRes.size());
+
+        for (int i = 0; i < nu - 1; i++) {
+            Integer count = groupRes.get(this.testUsers.get(i).getUsername());
+            Assert.assertNotNull("count not null", count);
+            Assert.assertEquals("Nb of user/project", testProjects.size() - i,
+                    count.intValue());
+        }
+        Assert.assertNull("Last user id has no project i.e count is null",
+                groupRes.get(this.testUsers.get(nu).getUsername()));
+
+        for (int i = 1; i < nu; i++) {
+            String anonymous_username = String.format("Anonymous-%d", i);
+            Integer count = groupRes.get(anonymous_username);
+            Assert.assertEquals("Nb of anonymous user/project", nu - i,
+                    count.intValue());
+        }
+
+    }
+
+    @Test
+    public void testGetCountByUsernameFilter() {
+
+        List<String> usernamesFilter = Arrays.asList(this.testUsers.get(0)
+                .getUsername());
+
+        Map<String, Integer> groupRes = projectsRepository
+                .getCountByUsername(usernamesFilter);
 
-	@Test
-	public void testIncrementEmpty() {
-		
-		int revCounter = projectsRepository.getRevCounter("");
-		Assert.assertEquals("Rev counter empty == -1", -1, revCounter);
-		
-	}
-	
-	@Test
-	public void testDateCreation() {
-		
-		for (Project p : projectsRepository.findAll()) {
-			Assert.assertEquals(this.creationDate, p.getCreated());
-		} 
-	}
-	
-	@Test
-	public void testGetCountBySpace() {
-		
-		Map<String, Integer> groupRes = projectsRepository.getCountBySpace();
-		
-		Assert.assertNotNull("GroupRes not null", groupRes);
-		Assert.assertEquals("Group res size", SPACE_NB-1, groupRes.size());
-		
-		for(int i=0;i<(SPACE_NB-1);i++) {
-			Integer count = groupRes.get(this.spaceIds.get(i));
-			Assert.assertNotNull("count not null", count);
-			Assert.assertEquals("Nb of project/space", 2-i, count.intValue());
-		}
-		
-		Assert.assertNull("Last space id has no project i.e count is null", groupRes.get(this.spaceIds.get(SPACE_NB-1)));		
-	}
-	
-	@Test
-	public void testGetCountBySpaceFilter() {
-		
-		List<String> spacesIdsFilter = Arrays.asList(this.spaceIds.get(0));
-		
-		Map<String, Integer> groupRes = projectsRepository.getCountBySpace(spacesIdsFilter);
-		
-		Assert.assertNotNull("GroupRes not null", groupRes);
-		Assert.assertEquals("Group res size", 1, groupRes.size());
-		
-		Integer count = groupRes.get(this.spaceIds.get(0));
-		Assert.assertNotNull("count not null", count);
-		Assert.assertEquals("Nb of project/space", 2, count.intValue());
-		
-		for(int i=1; i<SPACE_NB; i++) {
-			Assert.assertNull("other space id has no project i.e count is null", groupRes.get(this.spaceIds.get(i)));
-		}
-	}
-	
-	@Test
-	public void testCopyProjectCreation() {
-		DBCollection coll = mongoTemplate.getCollection(mongoTemplate.getCollectionName(Project.class));
-		
-		DBObject filter = new BasicDBObject();
-		filter.put("_id", copyProject.getId());
-		
-		DBCursor resFind = coll.find(filter);
-		
-		Assert.assertEquals("The project must be found", 1, resFind.count());
-		
-		for(DBObject obj: coll.find(filter)) {
-			Assert.assertEquals("id must be equal", copyProject.getId(), obj.get("_id"));
-		}
-	}
-	
-	@Test
-	public void testCopyProjectCopy() {
-		
-		Project newProject = this.projectsRepository.copy(this.copyProject, "copy_project");
-		
-		DBCollection coll = mongoTemplate.getCollection(mongoTemplate.getCollectionName(Project.class));
-		
-		DBObject filter = new BasicDBObject();
-		filter.put("_id", newProject.getId());
-		
-		DBCursor resFind = coll.find(filter);
-		
-		Assert.assertEquals("The project must be found", 1, resFind.count());
-		
-		for(DBObject obj: resFind) {
-			Assert.assertEquals("id must be equal", newProject.getId(), obj.get("_id"));
-			Assert.assertEquals("title must be must be copy_project", "copy_project", obj.get("title"));
-			Assert.assertEquals("space_id must be must be same than copyProject", this.copyProject.getSpaceId(), obj.get("space_id"));
-		}
-		
-		
-		filter = new BasicDBObject();
-		filter.put("project_id", newProject.getId());
-		
-		DBCollection nodesColl = mongoTemplate.getCollection(mongoTemplate.getCollectionName(Node.class));
-		resFind = nodesColl.find(filter);
-		
-		Assert.assertEquals("Must have 3 nodes", this.copyProject.getNodes().size(), resFind.count());
-		
-		for(DBObject obj: resFind) {
-			// find node with same title in copy project
-			Node originalNode = null;
-			for(Node n: this.copyProject.getNodes()) {
-				if(n.getTitle().equals(obj.get("title"))) {
-					originalNode = n;
-					break;
-				}
-			}
-			
-			Assert.assertNotNull("Must fincd original Node", originalNode);
-			
-			//color, desc, id diff, uri, created_by, image, position, diff projectif, size
-			Assert.assertNotSame("id must be differents", originalNode.getId(), obj.get("_id"));
-			Assert.assertNotSame("project id must be differents", originalNode.getProjectId(), obj.get("project_id"));
+        Assert.assertNotNull("GroupRes not null", groupRes);
+        Assert.assertEquals("Group res size", 1, groupRes.size());
+
+        Integer count = groupRes.get(this.testUsers.get(0).getUsername());
+        Assert.assertNotNull("count not null", count);
+        Assert.assertEquals("Nb of user/project", testProjects.size(),
+                count.intValue());
+
+    }
+
+    @Test
+    public void testCopyProjectCreation() {
+        DBCollection coll = mongoTemplate.getCollection(mongoTemplate
+                .getCollectionName(Project.class));
+
+        DBObject filter = new BasicDBObject();
+        filter.put("_id", copyProject.getId());
+
+        DBCursor resFind = coll.find(filter);
+
+        Assert.assertEquals("The project must be found", 1, resFind.count());
+
+        for (DBObject obj : coll.find(filter)) {
+            Assert.assertEquals("id must be equal", copyProject.getId(),
+                    obj.get("_id"));
+        }
+    }
+
+    @Test
+    public void testCopyProjectCopy() {
+
+        Project newProject = this.projectsRepository.copy(this.copyProject,
+                "copy_project");
+
+        DBCollection coll = mongoTemplate.getCollection(mongoTemplate
+                .getCollectionName(Project.class));
+
+        DBObject filter = new BasicDBObject();
+        filter.put("_id", newProject.getId());
+
+        DBCursor resFind = coll.find(filter);
+
+        Assert.assertEquals("The project must be found", 1, resFind.count());
+
+        for (DBObject obj : resFind) {
+            Assert.assertEquals("id must be equal", newProject.getId(),
+                    obj.get("_id"));
+            Assert.assertEquals("title must be must be copy_project",
+                    "copy_project", obj.get("title"));
+            Assert.assertEquals(
+                    "space_id must be must be same than copyProject",
+                    this.copyProject.getSpaceId(), obj.get("space_id"));
+        }
+
+        filter = new BasicDBObject();
+        filter.put("project_id", newProject.getId());
+
+        DBCollection nodesColl = mongoTemplate.getCollection(mongoTemplate
+                .getCollectionName(Node.class));
+        resFind = nodesColl.find(filter);
+
+        Assert.assertEquals("Must have 3 nodes", this.copyProject.getNodes()
+                .size(), resFind.count());
+
+        for (DBObject obj : resFind) {
+            // find node with same title in copy project
+            Node originalNode = null;
+            for (Node n : this.copyProject.getNodes()) {
+                if (n.getTitle().equals(obj.get("title"))) {
+                    originalNode = n;
+                    break;
+                }
+            }
+
+            Assert.assertNotNull("Must fincd original Node", originalNode);
 
-			Assert.assertEquals("same color", originalNode.getColor(), obj.get("color"));
-			Assert.assertEquals("same desc", originalNode.getDescription(), obj.get("description"));
-			Assert.assertEquals("same uri", originalNode.getUri(), obj.get("uri"));
-			Assert.assertEquals("same image", originalNode.getImage(), obj.get("image"));
-			Assert.assertEquals("same position", originalNode.getPosition().getX(), ((DBObject)obj.get("position")).get("x"));
-			Assert.assertEquals("same position", originalNode.getPosition().getY(), ((DBObject)obj.get("position")).get("y"));
-			Assert.assertEquals("same size", originalNode.getSize(), obj.get("size"));			
-			
-		}
-		
-		DBCollection edgesColl = mongoTemplate.getCollection(mongoTemplate.getCollectionName(Edge.class));
-		resFind = edgesColl.find(filter);
-		
-		Assert.assertEquals("Must have 3 edges", this.copyProject.getEdges().size(), resFind.count());
-		
-		for(DBObject obj: resFind) {
-			// find node with same title in copy project
-			Edge originalEdge = null;
-			for(Edge e: this.copyProject.getEdges()) {
-				if(e.getTitle().equals(obj.get("title"))) {
-					originalEdge = e;
-					break;
-				}
-			}
-			
-			Assert.assertNotNull("Must find original Node", originalEdge);
-			
-			//color, desc, id diff, uri, created_by, image, position, diff projectif, size
-			Assert.assertFalse("id must be differents", originalEdge.getId().equals(obj.get("_id")));
-			Assert.assertFalse("project id must be differents", originalEdge.getProjectId().equals(obj.get("project_id")));
+            // color, desc, id diff, uri, created_by, image, position, diff
+            // projectif, size
+            Assert.assertNotSame("id must be differents", originalNode.getId(),
+                    obj.get("_id"));
+            Assert.assertNotSame("project id must be differents",
+                    originalNode.getProjectId(), obj.get("project_id"));
+
+            Assert.assertEquals("same color", originalNode.getColor(),
+                    obj.get("color"));
+            Assert.assertEquals("same desc", originalNode.getDescription(),
+                    obj.get("description"));
+            Assert.assertEquals("same uri", originalNode.getUri(),
+                    obj.get("uri"));
+            Assert.assertEquals("same image", originalNode.getImage(),
+                    obj.get("image"));
+            Assert.assertEquals("same position", originalNode.getPosition()
+                    .getX(), ((DBObject) obj.get("position")).get("x"));
+            Assert.assertEquals("same position", originalNode.getPosition()
+                    .getY(), ((DBObject) obj.get("position")).get("y"));
+            Assert.assertEquals("same size", originalNode.getSize(),
+                    obj.get("size"));
+
+        }
+
+        DBCollection edgesColl = mongoTemplate.getCollection(mongoTemplate
+                .getCollectionName(Edge.class));
+        resFind = edgesColl.find(filter);
+
+        Assert.assertEquals("Must have 3 edges", this.copyProject.getEdges()
+                .size(), resFind.count());
+
+        for (DBObject obj : resFind) {
+            // find node with same title in copy project
+            Edge originalEdge = null;
+            for (Edge e : this.copyProject.getEdges()) {
+                if (e.getTitle().equals(obj.get("title"))) {
+                    originalEdge = e;
+                    break;
+                }
+            }
+
+            Assert.assertNotNull("Must find original Node", originalEdge);
+
+            // color, desc, id diff, uri, created_by, image, position, diff
+            // projectif, size
+            Assert.assertFalse("id must be differents", originalEdge.getId()
+                    .equals(obj.get("_id")));
+            Assert.assertFalse("project id must be differents", originalEdge
+                    .getProjectId().equals(obj.get("project_id")));
+
+            Assert.assertEquals("same color", originalEdge.getColor(),
+                    obj.get("color"));
+            Assert.assertEquals("same desc", originalEdge.getDescription(),
+                    obj.get("description"));
+            Assert.assertEquals("same uri", originalEdge.getUri(),
+                    obj.get("uri"));
+
+            // get FromNode
+            DBObject fromNode = nodesColl.findOne(((DBRef) obj.get("from"))
+                    .getId());
+            Assert.assertNotNull("fromNode must exits ", fromNode);
+            Assert.assertFalse("must be different from node", originalEdge
+                    .getFrom().equals(fromNode.get("_id")));
+            Assert.assertEquals("same from title", originalEdge.getFromNode()
+                    .getTitle(), fromNode.get("title"));
+
+            DBObject toNode = nodesColl
+                    .findOne(((DBRef) obj.get("to")).getId());
+            Assert.assertNotNull("toNode must exits", toNode);
+            Assert.assertFalse("must be different to node", originalEdge
+                    .getTo().equals(toNode.get("_id")));
+            Assert.assertEquals("same to title", originalEdge.getToNode()
+                    .getTitle(), toNode.get("title"));
+
+        }
+    }
+
+    @Test
+    public void testDeleteRecursive() {
+
+        List<Node> nodes = copyProject.getNodes();
+        List<Edge> edges = copyProject.getEdges();
+
+        this.projectsRepository.deleteRecursive(copyProject);
 
-			Assert.assertEquals("same color", originalEdge.getColor(), obj.get("color"));
-			Assert.assertEquals("same desc", originalEdge.getDescription(), obj.get("description"));
-			Assert.assertEquals("same uri", originalEdge.getUri(), obj.get("uri"));
-			
-			
-			// get FromNode
-			DBObject fromNode = nodesColl.findOne(((DBRef)obj.get("from")).getId());
-			Assert.assertNotNull("fromNode must exits ", fromNode);
-			Assert.assertFalse("must be different from node", originalEdge.getFrom().equals(fromNode.get("_id")));
-			Assert.assertEquals("same from title", originalEdge.getFromNode().getTitle(), fromNode.get("title"));
-			
-			DBObject toNode = nodesColl.findOne(((DBRef)obj.get("to")).getId());
-			Assert.assertNotNull("toNode must exits", toNode);
-			Assert.assertFalse("must be different to node", originalEdge.getTo().equals(toNode.get("_id")));
-			Assert.assertEquals("same to title", originalEdge.getToNode().getTitle(), toNode.get("title"));
-			
-		}		
-	}
-	
-	@Test
-	public void testDeleteRecursive() {
-		
-		List<Node> nodes= copyProject.getNodes();
-		List<Edge> edges= copyProject.getEdges();
-		
-		this.projectsRepository.deleteRecursive(copyProject);
-		
-		DBObject filter = new BasicDBObject();
-		filter.put("_id", copyProject.getId());
-		
-		DBCollection coll = mongoTemplate.getCollection(mongoTemplate.getCollectionName(Project.class));
-		DBCursor resFind = coll.find(filter);
-		
-		Assert.assertEquals("The project must not be found", 0, resFind.count());
-		
-		filter = new BasicDBObject();
-		filter.put("project_id", copyProject.getId());
-		
-		DBCollection nodesColl = mongoTemplate.getCollection(mongoTemplate.getCollectionName(Node.class));
-		resFind = nodesColl.find(filter);
-		
-		Assert.assertEquals("no nodes left", 0, resFind.count());
-		
-		for(Node n: nodes) {
-			DBObject nobj = nodesColl.findOne(n.getId());
-			Assert.assertNull("node should be deleted", nobj);
-		}
+        DBObject filter = new BasicDBObject();
+        filter.put("_id", copyProject.getId());
+
+        DBCollection coll = mongoTemplate.getCollection(mongoTemplate
+                .getCollectionName(Project.class));
+        DBCursor resFind = coll.find(filter);
+
+        Assert.assertEquals("The project must not be found", 0, resFind.count());
+
+        filter = new BasicDBObject();
+        filter.put("project_id", copyProject.getId());
+
+        DBCollection nodesColl = mongoTemplate.getCollection(mongoTemplate
+                .getCollectionName(Node.class));
+        resFind = nodesColl.find(filter);
+
+        Assert.assertEquals("no nodes left", 0, resFind.count());
+
+        for (Node n : nodes) {
+            DBObject nobj = nodesColl.findOne(n.getId());
+            Assert.assertNull("node should be deleted", nobj);
+        }
+
+        DBCollection edgesColl = mongoTemplate.getCollection(mongoTemplate
+                .getCollectionName(Edge.class));
+        resFind = edgesColl.find(filter);
+
+        Assert.assertEquals("no edges left", 0, resFind.count());
+
+        for (Edge e : edges) {
+            DBObject eobj = edgesColl.findOne(e.getId());
+            Assert.assertNull("edge should be deleted", eobj);
+        }
+
+    }
 
-		
-		DBCollection edgesColl = mongoTemplate.getCollection(mongoTemplate.getCollectionName(Edge.class));
-		resFind = edgesColl.find(filter);
-		
-		Assert.assertEquals("no edges left", 0, resFind.count());
-		
-		for(Edge e: edges) {
-			DBObject eobj = edgesColl.findOne(e.getId());
-			Assert.assertNull("edge should be deleted", eobj);
-		}
-		
-	}
-	
-	@SuppressWarnings("unchecked")
-	@Test
-	public void testDeleteRecursiveProjectRevision() {
-		
-		List<Node> nodes= copyProject.getNodes();
-		List<Edge> edges= copyProject.getEdges();
-		
-		int revCounter = copyProject.getRevCounter();
-		
-		this.projectsRepository.deleteRecursive(copyProject);
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testDeleteRecursiveProjectRevision() {
+
+        List<Node> nodes = copyProject.getNodes();
+        List<Edge> edges = copyProject.getEdges();
+
+        int revCounter = copyProject.getRevCounter();
+
+        this.projectsRepository.deleteRecursive(copyProject);
+
+        DBCollection coll = mongoTemplate.getCollection(mongoTemplate
+                .getCollectionName(ProjectRevision.class));
+
+        DBObject filter = new BasicDBObject();
+        filter.put("project", new DBRef(mongoTemplate.getDb(), "projects",
+                copyProject.getId()));
+        filter.put("revision", new Integer(revCounter));
+
+        DBObject revision = coll.findOne(filter);
+
+        Assert.assertNotNull("Must find revision", revision);
+
+        for (DBObject nobj : ((Iterable<DBObject>) revision.get("nodes"))) {
+            Node node = null;
+            for (Node n : nodes) {
+                if (n.getId().equals(nobj.get("_id"))) {
+                    node = n;
+                    break;
+                }
+            }
+            Assert.assertNotNull("Node must be in the original list", node);
+            Assert.assertEquals("Nodes must have same title", node.getTitle(),
+                    nobj.get("title"));
+        }
 
-		DBCollection coll = mongoTemplate.getCollection(mongoTemplate.getCollectionName(ProjectRevision.class));
-		
-		DBObject filter = new BasicDBObject();
-		filter.put("project", new DBRef(mongoTemplate.getDb(), "projects", copyProject.getId()));
-		filter.put("revision", new Integer(revCounter));
-		
-		DBObject revision = coll.findOne(filter);
-		
-		Assert.assertNotNull("Must find revision", revision);
-		
-		for(DBObject nobj: ((Iterable<DBObject>)revision.get("nodes"))) {
-			Node node = null;
-			for(Node n: nodes) {
-				if(n.getId().equals(nobj.get("_id"))) {
-					node = n;
-					break;
-				}
-			}
-			Assert.assertNotNull("Node must be in the original list", node);
-			Assert.assertEquals("Nodes must have same title", node.getTitle(), nobj.get("title"));
-		}
-		
-		for(DBObject eobj: ((Iterable<DBObject>)revision.get("edges"))) {
-			Edge edge = null;
-			for(Edge e: edges) {
-				if(e.getId().equals(eobj.get("_id"))) {
-					edge = e;
-					break;
-				}
-			}
-			Assert.assertNotNull("Edge must be in the original list", edge);
-			Assert.assertEquals("Edges must have same title", edge.getTitle(), eobj.get("title"));
-		}
-		
-	}
-	
-	@Test
-	public void testFindBySpaceIdAndTitleRegex() {
-		
-		List<Project> res = this.projectsRepository.findBySpaceIdAndTitleRegex(this.spaceIds.get(0), ".*Project.*");
-		
-		Assert.assertEquals("res must have length " + (SPACE_NB -1) , SPACE_NB-1, res.size());
-		for(Project p: res) {
-			Assert.assertEquals("project must belong to the same space", this.spaceIds.get(0), p.getSpaceId());
-			Assert.assertNotNull("project title must not be null", p.getTitle());
-			Assert.assertTrue("project tilte must contains title", p.getTitle().matches(".*project.*"));
-		}		
-	}
-	
-	@Test
-	public void testFindBySpaceIdAndTitleRegexBad() {
-		
-		List<Project> res = this.projectsRepository.findBySpaceIdAndTitleRegex(this.spaceIds.get(0), ".*foo.*");
-		
-		Assert.assertEquals("res must have zero length", 0, res.size());
-	}
-	
-	@Test
-	public void testFindBySpaceIdAndTitleRegexPageable() {
-		
-		PageRequest pr = new PageRequest(0, 1);
-		
-		Page<Project> res = this.projectsRepository.findBySpaceIdAndTitleRegex(this.spaceIds.get(0), ".*Project.*", pr);
-		
-		Assert.assertEquals("res must have length 1", 1, res.getNumberOfElements());
-		for(Project p: res) {
-			Assert.assertEquals("project must belong to the same space", this.spaceIds.get(0), p.getSpaceId());
-			Assert.assertNotNull("project title must not be null", p.getTitle());
-			Assert.assertTrue("project tilte must contains title", p.getTitle().matches(".*project.*"));
-		}		
-	}
-	
-	@Test
-	public void testFindBySpaceIdAndTitleRegexPageableBadSize() {
-		
-		PageRequest pr = new PageRequest(0, 3);
-		
-		Page<Project> res = this.projectsRepository.findBySpaceIdAndTitleRegex(this.spaceIds.get(0), ".*Project.*", pr);
-		
-		Assert.assertEquals("res must have length 2", 2, res.getNumberOfElements());
-		for(Project p: res) {
-			Assert.assertEquals("project must belong to the same space", this.spaceIds.get(0), p.getSpaceId());
-			Assert.assertNotNull("project title must not be null", p.getTitle());
-			Assert.assertTrue("project tilte must contains title", p.getTitle().matches(".*project.*"));
-		}		
-	}	
-	
-	@Test
-	public void testFindBySpaceIdAndTitleRegexPageableBadPage() {
-		
-		PageRequest pr = new PageRequest(1, 3);
-		
-		Page<Project> res = this.projectsRepository.findBySpaceIdAndTitleRegex(this.spaceIds.get(0), ".*Project.*", pr);
-		
-		Assert.assertEquals("res must have length 0", 0, res.getNumberOfElements());
-	}
+        for (DBObject eobj : ((Iterable<DBObject>) revision.get("edges"))) {
+            Edge edge = null;
+            for (Edge e : edges) {
+                if (e.getId().equals(eobj.get("_id"))) {
+                    edge = e;
+                    break;
+                }
+            }
+            Assert.assertNotNull("Edge must be in the original list", edge);
+            Assert.assertEquals("Edges must have same title", edge.getTitle(),
+                    eobj.get("title"));
+        }
+
+    }
+
+    @Test
+    public void testFindBySpaceIdAndTitleRegex() {
+
+        List<Project> res = this.projectsRepository.findBySpaceIdAndTitleRegex(
+                this.spaceIds.get(0), ".*Project.*");
+
+        Assert.assertEquals("res must have length " + (SPACE_NB - 1),
+                SPACE_NB - 1, res.size());
+        for (Project p : res) {
+            Assert.assertEquals("project must belong to the same space",
+                    this.spaceIds.get(0), p.getSpaceId());
+            Assert.assertNotNull("project title must not be null", p.getTitle());
+            Assert.assertTrue("project tilte must contains title", p.getTitle()
+                    .matches(".*project.*"));
+        }
+    }
+
+    @Test
+    public void testFindBySpaceIdAndTitleRegexBad() {
+
+        List<Project> res = this.projectsRepository.findBySpaceIdAndTitleRegex(
+                this.spaceIds.get(0), ".*foo.*");
+
+        Assert.assertEquals("res must have zero length", 0, res.size());
+    }
+
+    @Test
+    public void testFindBySpaceIdAndTitleRegexPageable() {
+
+        PageRequest pr = new PageRequest(0, 1);
+
+        Page<Project> res = this.projectsRepository.findBySpaceIdAndTitleRegex(
+                this.spaceIds.get(0), ".*Project.*", pr);
+
+        Assert.assertEquals("res must have length 1", 1,
+                res.getNumberOfElements());
+        for (Project p : res) {
+            Assert.assertEquals("project must belong to the same space",
+                    this.spaceIds.get(0), p.getSpaceId());
+            Assert.assertNotNull("project title must not be null", p.getTitle());
+            Assert.assertTrue("project tilte must contains title", p.getTitle()
+                    .matches(".*project.*"));
+        }
+    }
+
+    @Test
+    public void testFindBySpaceIdAndTitleRegexPageableBadSize() {
+
+        PageRequest pr = new PageRequest(0, 3);
+
+        Page<Project> res = this.projectsRepository.findBySpaceIdAndTitleRegex(
+                this.spaceIds.get(0), ".*Project.*", pr);
+
+        Assert.assertEquals("res must have length 2", 2,
+                res.getNumberOfElements());
+        for (Project p : res) {
+            Assert.assertEquals("project must belong to the same space",
+                    this.spaceIds.get(0), p.getSpaceId());
+            Assert.assertNotNull("project title must not be null", p.getTitle());
+            Assert.assertTrue("project tilte must contains title", p.getTitle()
+                    .matches(".*project.*"));
+        }
+    }
+
+    @Test
+    public void testFindBySpaceIdAndTitleRegexPageableBadPage() {
+
+        PageRequest pr = new PageRequest(1, 3);
+
+        Page<Project> res = this.projectsRepository.findBySpaceIdAndTitleRegex(
+                this.spaceIds.get(0), ".*Project.*", pr);
+
+        Assert.assertEquals("res must have length 0", 0,
+                res.getNumberOfElements());
+    }
 }
--- a/server/src/test/java/org/iri_research/renkan/test/repositories/SpacesRepositoryTest.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/test/java/org/iri_research/renkan/test/repositories/SpacesRepositoryTest.java	Wed Jan 15 18:36:27 2014 +0100
@@ -1,14 +1,15 @@
 package org.iri_research.renkan.test.repositories;
 
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.TimeZone;
 import java.util.UUID;
 
 import org.iri_research.renkan.models.Space;
 import org.iri_research.renkan.repositories.SpacesRepository;
+import org.joda.time.DateTime;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -32,103 +33,131 @@
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration("repositories-context.xml")
 public class SpacesRepositoryTest {
-	
-	private final static int SPACE_NB = 3;
-	
-	private Logger logger = LoggerFactory.getLogger(SpacesRepositoryTest.class);
-	
-	@Autowired
-	private SpacesRepository spacesRepository;
+
+    private final static int SPACE_NB = 3;
+
+    private Logger logger = LoggerFactory.getLogger(SpacesRepositoryTest.class);
+
+    @Autowired
+    private SpacesRepository spacesRepository;
+
+    @Autowired
+    private MongoTemplate mongoTemplate;
+
+    private Map<String, Space> spacesList = new HashMap<String, Space>(SPACE_NB);
+    private List<String> spacesUuids = new ArrayList<>(SPACE_NB);
+
+    @Before
+    public void setup() {
 
-	@Autowired
-	private MongoTemplate mongoTemplate;
-	
-	private Map<String, Space> spacesList = new HashMap<String, Space>(SPACE_NB);
-	private List<String> spacesUuids = new ArrayList<>(SPACE_NB);	
-	
-	@Before
-	public void setup() {
-		
-		logger.debug("Setup");
-		spacesRepository.deleteAll();
-		for(int i=0;i<SPACE_NB;i++) {
-			Date creationDate = new Date();
-			String uuid = UUID.randomUUID().toString();
-			spacesUuids.add(uuid);
-			Space testSpace = new Space(uuid, "test " + i, "Test space " + 1, "{}", "http://ldt.iri.centrepompidou.fr", "#ababab", "test_user", "http://ldt.iri.centrepompidou.fr", creationDate);
-			testSpace = spacesRepository.save(testSpace);
-			this.spacesList.put(uuid, testSpace);
-			try {
-				Thread.sleep(1);
-			} catch (InterruptedException e) {
-				e.printStackTrace();
-			}
-		}
-	}
-	
-	@Test
-	public void testFieldMapping() {
-		// query json directly with mongodb driver
-		// check field values
-		DBCollection coll = mongoTemplate.getCollection(mongoTemplate.getCollectionName(Space.class));
-		
-		for(DBObject obj: coll.find()) {
-			Assert.assertTrue("mongo object must have _id field", obj.containsField("_id"));
+        logger.debug("Setup");
+        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+        spacesRepository.deleteAll();
+        for (int i = 0; i < SPACE_NB; i++) {
+            DateTime creationDate = new DateTime();
+            String uuid = UUID.randomUUID().toString();
+            spacesUuids.add(uuid);
+            Space testSpace = new Space(uuid, "test " + i, "Test space " + 1,
+                    "{}", "http://ldt.iri.centrepompidou.fr", "#ababab",
+                    "test_user", "http://ldt.iri.centrepompidou.fr",
+                    creationDate);
+            testSpace = spacesRepository.save(testSpace);
+            this.spacesList.put(uuid, testSpace);
+            try {
+                Thread.sleep(1);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
 
-			String id = obj.get("_id").toString();
-			
-			Space sp = this.spacesList.get(id);
-			
-			Assert.assertTrue("mongo object must have title field", obj.containsField("title"));
-			Assert.assertEquals("Titles must be the same", obj.get("title"), sp.getTitle());
+    @Test
+    public void testFieldMapping() {
+        // query json directly with mongodb driver
+        // check field values
+        DBCollection coll = mongoTemplate.getCollection(mongoTemplate
+                .getCollectionName(Space.class));
+
+        for (DBObject obj : coll.find()) {
+            Assert.assertTrue("mongo object must have _id field",
+                    obj.containsField("_id"));
+
+            String id = obj.get("_id").toString();
+
+            Space sp = this.spacesList.get(id);
+
+            Assert.assertTrue("mongo object must have title field",
+                    obj.containsField("title"));
+            Assert.assertEquals("Titles must be the same", obj.get("title"),
+                    sp.getTitle());
+
+            Assert.assertTrue("mongo object must have description field",
+                    obj.containsField("description"));
+            Assert.assertEquals("description must be the same",
+                    obj.get("description"), sp.getDescription());
 
-			Assert.assertTrue("mongo object must have description field", obj.containsField("description"));
-			Assert.assertEquals("description must be the same", obj.get("description"), sp.getDescription());
+            Assert.assertTrue("mongo object must have color field",
+                    obj.containsField("color"));
+            Assert.assertEquals("Color must be the same", obj.get("color"),
+                    sp.getColor());
 
-			Assert.assertTrue("mongo object must have color field", obj.containsField("color"));
-			Assert.assertEquals("Color must be the same", obj.get("color"), sp.getColor());
+            Assert.assertTrue("mongo object must have uri field",
+                    obj.containsField("uri"));
+            Assert.assertEquals("Uri must be the same", obj.get("uri"),
+                    sp.getUri());
 
-			Assert.assertTrue("mongo object must have uri field", obj.containsField("uri"));
-			Assert.assertEquals("Uri must be the same", obj.get("uri"), sp.getUri());
+            Assert.assertTrue("mongo object must have image field",
+                    obj.containsField("image"));
+            Assert.assertEquals("Image must be the same", obj.get("image"),
+                    sp.getImage());
 
-			Assert.assertTrue("mongo object must have image field", obj.containsField("image"));
-			Assert.assertEquals("Image must be the same", obj.get("image"), sp.getImage());
-			
-			Assert.assertTrue("mongo object must have created field", obj.containsField("created"));
-			Assert.assertEquals("Created must be the same", obj.get("created"), sp.getCreated());
+            Assert.assertTrue("mongo object must have created field",
+                    obj.containsField("created"));
+            Assert.assertEquals("Created must be the same", new DateTime(obj.get("created")),
+                    sp.getCreated());
 
-			Assert.assertTrue("mongo object must have bin_config field", obj.containsField("bin_config"));
-			Assert.assertEquals("Uri must be the same", obj.get("bin_config"), sp.getBinConfig());
+            Assert.assertTrue("mongo object must have bin_config field",
+                    obj.containsField("bin_config"));
+            Assert.assertEquals("Uri must be the same", obj.get("bin_config"),
+                    sp.getBinConfig());
+
+            Assert.assertTrue("mongo object must have created_by field",
+                    obj.containsField("created_by"));
+            Assert.assertEquals("created by must be the same",
+                    obj.get("created_by"), sp.getCreatedBy());
+
+        }
+    }
 
-			Assert.assertTrue("mongo object must have created_by field", obj.containsField("created_by"));
-			Assert.assertEquals("created by must be the same", obj.get("created_by"), sp.getCreatedBy());			
-			
-		}		
-	}
-	
-	@Test
-	public void testPagination() {
-		
-		Sort s = new Sort(Direction.DESC, "created");
-		Pageable p = new PageRequest(0, 2, s);
-		
-		Page<Space> page = this.spacesRepository.findAll(p);
-		
-		Assert.assertEquals("page content length must be two", 2, page.getNumberOfElements());
-		Assert.assertEquals("id must be id of last created space", this.spacesUuids.get(SPACE_NB-1), page.getContent().get(0).getId());
-		Assert.assertEquals("id must be id of last created space", this.spacesUuids.get(SPACE_NB-2), page.getContent().get(1).getId());
-		
-		p = new PageRequest(1, 2, s);
-		page = this.spacesRepository.findAll(p);
-		Assert.assertEquals("page content length must be one", 1, page.getNumberOfElements());
-		Assert.assertEquals("id must be id of first created space", this.spacesUuids.get(0), page.getContent().get(0).getId());
-		
-	}
-	
-	@After
-	public void teardown() {
-		spacesRepository.deleteAll();
-	}
+    @Test
+    public void testPagination() {
+
+        Sort s = new Sort(Direction.DESC, "created");
+        Pageable p = new PageRequest(0, 2, s);
+
+        Page<Space> page = this.spacesRepository.findAll(p);
 
-	
+        Assert.assertEquals("page content length must be two", 2,
+                page.getNumberOfElements());
+        Assert.assertEquals("id must be id of last created space",
+                this.spacesUuids.get(SPACE_NB - 1), page.getContent().get(0)
+                        .getId());
+        Assert.assertEquals("id must be id of last created space",
+                this.spacesUuids.get(SPACE_NB - 2), page.getContent().get(1)
+                        .getId());
+
+        p = new PageRequest(1, 2, s);
+        page = this.spacesRepository.findAll(p);
+        Assert.assertEquals("page content length must be one", 1,
+                page.getNumberOfElements());
+        Assert.assertEquals("id must be id of first created space",
+                this.spacesUuids.get(0), page.getContent().get(0).getId());
+
+    }
+
+    @After
+    public void teardown() {
+        spacesRepository.deleteAll();
+    }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/test/java/org/iri_research/renkan/test/repositories/UsersRepositoryTest.java	Wed Jan 15 18:36:27 2014 +0100
@@ -0,0 +1,402 @@
+package org.iri_research.renkan.test.repositories;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+import java.util.UUID;
+import java.util.Map.Entry;
+
+import org.iri_research.renkan.models.Group;
+import org.iri_research.renkan.models.User;
+import org.iri_research.renkan.repositories.GroupsRepository;
+import org.iri_research.renkan.repositories.UsersRepository;
+import org.joda.time.LocalDate;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import com.mongodb.DBCollection;
+import com.mongodb.DBObject;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration("repositories-context.xml")
+public class UsersRepositoryTest {
+
+    private final static int USER_NB = 3;
+    private final static int GROUP_NB = 3;
+
+    private Logger logger = LoggerFactory.getLogger(UsersRepositoryTest.class);
+
+    @Autowired
+    private UsersRepository usersRepository;
+    @Autowired
+    private GroupsRepository groupsRepository;
+
+    
+    @Autowired
+    private MongoTemplate mongoTemplate;
+
+    private Map<String, User> usersList = new HashMap<String, User>(USER_NB);
+    private List<String> usersUuids = new ArrayList<>(USER_NB);
+
+    private Map<String, Group> groupsList = new HashMap<String, Group>(GROUP_NB);
+    private List<String> groupsUuids = new ArrayList<>(GROUP_NB);
+
+    
+    @Before
+    public void setup() {
+
+        logger.debug("Setup");
+        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+        usersRepository.deleteAll();
+        for(int i=0; i < USER_NB; i++) {
+            String uuid = UUID.randomUUID().toString();
+            User user = new User(uuid, "user" + i, "User nb " + i, "http://www.iri.centrepompidou.fr", "#ababab");
+            user.setLocked(false);
+            user.setEnabled(true);
+            user.setAvatar("A pretty picture");
+            user.setExpirationDate(new LocalDate());
+            user.setCredentialsExpirationDate(new LocalDate());
+            user.setEmail(String.format("user%d@mail.com", i));
+            user = usersRepository.save(user);
+            this.usersUuids.add(uuid);
+            this.usersList.put(uuid, user);
+            try {
+                Thread.sleep(1);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+        
+        for(int i=0; i < GROUP_NB; i++) {
+            String uuid = UUID.randomUUID().toString();
+            Group group = new Group(uuid, "group" + i, "Group nb " + i, "http://www.iri.centrepompidou.fr/group/"+uuid, "#ababab");
+            group.setAvatar("A pretty group picture " + i);
+            group = groupsRepository.save(group);
+            this.groupsUuids.add(uuid);
+            this.groupsList.put(uuid, group);
+            try {
+                Thread.sleep(1);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+
+        }
+
+
+    }
+
+    @Test
+    public void testUserFieldMapping() {
+        // query json directly with mongodb driver
+        // check field values
+        DBCollection coll = mongoTemplate.getCollection(mongoTemplate
+                .getCollectionName(User.class));
+
+        for (DBObject obj : coll.find()) {
+            Assert.assertTrue("mongo object must have _id field",
+                    obj.containsField("_id"));
+
+            String id = obj.get("_id").toString();
+
+            User user = this.usersList.get(id);
+
+            Assert.assertTrue("mongo object must have title field",
+                    obj.containsField("title"));
+            Assert.assertEquals("Titles must be the same",
+                    user.getTitle(), obj.get("title"));
+
+            Assert.assertTrue("mongo object must have description field",
+                    obj.containsField("description"));
+            Assert.assertEquals("description must be the same",
+                    user.getDescription(), obj.get("description"));
+
+            Assert.assertTrue("mongo object must have color field",
+                    obj.containsField("color"));
+            Assert.assertEquals("Color must be the same", user.getColor(), obj.get("color"));
+
+            Assert.assertTrue("mongo object must have uri field",
+                    obj.containsField("uri"));
+            Assert.assertEquals("Uri must be the same", user.getUri(), obj.get("uri"));
+
+            Assert.assertTrue("mongo object must have locked field",
+                    obj.containsField("locked"));
+            Assert.assertEquals("Locked must be the same", user.isLocked(), obj.get("locked"));
+
+            Assert.assertTrue("mongo object must have activated field",
+                    obj.containsField("enabled"));
+            Assert.assertEquals("Enabled must be the same", user.isEnabled(), obj.get("enabled"));
+
+            Assert.assertTrue("mongo object must have expiration_date field",
+                    obj.containsField("expiration_date"));
+            Assert.assertEquals("expiration_date must be the same", user.getExpirationDate(), new LocalDate(obj.get("expiration_date")));
+
+            Assert.assertTrue("mongo object must have credentials_expiration_date field",
+                    obj.containsField("credentials_expiration_date"));
+            Assert.assertEquals("credentials_expiration_date by must be the same", user.getCredentialsExpirationDate(), new LocalDate(obj.get("credentials_expiration_date")));
+
+            Assert.assertTrue("mongo object must have email field",
+                    obj.containsField("email"));
+            Assert.assertEquals("Email must be the same", user.getEmail(), obj.get("email"));
+
+            
+        }
+    }
+    
+    @Test
+    public void testSetGroupsList() {
+
+        User user = this.usersList.get(this.usersUuids.get(0));
+        
+        List<String> groupIds = this.groupsUuids;
+        
+        this.usersRepository.setGroupsList(user, groupIds);
+        
+        //reload user
+        user = this.usersRepository.findOne(user.getId());
+        
+        Assert.assertEquals("user group is big enough", groupIds.size(), user.getGroups().size());
+        Assert.assertTrue("Group list contains all group", user.getGroups().containsAll(groupIds));
+
+        for (Group g : this.groupsRepository.findAll(groupIds)) {
+            Assert.assertEquals(String.format("user list for group %s must be size 1", g.getId()), 1, g.getUsers().size());
+            Assert.assertTrue(String.format("user list for group %s must contains user %s", g.getId(), user.getId()), g.getUsers().contains(user.getId()));
+        }
+    }
+    
+
+    @Test
+    public void testAddGroupsList() {
+        User user = this.usersList.get(this.usersUuids.get(1));
+        
+        List<String> groupIds = this.groupsUuids.subList(0, 1);
+        this.usersRepository.setGroupsList(user, groupIds);
+        
+        user = this.usersRepository.findOne(user.getId());
+        
+        Assert.assertEquals("user group is big enough", groupIds.size(), user.getGroups().size());
+        Assert.assertTrue("Group list contains all group", user.getGroups().containsAll(groupIds));
+        
+        Group group = this.groupsRepository.findOne(groupIds.get(0));
+        Assert.assertEquals(String.format("user list for group %s must be size 1", group.getId()), 1, group.getUsers().size());
+        Assert.assertTrue(String.format("user list for group %s must contains user %s", group.getId(), user.getId()), group.getUsers().contains(user.getId()));
+        
+        this.usersRepository.setGroupsList(user, this.groupsUuids);
+        
+        //reload user
+        user = this.usersRepository.findOne(user.getId());
+        
+        Assert.assertEquals("user group is big enough", this.groupsUuids.size(), user.getGroups().size());
+        Assert.assertTrue("Group list contains all group", user.getGroups().containsAll(this.groupsUuids));
+
+        for (Group g : this.groupsRepository.findAll(this.groupsUuids)) {
+            Assert.assertEquals(String.format("user list for group %s must be size 1", g.getId()), 1, g.getUsers().size());
+            Assert.assertTrue(String.format("user list for group %s must contains user %s", g.getId(), user.getId()), g.getUsers().contains(user.getId()));
+        }
+
+    }
+    
+    @Test
+    public void testRemoveGroupsList() {
+        User user = this.usersList.get(this.usersUuids.get(2));
+        
+        this.usersRepository.setGroupsList(user, this.groupsUuids);
+        
+        user = this.usersRepository.findOne(user.getId());
+        
+        Assert.assertEquals("user group is big enough", this.groupsUuids.size(), user.getGroups().size());
+        Assert.assertTrue("Group list contains all group", user.getGroups().containsAll(this.groupsUuids));
+        
+        for(Group group : this.groupsRepository.findAll(this.groupsUuids)) {
+            Assert.assertEquals(String.format("user list for group %s must be size 1", group.getId()), 1, group.getUsers().size());
+            Assert.assertTrue(String.format("user list for group %s must contains user %s", group.getId(), user.getId()), group.getUsers().contains(user.getId()));
+        }
+        
+        this.usersRepository.setGroupsList(user, this.groupsUuids.subList(GROUP_NB-1, GROUP_NB));
+        
+        //reload user
+        user = this.usersRepository.findOne(user.getId());
+        
+        Assert.assertEquals("user group is big enough", 1, user.getGroups().size());
+        Assert.assertTrue("Group list contains all group", user.getGroups().contains(this.groupsUuids.get(GROUP_NB-1)));
+
+        Group g = this.groupsRepository.findOne(this.groupsUuids.get(GROUP_NB-1));
+        Assert.assertEquals(String.format("user list for group %s must be size 1", g.getId()), 1, g.getUsers().size());
+        Assert.assertTrue(String.format("user list for group %s must contains user %s", g.getId(), user.getId()), g.getUsers().contains(user.getId()));
+        
+        for(Group otherGroup: this.groupsRepository.findAll(this.groupsUuids.subList(0, GROUP_NB-2))) {
+            Assert.assertEquals(String.format("user list for group %s must be size 0", otherGroup.getId()), 0, otherGroup.getUsers().size());
+        }
+
+    }
+    
+    @Test
+    public void testAddGroupsListExisting() {
+        
+       // get first user
+        User user = this.usersList.get(this.usersUuids.get(0));
+        
+        List<String> groupIds = this.groupsUuids;
+        
+        // set all groups for first user
+        this.usersRepository.setGroupsList(user, groupIds);
+        
+        //reload user
+        user = this.usersRepository.findOne(user.getId());
+        
+        //check that user has all group
+        Assert.assertEquals("user group is big enough", groupIds.size(), user.getGroups().size());
+        Assert.assertTrue("Group list contains all group", user.getGroups().containsAll(groupIds));
+
+        // and that groups have all new user
+        for (Group g : this.groupsRepository.findAll(groupIds)) {
+            Assert.assertEquals(String.format("user list for group %s must be size 1", g.getId()), 1, g.getUsers().size());
+            Assert.assertTrue(String.format("user list for group %s must contains user %s", g.getId(), user.getId()), g.getUsers().contains(user.getId()));
+        }
+
+        
+        // get second user
+        user = this.usersList.get(this.usersUuids.get(1));
+        
+        //first set one group
+        List<String> secondGroupIds = this.groupsUuids.subList(0, 1);
+        this.usersRepository.setGroupsList(user, secondGroupIds);
+        
+        // relaod user
+        user = this.usersRepository.findOne(user.getId());
+        
+        // check that second user has all groups
+        Assert.assertEquals("user group is big enough", secondGroupIds.size(), user.getGroups().size());
+        Assert.assertTrue("Group list contains all group", user.getGroups().containsAll(secondGroupIds));
+        
+        // check that group has new and old user
+        Group group = this.groupsRepository.findOne(secondGroupIds.get(0));
+        Assert.assertEquals(String.format("user list for group %s must be size 2", group.getId()), 2, group.getUsers().size());
+        Assert.assertTrue(String.format("user list for group %s must contains user %s", group.getId(), user.getId()), group.getUsers().contains(user.getId()));
+        Assert.assertTrue(String.format("user list for group %s must contains user %s", group.getId(), usersUuids.get(0)), group.getUsers().contains(usersUuids.get(0)));
+        
+        // set all new group list for second user
+        this.usersRepository.setGroupsList(user, this.groupsUuids);
+        
+        //reload user
+        user = this.usersRepository.findOne(user.getId());
+        
+        //check that user 2 has all groups 
+        Assert.assertEquals("user group is big enough", this.groupsUuids.size(), user.getGroups().size());
+        Assert.assertTrue("Group list contains all group", user.getGroups().containsAll(this.groupsUuids));
+
+        // check that all groups had user 1 and user 2
+        for (Group g : this.groupsRepository.findAll(this.groupsUuids)) {
+            Assert.assertEquals(String.format("user list for group %s must be size 1", g.getId()), 2, g.getUsers().size());
+            Assert.assertTrue(String.format("user list for group %s must contains user %s", g.getId(), user.getId()), g.getUsers().contains(user.getId()));
+            Assert.assertTrue(String.format("user list for group %s must contains user %s", g.getId(), usersUuids.get(0)), g.getUsers().contains(usersUuids.get(0)));
+        }
+
+    }
+
+    @Test
+    public void testRemoveGroupsListExisting() {
+        
+       // get first user
+        User user = this.usersList.get(this.usersUuids.get(0));
+        
+        List<String> groupIds = this.groupsUuids;
+        
+        // set all groups for first user
+        this.usersRepository.setGroupsList(user, groupIds);
+        
+        //reload user
+        user = this.usersRepository.findOne(user.getId());
+        
+        //check that user has all group
+        Assert.assertEquals("user group is big enough", groupIds.size(), user.getGroups().size());
+        Assert.assertTrue("Group list contains all group", user.getGroups().containsAll(groupIds));
+
+        // and that groups have all new user
+        for (Group g : this.groupsRepository.findAll(groupIds)) {
+            Assert.assertEquals(String.format("user list for group %s must be size 1", g.getId()), 1, g.getUsers().size());
+            Assert.assertTrue(String.format("user list for group %s must contains user %s", g.getId(), user.getId()), g.getUsers().contains(user.getId()));
+        }
+
+        // get 3rd user
+        user = this.usersList.get(this.usersUuids.get(2));
+        
+        // set all group for 3rd user
+        this.usersRepository.setGroupsList(user, this.groupsUuids);
+        
+        //reload 3rd user
+        user = this.usersRepository.findOne(user.getId());
+        
+        //check taht all group are set for 3rd user
+        Assert.assertEquals("user group is big enough", this.groupsUuids.size(), user.getGroups().size());
+        Assert.assertTrue("Group list contains all group", user.getGroups().containsAll(this.groupsUuids));
+        
+        //check that all group has 3rd user and 1st user
+        for(Group group : this.groupsRepository.findAll(this.groupsUuids)) {
+            Assert.assertEquals(String.format("user list for group %s must be size 2", group.getId()), 2, group.getUsers().size());
+            Assert.assertTrue(String.format("user list for group %s must contains user %s", group.getId(), user.getId()), group.getUsers().contains(user.getId()));
+            Assert.assertTrue(String.format("user list for group %s must contains user %s", group.getId(), this.usersUuids.get(0)), group.getUsers().contains(this.usersUuids.get(0)));
+        }
+        
+        //set new group list for 3rd user
+        this.usersRepository.setGroupsList(user, this.groupsUuids.subList(GROUP_NB-1, GROUP_NB));
+        
+        //reload 3rd user
+        user = this.usersRepository.findOne(user.getId());
+        
+        //check that 3rd user has only one group (last group)
+        Assert.assertEquals("user group is big enough", 1, user.getGroups().size());
+        Assert.assertTrue("Group list contains all group", user.getGroups().contains(this.groupsUuids.get(GROUP_NB-1)));
+
+        // check that last group has 3rd and 1rst user
+        Group g = this.groupsRepository.findOne(this.groupsUuids.get(GROUP_NB-1));
+        Assert.assertEquals(String.format("user list for group %s must be size 1", g.getId()), 2, g.getUsers().size());
+        Assert.assertTrue(String.format("user list for group %s must contains user %s", g.getId(), user.getId()), g.getUsers().contains(user.getId()));
+        Assert.assertTrue(String.format("user list for group %s must contains user %s", g.getId(), this.usersUuids.get(0)), g.getUsers().contains(this.usersUuids.get(0)));
+        
+        // check that other groups has only 1rst user 
+        for(Group otherGroup: this.groupsRepository.findAll(this.groupsUuids.subList(0, GROUP_NB-2))) {
+            Assert.assertEquals(String.format("user list for group %s must be size 0", otherGroup.getId()), 1, otherGroup.getUsers().size());
+            Assert.assertTrue(String.format("user list for group %s must contains user %s", otherGroup.getId(), this.usersUuids.get(0)), otherGroup.getUsers().contains(this.usersUuids.get(0)));
+        }
+
+    }
+    
+    @Test
+    public void testGetUsersMap() {
+        
+        User user = this.usersList.get(this.usersUuids.get(0));
+        
+        List<String> groupdIds = this.groupsUuids;
+        
+        this.usersRepository.setGroupsList(user, groupdIds);
+        
+        
+        Map<String, Group> groupsMap = this.usersRepository.getGroupsMap(user);
+        
+        Assert.assertEquals ("Group map should have same length than groups list", this.groupsUuids.size(), groupsMap.size());
+        Assert.assertTrue("Group map should contains all uuids", this.groupsUuids.containsAll(groupsMap.keySet()));
+        for (Entry<String, Group> entry : groupsMap.entrySet()) {
+            Assert.assertTrue("user id in user uuid", this.groupsUuids.contains(entry.getKey()));
+            Assert.assertEquals("key id and value user id must be the same", entry.getKey(), entry.getValue().getId());
+        }
+    }
+    
+
+    @After
+    public void teardown() {
+        this.usersRepository.deleteAll();
+        this.groupsRepository.deleteAll();
+    }
+
+}
--- a/server/src/test/java/org/iri_research/renkan/test/rest/ProjectRestTest.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/test/java/org/iri_research/renkan/test/rest/ProjectRestTest.java	Wed Jan 15 18:36:27 2014 +0100
@@ -1,10 +1,17 @@
 package org.iri_research.renkan.test.rest;
 
+import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
+import java.util.TimeZone;
 import java.util.UUID;
 
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.Application;
+import javax.ws.rs.core.MediaType;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
 import org.iri_research.renkan.models.Edge;
 import org.iri_research.renkan.models.Node;
 import org.iri_research.renkan.models.Project;
@@ -14,6 +21,9 @@
 import org.iri_research.renkan.repositories.ProjectRevisionsRepository;
 import org.iri_research.renkan.repositories.ProjectsRepository;
 import org.iri_research.renkan.repositories.SpacesRepository;
+import org.iri_research.renkan.rest.RestApplication;
+import org.joda.time.DateTime;
+import org.joda.time.format.ISODateTimeFormat;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -26,146 +36,198 @@
 import org.springframework.data.mongodb.core.geo.Point;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.web.context.ContextLoaderListener;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.joda.JodaModule;
 import com.mongodb.BasicDBObject;
 import com.mongodb.DBCollection;
 import com.mongodb.DBCursor;
 import com.mongodb.DBObject;
-import com.sun.jersey.api.client.WebResource;
-import com.sun.jersey.spi.spring.container.servlet.SpringServlet;
-import com.sun.jersey.test.framework.AppDescriptor;
-import com.sun.jersey.test.framework.JerseyTest;
-import com.sun.jersey.test.framework.WebAppDescriptor;
+
+//import com.sun.jersey.spi.spring.container.servlet.SpringServlet;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration("rest-context.xml")
 public class ProjectRestTest extends JerseyTest {
-	
-	private Logger logger = LoggerFactory.getLogger(ProjectRestTest.class);
-	
-	@Autowired
-	private ProjectsRepository projectsRepository;
-	
-	@Autowired
-	private SpacesRepository spacesRepository;
-		
-	@Autowired
-	private NodesRepository nodesRepository;
-	
-	@Autowired
-	private EdgesRepository edgesRepository;
-	
-	@Autowired
-	private ProjectRevisionsRepository projectRevisionsRepository;
-	
-	@Autowired
-	private MongoTemplate mongoTemplate;
-	
-	private Project testProject;
-	private List<Node> testNodes = new ArrayList<Node>();
-	private List<Edge> testEdges = new ArrayList<>();
-	
-	private Date creationDate = new Date();
-	
-	private String spaceId = UUID.randomUUID().toString(); 
-		
-	public ProjectRestTest() {
-	}
-	
-	@Override
-	protected AppDescriptor configure() {
-		return new WebAppDescriptor.Builder("org.iri_research.renkan.rest")
-			.contextPath("rest")
-			.contextParam("contextConfigLocation", "classpath:/org/iri_research/renkan/test/rest/rest-context.xml")
-			.initParam("com.sun.jersey.config.property.packages", "org.iri_research.renkan.rest")
-			.servletClass(SpringServlet.class)
-			.contextListenerClass(ContextLoaderListener.class)
-			.build();
-	};
-	
-	@Before
-	public void setup() {
+
+    private Logger logger = LoggerFactory.getLogger(ProjectRestTest.class);
+
+    @Autowired
+    private ProjectsRepository projectsRepository;
+
+    @Autowired
+    private SpacesRepository spacesRepository;
+
+    @Autowired
+    private NodesRepository nodesRepository;
+
+    @Autowired
+    private EdgesRepository edgesRepository;
+
+    @Autowired
+    private ProjectRevisionsRepository projectRevisionsRepository;
+
+    @Autowired
+    private MongoTemplate mongoTemplate;
+
+    private Project testProject;
+    private List<Node> testNodes = new ArrayList<Node>();
+    private List<Edge> testEdges = new ArrayList<>();
+
+    private DateTime creationDate = new DateTime();
+
+    private String spaceId = UUID.randomUUID().toString();
+    private String projectId = UUID.randomUUID().toString();
+    
+    private ObjectMapper getObjectMapper() {
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JodaModule());
+        return mapper;
+    }
+
+    public ProjectRestTest() {
+    }
+
+    // @Override
+    // protected AppDescriptor configure() {
+    // return new WebAppDescriptor.Builder("org.iri_research.renkan.rest")
+    // .contextPath("rest")
+    // .contextParam("contextConfigLocation",
+    // "classpath:/org/iri_research/renkan/test/rest/rest-context.xml")
+    // .initParam("com.sun.jersey.config.property.packages",
+    // "org.iri_research.renkan.rest")
+    // .servletClass(SpringServlet.class)
+    // .contextListenerClass(ContextLoaderListener.class)
+    // .build();
+    // };
+
+    @Override
+    protected Application configure() {
+        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+        ResourceConfig rc = new RestApplication()
+                .property("contextConfigLocation",
+                        "classpath:/org/iri_research/renkan/test/rest/rest-context.xml");
+        rc.setApplicationName("rest");
+        return rc;
+    };
+
+    @Before
+    public void setup() {
+
+        logger.debug("Setup");
+        Space testSpace = new Space(this.spaceId, "test space", "Test space",
+                null, null, null, "test_user", null, this.creationDate);
+        testSpace = spacesRepository.save(testSpace);
+        testProject = new Project(testSpace.getId(), this.projectId, "test", "desc",
+                "http://localhost:8080/rest/projects/id", this.creationDate);
+
+        for (int i = 0; i < 3; i++) {
+            Node node = new Node("Node" + i, "Node" + i, "Node " + i,
+                    "http://renkan.org/nodes/node" + i, "#ffff0" + i,
+                    "test_user", new Point(0, i),
+                    "http://renkan.org/images/node" + i, i, testProject.getId());
+            node = this.nodesRepository.save(node);
+            testProject.getNodes().add(node);
+            this.testNodes.add(node);
+        }
 
-		logger.debug("Setup");
-		Space testSpace = new Space(this.spaceId, "test space", "Test space", null, null, null, "test_user", null, this.creationDate);
-		testSpace = spacesRepository.save(testSpace);
-		testProject = new Project(testSpace.getId(), UUID.randomUUID().toString(), "test", "desc", "http://localhost:8080/rest/projects/id", this.creationDate);
-		
-		for(int i=0;i<3;i++) {
-			Node node = new Node("Node"+i, "Node"+i, "Node "+i, "http://renkan.org/nodes/node"+i, "#ffff0"+i, "test_user", new Point(0, i), "http://renkan.org/images/node"+i, i, testProject.getId());
-			node = this.nodesRepository.save(node);
-			testProject.getNodes().add(node);
-			this.testNodes.add(node);
-		}
-		
-		for(int i=0;i<3;i++) {
-			Edge edge = new Edge("Node"+i, "Node"+i, "Node "+i, "http://renkan.org/edges/edge"+i, "#ffff0"+i, this.testNodes.get((i+2)%3), this.testNodes.get(i), "test_user", testProject.getId());
-			edge = this.edgesRepository.save(edge);
-			testProject.getEdges().add(edge);
-			this.testEdges.add(edge);
-		}
-		
-		this.projectsRepository.save(testProject);
+        for (int i = 0; i < 3; i++) {
+            Edge edge = new Edge("Node" + i, "Node" + i, "Node " + i,
+                    "http://renkan.org/edges/edge" + i, "#ffff0" + i,
+                    this.testNodes.get((i + 2) % 3), this.testNodes.get(i),
+                    "test_user", testProject.getId());
+            edge = this.edgesRepository.save(edge);
+            testProject.getEdges().add(edge);
+            this.testEdges.add(edge);
+        }
+
+        this.projectsRepository.save(testProject);
+
+    }
 
-	}
-	
-	@After
-	public void teardown() {
-		logger.debug("Teardown");
-		edgesRepository.deleteAll();
-		nodesRepository.deleteAll();
-		projectRevisionsRepository.deleteAll();
-		projectsRepository.deleteAll();
-		spacesRepository.deleteAll();
-	}
-	
-	
-	@Test
-	public void testDeleteProject() {
+    @After
+    public void teardown() {
+        logger.debug("Teardown");
+        edgesRepository.deleteAll();
+        nodesRepository.deleteAll();
+        projectRevisionsRepository.deleteAll();
+        projectsRepository.deleteAll();
+        spacesRepository.deleteAll();
+    }
+    
+    @Test
+    public void testGetProject() throws JsonProcessingException, IOException {
+        WebTarget webResource = this.target();
+        String respString = webResource.path("projects")
+                .path(testProject.getId()).request().acceptEncoding("UTF-8").accept(MediaType.APPLICATION_JSON_TYPE).get(String.class);
+        Assert.assertNotNull("get resp String not empty", respString);
+        Assert.assertFalse("get resp String non empty", respString.isEmpty());
+        
+        logger.debug("Test get Project : respString : " + respString);
+        
+        ObjectMapper mapper = this.getObjectMapper();
+        
+        JsonNode projectNode = mapper.readTree(respString);
+        
+        Assert.assertNotNull("project node not null", projectNode);
+        
+        Assert.assertNotNull("Must have an id", projectNode.get("id"));
+        Assert.assertEquals("id must match", this.projectId, projectNode.get("id").asText());
+        Assert.assertNotNull("Must have a created date", projectNode.get("created"));
+        Assert.assertEquals("creation date must match", this.creationDate.toString(ISODateTimeFormat.dateTime()), projectNode.get("created").asText());
+    }
 
-		List<Node> nodes= testProject.getNodes();
-		List<Edge> edges= testProject.getEdges();
-		
-		WebResource webResource = this.resource();
-		String respString = webResource.path("projects").path(testProject.getId()).delete(String.class);
-		
-		Assert.assertTrue("Response text must contain deleted", respString.contains("deleted"));
-		Assert.assertTrue("Response text must contain id", respString.contains(this.testProject.getId()));
-		
-		DBObject filter = new BasicDBObject();
-		filter.put("_id", testProject.getId());
-		
-		DBCollection coll = mongoTemplate.getCollection(mongoTemplate.getCollectionName(Project.class));
-		DBCursor resFind = coll.find(filter);
-		
-		Assert.assertEquals("The project must not be found", 0, resFind.count());
-		
-		filter = new BasicDBObject();
-		filter.put("project_id", testProject.getId());
-		
-		DBCollection nodesColl = mongoTemplate.getCollection(mongoTemplate.getCollectionName(Node.class));
-		resFind = nodesColl.find(filter);
-		
-		Assert.assertEquals("no nodes left", 0, resFind.count());
-		
-		for(Node n: nodes) {
-			DBObject nobj = nodesColl.findOne(n.getId());
-			Assert.assertNull("node should be deleted", nobj);
-		}
+    @Test
+    public void testDeleteProject() {
+
+        List<Node> nodes = testProject.getNodes();
+        List<Edge> edges = testProject.getEdges();
+
+        WebTarget webResource = this.target();
+        String respString = webResource.path("projects")
+                .path(testProject.getId()).request().delete(String.class);
+
+        Assert.assertTrue("Response text must contain deleted",
+                respString.contains("deleted"));
+        Assert.assertTrue("Response text must contain id",
+                respString.contains(this.testProject.getId()));
+
+        DBObject filter = new BasicDBObject();
+        filter.put("_id", testProject.getId());
+
+        DBCollection coll = mongoTemplate.getCollection(mongoTemplate
+                .getCollectionName(Project.class));
+        DBCursor resFind = coll.find(filter);
+
+        Assert.assertEquals("The project must not be found", 0, resFind.count());
 
-		
-		DBCollection edgesColl = mongoTemplate.getCollection(mongoTemplate.getCollectionName(Edge.class));
-		resFind = edgesColl.find(filter);
-		
-		Assert.assertEquals("no edges left", 0, resFind.count());
-		
-		for(Edge e: edges) {
-			DBObject eobj = edgesColl.findOne(e.getId());
-			Assert.assertNull("edge should be deleted", eobj);
-		}
-		
-	}
+        filter = new BasicDBObject();
+        filter.put("project_id", testProject.getId());
+
+        DBCollection nodesColl = mongoTemplate.getCollection(mongoTemplate
+                .getCollectionName(Node.class));
+        resFind = nodesColl.find(filter);
+
+        Assert.assertEquals("no nodes left", 0, resFind.count());
 
+        for (Node n : nodes) {
+            DBObject nobj = nodesColl.findOne(n.getId());
+            Assert.assertNull("node should be deleted", nobj);
+        }
+
+        DBCollection edgesColl = mongoTemplate.getCollection(mongoTemplate
+                .getCollectionName(Edge.class));
+        resFind = edgesColl.find(filter);
+
+        Assert.assertEquals("no edges left", 0, resFind.count());
+
+        for (Edge e : edges) {
+            DBObject eobj = edgesColl.findOne(e.getId());
+            Assert.assertNull("edge should be deleted", eobj);
+        }
+
+    }
 
 }
--- a/server/src/test/java/org/iri_research/renkan/test/rest/SpaceRestTest.java	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/test/java/org/iri_research/renkan/test/rest/SpaceRestTest.java	Wed Jan 15 18:36:27 2014 +0100
@@ -2,22 +2,30 @@
 
 import java.io.IOException;
 import java.net.URI;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.TimeZone;
 import java.util.UUID;
 
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.Application;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 
-import junit.framework.Assert;
-
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.model.Resource;
+import org.glassfish.jersey.test.JerseyTest;
 import org.iri_research.renkan.models.Space;
 import org.iri_research.renkan.repositories.SpacesRepository;
+import org.iri_research.renkan.rest.RestApplication;
+import org.iri_research.renkan.rest.SpacesResource;
 import org.joda.time.DateTime;
 import org.joda.time.format.DateTimeFormatter;
 import org.joda.time.format.ISODateTimeFormat;
 import org.junit.After;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -26,762 +34,857 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.web.context.ContextLoaderListener;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.sun.jersey.api.client.ClientHandlerException;
-import com.sun.jersey.api.client.ClientResponse;
-import com.sun.jersey.api.client.UniformInterfaceException;
-import com.sun.jersey.api.client.WebResource;
-import com.sun.jersey.spi.spring.container.servlet.SpringServlet;
-import com.sun.jersey.test.framework.AppDescriptor;
-import com.sun.jersey.test.framework.JerseyTest;
-import com.sun.jersey.test.framework.WebAppDescriptor;
+import com.fasterxml.jackson.datatype.joda.JodaModule;
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration("rest-context.xml")
 public class SpaceRestTest extends JerseyTest {
-	
-	private Logger logger = LoggerFactory.getLogger(SpaceRestTest.class);
-	
-	@Autowired
-	private SpacesRepository spacesRepository;
-		
-	private Map<String,Space> spacesList = new HashMap<String, Space>();
-	private String firstSpaceUUID = null;
-		
+
+    private Logger logger = LoggerFactory.getLogger(SpaceRestTest.class);
+
+    @Autowired
+    private SpacesRepository spacesRepository;
+
+    private Map<String, Space> spacesList = new HashMap<String, Space>();
+    private String firstSpaceUUID = null;
+    
+    public SpaceRestTest() {
+    }
+
+    // @Override
+    // protected AppDescriptor configure() {
+    // return new WebAppDescriptor.Builder("org.iri_research.renkan.rest")
+    // .contextPath("rest")
+    // .contextParam("contextConfigLocation",
+    // "classpath:/org/iri_research/renkan/test/rest/rest-context.xml")
+    // .initParam("com.sun.jersey.config.property.packages",
+    // "org.iri_research.renkan.rest")
+    // .servletClass(SpringServlet.class)
+    // .contextListenerClass(ContextLoaderListener.class)
+    // .build();
+    // };
+
+    @Override
+    protected Application configure() {
+        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+        ResourceConfig rc = new RestApplication()
+                .property("contextConfigLocation",
+                        "classpath:/org/iri_research/renkan/test/rest/rest-context.xml");
+        rc.setApplicationName("rest");
+        return rc;
+    };
+
+    @Before
+    public void setup() {
+
+        logger.debug("Setup");
+        spacesRepository.deleteAll();
+        DateTime creationDate = new DateTime();
+        this.firstSpaceUUID = UUID.randomUUID().toString();
+        Space testSpace = new Space(firstSpaceUUID, "test", "Test space", "{}",
+                "http://ldt.iri.centrepompidou.fr", "#ababab", "test_user",
+                "http://ldt.iri.centrepompidou.fr", creationDate);
+        testSpace = spacesRepository.save(testSpace);
+        this.spacesList.put(firstSpaceUUID, testSpace);
 
-	public SpaceRestTest() {
-	}
-	
-	@Override
-	protected AppDescriptor configure() {
-		return new WebAppDescriptor.Builder("org.iri_research.renkan.rest")
-			.contextPath("rest")
-			.contextParam("contextConfigLocation", "classpath:/org/iri_research/renkan/test/rest/rest-context.xml")
-			.initParam("com.sun.jersey.config.property.packages", "org.iri_research.renkan.rest")
-			.servletClass(SpringServlet.class)
-			.contextListenerClass(ContextLoaderListener.class)
-			.build();
-	};
-	
-	@Before
-	public void setup() {
-		
-		logger.debug("Setup");
-		spacesRepository.deleteAll();
-		Date creationDate = new Date();
-		this.firstSpaceUUID = UUID.randomUUID().toString();
-		Space testSpace = new Space(firstSpaceUUID, "test", "Test space", "{}", "http://ldt.iri.centrepompidou.fr", "#ababab", "test_user", "http://ldt.iri.centrepompidou.fr", creationDate);
-		testSpace = spacesRepository.save(testSpace);
-		this.spacesList.put(firstSpaceUUID, testSpace);
-	}
-	
-	@After
-	public void teardown() {
-		spacesRepository.deleteAll();
-	}
+        Resource resource = Resource.builder(SpacesResource.class).build();
+        String baseUri = resource.getPath();
+        logger.debug("Path is " + baseUri);
+        for (Resource cres : resource.getChildResources()) {
+            logger.debug(cres.getAllMethods().toString() + " at " + baseUri
+                    + "/" + cres.getPath());
+        }
+
+    }
+
+    @After
+    public void teardown() {
+        spacesRepository.deleteAll();
+    }
+
+    @Test
+    public void testSetup() throws JsonProcessingException, IOException {
+
+        WebTarget webTarget = this.target("spaces");
+        String respString = webTarget.request().get(String.class);
+
+        Assert.assertNotNull(
+                "The response string for the list of spaces must not be null",
+                respString);
 
-	
-	@Test
-	public void testSetup() throws JsonProcessingException, IOException {
+        logger.debug("RESPONSE : " + respString);
+
+        Assert.assertTrue(
+                "The length of the space list resp. string must be > 0",
+                respString.length() > 0);
+
+        ObjectMapper mapper = getObjectMapper();
+        
+        JsonNode spacesList = mapper.readTree(respString);
+
+        Assert.assertTrue("The spaceList must be an array",
+                spacesList.isArray());
+        Assert.assertEquals(
+                "The spaceList length must be = " + this.spacesList.size(),
+                this.spacesList.size(), spacesList.size());
+
+        for (JsonNode jsonNode : spacesList) {
+            Assert.assertTrue("the space must have an id",
+                    jsonNode.hasNonNull("id"));
+            String id = jsonNode.get("id").asText();
+            Assert.assertTrue("The id must be in the spacesList",
+                    this.spacesList.containsKey(id));
+            Space space = this.spacesList.get(id);
+            Assert.assertNotNull(
+                    "The object must in the spacesList must not be null", space);
+
+        }
 
-		WebResource webResource = this.resource();
-		String respString = webResource.path("spaces").get(String.class);
-		
-		Assert.assertNotNull("The response string for the list of spaces must not be null", respString);
-		
-		logger.debug("RESPONSE : " + respString);
-		
-		Assert.assertTrue("The length of the space list resp. string must be > 0", respString.length() > 0);
-		
-		
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode spacesList = mapper.readTree(respString);
-		
-		Assert.assertTrue("The spaceList must be an array", spacesList.isArray());
-		Assert.assertEquals("The spaceList length must be = " + this.spacesList.size(), this.spacesList.size(), spacesList.size());
-		
-		for (JsonNode jsonNode : spacesList) {
-			Assert.assertTrue("the space must have an id", jsonNode.hasNonNull("id"));
-			String id = jsonNode.get("id").asText();
-			Assert.assertTrue("The id must be in the spacesList", this.spacesList.containsKey(id));
-			Space space = this.spacesList.get(id);
-			Assert.assertNotNull("The object must in the spacesList must not be null", space);
-								
-		}
-		
-	}
-	
-	@Test
-	public void testTitle() throws JsonProcessingException, IOException {
-		
-		WebResource webResource = this.resource();
-		String respString = webResource.path("spaces").get(String.class);
-		logger.debug("RESPONSE : " + respString);
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode spacesList = mapper.readTree(respString);
-		
-		for (JsonNode jsonNode : spacesList) {
-			String id = jsonNode.get("_id").asText();
-			Space space = this.spacesList.get(id);
-			
-			Assert.assertTrue("the space must have a title", jsonNode.hasNonNull("title"));
-			String title = jsonNode.get("title").asText();
-			Assert.assertEquals("space title must be equals to " + space.getTitle(), space.getTitle(), title);
-		}
+    }
+
+    @Test
+    public void testTitle() throws JsonProcessingException, IOException {
+
+        WebTarget WebTarget = this.target();
+        String respString = WebTarget.path("spaces").request()
+                .get(String.class);
+        logger.debug("RESPONSE : " + respString);
+        ObjectMapper mapper = getObjectMapper();
+        JsonNode spacesList = mapper.readTree(respString);
+
+        for (JsonNode jsonNode : spacesList) {
+            String id = jsonNode.get("_id").asText();
+            Space space = this.spacesList.get(id);
+
+            Assert.assertTrue("the space must have a title",
+                    jsonNode.hasNonNull("title"));
+            String title = jsonNode.get("title").asText();
+            Assert.assertEquals(
+                    "space title must be equals to " + space.getTitle(),
+                    space.getTitle(), title);
+        }
 
-	}
+    }
+
+    @Test
+    public void testDescription() throws JsonProcessingException, IOException {
+
+        WebTarget WebTarget = this.target();
+        String respString = WebTarget.path("spaces").request()
+                .get(String.class);
+        logger.debug("RESPONSE : " + respString);
+        ObjectMapper mapper = getObjectMapper();
+        JsonNode spacesList = mapper.readTree(respString);
+
+        for (JsonNode jsonNode : spacesList) {
+            String id = jsonNode.get("id").asText();
+            Space space = this.spacesList.get(id);
+
+            Assert.assertTrue("the space must have a description",
+                    jsonNode.hasNonNull("description"));
+            String description = jsonNode.get("description").asText();
+            Assert.assertEquals(
+                    "space description must be equals to "
+                            + space.getDescription(), space.getDescription(),
+                    description);
+        }
+
+    }
 
-	@Test
-	public void testDescription() throws JsonProcessingException, IOException {
-		
-		WebResource webResource = this.resource();
-		String respString = webResource.path("spaces").get(String.class);
-		logger.debug("RESPONSE : " + respString);
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode spacesList = mapper.readTree(respString);
-		
-		for (JsonNode jsonNode : spacesList) {
-			String id = jsonNode.get("id").asText();
-			Space space = this.spacesList.get(id);
-			
-			Assert.assertTrue("the space must have a description", jsonNode.hasNonNull("description"));
-			String description = jsonNode.get("description").asText();
-			Assert.assertEquals("space description must be equals to " + space.getDescription(), space.getDescription(), description);
-		}
+    @Test
+    public void testUri() throws JsonProcessingException, IOException {
+
+        WebTarget WebTarget = this.target();
+        String respString = WebTarget.path("spaces").request()
+                .get(String.class);
+        logger.debug("RESPONSE : " + respString);
+        ObjectMapper mapper = getObjectMapper();
+        JsonNode spacesList = mapper.readTree(respString);
 
-	}
+        for (JsonNode jsonNode : spacesList) {
+            String id = jsonNode.get("id").asText();
+            Space space = this.spacesList.get(id);
+
+            Assert.assertTrue("the space must have a uri",
+                    jsonNode.hasNonNull("uri"));
+            String uri = jsonNode.get("uri").asText();
+            Assert.assertEquals(
+                    "space uri must be equals to " + space.getUri(),
+                    space.getUri(), uri);
+        }
+
+    }
 
-	@Test
-	public void testUri() throws JsonProcessingException, IOException {
-		
-		WebResource webResource = this.resource();
-		String respString = webResource.path("spaces").get(String.class);
-		logger.debug("RESPONSE : " + respString);
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode spacesList = mapper.readTree(respString);
-		
-		for (JsonNode jsonNode : spacesList) {
-			String id = jsonNode.get("id").asText();
-			Space space = this.spacesList.get(id);
-			
-			Assert.assertTrue("the space must have a uri", jsonNode.hasNonNull("uri"));
-			String uri = jsonNode.get("uri").asText();
-			Assert.assertEquals("space uri must be equals to " + space.getUri(), space.getUri(), uri);
-		}
+    @Test
+    public void testColor() throws JsonProcessingException, IOException {
 
-	}
+        WebTarget WebTarget = this.target();
+        String respString = WebTarget.path("spaces").request()
+                .get(String.class);
+        logger.debug("RESPONSE : " + respString);
+        ObjectMapper mapper = getObjectMapper();
+        mapper.registerModule(new JodaModule());
+        JsonNode spacesList = mapper.readTree(respString);
 
-	@Test
-	public void testColor() throws JsonProcessingException, IOException {
-		
-		WebResource webResource = this.resource();
-		String respString = webResource.path("spaces").get(String.class);
-		logger.debug("RESPONSE : " + respString);
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode spacesList = mapper.readTree(respString);
-		
-		for (JsonNode jsonNode : spacesList) {
-			String id = jsonNode.get("id").asText();
-			Space space = this.spacesList.get(id);
-			
-			Assert.assertTrue("the space must have a color", jsonNode.hasNonNull("color"));
-			String color = jsonNode.get("color").asText();
-			Assert.assertEquals("space color must be equals to " + space.getColor(), space.getColor(), color);
-		}
+        for (JsonNode jsonNode : spacesList) {
+            String id = jsonNode.get("id").asText();
+            Space space = this.spacesList.get(id);
 
-	}
+            Assert.assertTrue("the space must have a color",
+                    jsonNode.hasNonNull("color"));
+            String color = jsonNode.get("color").asText();
+            Assert.assertEquals(
+                    "space color must be equals to " + space.getColor(),
+                    space.getColor(), color);
+        }
+
+    }
+
+    @Test
+    public void testBinConfig() throws JsonProcessingException, IOException {
 
-	
-	
-	@Test
-	public void testBinConfig() throws JsonProcessingException, IOException {
-		
-		WebResource webResource = this.resource();
-		String respString = webResource.path("spaces").get(String.class);
-		logger.debug("RESPONSE : " + respString);
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode spacesList = mapper.readTree(respString);
-		
-		for (JsonNode jsonNode : spacesList) {
-			String id = jsonNode.get("id").asText();
-			Space space = this.spacesList.get(id);
-			
-			Assert.assertTrue("the space must have a bin_config", jsonNode.hasNonNull("bin_config"));
-			String binConfig = jsonNode.get("bin_config").asText();
-			Assert.assertEquals("space bin_config must be equals to " + space.getBinConfig(), space.getBinConfig(), binConfig);
-		}
+        WebTarget WebTarget = this.target();
+        String respString = WebTarget.path("spaces").request()
+                .get(String.class);
+        logger.debug("RESPONSE : " + respString);
+        ObjectMapper mapper = getObjectMapper();
+        
+        JsonNode spacesList = mapper.readTree(respString);
+
+        for (JsonNode jsonNode : spacesList) {
+            String id = jsonNode.get("id").asText();
+            Space space = this.spacesList.get(id);
+
+            Assert.assertTrue("the space must have a bin_config",
+                    jsonNode.hasNonNull("bin_config"));
+            String binConfig = jsonNode.get("bin_config").asText();
+            Assert.assertEquals(
+                    "space bin_config must be equals to "
+                            + space.getBinConfig(), space.getBinConfig(),
+                    binConfig);
+        }
+
+    }
+
+    private ObjectMapper getObjectMapper() {
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.registerModule(new JodaModule());
+        return mapper;
+    }
+
+    @Test
+    public void testCreatedBy() throws JsonProcessingException, IOException {
+
+        WebTarget WebTarget = this.target();
+        String respString = WebTarget.path("spaces").request()
+                .get(String.class);
+        logger.debug("RESPONSE : " + respString);
+        ObjectMapper mapper = getObjectMapper();
+        JsonNode spacesList = mapper.readTree(respString);
+
+        for (JsonNode jsonNode : spacesList) {
+            String id = jsonNode.get("id").asText();
+            Space space = this.spacesList.get(id);
+
+            Assert.assertTrue("the space must have a created_by",
+                    jsonNode.hasNonNull("created_by"));
+            String createdBy = jsonNode.get("created_by").asText();
+            Assert.assertEquals(
+                    "space created_by must be equals to "
+                            + space.getCreatedBy(), space.getCreatedBy(),
+                    createdBy);
+        }
 
-	}
-	
-	@Test
-	public void testCreatedBy() throws JsonProcessingException, IOException {
-		
-		WebResource webResource = this.resource();
-		String respString = webResource.path("spaces").get(String.class);
-		logger.debug("RESPONSE : " + respString);
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode spacesList = mapper.readTree(respString);
-		
-		for (JsonNode jsonNode : spacesList) {
-			String id = jsonNode.get("id").asText();
-			Space space = this.spacesList.get(id);
-			
-			Assert.assertTrue("the space must have a created_by", jsonNode.hasNonNull("created_by"));
-			String createdBy = jsonNode.get("created_by").asText();
-			Assert.assertEquals("space created_by must be equals to " + space.getCreatedBy(), space.getCreatedBy(), createdBy);
-		}
+    }
+
+    @Test
+    public void testCreated() throws JsonProcessingException, IOException {
+
+        WebTarget WebTarget = this.target();
+        String respString = WebTarget.path("spaces").request()
+                .get(String.class);
+        logger.debug("RESPONSE : " + respString);
+        ObjectMapper mapper = getObjectMapper();
+        JsonNode spacesList = mapper.readTree(respString);
+
+        for (JsonNode jsonNode : spacesList) {
+            String id = jsonNode.get("id").asText();
+            Space space = this.spacesList.get(id);
+
+            Assert.assertTrue("the space must have a created",
+                    jsonNode.hasNonNull("created"));
+
+            String dateStr = jsonNode.get("created").asText();
+
+            DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
+            DateTime date = fmt.parseDateTime(dateStr);
+
+            Assert.assertEquals("Created date must be the same",
+                    space.getCreated(), date);
 
-	}
-	
-	
-	@Test
-	public void testCreated() throws JsonProcessingException, IOException {
-		
-		WebResource webResource = this.resource();
-		String respString = webResource.path("spaces").get(String.class);
-		logger.debug("RESPONSE : " + respString);
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode spacesList = mapper.readTree(respString);
-		
-		for (JsonNode jsonNode : spacesList) {
-			String id = jsonNode.get("id").asText();
-			Space space = this.spacesList.get(id);
-			
-			Assert.assertTrue("the space must have a created", jsonNode.hasNonNull("created"));
-			
-			String dateStr = jsonNode.get("created").asText();
-			
-			DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
-			DateTime date = fmt.parseDateTime(dateStr);
-			
-			Assert.assertEquals("Created date must be the same", space.getCreated(), date.toDate());				
-			
-		}
+        }
+
+    }
+
+    @Test
+    public void testImage() throws JsonProcessingException, IOException {
+
+        WebTarget WebTarget = this.target();
+        String respString = WebTarget.path("spaces").request()
+                .get(String.class);
+        logger.debug("RESPONSE : " + respString);
+        ObjectMapper mapper = getObjectMapper();
+        JsonNode spacesList = mapper.readTree(respString);
+
+        for (JsonNode jsonNode : spacesList) {
+            String id = jsonNode.get("id").asText();
+            Space space = this.spacesList.get(id);
+
+            Assert.assertTrue("the space must have a image",
+                    jsonNode.hasNonNull("image"));
+            String image = jsonNode.get("image").asText();
+            Assert.assertEquals(
+                    "space image must be equals to " + space.getImage(),
+                    space.getImage(), image);
+        }
+
+    }
 
-	}
-	
-	@Test
-	public void testImage() throws JsonProcessingException, IOException {
-		
-		WebResource webResource = this.resource();
-		String respString = webResource.path("spaces").get(String.class);
-		logger.debug("RESPONSE : " + respString);
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode spacesList = mapper.readTree(respString);
-		
-		for (JsonNode jsonNode : spacesList) {
-			String id = jsonNode.get("id").asText();
-			Space space = this.spacesList.get(id);
-			
-			Assert.assertTrue("the space must have a image", jsonNode.hasNonNull("image"));
-			String image = jsonNode.get("image").asText();
-			Assert.assertEquals("space image must be equals to " + space.getImage(), space.getImage(), image);
-		}
+    @Test
+    public void testSingleCreated() throws JsonProcessingException, IOException {
+
+        Space space = this.spacesList.get(this.firstSpaceUUID);
+        WebTarget WebTarget = this.target();
+        String respString = WebTarget.path("spaces").path(this.firstSpaceUUID)
+                .request().accept(MediaType.APPLICATION_JSON).get(String.class);
+        logger.debug("RESPONSE : " + respString);
+        ObjectMapper mapper = getObjectMapper();
+        JsonNode jsonNode = mapper.readTree(respString);
+
+        String id = jsonNode.get("id").asText();
+        Assert.assertEquals("id must be equals", space.getId(), id);
+
+        Assert.assertTrue("the space must have a created",
+                jsonNode.hasNonNull("created"));
+
+        String dateStr = jsonNode.get("created").asText();
+
+        DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
+        DateTime date = fmt.parseDateTime(dateStr);
+
+        Assert.assertEquals("Created date must be the same",
+                space.getCreated(), date);
 
-	}
-	
-	@Test
-	public void testSingleCreated() throws JsonProcessingException, IOException {
-		
-		Space space = this.spacesList.get(this.firstSpaceUUID);
-		WebResource webResource = this.resource();
-		String respString = webResource.path("spaces").path(this.firstSpaceUUID).accept(MediaType.APPLICATION_JSON).get(String.class);
-		logger.debug("RESPONSE : " + respString);
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode jsonNode = mapper.readTree(respString);
-		
-		String id = jsonNode.get("id").asText();
-		Assert.assertEquals("id must be equals", space.getId(), id);
-		
-		Assert.assertTrue("the space must have a created", jsonNode.hasNonNull("created"));
-		
-		String dateStr = jsonNode.get("created").asText();
-		
-		DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
-		DateTime date = fmt.parseDateTime(dateStr);
-		
-		Assert.assertEquals("Created date must be the same", space.getCreated(), date.toDate());				
+    }
+
+    @Test
+    public void testSingleTitle() throws JsonProcessingException, IOException {
+
+        Space space = this.spacesList.get(this.firstSpaceUUID);
+        WebTarget WebTarget = this.target();
+        String respString = WebTarget.path("spaces").path(this.firstSpaceUUID)
+                .request().accept(MediaType.APPLICATION_JSON).get(String.class);
+        logger.debug("RESPONSE : " + respString);
+        ObjectMapper mapper = getObjectMapper();
+        JsonNode jsonNode = mapper.readTree(respString);
+
+        Assert.assertTrue("the space must have a title",
+                jsonNode.hasNonNull("title"));
+        String title = jsonNode.get("title").asText();
+        Assert.assertEquals(
+                "space title must be equals to " + space.getTitle(),
+                space.getTitle(), title);
+    }
+
+    @Test
+    public void testSingleDescription() throws JsonProcessingException,
+            IOException {
 
-	}
-	
-	@Test
-	public void testSingleTitle() throws JsonProcessingException, IOException {
-		
-		Space space = this.spacesList.get(this.firstSpaceUUID);
-		WebResource webResource = this.resource();
-		String respString = webResource.path("spaces").path(this.firstSpaceUUID).accept(MediaType.APPLICATION_JSON).get(String.class);
-		logger.debug("RESPONSE : " + respString);
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode jsonNode = mapper.readTree(respString);
-					
-		Assert.assertTrue("the space must have a title", jsonNode.hasNonNull("title"));
-		String title = jsonNode.get("title").asText();
-		Assert.assertEquals("space title must be equals to " + space.getTitle(), space.getTitle(), title);
-	}
+        Space space = this.spacesList.get(this.firstSpaceUUID);
+        WebTarget WebTarget = this.target();
+        String respString = WebTarget.path("spaces").path(this.firstSpaceUUID)
+                .request().accept(MediaType.APPLICATION_JSON).get(String.class);
+        logger.debug("RESPONSE : " + respString);
+        ObjectMapper mapper = getObjectMapper();
+        JsonNode jsonNode = mapper.readTree(respString);
+
+        Assert.assertTrue("the space must have a description",
+                jsonNode.hasNonNull("description"));
+        String description = jsonNode.get("description").asText();
+        Assert.assertEquals(
+                "space description must be equals to " + space.getDescription(),
+                space.getDescription(), description);
+    }
+
+    @Test
+    public void testSingleUri() throws JsonProcessingException, IOException {
+
+        Space space = this.spacesList.get(this.firstSpaceUUID);
+        WebTarget WebTarget = this.target();
+        String respString = WebTarget.path("spaces").path(this.firstSpaceUUID)
+                .request().accept(MediaType.APPLICATION_JSON).get(String.class);
+        logger.debug("RESPONSE : " + respString);
+        ObjectMapper mapper = getObjectMapper();
+        JsonNode jsonNode = mapper.readTree(respString);
 
-	@Test
-	public void testSingleDescription() throws JsonProcessingException, IOException {
-		
-		Space space = this.spacesList.get(this.firstSpaceUUID);
-		WebResource webResource = this.resource();
-		String respString = webResource.path("spaces").path(this.firstSpaceUUID).accept(MediaType.APPLICATION_JSON).get(String.class);
-		logger.debug("RESPONSE : " + respString);
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode jsonNode = mapper.readTree(respString);
-					
-		Assert.assertTrue("the space must have a description", jsonNode.hasNonNull("description"));
-		String description = jsonNode.get("description").asText();
-		Assert.assertEquals("space description must be equals to " + space.getDescription(), space.getDescription(), description);
-	}
+        Assert.assertTrue("the space must have a uri",
+                jsonNode.hasNonNull("uri"));
+        String uri = jsonNode.get("uri").asText();
+        Assert.assertEquals("space uri must be equals to " + space.getUri(),
+                space.getUri(), uri);
+    }
+
+    @Test
+    public void testSingleColor() throws JsonProcessingException, IOException {
 
-	@Test
-	public void testSingleUri() throws JsonProcessingException, IOException {
-		
-		Space space = this.spacesList.get(this.firstSpaceUUID);
-		WebResource webResource = this.resource();
-		String respString = webResource.path("spaces").path(this.firstSpaceUUID).accept(MediaType.APPLICATION_JSON).get(String.class);
-		logger.debug("RESPONSE : " + respString);
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode jsonNode = mapper.readTree(respString);
-		
-		Assert.assertTrue("the space must have a uri", jsonNode.hasNonNull("uri"));
-		String uri = jsonNode.get("uri").asText();
-		Assert.assertEquals("space uri must be equals to " + space.getUri(), space.getUri(), uri);
-	}
+        Space space = this.spacesList.get(this.firstSpaceUUID);
+        WebTarget WebTarget = this.target();
+        String respString = WebTarget.path("spaces").path(this.firstSpaceUUID)
+                .request().accept(MediaType.APPLICATION_JSON).get(String.class);
+        logger.debug("RESPONSE : " + respString);
+        ObjectMapper mapper = getObjectMapper();
+        JsonNode jsonNode = mapper.readTree(respString);
 
-	@Test
-	public void testSingleColor() throws JsonProcessingException, IOException {
-		
-		Space space = this.spacesList.get(this.firstSpaceUUID);
-		WebResource webResource = this.resource();
-		String respString = webResource.path("spaces").path(this.firstSpaceUUID).accept(MediaType.APPLICATION_JSON).get(String.class);
-		logger.debug("RESPONSE : " + respString);
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode jsonNode = mapper.readTree(respString);
-					
-		Assert.assertTrue("the space must have a color", jsonNode.hasNonNull("color"));
-		String color = jsonNode.get("color").asText();
-		Assert.assertEquals("space color must be equals to " + space.getColor(), space.getColor(), color);
-	}
+        Assert.assertTrue("the space must have a color",
+                jsonNode.hasNonNull("color"));
+        String color = jsonNode.get("color").asText();
+        Assert.assertEquals(
+                "space color must be equals to " + space.getColor(),
+                space.getColor(), color);
+    }
+
+    @Test
+    public void testSingleBinConfig() throws JsonProcessingException,
+            IOException {
 
-	
-	
-	@Test
-	public void testSingleBinConfig() throws JsonProcessingException, IOException {
-		
-		Space space = this.spacesList.get(this.firstSpaceUUID);
-		WebResource webResource = this.resource();
-		String respString = webResource.path("spaces").path(this.firstSpaceUUID).accept(MediaType.APPLICATION_JSON).get(String.class);
-		logger.debug("RESPONSE : " + respString);
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode jsonNode = mapper.readTree(respString);
-		
-		Assert.assertTrue("the space must have a bin_config", jsonNode.hasNonNull("bin_config"));
-		String binConfig = jsonNode.get("bin_config").asText();
-		Assert.assertEquals("space bin_config must be equals to " + space.getBinConfig(), space.getBinConfig(), binConfig);
-	}
-	
-	@Test
-	public void testSingleCreatedBy() throws JsonProcessingException, IOException {
-		
-		Space space = this.spacesList.get(this.firstSpaceUUID);
-		WebResource webResource = this.resource();
-		String respString = webResource.path("spaces").path(this.firstSpaceUUID).accept(MediaType.APPLICATION_JSON).get(String.class);
-		logger.debug("RESPONSE : " + respString);
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode jsonNode = mapper.readTree(respString);
-		
-		Assert.assertTrue("the space must have a created_by", jsonNode.hasNonNull("created_by"));
-		String createdBy = jsonNode.get("created_by").asText();
-		Assert.assertEquals("space created_by must be equals to " + space.getCreatedBy(), space.getCreatedBy(), createdBy);
-	}
-	
-		
-	@Test
-	public void testSingleImage() throws JsonProcessingException, IOException {
-	
-		Space space = this.spacesList.get(this.firstSpaceUUID);
-		WebResource webResource = this.resource();
-		String respString = webResource.path("spaces").path(this.firstSpaceUUID).accept(MediaType.APPLICATION_JSON).get(String.class);
-		logger.debug("RESPONSE : " + respString);
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode jsonNode = mapper.readTree(respString);
-					
-		Assert.assertTrue("the space must have a image", jsonNode.hasNonNull("image"));
-		String image = jsonNode.get("image").asText();
-		Assert.assertEquals("space image must be equals to " + space.getImage(), space.getImage(), image);
-	}
-	
-	
-	@Test
-	public void testPost() throws JsonProcessingException, ClientHandlerException, UniformInterfaceException, IOException {
-		
-		String title = "test_post";
-		String description = "test space post";
-		String uri = "http://ldt.iri.centrepompidou.fr/test_post";
-		String color = "#bcbcbc";
-		String image = "http://ldt.iri.centrepompidou.fr/test_post/image";
-		String created = "2013-01-01T01:01:01.001+0000";
-		String bin_config = "{name: 'test_post_config'}";
-		String created_by = "test_user_post";
-		
-		String spaceJson = String.format("{" +
-				"\"title\":\"%s\"," +
-				"\"description\":\"%s\"," +
-				"\"uri\":\"%s\"," +
-				"\"color\":\"%s\"," +
-				"\"image\":\"%s\"," +
-				"\"created\":\"%s\"," +
-				"\"bin_config\":\"%s\"," +
-				"\"created_by\":\"%s\"" +
-				"}",
-				title,
-				description,
-				uri,
-				color,
-				image,
-				created,
-				bin_config,
-				created_by);
-		
-		WebResource webResource = this.resource();
-		ClientResponse resp = webResource.path("spaces").type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).entity(spaceJson).post(ClientResponse.class);
-		
-		String respStr = resp.getEntity(String.class);
-		
-		Assert.assertEquals("Resp status = created : " + respStr, Status.CREATED.getStatusCode(), resp.getStatus());
-		Assert.assertTrue("Resp must be application/json", resp.getType().isCompatible(MediaType.APPLICATION_JSON_TYPE));		
-		
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode objNode = mapper.readTree(respStr);
+        Space space = this.spacesList.get(this.firstSpaceUUID);
+        WebTarget WebTarget = this.target();
+        String respString = WebTarget.path("spaces").path(this.firstSpaceUUID)
+                .request().accept(MediaType.APPLICATION_JSON).get(String.class);
+        logger.debug("RESPONSE : " + respString);
+        ObjectMapper mapper = getObjectMapper();
+        JsonNode jsonNode = mapper.readTree(respString);
+
+        Assert.assertTrue("the space must have a bin_config",
+                jsonNode.hasNonNull("bin_config"));
+        String binConfig = jsonNode.get("bin_config").asText();
+        Assert.assertEquals(
+                "space bin_config must be equals to " + space.getBinConfig(),
+                space.getBinConfig(), binConfig);
+    }
+
+    @Test
+    public void testSingleCreatedBy() throws JsonProcessingException,
+            IOException {
+
+        Space space = this.spacesList.get(this.firstSpaceUUID);
+        WebTarget WebTarget = this.target();
+        String respString = WebTarget.path("spaces").path(this.firstSpaceUUID)
+                .request().accept(MediaType.APPLICATION_JSON).get(String.class);
+        logger.debug("RESPONSE : " + respString);
+        ObjectMapper mapper = getObjectMapper();
+        JsonNode jsonNode = mapper.readTree(respString);
+
+        Assert.assertTrue("the space must have a created_by",
+                jsonNode.hasNonNull("created_by"));
+        String createdBy = jsonNode.get("created_by").asText();
+        Assert.assertEquals(
+                "space created_by must be equals to " + space.getCreatedBy(),
+                space.getCreatedBy(), createdBy);
+    }
+
+    @Test
+    public void testSingleImage() throws JsonProcessingException, IOException {
+
+        Space space = this.spacesList.get(this.firstSpaceUUID);
+        WebTarget WebTarget = this.target();
+        String respString = WebTarget.path("spaces").path(this.firstSpaceUUID)
+                .request().accept(MediaType.APPLICATION_JSON).get(String.class);
+        logger.debug("RESPONSE : " + respString);
+        ObjectMapper mapper = getObjectMapper();
+        JsonNode jsonNode = mapper.readTree(respString);
+
+        Assert.assertTrue("the space must have a image",
+                jsonNode.hasNonNull("image"));
+        String image = jsonNode.get("image").asText();
+        Assert.assertEquals(
+                "space image must be equals to " + space.getImage(),
+                space.getImage(), image);
+    }
+
+    @Test
+    public void testPost() throws JsonProcessingException, IOException {
+
+        String title = "test_post";
+        String description = "test space post";
+        String uri = "http://ldt.iri.centrepompidou.fr/test_post";
+        String color = "#bcbcbc";
+        String image = "http://ldt.iri.centrepompidou.fr/test_post/image";
+        String created = "2013-01-01T01:01:01.001+0000";
+        String expectedCreated = "2013-01-01T01:01:01.001Z";
+        String bin_config = "{name: 'test_post_config'}";
+        String created_by = "test_user_post";
+
+        String spaceJson = String.format("{" + "\"title\":\"%s\","
+                + "\"description\":\"%s\"," + "\"uri\":\"%s\","
+                + "\"color\":\"%s\"," + "\"image\":\"%s\","
+                + "\"created\":\"%s\"," + "\"bin_config\":\"%s\","
+                + "\"created_by\":\"%s\"" + "}", title, description, uri,
+                color, image, created, bin_config, created_by);
+
+        WebTarget webTarget = this.target();
+        Response resp = webTarget.path("spaces").request()
+                .accept(MediaType.APPLICATION_JSON)
+                .post(Entity.entity(spaceJson, MediaType.APPLICATION_JSON));
+
+        String respStr = resp.readEntity(String.class);
+
+        Assert.assertEquals("Resp status = created : " + respStr,
+                Status.CREATED.getStatusCode(), resp.getStatus());
+        Assert.assertTrue("Resp must be application/json", resp.getMediaType()
+                .isCompatible(MediaType.APPLICATION_JSON_TYPE));
+
+        ObjectMapper mapper = getObjectMapper();
+        JsonNode objNode = mapper.readTree(respStr);
+
+        Assert.assertTrue("the space must have an id", objNode.hasNonNull("id"));
+        String idStr = objNode.get("id").asText();
+        Assert.assertFalse("The id str must not be empty", idStr.length() == 0);
+
+        Assert.assertTrue("the space must have a title",
+                objNode.hasNonNull("title"));
+        String titleStr = objNode.get("title").asText();
+        Assert.assertEquals("space title must be equals to " + title, title,
+                titleStr);
+
+        Assert.assertTrue("the space must have a description",
+                objNode.hasNonNull("description"));
+        String descriptionStr = objNode.get("description").asText();
+        Assert.assertEquals("space description must be equals to "
+                + description, description, descriptionStr);
 
-		Assert.assertTrue("the space must have an id", objNode.hasNonNull("id"));
-		String idStr = objNode.get("id").asText();
-		Assert.assertFalse("The id str must not be empty", idStr.length()==0);
-		
-		Assert.assertTrue("the space must have a title", objNode.hasNonNull("title"));
-		String titleStr = objNode.get("title").asText();
-		Assert.assertEquals("space title must be equals to " + title, title, titleStr);
+        Assert.assertTrue("the space must have a uri",
+                objNode.hasNonNull("uri"));
+        String uriStr = objNode.get("uri").asText();
+        Assert.assertEquals("space uri must be equals to " + uri, uri, uriStr);
+
+        Assert.assertTrue("the space must have a color",
+                objNode.hasNonNull("color"));
+        String colorStr = objNode.get("color").asText();
+        Assert.assertEquals("space color must be equals to " + color, color,
+                colorStr);
 
-		Assert.assertTrue("the space must have a description", objNode.hasNonNull("description"));
-		String descriptionStr = objNode.get("description").asText();
-		Assert.assertEquals("space description must be equals to " + description, description, descriptionStr);
+        Assert.assertTrue("the space must have a bin_config",
+                objNode.hasNonNull("bin_config"));
+        String bin_configStr = objNode.get("bin_config").asText();
+        Assert.assertEquals("space bin_config must be equals to " + bin_config,
+                bin_config, bin_configStr);
+
+        Assert.assertTrue("the space must have a created_by",
+                objNode.hasNonNull("created_by"));
+        String created_byStr = objNode.get("created_by").asText();
+        Assert.assertEquals("space created_by must be equals to " + created_by,
+                created_by, created_byStr);
 
-		Assert.assertTrue("the space must have a uri", objNode.hasNonNull("uri"));
-		String uriStr = objNode.get("uri").asText();
-		Assert.assertEquals("space uri must be equals to " + uri, uri, uriStr);
+        Assert.assertTrue("the space must have a created",
+                objNode.hasNonNull("created"));
+        String createdStr = objNode.get("created").asText();
+        Assert.assertEquals("space created must be equals to " + expectedCreated,
+                expectedCreated, createdStr);
+
+        // object must be created
+        Space sp = this.spacesRepository.findOne(idStr);
+
+        Assert.assertNotNull("Space object must be in rep", sp);
 
-		Assert.assertTrue("the space must have a color", objNode.hasNonNull("color"));
-		String colorStr = objNode.get("color").asText();
-		Assert.assertEquals("space color must be equals to " + color, color, colorStr);
+        Assert.assertEquals("space title must be equals to " + title, title,
+                sp.getTitle());
+        Assert.assertEquals("space description must be equals to "
+                + description, description, sp.getDescription());
+        Assert.assertEquals("space uri must be equals to " + uri, uri,
+                sp.getUri());
+        Assert.assertEquals("space color must be equals to " + color, color,
+                sp.getColor());
+        Assert.assertEquals("space bin_config must be equals to " + bin_config,
+                bin_config, sp.getBinConfig());
+        Assert.assertEquals("space created_by must be equals to " + created_by,
+                created_by, sp.getCreatedBy());
+        DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
+        DateTime created_date = fmt.parseDateTime(created);
+        Assert.assertEquals("space created must be equals to " + created,
+                created_date, sp.getCreated());
 
-		Assert.assertTrue("the space must have a bin_config", objNode.hasNonNull("bin_config"));
-		String bin_configStr = objNode.get("bin_config").asText();
-		Assert.assertEquals("space bin_config must be equals to " + bin_config, bin_config, bin_configStr);
+    }
 
-		Assert.assertTrue("the space must have a created_by", objNode.hasNonNull("created_by"));
-		String created_byStr = objNode.get("created_by").asText();
-		Assert.assertEquals("space created_by must be equals to " + created_by, created_by, created_byStr);
-		
-		Assert.assertTrue("the space must have a created", objNode.hasNonNull("created"));
-		String createdStr = objNode.get("created").asText();
-		Assert.assertEquals("space created must be equals to " + created, created, createdStr);
-		
-		// object must be created
-		Space sp = this.spacesRepository.findOne(idStr);
-		
-		Assert.assertNotNull("Space object must be in rep", sp);
-		
-		Assert.assertEquals("space title must be equals to " + title, title, sp.getTitle());
-		Assert.assertEquals("space description must be equals to " + description, description, sp.getDescription());
-		Assert.assertEquals("space uri must be equals to " + uri, uri, sp.getUri());
-		Assert.assertEquals("space color must be equals to " + color, color, sp.getColor());
-		Assert.assertEquals("space bin_config must be equals to " + bin_config, bin_config, sp.getBinConfig());
-		Assert.assertEquals("space created_by must be equals to " + created_by, created_by, sp.getCreatedBy());
-		DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
-		DateTime created_date = fmt.parseDateTime(created);
-		Assert.assertEquals("space created must be equals to " + created, created_date.toDate(), sp.getCreated());
-		
-	}
+    @Test
+    public void testPostWithId() {
+
+        String id = UUID.randomUUID().toString();
+        String title = "test_post";
+        String description = "test space post";
+        String uri = "http://ldt.iri.centrepompidou.fr/test_post";
+        String color = "#bcbcbc";
+        String image = "http://ldt.iri.centrepompidou.fr/test_post/image";
+        String created = "2013-01-01T01:01:01.001+0000";
+        String bin_config = "{name: 'test_post_config'}";
+        String created_by = "test_user_post";
+
+        String spaceJson = String.format("{" + "\"id\":\"%s\","
+                + "\"title\":\"%s\"," + "\"description\":\"%s\","
+                + "\"uri\":\"%s\"," + "\"color\":\"%s\"," + "\"image\":\"%s\","
+                + "\"created\":\"%s\"," + "\"bin_config\":\"%s\","
+                + "\"created_by\":\"%s\"" + "}", id, title, description, uri,
+                color, image, created, bin_config, created_by);
+
+        WebTarget WebTarget = this.target();
+        Response resp = WebTarget.path("spaces").request()
+                .accept(MediaType.APPLICATION_JSON)
+                .post(Entity.entity(spaceJson, MediaType.APPLICATION_JSON));
+
+        String respStr = resp.readEntity(String.class);
+
+        Assert.assertEquals("Resp status = Bad Request : " + respStr,
+                Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
+        Assert.assertEquals("Error message", "Id in JSON must be null", respStr);
+
+    }
+
+    @Test
+    public void testPut() throws JsonProcessingException, IOException {
+
+        String id = this.firstSpaceUUID;
+        String title = "test_post";
+        String description = "test space put";
+        String uri = "http://ldt.iri.centrepompidou.fr/test_put";
+        String color = "#bcbcbc";
+        String image = "http://ldt.iri.centrepompidou.fr/test_put/image";
+        String created = "2013-01-01T01:01:01.001+0000";
+        String bin_config = "{name: 'test_put_config'}";
+        String created_by = "test_user_put";
+
+        String spaceJson = String.format("{" + "\"id\":\"%s\","
+                + "\"title\":\"%s\"," + "\"description\":\"%s\","
+                + "\"uri\":\"%s\"," + "\"color\":\"%s\"," + "\"image\":\"%s\","
+                + "\"created\":\"%s\"," + "\"bin_config\":\"%s\","
+                + "\"created_by\":\"%s\"" + "}", id, title, description, uri,
+                color, image, created, bin_config, created_by);
 
-	
-	@Test
-	public void testPostWithId() {
-		
-		String id = UUID.randomUUID().toString();
-		String title = "test_post";
-		String description = "test space post";
-		String uri = "http://ldt.iri.centrepompidou.fr/test_post";
-		String color = "#bcbcbc";
-		String image = "http://ldt.iri.centrepompidou.fr/test_post/image";
-		String created = "2013-01-01T01:01:01.001+0000";
-		String bin_config = "{name: 'test_post_config'}";
-		String created_by = "test_user_post";
-		
-		String spaceJson = String.format("{" +
-		        "\"id\":\"%s\"," +
-				"\"title\":\"%s\"," +
-				"\"description\":\"%s\"," +
-				"\"uri\":\"%s\"," +
-				"\"color\":\"%s\"," +
-				"\"image\":\"%s\"," +
-				"\"created\":\"%s\"," +
-				"\"bin_config\":\"%s\"," +
-				"\"created_by\":\"%s\"" +
-				"}",
-				id,
-				title,
-				description,
-				uri,
-				color,
-				image,
-				created,
-				bin_config,
-				created_by);
-		
-		WebResource webResource = this.resource();
-		ClientResponse resp = webResource.path("spaces").type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).entity(spaceJson).post(ClientResponse.class);
-		
-		String respStr = resp.getEntity(String.class);
-		
-		Assert.assertEquals("Resp status = Bad Request : " + respStr, Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
-		Assert.assertEquals("Error message", "Id in JSON must be null", respStr);
-		
-	}
-		
-	@Test
-	public void testPut() throws JsonProcessingException, IOException {
-		
-		String id = this.firstSpaceUUID;
-		String title = "test_post";
-		String description = "test space put";
-		String uri = "http://ldt.iri.centrepompidou.fr/test_put";
-		String color = "#bcbcbc";
-		String image = "http://ldt.iri.centrepompidou.fr/test_put/image";
-		String created = "2013-01-01T01:01:01.001+0000";
-		String bin_config = "{name: 'test_put_config'}";
-		String created_by = "test_user_put";
-		
-		String spaceJson = String.format("{" +
-		        "\"id\":\"%s\"," +
-				"\"title\":\"%s\"," +
-				"\"description\":\"%s\"," +
-				"\"uri\":\"%s\"," +
-				"\"color\":\"%s\"," +
-				"\"image\":\"%s\"," +
-				"\"created\":\"%s\"," +
-				"\"bin_config\":\"%s\"," +
-				"\"created_by\":\"%s\"" +
-				"}",
-				id,
-				title,
-				description,
-				uri,
-				color,
-				image,
-				created,
-				bin_config,
-				created_by);
-		
-		WebResource webResource = this.resource();
-		ClientResponse resp = webResource.path("spaces").path(this.firstSpaceUUID).type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).entity(spaceJson).put(ClientResponse.class);
-		
-		String respStr = "";
-		
-		if(resp.getStatus() != 204) {
-			respStr = resp.getEntity(String.class);
-		}
-		
-		Assert.assertEquals("Resp status = created : " + respStr, Status.NO_CONTENT.getStatusCode(), resp.getStatus());
-		Assert.assertNull("Resp type must be null", resp.getType());		
+        WebTarget WebTarget = this.target();
+        Response resp = WebTarget.path("spaces").path(this.firstSpaceUUID)
+                .request()// type(MediaType.APPLICATION_JSON)
+                .accept(MediaType.APPLICATION_JSON)// .entity(spaceJson)
+                .put(Entity.entity(spaceJson, MediaType.APPLICATION_JSON));
+
+        String respStr = "";
+
+        if (resp.getStatus() != 204) {
+            respStr = resp.readEntity(String.class);
+        }
+
+        Assert.assertEquals("Resp status = created : " + respStr,
+                Status.NO_CONTENT.getStatusCode(), resp.getStatus());
+        Assert.assertNull("Resp type must be null", resp.getMediaType());
+
+        // object must be updated
+        Space sp = this.spacesRepository.findOne(id);
+
+        Assert.assertNotNull("Space object must be in rep", sp);
+
+        Assert.assertEquals("space title must be equals to " + title, title,
+                sp.getTitle());
+        Assert.assertEquals("space description must be equals to "
+                + description, description, sp.getDescription());
+        Assert.assertEquals("space uri must be equals to " + uri, uri,
+                sp.getUri());
+        Assert.assertEquals("space color must be equals to " + color, color,
+                sp.getColor());
+        Assert.assertEquals("space bin_config must be equals to " + bin_config,
+                bin_config, sp.getBinConfig());
+        Assert.assertEquals("space created_by must be equals to " + created_by,
+                created_by, sp.getCreatedBy());
+        DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
+        DateTime created_date = fmt.parseDateTime(created);
+        Assert.assertEquals("space created must be equals to " + created,
+                created_date, sp.getCreated());
+
+    }
+
+    @Test
+    public void testPutWithoutId() {
+
+        String title = "test_put";
+        String description = "test space put";
+        String uri = "http://ldt.iri.centrepompidou.fr/test_put";
+        String color = "#bcbcbc";
+        String image = "http://ldt.iri.centrepompidou.fr/test_put/image";
+        String created = "2013-01-01T01:01:01.001+0000";
+        String bin_config = "{name: 'test_put_config'}";
+        String created_by = "test_user_put";
 
-		
-		// object must be updated
-		Space sp = this.spacesRepository.findOne(id);
-		
-		Assert.assertNotNull("Space object must be in rep", sp);
-		
-		Assert.assertEquals("space title must be equals to " + title, title, sp.getTitle());
-		Assert.assertEquals("space description must be equals to " + description, description, sp.getDescription());
-		Assert.assertEquals("space uri must be equals to " + uri, uri, sp.getUri());
-		Assert.assertEquals("space color must be equals to " + color, color, sp.getColor());
-		Assert.assertEquals("space bin_config must be equals to " + bin_config, bin_config, sp.getBinConfig());
-		Assert.assertEquals("space created_by must be equals to " + created_by, created_by, sp.getCreatedBy());
-		DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
-		DateTime created_date = fmt.parseDateTime(created);
-		Assert.assertEquals("space created must be equals to " + created, created_date.toDate(), sp.getCreated());
+        String spaceJson = String.format("{" + "\"title\":\"%s\","
+                + "\"description\":\"%s\"," + "\"uri\":\"%s\","
+                + "\"color\":\"%s\"," + "\"image\":\"%s\","
+                + "\"created\":\"%s\"," + "\"bin_config\":\"%s\","
+                + "\"created_by\":\"%s\"" + "}", title, description, uri,
+                color, image, created, bin_config, created_by);
+
+        WebTarget WebTarget = this.target();
+        Response resp = WebTarget.path("spaces").path(this.firstSpaceUUID)
+                .request().accept(MediaType.APPLICATION_JSON)
+                .put(Entity.entity(spaceJson, MediaType.APPLICATION_JSON));
+
+        String respStr = resp.readEntity(String.class);
+
+        Assert.assertEquals("Resp status = Bad Request : " + respStr,
+                Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
+        Assert.assertEquals("Error message",
+                "Id parameter and id in JSON do not match", respStr);
+    }
+
+    @Test
+    public void testPutBadId() {
 
-	}
-	
-	@Test
-	public void testPutWithoutId() {
+        String id = UUID.randomUUID().toString();
+        String title = "test_post";
+        String description = "test space put";
+        String uri = "http://ldt.iri.centrepompidou.fr/test_put";
+        String color = "#bcbcbc";
+        String image = "http://ldt.iri.centrepompidou.fr/test_put/image";
+        String created = "2013-01-01T01:01:01.001+0000";
+        String bin_config = "{name: 'test_put_config'}";
+        String created_by = "test_user_put";
+
+        String spaceJson = String.format("{" + "\"id\":\"%s\","
+                + "\"title\":\"%s\"," + "\"description\":\"%s\","
+                + "\"uri\":\"%s\"," + "\"color\":\"%s\"," + "\"image\":\"%s\","
+                + "\"created\":\"%s\"," + "\"bin_config\":\"%s\","
+                + "\"created_by\":\"%s\"" + "}", id, title, description, uri,
+                color, image, created, bin_config, created_by);
+
+        WebTarget WebTarget = this.target();
+        Response resp = WebTarget.path("spaces").path(id)
+                .request(MediaType.APPLICATION_JSON)
+                .accept(MediaType.APPLICATION_JSON)
+                .put(Entity.entity(spaceJson, MediaType.APPLICATION_JSON));
+
+        String respStr = resp.readEntity(String.class);
+
+        Assert.assertEquals("Resp status = Bad Request : " + respStr,
+                Status.NOT_FOUND.getStatusCode(), resp.getStatus());
+
+    }
+
+    @Test
+    public void testDelete() {
 
-		String title = "test_put";
-		String description = "test space put";
-		String uri = "http://ldt.iri.centrepompidou.fr/test_put";
-		String color = "#bcbcbc";
-		String image = "http://ldt.iri.centrepompidou.fr/test_put/image";
-		String created = "2013-01-01T01:01:01.001+0000";
-		String bin_config = "{name: 'test_put_config'}";
-		String created_by = "test_user_put";
-		
-		String spaceJson = String.format("{" +
-				"\"title\":\"%s\"," +
-				"\"description\":\"%s\"," +
-				"\"uri\":\"%s\"," +
-				"\"color\":\"%s\"," +
-				"\"image\":\"%s\"," +
-				"\"created\":\"%s\"," +
-				"\"bin_config\":\"%s\"," +
-				"\"created_by\":\"%s\"" +
-				"}",
-				title,
-				description,
-				uri,
-				color,
-				image,
-				created,
-				bin_config,
-				created_by);
-		
-		WebResource webResource = this.resource();
-		ClientResponse resp = webResource.path("spaces").path(this.firstSpaceUUID).type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).entity(spaceJson).put(ClientResponse.class);
-		
-		String respStr = resp.getEntity(String.class);
-		
-		Assert.assertEquals("Resp status = Bad Request : " + respStr, Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
-		Assert.assertEquals("Error message", "Id parameter and id in JSON do not match", respStr);		
-	}
-	
-	@Test
-	public void testPutBadId() {
-		
-		String id = UUID.randomUUID().toString();
-		String title = "test_post";
-		String description = "test space put";
-		String uri = "http://ldt.iri.centrepompidou.fr/test_put";
-		String color = "#bcbcbc";
-		String image = "http://ldt.iri.centrepompidou.fr/test_put/image";
-		String created = "2013-01-01T01:01:01.001+0000";
-		String bin_config = "{name: 'test_put_config'}";
-		String created_by = "test_user_put";
-		
-		String spaceJson = String.format("{" +
-		        "\"id\":\"%s\"," +
-				"\"title\":\"%s\"," +
-				"\"description\":\"%s\"," +
-				"\"uri\":\"%s\"," +
-				"\"color\":\"%s\"," +
-				"\"image\":\"%s\"," +
-				"\"created\":\"%s\"," +
-				"\"bin_config\":\"%s\"," +
-				"\"created_by\":\"%s\"" +
-				"}",
-				id,
-				title,
-				description,
-				uri,
-				color,
-				image,
-				created,
-				bin_config,
-				created_by);
-		
-		WebResource webResource = this.resource();
-		ClientResponse resp = webResource.path("spaces").path(id).type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).entity(spaceJson).put(ClientResponse.class);
-		
-		String respStr = resp.getEntity(String.class);
-		
-		Assert.assertEquals("Resp status = Bad Request : " + respStr, Status.NOT_FOUND.getStatusCode(), resp.getStatus());
-		
-	}
-	
-	@Test
-	public void testDelete() {
+        WebTarget WebTarget = this.target();
+        Response resp = WebTarget.path("spaces").path(this.firstSpaceUUID)
+                .request().accept(MediaType.TEXT_PLAIN).delete();
+
+        String respStr = resp.readEntity(String.class);
+        URI reqUri = WebTarget.getUriBuilder().path("spaces")
+                .path(this.firstSpaceUUID).build();
+
+        Assert.assertEquals("Status must be deleted : " + respStr,
+                Status.OK.getStatusCode(), resp.getStatus());
+        Assert.assertEquals(
+                String.format("Message must be \"%s deleted\"", reqUri),
+                String.format("%s deleted", reqUri), respStr);
+
+        // object must be updated
+        Space sp = this.spacesRepository.findOne(this.firstSpaceUUID);
+
+        Assert.assertNull("Space object must be in rep", sp);
+
+    }
+
+    @Test
+    public void testSingleGetJsonp() throws JsonProcessingException,
+            IOException {
+        WebTarget WebTarget = this.target();
+        Response resp = WebTarget.path("spaces").path(this.firstSpaceUUID)
+                .queryParam("callback", "callback_func").request()
+                .accept("application/javascript").get();
+        Assert.assertEquals("return type must be application/javascript",
+                "application/javascript", resp.getMediaType().toString());
+
+        String respStr = resp.readEntity(String.class);
+
+        Assert.assertTrue("resp must start with callback call",
+                respStr.startsWith("callback_func("));
+        Assert.assertTrue("resp must start with callback call",
+                respStr.endsWith(")"));
+
+        String jsonStr = respStr.substring("callback_func(".length(),
+                respStr.length() - 1);
+        ObjectMapper mapper = getObjectMapper();
+        JsonNode jsonNode = mapper.readTree(jsonStr);
+
+        Space space = this.spacesList.get(this.firstSpaceUUID);
+
+        String id = jsonNode.get("id").asText();
+        Assert.assertEquals("id must be equals", space.getId(), id);
+
+        Assert.assertTrue("the space must have a created",
+                jsonNode.hasNonNull("created"));
+
+        String dateStr = jsonNode.get("created").asText();
 
-		WebResource webResource = this.resource();
-		ClientResponse resp = webResource.path("spaces").path(this.firstSpaceUUID).accept(MediaType.TEXT_PLAIN).delete(ClientResponse.class);
-		
-		String respStr = resp.getEntity(String.class);
-		URI reqUri = webResource.getUriBuilder().path("spaces").path(this.firstSpaceUUID).build();
+        DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
+        DateTime date = fmt.parseDateTime(dateStr);
+
+        Assert.assertEquals("Created date must be the same",
+                space.getCreated(), date);
+
+        Assert.assertEquals("title must be the same", space.getTitle(),
+                jsonNode.get("title").asText());
+
+    }
 
-		Assert.assertEquals("Status must be deleted : " + respStr, Status.OK.getStatusCode(), resp.getStatus());
-		Assert.assertEquals(String.format("Message must be \"%s deleted\"", reqUri), String.format("%s deleted",reqUri) , respStr);
-		
-		// object must be updated
-		Space sp = this.spacesRepository.findOne(this.firstSpaceUUID);
-		
-		Assert.assertNull("Space object must be in rep", sp);
+    @Test
+    public void testSingleGetJsonpAcceptAll() throws JsonProcessingException,
+            IOException {
+        WebTarget WebTarget = this.target();
+        Response resp = WebTarget.path("spaces").path(this.firstSpaceUUID)
+                .queryParam("callback", "callback_func").request()
+                .accept("*/*").get();
+        Assert.assertEquals("return type must be application/javascript",
+                "application/javascript", resp.getMediaType().toString());
 
-	}
-	
-	@Test
-	public void testSingleGetJsonp() throws JsonProcessingException, IOException {
-		WebResource webResource = this.resource();
-		ClientResponse resp = webResource.path("spaces").path(this.firstSpaceUUID).queryParam("callback", "callback_func").accept("application/javascript").get(ClientResponse.class);
-		Assert.assertEquals("return type must be application/javascript","application/javascript", resp.getType().toString());
+        String respStr = resp.readEntity(String.class);
 
-		String respStr = resp.getEntity(String.class);
-		
-		Assert.assertTrue("resp must start with callback call", respStr.startsWith("callback_func("));
-		Assert.assertTrue("resp must start with callback call", respStr.endsWith(")"));
-		
-		String jsonStr = respStr.substring("callback_func(".length(), respStr.length()-1);
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode jsonNode = mapper.readTree(jsonStr);
-		
-		Space space = this.spacesList.get(this.firstSpaceUUID);
-		
-		String id = jsonNode.get("id").asText();
-		Assert.assertEquals("id must be equals", space.getId(), id);
-		
-		Assert.assertTrue("the space must have a created", jsonNode.hasNonNull("created"));
-		
-		String dateStr = jsonNode.get("created").asText();
-		
-		DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
-		DateTime date = fmt.parseDateTime(dateStr);
-		
-		Assert.assertEquals("Created date must be the same", space.getCreated(), date.toDate());
-		
-		Assert.assertEquals("title must be the same", space.getTitle(), jsonNode.get("title").asText());
-		
-	}
-	
-	@Test
-	public void testSingleGetJsonpAcceptAll() throws JsonProcessingException, IOException {
-		WebResource webResource = this.resource();
-		ClientResponse resp = webResource.path("spaces").path(this.firstSpaceUUID).queryParam("callback", "callback_func").accept("*/*").get(ClientResponse.class);
-		Assert.assertEquals("return type must be application/javascript","application/javascript", resp.getType().toString());
+        Assert.assertTrue("resp must start with callback call",
+                respStr.startsWith("callback_func("));
+        Assert.assertTrue("resp must start with callback call",
+                respStr.endsWith(")"));
+
+        String jsonStr = respStr.substring("callback_func(".length(),
+                respStr.length() - 1);
+        ObjectMapper mapper = getObjectMapper();
+        JsonNode jsonNode = mapper.readTree(jsonStr);
+
+        Space space = this.spacesList.get(this.firstSpaceUUID);
+
+        String id = jsonNode.get("id").asText();
+        Assert.assertEquals("id must be equals", space.getId(), id);
 
-		String respStr = resp.getEntity(String.class);
-		
-		Assert.assertTrue("resp must start with callback call", respStr.startsWith("callback_func("));
-		Assert.assertTrue("resp must start with callback call", respStr.endsWith(")"));
-		
-		String jsonStr = respStr.substring("callback_func(".length(), respStr.length()-1);
-		ObjectMapper mapper = new ObjectMapper();
-		JsonNode jsonNode = mapper.readTree(jsonStr);
-		
-		Space space = this.spacesList.get(this.firstSpaceUUID);
-		
-		String id = jsonNode.get("id").asText();
-		Assert.assertEquals("id must be equals", space.getId(), id);
-		
-		Assert.assertTrue("the space must have a created", jsonNode.hasNonNull("created"));
-		
-		String dateStr = jsonNode.get("created").asText();
-		
-		DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
-		DateTime date = fmt.parseDateTime(dateStr);
-		
-		Assert.assertEquals("Created date must be the same", space.getCreated(), date.toDate());
-		
-		Assert.assertEquals("title must be the same", space.getTitle(), jsonNode.get("title").asText());
-		
-	}
+        Assert.assertTrue("the space must have a created",
+                jsonNode.hasNonNull("created"));
+
+        String dateStr = jsonNode.get("created").asText();
+
+        DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
+        DateTime date = fmt.parseDateTime(dateStr);
+
+        Assert.assertEquals("Created date must be the same",
+                space.getCreated(), date);
+
+        Assert.assertEquals("title must be the same", space.getTitle(),
+                jsonNode.get("title").asText());
+
+    }
 }
--- a/server/src/test/resources/log4j.xml	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/test/resources/log4j.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -17,6 +17,9 @@
   <logger name="org.springframework.test">
       <level value="DEBUG" />
   </logger>
+  <logger name="org.springframework.data.mongodb">
+      <level value="DEBUG" />
+  </logger>
   <root> 
     <priority value ="WARN" /> 
     <appender-ref ref="console" /> 
--- a/server/src/test/resources/org/iri_research/renkan/test/controller/controller-context.xml	Fri Oct 25 16:42:11 2013 +0200
+++ b/server/src/test/resources/org/iri_research/renkan/test/controller/controller-context.xml	Wed Jan 15 18:36:27 2014 +0100
@@ -13,6 +13,10 @@
     <!-- Configures the annotation-driven Spring MVC Controller programming model.
     Note that, with Spring 3.0, this tag works in Servlet MVC only!  -->
 
+    <bean class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" id="renkanPasswordEncoder">
+        <constructor-arg name="strength" value="10" type="int"/>
+    </bean>
+
     <!-- Loads MongoDB configuraton -->
     <import resource="mongo-config.xml"/>