Sandbox-commits
Threads by month
- ----- 2026 -----
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
June 2013
- 4 participants
- 42 discussions
r681 - nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates
by bleny@users.nuiton.org June 27, 2013
by bleny@users.nuiton.org June 27, 2013
June 27, 2013
Author: bleny
Date: 2013-06-27 16:24:38 +0200 (Thu, 27 Jun 2013)
New Revision: 681
Url: http://nuiton.org/projects/sandbox/repository/revisions/681
Log:
do not generate on prepersit if it is already manually set
Modified:
nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java
Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java 2013-06-27 09:34:46 UTC (rev 680)
+++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java 2013-06-27 14:24:38 UTC (rev 681)
@@ -191,17 +191,19 @@
// use an idGenerator
- // add prepersist method
+ // add prePersist method
ObjectModelOperation operation = addOperation(
output,
- "prepersist",
+ "prePersist",
void.class,
ObjectModelJavaModifier.PUBLIC);
addAnnotation(output, operation, PrePersist.class);
addImport(output, JpaEntityIdFactoryResolver.class);
setOperationBody(operation, ""
/*{
- this.id = new JpaEntityIdFactoryResolver().newId(this);
+ if (this.id == null) {
+ this.id = new JpaEntityIdFactoryResolver().newId(this);
+ }
}*/
);
}
1
0
r680 - nuiton-jpa/nuiton-jpa-junit/src/main/java/org/nuiton/jpa/junit
by bleny@users.nuiton.org June 27, 2013
by bleny@users.nuiton.org June 27, 2013
June 27, 2013
Author: bleny
Date: 2013-06-27 11:34:46 +0200 (Thu, 27 Jun 2013)
New Revision: 680
Url: http://nuiton.org/projects/sandbox/repository/revisions/680
Log:
allow use of multiple entity managers in the junit rule
Modified:
nuiton-jpa/nuiton-jpa-junit/src/main/java/org/nuiton/jpa/junit/JpaEntityManagerRule.java
Modified: nuiton-jpa/nuiton-jpa-junit/src/main/java/org/nuiton/jpa/junit/JpaEntityManagerRule.java
===================================================================
--- nuiton-jpa/nuiton-jpa-junit/src/main/java/org/nuiton/jpa/junit/JpaEntityManagerRule.java 2013-06-26 07:17:58 UTC (rev 679)
+++ nuiton-jpa/nuiton-jpa-junit/src/main/java/org/nuiton/jpa/junit/JpaEntityManagerRule.java 2013-06-27 09:34:46 UTC (rev 680)
@@ -34,6 +34,8 @@
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
public class JpaEntityManagerRule implements TestRule {
@@ -44,12 +46,14 @@
protected static String timestamp = String.valueOf(new Date().getTime());
- protected EntityManager entityManager;
-
protected boolean open = false;
protected Map<String, String> jpaParameters;
+ protected EntityManagerFactory entityManagerFactory;
+
+ protected List<EntityManager> openedEntityManagers = new LinkedList<EntityManager>();
+
public JpaEntityManagerRule(String persistenceUnitName, Map<String, String> jpaParameters) {
this.persistenceUnitName = persistenceUnitName;
this.jpaParameters = jpaParameters;
@@ -70,7 +74,7 @@
return new Statement() {
@Override
public void evaluate() throws Throwable {
- createEntityManager(testClassName, testMethodName);
+ createEntityManagerFactory(testClassName, testMethodName);
try {
base.evaluate();
} finally {
@@ -80,32 +84,49 @@
};
}
- protected void createEntityManager(String testClassName, String testMethodName) {
+ protected void createEntityManagerFactory(String testClassName, String testMethodName) {
String context = testClassName
+ '_' + testMethodName
+ '_' + timestamp;
- EntityManagerFactory entityManagerFactory =
- HibernateUtil.createTempEntityManagerFactory(
+ entityManagerFactory = HibernateUtil.createTempEntityManagerFactory(
persistenceUnitName, context, jpaParameters);
- entityManager = entityManagerFactory.createEntityManager();
-
if (log.isDebugEnabled()) {
- log.debug("created entityManager " + entityManager);
+ log.debug("created entityManagerFactory " + entityManagerFactory);
}
open = true;
}
+ /**
+ * @deprecated use {@link #newEntityManager()} and save a reference to it
+ */
public EntityManager getEntityManager() {
- if (!open) {
+ if (openedEntityManagers.isEmpty()) {
+
+ openedEntityManagers.add(newEntityManager());
+
+ }
+
+ return openedEntityManagers.get(0);
+
+ }
+
+ public EntityManager newEntityManager() {
+
+ if ( ! open) {
throw new IllegalStateException("entity manager is not yet opened");
}
+ EntityManager entityManager =
+ entityManagerFactory.createEntityManager();
+
+ openedEntityManagers.add(entityManager);
+
return entityManager;
}
@@ -113,14 +134,18 @@
/** Override to tear down your specific external resource. */
protected void closeEntityManager() {
- if (log.isDebugEnabled()) {
- log.debug("close entityManager " + entityManager);
- }
-
open = false;
- entityManager.close();
+ for (EntityManager openedEntityManager : openedEntityManagers) {
+ if (log.isDebugEnabled()) {
+ log.debug("close entityManager " + openedEntityManager);
+ }
+
+ openedEntityManager.close();
+
+ }
+
}
}
1
0
r679 - in nuiton-jpa/nuiton-jpa-hibernate: . src/license src/main/java/org/nuiton/jpa/hibernate src/test/java/org/nuiton/jpa/hibernate
by tchemit@users.nuiton.org June 26, 2013
by tchemit@users.nuiton.org June 26, 2013
June 26, 2013
Author: tchemit
Date: 2013-06-26 09:17:58 +0200 (Wed, 26 Jun 2013)
New Revision: 679
Url: http://nuiton.org/projects/sandbox/repository/revisions/679
Log:
add svn properties + missing license headers
Modified:
nuiton-jpa/nuiton-jpa-hibernate/LICENSE.txt
nuiton-jpa/nuiton-jpa-hibernate/README.txt
nuiton-jpa/nuiton-jpa-hibernate/changelog.txt
nuiton-jpa/nuiton-jpa-hibernate/pom.xml
nuiton-jpa/nuiton-jpa-hibernate/src/license/THIRD-PARTY.properties
nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategy.java
nuiton-jpa/nuiton-jpa-hibernate/src/test/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategyTest.java
Property changes on: nuiton-jpa/nuiton-jpa-hibernate/LICENSE.txt
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Property changes on: nuiton-jpa/nuiton-jpa-hibernate/README.txt
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Property changes on: nuiton-jpa/nuiton-jpa-hibernate/changelog.txt
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Property changes on: nuiton-jpa/nuiton-jpa-hibernate/pom.xml
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Property changes on: nuiton-jpa/nuiton-jpa-hibernate/src/license/THIRD-PARTY.properties
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Modified: nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategy.java
===================================================================
--- nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategy.java 2013-06-25 13:23:08 UTC (rev 678)
+++ nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategy.java 2013-06-26 07:17:58 UTC (rev 679)
@@ -1,5 +1,29 @@
package org.nuiton.jpa.hibernate;
+/*
+ * #%L
+ * Nuiton Jpa :: Hibernate
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2013 CodeLutin
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Lesser Public License for more details.
+ *
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/lgpl-3.0.html>.
+ * #L%
+ */
+
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.BiMap;
Property changes on: nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategy.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Modified: nuiton-jpa/nuiton-jpa-hibernate/src/test/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategyTest.java
===================================================================
--- nuiton-jpa/nuiton-jpa-hibernate/src/test/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategyTest.java 2013-06-25 13:23:08 UTC (rev 678)
+++ nuiton-jpa/nuiton-jpa-hibernate/src/test/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategyTest.java 2013-06-26 07:17:58 UTC (rev 679)
@@ -1,5 +1,29 @@
package org.nuiton.jpa.hibernate;
+/*
+ * #%L
+ * Nuiton Jpa :: Hibernate
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2013 CodeLutin
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Lesser Public License for more details.
+ *
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/lgpl-3.0.html>.
+ * #L%
+ */
+
import com.google.common.base.Preconditions;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.HibernateException;
Property changes on: nuiton-jpa/nuiton-jpa-hibernate/src/test/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategyTest.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
1
0
r678 - in nuiton-jpa/nuiton-jpa-hibernate/src: main/java/org/nuiton/jpa/hibernate test/java/org/nuiton/jpa/hibernate
by bleny@users.nuiton.org June 25, 2013
by bleny@users.nuiton.org June 25, 2013
June 25, 2013
Author: bleny
Date: 2013-06-25 15:23:08 +0200 (Tue, 25 Jun 2013)
New Revision: 678
Url: http://nuiton.org/projects/sandbox/repository/revisions/678
Log:
improve OracleCompliantImprovedNamingStrategy by preventing conflicts
Modified:
nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategy.java
nuiton-jpa/nuiton-jpa-hibernate/src/test/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategyTest.java
Modified: nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategy.java
===================================================================
--- nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategy.java 2013-06-24 21:16:58 UTC (rev 677)
+++ nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategy.java 2013-06-25 13:23:08 UTC (rev 678)
@@ -2,15 +2,16 @@
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
+import org.hibernate.HibernateException;
import org.hibernate.cfg.ImprovedNamingStrategy;
import org.hibernate.cfg.NamingStrategy;
import java.util.List;
-import java.util.Map;
/**
* Oracle doesn't support table names and columns names longer than 30 characters.
@@ -34,7 +35,7 @@
*/
protected static final int MAXIMUM_IDENTIFIER_LENGTH = 30;
- protected Map<String, String> cache = Maps.newConcurrentMap();
+ protected BiMap<String, String> identifierToShortenedIdentifier = HashBiMap.create();
/**
* Given an identifier, return a similar identifier but no longer
@@ -52,15 +53,27 @@
protected String getShortenedIdentifier(String value) {
String reducedValue = value;
if (value.length() > MAXIMUM_IDENTIFIER_LENGTH) {
- reducedValue = cache.get(value);
+ reducedValue = identifierToShortenedIdentifier.get(value);
if (reducedValue == null) {
reducedValue = shortenIdentifier(value);
- cache.put(value, reducedValue);
+ checkConflict(value, reducedValue);
+ identifierToShortenedIdentifier.put(value, reducedValue);
}
}
return reducedValue;
}
+ protected void checkConflict(String value, String reducedValue) {
+ boolean conflictInShortenedIdentifier = identifierToShortenedIdentifier.inverse().containsKey(reducedValue);
+ if (conflictInShortenedIdentifier) {
+ String otherIdentifier = identifierToShortenedIdentifier.inverse().get(reducedValue);
+ throw new HibernateException(
+ "error while using this naming strategy, a conflict occurred when short identifier for '"
+ + value + "' was computed. Generated short identifier (" + reducedValue +
+ ") is already used for identifier " + otherIdentifier);
+ }
+ }
+
protected String shortenIdentifier(String identifier) {
Iterable <String> split = Splitter.on('_').split(identifier);
int numberOfElements = Iterables.size(split);
Modified: nuiton-jpa/nuiton-jpa-hibernate/src/test/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategyTest.java
===================================================================
--- nuiton-jpa/nuiton-jpa-hibernate/src/test/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategyTest.java 2013-06-24 21:16:58 UTC (rev 677)
+++ nuiton-jpa/nuiton-jpa-hibernate/src/test/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategyTest.java 2013-06-25 13:23:08 UTC (rev 678)
@@ -1,6 +1,8 @@
package org.nuiton.jpa.hibernate;
+import com.google.common.base.Preconditions;
import org.apache.commons.lang3.StringUtils;
+import org.hibernate.HibernateException;
import org.junit.Assert;
import org.junit.Test;
@@ -79,4 +81,30 @@
return StringUtils.rightPad(value, 50, "LONG");
}
+ @Test
+ public void testConflictsRaiseException() {
+
+ String longClassName1 = getLongValue("LONG_CLASS_NAME_") + "1";
+ String longClassName2 = getLongValue("LONG_CLASS_NAME_") + "2";
+
+ // to lead to a conflict, we must check that both long class names
+ // will have the same reduced identifier
+ String shortenedIdentifier = oracleCompliantImprovedNamingStrategy.shortenIdentifier(longClassName1);
+ Preconditions.checkState(
+ shortenedIdentifier.equals(oracleCompliantImprovedNamingStrategy.shortenIdentifier(longClassName2))
+ );
+
+ // now check that an exception is raised and exception message is explicit
+ oracleCompliantImprovedNamingStrategy.classToTableName(longClassName1);
+
+ try {
+ oracleCompliantImprovedNamingStrategy.classToTableName(longClassName2);
+ Assert.fail("an exception should have been raised");
+ } catch (HibernateException e) {
+ Assert.assertTrue(StringUtils.containsIgnoreCase(e.getMessage(), longClassName1));
+ Assert.assertTrue(StringUtils.containsIgnoreCase(e.getMessage(), longClassName2));
+ Assert.assertTrue(StringUtils.containsIgnoreCase(e.getMessage(), shortenedIdentifier));
+ }
+
+ }
}
1
0
r677 - testEugeneUML-YAML/pollen/demo-pollen-user_friendly
by agiraudet@users.nuiton.org June 24, 2013
by agiraudet@users.nuiton.org June 24, 2013
June 24, 2013
Author: agiraudet
Date: 2013-06-24 23:16:58 +0200 (Mon, 24 Jun 2013)
New Revision: 677
Url: http://nuiton.org/projects/sandbox/repository/revisions/677
Log:
mise a jour des modeles yaml
Modified:
testEugeneUML-YAML/pollen/demo-pollen-user_friendly/pollen.yamlobjectmodel
Modified: testEugeneUML-YAML/pollen/demo-pollen-user_friendly/pollen.yamlobjectmodel
===================================================================
--- testEugeneUML-YAML/pollen/demo-pollen-user_friendly/pollen.yamlobjectmodel 2013-06-20 15:38:34 UTC (rev 676)
+++ testEugeneUML-YAML/pollen/demo-pollen-user_friendly/pollen.yamlobjectmodel 2013-06-24 21:16:58 UTC (rev 677)
@@ -31,7 +31,7 @@
String name:
double weight:
PollAccount ordered [1..*] "PersonToList":
- Vote unordered [0..1]:
+ Vote unordered [0..1]: unordered [0..1]
class Vote <<entity>>:
double weight:
@@ -48,7 +48,7 @@
boolean administrator:
String language:
String email:
- getDisplayName(): String
+ String getDisplayName():
PersonList favoriteList ordered [*] "UserAccount--PersonList":
PollAccount ordered [*] "PollAccount--UserAccount":
@@ -75,25 +75,25 @@
boolean continuousResults:
Date endChoiceDate:
int voteCountingType:
- getVoteByPollAccount(PollAccount account): Vote
- getAdminId(): String
- getVoteId(PollAccount account): String
- isStarted(Date currentDate): boolean
- isRunning(Date currentDate): boolean
- isFinished(Date currentDate): boolean
- isAddChoiceStarted(Date currentDate): boolean
- isAddChoiceRunning(Date currentDate): boolean
- isAddChoiceFinished(Date currentDate): boolean
- getPollAccounts(boolean withNoVote): List<PollAccount>
- getPersonToListByVote(Vote vote): PersonToList
- getPreventRuleByScope(String scope): PreventRule
- isAnonymous(): boolean
- isPollFree(): boolean
- isPollGroup(): boolean
- isPollRestricted(): boolean
+ Vote getVoteByPollAccount(PollAccount account):
+ String getAdminId():
+ String getVoteId(PollAccount account):
+ boolean isStarted(Date currentDate):
+ boolean isRunning(Date currentDate):
+ boolean isFinished(Date currentDate):
+ boolean isAddChoiceStarted(Date currentDate):
+ boolean isAddChoiceRunning(Date currentDate):
+ boolean isAddChoiceFinished(Date currentDate):
+ List<PollAccount> getPollAccounts(boolean withNoVote):
+ PersonToList getPersonToListByVote(Vote vote):
+ PreventRule getPreventRuleByScope(String scope):
+ boolean isAnonymous():
+ boolean isPollFree():
+ boolean isPollGroup():
+ boolean isPollRestricted():
Vote ordered [*]:
Choice ordered [*]:
- PollAccount creator unordered [0..1]:
+ PollAccount creator unordered [0..1]: ordered [*]
Comment ordered [*]:
PreventRule ordered [*]:
VotingList ordered [*]:
@@ -111,7 +111,7 @@
String text:
Date postDate:
String author:
- PollAccount unordered:
+ PollAccount unordered: ordered [*]
associationclass PersonToList <<entity>>:
participant:
1
0
June 20, 2013
Author: bleny
Date: 2013-06-20 17:38:34 +0200 (Thu, 20 Jun 2013)
New Revision: 676
Url: http://nuiton.org/projects/sandbox/repository/revisions/676
Log:
add THIRD-PARTY.properties for nuiton-jpa-hibernate
Added:
nuiton-jpa/nuiton-jpa-hibernate/src/license/
nuiton-jpa/nuiton-jpa-hibernate/src/license/THIRD-PARTY.properties
Added: nuiton-jpa/nuiton-jpa-hibernate/src/license/THIRD-PARTY.properties
===================================================================
--- nuiton-jpa/nuiton-jpa-hibernate/src/license/THIRD-PARTY.properties (rev 0)
+++ nuiton-jpa/nuiton-jpa-hibernate/src/license/THIRD-PARTY.properties 2013-06-20 15:38:34 UTC (rev 676)
@@ -0,0 +1,21 @@
+# Generated by org.codehaus.mojo.license.AddThirdPartyMojo
+#-------------------------------------------------------------------------------
+# Already used licenses in project :
+# - Apache License 2.0
+# - BSD License
+# - COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
+# - GNU Lesser General Public License, version 2.1
+# - Indiana University Extreme! Lab Software License, vesion 1.1.1
+# - Lesser General Public License (LPGL)
+# - Lesser General Public License (LPGL) v 2.1
+# - MIT License
+# - MPL 1.1
+# - The Apache Software License, Version 2.0
+# - The H2 License, Version 1.0
+# - license.txt
+#-------------------------------------------------------------------------------
+# Please fill the missing licenses for dependencies :
+#
+#
+#Sat May 25 00:05:21 CEST 2013
+dom4j--dom4j--1.6.1=BSD License
1
0
r675 - nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate
by bleny@users.nuiton.org June 20, 2013
by bleny@users.nuiton.org June 20, 2013
June 20, 2013
Author: bleny
Date: 2013-06-20 17:06:11 +0200 (Thu, 20 Jun 2013)
New Revision: 675
Url: http://nuiton.org/projects/sandbox/repository/revisions/675
Log:
add a piece of documentation about how to enable OracleCompliantImprovedNamingStrategy
Modified:
nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategy.java
Modified: nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategy.java
===================================================================
--- nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategy.java 2013-06-20 15:03:28 UTC (rev 674)
+++ nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategy.java 2013-06-20 15:06:11 UTC (rev 675)
@@ -19,6 +19,11 @@
* the name can lead to collisions according to your classes and their attributes names
* </strong>
*
+ * To use it, add the following configuration in Hibernate:
+ *
+ * <pre>
+ * hibernate.ejb.naming_strategy=org.nuiton.jpa.hibernate.OracleCompliantImprovedNamingStrategy
+ * </pre>
*/
public class OracleCompliantImprovedNamingStrategy extends ImprovedNamingStrategy implements NamingStrategy {
1
0
Author: bleny
Date: 2013-06-20 17:03:28 +0200 (Thu, 20 Jun 2013)
New Revision: 674
Url: http://nuiton.org/projects/sandbox/repository/revisions/674
Log:
remove usage of markdown doxia module
Modified:
nuiton-jpa/pom.xml
Modified: nuiton-jpa/pom.xml
===================================================================
--- nuiton-jpa/pom.xml 2013-06-20 15:01:45 UTC (rev 673)
+++ nuiton-jpa/pom.xml 2013-06-20 15:03:28 UTC (rev 674)
@@ -162,9 +162,9 @@
<artifactId>maven-site-plugin</artifactId>
<dependencies>
<dependency>
- <groupId>org.apache.maven.doxia</groupId>
- <artifactId>doxia-module-markdown</artifactId>
- <version>1.3</version>
+ <groupId>org.nuiton.jrst</groupId>
+ <artifactId>doxia-module-jrst</artifactId>
+ <version>${jrstPluginVersion}</version>
</dependency>
</dependencies>
</plugin>
1
0
Author: bleny
Date: 2013-06-20 17:01:45 +0200 (Thu, 20 Jun 2013)
New Revision: 673
Url: http://nuiton.org/projects/sandbox/repository/revisions/673
Log:
introduce nuiton-jpa-hibernate module, moving HibernateUtil inside it, introduce OracleCompliantImprovedNamingStrategy
Added:
nuiton-jpa/nuiton-jpa-api/src/test/
nuiton-jpa/nuiton-jpa-api/src/test/java/
nuiton-jpa/nuiton-jpa-hibernate/
nuiton-jpa/nuiton-jpa-hibernate/LICENSE.txt
nuiton-jpa/nuiton-jpa-hibernate/README.txt
nuiton-jpa/nuiton-jpa-hibernate/changelog.txt
nuiton-jpa/nuiton-jpa-hibernate/pom.xml
nuiton-jpa/nuiton-jpa-hibernate/src/
nuiton-jpa/nuiton-jpa-hibernate/src/main/
nuiton-jpa/nuiton-jpa-hibernate/src/main/java/
nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/
nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/
nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/
nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/
nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/HibernateUtil.java
nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategy.java
nuiton-jpa/nuiton-jpa-hibernate/src/test/
nuiton-jpa/nuiton-jpa-hibernate/src/test/java/
nuiton-jpa/nuiton-jpa-hibernate/src/test/java/org/
nuiton-jpa/nuiton-jpa-hibernate/src/test/java/org/nuiton/
nuiton-jpa/nuiton-jpa-hibernate/src/test/java/org/nuiton/jpa/
nuiton-jpa/nuiton-jpa-hibernate/src/test/java/org/nuiton/jpa/hibernate/
nuiton-jpa/nuiton-jpa-hibernate/src/test/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategyTest.java
Removed:
nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/hibernate/
Modified:
nuiton-jpa/nuiton-jpa-api/pom.xml
nuiton-jpa/nuiton-jpa-junit/pom.xml
nuiton-jpa/nuiton-jpa-junit/src/main/java/org/nuiton/jpa/junit/JpaEntityManagerRule.java
nuiton-jpa/pom.xml
Modified: nuiton-jpa/nuiton-jpa-api/pom.xml
===================================================================
--- nuiton-jpa/nuiton-jpa-api/pom.xml 2013-06-19 07:57:46 UTC (rev 672)
+++ nuiton-jpa/nuiton-jpa-api/pom.xml 2013-06-20 15:01:45 UTC (rev 673)
@@ -22,16 +22,6 @@
</dependency>
<dependency>
- <groupId>org.hibernate</groupId>
- <artifactId>hibernate-core</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.hibernate</groupId>
- <artifactId>hibernate-entitymanager</artifactId>
- </dependency>
-
- <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
Property changes on: nuiton-jpa/nuiton-jpa-hibernate
___________________________________________________________________
Added: svn:ignore
+ target
*.iml
Added: nuiton-jpa/nuiton-jpa-hibernate/LICENSE.txt
===================================================================
--- nuiton-jpa/nuiton-jpa-hibernate/LICENSE.txt (rev 0)
+++ nuiton-jpa/nuiton-jpa-hibernate/LICENSE.txt 2013-06-20 15:01:45 UTC (rev 673)
@@ -0,0 +1,166 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
+
Added: nuiton-jpa/nuiton-jpa-hibernate/README.txt
===================================================================
Added: nuiton-jpa/nuiton-jpa-hibernate/changelog.txt
===================================================================
Added: nuiton-jpa/nuiton-jpa-hibernate/pom.xml
===================================================================
--- nuiton-jpa/nuiton-jpa-hibernate/pom.xml (rev 0)
+++ nuiton-jpa/nuiton-jpa-hibernate/pom.xml 2013-06-20 15:01:45 UTC (rev 673)
@@ -0,0 +1,61 @@
+<?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>
+
+ <parent>
+ <groupId>org.nuiton</groupId>
+ <artifactId>nuiton-jpa</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.nuiton.jpa</groupId>
+ <artifactId>nuiton-jpa-hibernate</artifactId>
+
+ <name>Nuiton Jpa :: Hibernate</name>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.hibernate</groupId>
+ <artifactId>hibernate-entitymanager</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+
+
+ </build>
+
+</project>
Copied: nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/HibernateUtil.java (from rev 672, nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/hibernate/HibernateUtil.java)
===================================================================
--- nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/HibernateUtil.java (rev 0)
+++ nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/HibernateUtil.java 2013-06-20 15:01:45 UTC (rev 673)
@@ -0,0 +1,159 @@
+package org.nuiton.jpa.hibernate;
+
+/*
+ * #%L
+ * nuiton-jpa-api
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2013 CodeLutin
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Lesser Public License for more details.
+ *
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/lgpl-3.0.html>.
+ * #L%
+ */
+
+import org.apache.commons.lang3.SystemUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.ejb.AvailableSettings;
+import org.hibernate.ejb.EntityManagerFactoryImpl;
+import org.hibernate.service.ServiceRegistry;
+import org.hibernate.service.internal.SessionFactoryServiceRegistryImpl;
+import org.hibernate.tool.hbm2ddl.SchemaExport;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import java.io.File;
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+public class HibernateUtil {
+
+ private static final Log log = LogFactory.getLog(HibernateUtil.class);
+
+ protected static final Map<String, String> HIBERNATE_H2_CONFIG;
+
+ public static final String HBM2DDL_AUTO_VALIDATE = "validate";
+
+ public static final String HBM2DDL_AUTO_CREATE_DROP = "create-drop";
+
+ public static final String HBM2DDL_AUTO_CREATE = "create";
+
+ public static final String HBM2DDL_AUTO_UPDATE = "update";
+
+ static {
+
+ Map<String, String> hibernateH2Config = new HashMap<String, String>();
+
+ hibernateH2Config.put(AvailableSettings.JDBC_DRIVER, org.h2.Driver.class.getName());
+ hibernateH2Config.put(AvailableSettings.JDBC_USER, "sa");
+ hibernateH2Config.put(AvailableSettings.JDBC_PASSWORD, "");
+ hibernateH2Config.put(Environment.DIALECT, org.hibernate.dialect.H2Dialect.class.getName());
+ hibernateH2Config.put(Environment.HBM2DDL_AUTO, HBM2DDL_AUTO_UPDATE);
+
+ HIBERNATE_H2_CONFIG = Collections.unmodifiableMap(hibernateH2Config);
+
+ }
+
+ private HibernateUtil() {
+ }
+
+ public static EntityManagerFactory createTempEntityManagerFactory(String persistenceUnitName, String context) {
+
+ EntityManagerFactory tempEntityManagerFactory =
+ createTempEntityManagerFactory(
+ persistenceUnitName,
+ context, Collections.<String, String>emptyMap());
+
+ return tempEntityManagerFactory;
+
+ }
+
+ public static EntityManagerFactory createTempEntityManagerFactory(String persistenceUnitName, String context, Map<String, String> jpaParameters) {
+
+ Map<String, String> allJpaParameters = new HashMap<String, String>();
+
+ allJpaParameters.putAll(jpaParameters);
+
+ allJpaParameters.putAll(HIBERNATE_H2_CONFIG);
+
+ File tempDirFile = SystemUtils.getJavaIoTmpDir();
+
+ File databaseFile = new File(tempDirFile, context);
+
+ String h2dataPath = databaseFile.getAbsolutePath() + File.separator + "h2data";
+
+ String jdbcUrl = "jdbc:h2:file:" + h2dataPath;
+
+ allJpaParameters.put(AvailableSettings.JDBC_URL, jdbcUrl);
+
+ if (log.isTraceEnabled()) {
+ log.trace("will store H2 data in " + h2dataPath);
+ log.trace("allJpaParameters = " + allJpaParameters);
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("jdbc url is\n" + jdbcUrl);
+ }
+
+ EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory(persistenceUnitName, allJpaParameters);
+
+ return entityManagerFactory;
+
+ }
+
+ public static void cleanDatabase(EntityManager entityManager) {
+
+ if (log.isInfoEnabled()) {
+ log.info("will clean database");
+ }
+
+ ServiceRegistry serviceRegistry =
+ ((EntityManagerFactoryImpl) entityManager.getEntityManagerFactory())
+ .getSessionFactory().getServiceRegistry();
+
+ Configuration configuration = null;
+ try {
+ Field configurationField = SessionFactoryServiceRegistryImpl.class.getDeclaredField("configuration");
+ configurationField.setAccessible(true);
+ configuration = (Configuration) configurationField.get(serviceRegistry);
+ } catch (IllegalAccessException e) {
+ if (log.isErrorEnabled()) {
+ log.error("should not occur", e);
+ }
+ } catch (NoSuchFieldException e) {
+ if (log.isErrorEnabled()) {
+ log.error("should not occur", e);
+ }
+ }
+
+ SchemaExport schemaExport = new SchemaExport(serviceRegistry, configuration);
+
+ schemaExport.setHaltOnError(true);
+
+ // drop
+ schemaExport.execute(true, true, true, false);
+
+ // create
+ schemaExport.execute(true, true, false, true);
+
+ }
+
+}
\ No newline at end of file
Property changes on: nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/HibernateUtil.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Added: nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategy.java
===================================================================
--- nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategy.java (rev 0)
+++ nuiton-jpa/nuiton-jpa-hibernate/src/main/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategy.java 2013-06-20 15:01:45 UTC (rev 673)
@@ -0,0 +1,122 @@
+package org.nuiton.jpa.hibernate;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.commons.lang3.StringUtils;
+import org.hibernate.cfg.ImprovedNamingStrategy;
+import org.hibernate.cfg.NamingStrategy;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Oracle doesn't support table names and columns names longer than 30 characters.
+ *
+ * This naming strategy solve the issue. <strong>This is not safe, since reducing
+ * the name can lead to collisions according to your classes and their attributes names
+ * </strong>
+ *
+ */
+public class OracleCompliantImprovedNamingStrategy extends ImprovedNamingStrategy implements NamingStrategy {
+
+ /**
+ * Arbitrary value fixed by Oracle.
+ *
+ * @link http://stackoverflow.com/questions/8701479/table-name-with-more-than-30-cha…
+ */
+ protected static final int MAXIMUM_IDENTIFIER_LENGTH = 30;
+
+ protected Map<String, String> cache = Maps.newConcurrentMap();
+
+ /**
+ * Given an identifier, return a similar identifier but no longer
+ * than MAXIMUM_IDENTIFIER_LENGTH. Some characters are removed
+ * at the end of each part of the identifier.
+ *
+ * Any given identifier shorter than MAXIMUM_IDENTIFIER_LENGTH
+ * will be returned as it.
+ *
+ * @param value a string that may contain some underscores
+ * @return a string that looks like given value but without
+ * removed characters in order to make the total
+ * length lower than MAXIMUM_IDENTIFIER_LENGTH
+ */
+ protected String getShortenedIdentifier(String value) {
+ String reducedValue = value;
+ if (value.length() > MAXIMUM_IDENTIFIER_LENGTH) {
+ reducedValue = cache.get(value);
+ if (reducedValue == null) {
+ reducedValue = shortenIdentifier(value);
+ cache.put(value, reducedValue);
+ }
+ }
+ return reducedValue;
+ }
+
+ protected String shortenIdentifier(String identifier) {
+ Iterable <String> split = Splitter.on('_').split(identifier);
+ int numberOfElements = Iterables.size(split);
+ int numberOfUnderscores = numberOfElements - 1;
+ int acceptedLengthForAnElement = (MAXIMUM_IDENTIFIER_LENGTH - numberOfUnderscores) / numberOfElements;
+ List<String> reducedElements = Lists.newLinkedList();
+ for (String element : split) {
+ reducedElements.add(StringUtils.left(element, acceptedLengthForAnElement));
+ }
+ String reducedIdentifier = Joiner.on('_').join(reducedElements);
+ return reducedIdentifier;
+ }
+
+ @Override
+ public String classToTableName(String className) {
+ return getShortenedIdentifier(super.classToTableName(className));
+ }
+
+ @Override
+ public String propertyToColumnName(String propertyName) {
+ return getShortenedIdentifier(super.propertyToColumnName(propertyName));
+ }
+
+ @Override
+ public String tableName(String tableName) {
+ return getShortenedIdentifier(super.tableName(tableName));
+ }
+
+ @Override
+ public String columnName(String columnName) {
+ return getShortenedIdentifier(super.columnName(columnName));
+ }
+
+ @Override
+ public String collectionTableName(String ownerEntity, String ownerEntityTable, String associatedEntity, String associatedEntityTable, String propertyName) {
+ return getShortenedIdentifier(super.collectionTableName(ownerEntity, ownerEntityTable, associatedEntity, associatedEntityTable, propertyName));
+ }
+
+ @Override
+ public String joinKeyColumnName(String joinedColumn, String joinedTable) {
+ return getShortenedIdentifier(super.joinKeyColumnName(joinedColumn, joinedTable));
+ }
+
+ @Override
+ public String foreignKeyColumnName(String propertyName, String propertyEntityName, String propertyTableName, String referencedColumnName) {
+ return getShortenedIdentifier(super.foreignKeyColumnName(propertyName, propertyEntityName, propertyTableName, referencedColumnName));
+ }
+
+ @Override
+ public String logicalColumnName(String columnName, String propertyName) {
+ return getShortenedIdentifier(super.logicalColumnName(columnName, propertyName));
+ }
+
+ @Override
+ public String logicalCollectionTableName(String tableName, String ownerEntityTable, String associatedEntityTable, String propertyName) {
+ return getShortenedIdentifier(super.logicalCollectionTableName(tableName, ownerEntityTable, associatedEntityTable, propertyName));
+ }
+
+ @Override
+ public String logicalCollectionColumnName(String columnName, String propertyName, String referencedColumn) {
+ return getShortenedIdentifier(super.logicalCollectionColumnName(columnName, propertyName, referencedColumn));
+ }
+
+}
Added: nuiton-jpa/nuiton-jpa-hibernate/src/test/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategyTest.java
===================================================================
--- nuiton-jpa/nuiton-jpa-hibernate/src/test/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategyTest.java (rev 0)
+++ nuiton-jpa/nuiton-jpa-hibernate/src/test/java/org/nuiton/jpa/hibernate/OracleCompliantImprovedNamingStrategyTest.java 2013-06-20 15:01:45 UTC (rev 673)
@@ -0,0 +1,82 @@
+package org.nuiton.jpa.hibernate;
+
+import org.apache.commons.lang3.StringUtils;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class OracleCompliantImprovedNamingStrategyTest {
+
+ protected OracleCompliantImprovedNamingStrategy oracleCompliantImprovedNamingStrategy = new OracleCompliantImprovedNamingStrategy();
+
+ @Test
+ public void testNamingStrategy() {
+
+ String className = getLongValue("LONG_CLASS_NAME_");
+
+ String ownerEntity = getLongValue("LONG_OWNER_ENTITY_");
+
+ String ownerEntityTable = getLongValue("LONG_OWNER_ENTITY_TABLE_");
+
+ String associatedEntity = getLongValue("LONG_ASSOCIATED_ENTITY_");
+
+ String associatedEntityTable = getLongValue("LONG_ASSOCIATED_ENTITY_TABLE_");
+
+ String propertyName = getLongValue("LONG_PROPERTY_NAME_");
+
+ String tableName = getLongValue("LONG_TABLE_NAME_");
+
+ String columnName = getLongValue("LONG_COLUMN_NAME_");
+
+ String propertyEntityName = getLongValue("LONG_PROPERTY_ENTITY_NAME");
+
+ String propertyTableName = getLongValue("LONG_PROPERTY_TABLE_NAME");
+
+ String referencedColumnName = getLongValue("LONG_REFERENCED_COLUMN_NAME");
+
+ String referencedColumn = getLongValue("LONG_REFERENCED_COLUMN");
+
+ String joinedColumn = getLongValue("LONG_JOINED_COLUMN");
+
+ String joinedTable = getLongValue("LONG_JOINED_TABLE");
+
+ check(oracleCompliantImprovedNamingStrategy.classToTableName(className));
+
+ check(oracleCompliantImprovedNamingStrategy.classToTableName("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
+
+ check(oracleCompliantImprovedNamingStrategy.collectionTableName(ownerEntity, ownerEntityTable, associatedEntity, associatedEntityTable, propertyName));
+
+ check(oracleCompliantImprovedNamingStrategy.logicalCollectionTableName(tableName, ownerEntityTable, associatedEntityTable, propertyName));
+
+ check(oracleCompliantImprovedNamingStrategy.columnName(columnName));
+
+ check(oracleCompliantImprovedNamingStrategy.tableName(tableName));
+
+ check(oracleCompliantImprovedNamingStrategy.foreignKeyColumnName(propertyName, propertyEntityName, propertyTableName, referencedColumnName));
+
+ check(oracleCompliantImprovedNamingStrategy.propertyToColumnName(propertyName));
+
+ check(oracleCompliantImprovedNamingStrategy.logicalCollectionColumnName(columnName, propertyName, referencedColumn));
+
+ check(oracleCompliantImprovedNamingStrategy.logicalColumnName(columnName, propertyName));
+
+ check(oracleCompliantImprovedNamingStrategy.joinKeyColumnName(joinedColumn, joinedTable));
+
+ }
+
+ protected void check(String reducedValue) {
+
+ Assert.assertFalse(
+ "'" + reducedValue + "' length (" + reducedValue.length() + ") is too long",
+ reducedValue.length() > oracleCompliantImprovedNamingStrategy.MAXIMUM_IDENTIFIER_LENGTH);
+
+ Assert.assertFalse(reducedValue.startsWith("_"));
+
+ Assert.assertFalse(reducedValue.endsWith("_"));
+
+ }
+
+ protected String getLongValue(String value) {
+ return StringUtils.rightPad(value, 50, "LONG");
+ }
+
+}
Modified: nuiton-jpa/nuiton-jpa-junit/pom.xml
===================================================================
--- nuiton-jpa/nuiton-jpa-junit/pom.xml 2013-06-19 07:57:46 UTC (rev 672)
+++ nuiton-jpa/nuiton-jpa-junit/pom.xml 2013-06-20 15:01:45 UTC (rev 673)
@@ -16,9 +16,10 @@
<dependencies>
+ <!-- fixme bleny 20/06/2013 we shouldn't rely on a particular implemetation of JPA -->
<dependency>
<groupId>${project.groupId}</groupId>
- <artifactId>nuiton-jpa-api</artifactId>
+ <artifactId>nuiton-jpa-hibernate</artifactId>
<version>${project.version}</version>
</dependency>
Modified: nuiton-jpa/nuiton-jpa-junit/src/main/java/org/nuiton/jpa/junit/JpaEntityManagerRule.java
===================================================================
--- nuiton-jpa/nuiton-jpa-junit/src/main/java/org/nuiton/jpa/junit/JpaEntityManagerRule.java 2013-06-19 07:57:46 UTC (rev 672)
+++ nuiton-jpa/nuiton-jpa-junit/src/main/java/org/nuiton/jpa/junit/JpaEntityManagerRule.java 2013-06-20 15:01:45 UTC (rev 673)
@@ -29,7 +29,7 @@
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
-import org.nuiton.jpa.api.hibernate.HibernateUtil;
+import org.nuiton.jpa.hibernate.HibernateUtil;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
Modified: nuiton-jpa/pom.xml
===================================================================
--- nuiton-jpa/pom.xml 2013-06-19 07:57:46 UTC (rev 672)
+++ nuiton-jpa/pom.xml 2013-06-20 15:01:45 UTC (rev 673)
@@ -47,6 +47,7 @@
<modules>
<module>nuiton-jpa-api</module>
+ <module>nuiton-jpa-hibernate</module>
<module>nuiton-jpa-junit</module>
<module>nuiton-jpa-templates</module>
</modules>
@@ -161,9 +162,9 @@
<artifactId>maven-site-plugin</artifactId>
<dependencies>
<dependency>
- <groupId>org.nuiton.jrst</groupId>
- <artifactId>doxia-module-jrst</artifactId>
- <version>${jrstPluginVersion}</version>
+ <groupId>org.apache.maven.doxia</groupId>
+ <artifactId>doxia-module-markdown</artifactId>
+ <version>1.3</version>
</dependency>
</dependencies>
</plugin>
1
0
r672 - in nuiton-jpa/nuiton-jpa-templates/src: it/magalie-with-generated-value/src/main/xmi main/java/org/nuiton/jpa/templates
by tchemit@users.nuiton.org June 19, 2013
by tchemit@users.nuiton.org June 19, 2013
June 19, 2013
Author: tchemit
Date: 2013-06-19 09:57:46 +0200 (Wed, 19 Jun 2013)
New Revision: 672
Url: http://nuiton.org/projects/sandbox/repository/revisions/672
Log:
add generate extra technical fields tag value
Modified:
nuiton-jpa/nuiton-jpa-templates/src/it/magalie-with-generated-value/src/main/xmi/magalie.properties
nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java
nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java
nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesTagValues.java
Modified: nuiton-jpa/nuiton-jpa-templates/src/it/magalie-with-generated-value/src/main/xmi/magalie.properties
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/it/magalie-with-generated-value/src/main/xmi/magalie.properties 2013-06-15 14:27:31 UTC (rev 671)
+++ nuiton-jpa/nuiton-jpa-templates/src/it/magalie-with-generated-value/src/main/xmi/magalie.properties 2013-06-19 07:57:46 UTC (rev 672)
@@ -24,6 +24,7 @@
model.tagValue.idFactory=true
model.tagValue.generatePropertyChangeListeners=true
model.tagValue.generateVisitors=true
+model.tagValue.generateExtraTechnicalFields=true
com.franciaflex.magalie.persistence.entity.Article.attribute.fixedLocations.stereotype=unique
Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java 2013-06-15 14:27:31 UTC (rev 671)
+++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java 2013-06-19 07:57:46 UTC (rev 672)
@@ -57,9 +57,11 @@
import javax.persistence.OneToOne;
import javax.persistence.OrderColumn;
import javax.persistence.PrePersist;
+import javax.persistence.Version;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.Collection;
+import java.util.Date;
import java.util.List;
import java.util.Set;
@@ -84,6 +86,10 @@
private static final Log log =
LogFactory.getLog(JpaEntityTransformer.class);
+ public static final String PROPERTY_VERSION = "version";
+
+ public static final String PROPERTY_CREATE_DATE = "createDate";
+
@Override
public void transformFromClass(ObjectModelClass input) {
@@ -238,11 +244,36 @@
idAttr.setType(String.class.getName());
properties.add(0, idAttr);
+ boolean generateTechnicalFields =
+ JpaTemplatesGeneratorUtil.useGenerateExtraTechnicalFields(getModel(), input);
+
+ if (generateTechnicalFields) {
+
+ // add version field
+ ObjectModelAttributeImpl versionAttr = new ObjectModelAttributeImpl();
+ versionAttr.setDeclaringElement(input);
+ versionAttr.setName(PROPERTY_VERSION);
+ versionAttr.setType(int.class.getName());
+ properties.add(1, versionAttr);
+
+ // add createDate field
+ ObjectModelAttributeImpl createDateAttr = new ObjectModelAttributeImpl();
+ createDateAttr.setDeclaringElement(input);
+ createDateAttr.setName(PROPERTY_CREATE_DATE);
+ createDateAttr.setType(Date.class.getName());
+ createDateAttr.setDefaultValue("new Date()");
+ properties.add(2, createDateAttr);
+ }
+
+
//TODO Si ORDERED ou et UNIQUE choisir le bon type de collection (O+U = LHS (laisser ça comme definition), (U = HS + S), (O = ArrayList +L), ( = ArrayList + C)
//TODO Si enumeration @Enumeration(value = EnumType.STRING) (Voir pour mettre une tag-value pour mettre en ordinal) + voir comment ça marche pour les collections
Multimap<ObjectModelAttribute, String> annotationsForAttributes =
- generateAnnotationsForProperties(input, output, properties);
+ generateAnnotationsForProperties(input,
+ output,
+ properties,
+ generateTechnicalFields);
// Add properties constant
for (ObjectModelAttribute attr : properties) {
@@ -308,7 +339,8 @@
protected Multimap<ObjectModelAttribute, String> generateAnnotationsForProperties(ObjectModelClass input,
ObjectModelClass output,
- List<ObjectModelAttribute> properties) {
+ List<ObjectModelAttribute> properties,
+ boolean generateTechnicalFields) {
ArrayListMultimap<ObjectModelAttribute, String> result =
ArrayListMultimap.create();
@@ -324,6 +356,12 @@
continue;
}
+ if (PROPERTY_VERSION.equals(propertyName) && generateTechnicalFields) {
+
+ addAnnotation(result, property, output, Version.class);
+ continue;
+ }
+
ObjectModelAttribute reverseAttribute =
property.getReverseAttribute();
@@ -566,7 +604,7 @@
ObjectModelAttribute attribute = addAttribute(output,
attrName,
attrType,
- "",
+ attr.getDefaultValue(),
ObjectModelJavaModifier.PROTECTED
);
Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java 2013-06-15 14:27:31 UTC (rev 671)
+++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java 2013-06-19 07:57:46 UTC (rev 672)
@@ -325,6 +325,26 @@
}
/**
+ * Obtain the value of the {@link JpaTemplatesTagValues#TAG_GENERATE_EXTRA_TECHNICAL_FIELDS}
+ * tag value on the given model.
+ *
+ * @param model model to seek
+ * @return the none empty value of the found tag value or {@code null}
+ * if not found nor empty.
+ * @see JpaTemplatesTagValues#TAG_GENERATE_EXTRA_TECHNICAL_FIELDS
+ * @since 0.1
+ */
+ public static String getGenerateExtraTechnicalFieldsTagValue(ObjectModel model, ObjectModelClassifier classifier) {
+ String value = findTagValue(JpaTemplatesTagValues.TAG_GENERATE_EXTRA_TECHNICAL_FIELDS, null, model);
+ return value;
+ }
+
+ public static boolean useGenerateExtraTechnicalFields(ObjectModel model,ObjectModelClassifier classifier) {
+ String value = getGenerateExtraTechnicalFieldsTagValue(model, classifier);
+ return ObjectUtils.equals("true", value);
+ }
+
+ /**
* Obtain the value of the {@link JpaTemplatesTagValues#TAG_ENTITY_SUPER_CLASS}
* tag value on the given model or classifier.
* <p/>
Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesTagValues.java
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesTagValues.java 2013-06-15 14:27:31 UTC (rev 671)
+++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesTagValues.java 2013-06-19 07:57:46 UTC (rev 672)
@@ -113,7 +113,7 @@
/**
* Tag value to generate visitors on entities if setted to {@code true}.
*
- * @see JpaTemplatesGeneratorUtil#getGeneratePropertyChangeListenersTagValue(ObjectModel)
+ * @see JpaTemplatesGeneratorUtil#getGenerateVisitorsTagValue(ObjectModel)
* @since 0.1
*/
@ModelPropertiesUtil.TagValueDefinition(
@@ -121,4 +121,17 @@
documentation = "Tag value to generate visitors on entities.")
String TAG_GENERATE_VISITORS = "generateVisitors";
+ /**
+ * Tag value to generate extra technical fields (version, createDate) for
+ * a specific entity or for all entities of a model.
+ *
+ * @see JpaTemplatesGeneratorUtil#getGenerateExtraTechnicalFieldsTagValue(ObjectModel, ObjectModelClassifier)
+ * @since 0.1
+ */
+ @ModelPropertiesUtil.TagValueDefinition(
+ target = {ObjectModel.class, ObjectModelClassifier.class},
+ documentation = "Tag value to generate extra technical fields (version, createDate) for \n" +
+ "a specific entity or for all entities of a model.")
+ String TAG_GENERATE_EXTRA_TECHNICAL_FIELDS = "generateExtraTechnicalFields";
+
}
1
0
r671 - in nuiton-jpa: nuiton-jpa-api/src/main/java/org/nuiton/jpa/api nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/hibernate nuiton-jpa-junit/src/main/java/org/nuiton/jpa/junit nuiton-jpa-templates/src/it/magalie-with-generated-value/src/main/xmi nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates
by tchemit@users.nuiton.org June 15, 2013
by tchemit@users.nuiton.org June 15, 2013
June 15, 2013
Author: tchemit
Date: 2013-06-15 16:27:31 +0200 (Sat, 15 Jun 2013)
New Revision: 671
Url: http://nuiton.org/projects/sandbox/repository/revisions/671
Log:
- add Entity visitor api
- improve entity template (deal with not null collection)
- reformat code + optimize dependencies
Added:
nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntityVisitable.java
nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntityVisitor.java
Modified:
nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaEntity.java
nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaDao.java
nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntities.java
nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/hibernate/HibernateUtil.java
nuiton-jpa/nuiton-jpa-junit/src/main/java/org/nuiton/jpa/junit/JpaEntityManagerRule.java
nuiton-jpa/nuiton-jpa-templates/src/it/magalie-with-generated-value/src/main/xmi/magalie.properties
nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/AbstractJpaTransformer.java
nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java
nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java
nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesTagValues.java
Modified: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaEntity.java
===================================================================
--- nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaEntity.java 2013-06-14 09:20:52 UTC (rev 670)
+++ nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaEntity.java 2013-06-15 14:27:31 UTC (rev 671)
@@ -33,7 +33,7 @@
* @author tchemit <chemit(a)codelutin.com>
* @since 0.1
*/
-public abstract class AbstractJpaEntity implements JpaEntity{
+public abstract class AbstractJpaEntity implements JpaEntity {
@Override
public boolean equals(Object other) {
Modified: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaDao.java
===================================================================
--- nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaDao.java 2013-06-14 09:20:52 UTC (rev 670)
+++ nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaDao.java 2013-06-15 14:27:31 UTC (rev 671)
@@ -30,7 +30,6 @@
* Represents de common operation we can do using JPA
*
* @param <E> is the type of the entity manipulated with this DAO
- *
* @author bleny <leny(a)codelutin.com>
* @author tchemit <chemit(a)codelutin.com>
* @since 0.1
Modified: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntities.java
===================================================================
--- nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntities.java 2013-06-14 09:20:52 UTC (rev 670)
+++ nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntities.java 2013-06-15 14:27:31 UTC (rev 671)
@@ -28,12 +28,10 @@
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
-import com.google.common.collect.Collections2;
import com.google.common.collect.Iterables;
import org.apache.commons.lang3.ObjectUtils;
import java.io.Serializable;
-import java.util.Collection;
import java.util.Comparator;
/**
Added: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntityVisitable.java
===================================================================
--- nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntityVisitable.java (rev 0)
+++ nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntityVisitable.java 2013-06-15 14:27:31 UTC (rev 671)
@@ -0,0 +1,37 @@
+
+package org.nuiton.jpa.api;
+
+/*
+ * #%L
+ * Nuiton Jpa :: API
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2013 CodeLutin
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Lesser Public License for more details.
+ *
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/lgpl-3.0.html>.
+ * #L%
+ */
+
+/**
+ * The contract of a visitable entity.
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 0.1
+ */
+public interface JpaEntityVisitable {
+
+ void accept(JpaEntityVisitor visitor);
+}
Property changes on: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntityVisitable.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Added: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntityVisitor.java
===================================================================
--- nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntityVisitor.java (rev 0)
+++ nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntityVisitor.java 2013-06-15 14:27:31 UTC (rev 671)
@@ -0,0 +1,37 @@
+
+package org.nuiton.jpa.api;
+
+/*
+ * #%L
+ * Nuiton Jpa :: API
+ * $Id$
+ * $HeadURL$
+ * %%
+ * Copyright (C) 2013 CodeLutin
+ * %%
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Lesser Public License for more details.
+ *
+ * You should have received a copy of the GNU General Lesser Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/lgpl-3.0.html>.
+ * #L%
+ */
+
+/**
+ * The contract of a visitor of any {@link JpaEntity}.
+ *
+ * @author tchemit <chemit(a)codelutin.com>
+ * @since 0.1
+ */
+public interface JpaEntityVisitor {
+
+ void visit(JpaEntity entity);
+}
Property changes on: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntityVisitor.java
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision HeadURL
Added: svn:eol-style
+ native
Modified: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/hibernate/HibernateUtil.java
===================================================================
--- nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/hibernate/HibernateUtil.java 2013-06-14 09:20:52 UTC (rev 670)
+++ nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/hibernate/HibernateUtil.java 2013-06-15 14:27:31 UTC (rev 671)
@@ -72,7 +72,8 @@
}
- private HibernateUtil() {}
+ private HibernateUtil() {
+ }
public static EntityManagerFactory createTempEntityManagerFactory(String persistenceUnitName, String context) {
@@ -143,7 +144,7 @@
}
}
- SchemaExport schemaExport= new SchemaExport(serviceRegistry, configuration);
+ SchemaExport schemaExport = new SchemaExport(serviceRegistry, configuration);
schemaExport.setHaltOnError(true);
Modified: nuiton-jpa/nuiton-jpa-junit/src/main/java/org/nuiton/jpa/junit/JpaEntityManagerRule.java
===================================================================
--- nuiton-jpa/nuiton-jpa-junit/src/main/java/org/nuiton/jpa/junit/JpaEntityManagerRule.java 2013-06-14 09:20:52 UTC (rev 670)
+++ nuiton-jpa/nuiton-jpa-junit/src/main/java/org/nuiton/jpa/junit/JpaEntityManagerRule.java 2013-06-15 14:27:31 UTC (rev 671)
@@ -42,7 +42,7 @@
protected String persistenceUnitName;
- protected String timestamp = String.valueOf(new Date().getTime());
+ protected static String timestamp = String.valueOf(new Date().getTime());
protected EntityManager entityManager;
@@ -64,7 +64,7 @@
if (log.isDebugEnabled()) {
log.debug("will create entityManager for test class "
- + testClassName + " and method " + testMethodName);
+ + testClassName + " and method " + testMethodName);
}
return new Statement() {
@@ -83,8 +83,8 @@
protected void createEntityManager(String testClassName, String testMethodName) {
String context = testClassName
- + '_' + testMethodName
- + '_' + timestamp;
+ + '_' + testMethodName
+ + '_' + timestamp;
EntityManagerFactory entityManagerFactory =
HibernateUtil.createTempEntityManagerFactory(
@@ -102,7 +102,7 @@
public EntityManager getEntityManager() {
- if ( ! open) {
+ if (!open) {
throw new IllegalStateException("entity manager is not yet opened");
}
@@ -110,9 +110,7 @@
}
- /**
- * Override to tear down your specific external resource.
- */
+ /** Override to tear down your specific external resource. */
protected void closeEntityManager() {
if (log.isDebugEnabled()) {
Modified: nuiton-jpa/nuiton-jpa-templates/src/it/magalie-with-generated-value/src/main/xmi/magalie.properties
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/it/magalie-with-generated-value/src/main/xmi/magalie.properties 2013-06-14 09:20:52 UTC (rev 670)
+++ nuiton-jpa/nuiton-jpa-templates/src/it/magalie-with-generated-value/src/main/xmi/magalie.properties 2013-06-15 14:27:31 UTC (rev 671)
@@ -23,6 +23,7 @@
###
model.tagValue.idFactory=true
model.tagValue.generatePropertyChangeListeners=true
+model.tagValue.generateVisitors=true
com.franciaflex.magalie.persistence.entity.Article.attribute.fixedLocations.stereotype=unique
Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/AbstractJpaTransformer.java
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/AbstractJpaTransformer.java 2013-06-14 09:20:52 UTC (rev 670)
+++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/AbstractJpaTransformer.java 2013-06-15 14:27:31 UTC (rev 671)
@@ -37,8 +37,6 @@
import org.nuiton.eugene.models.object.ObjectModelOperation;
import javax.persistence.EntityManager;
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
import java.io.Serializable;
import java.util.Collection;
import java.util.Set;
Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java 2013-06-14 09:20:52 UTC (rev 670)
+++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java 2013-06-15 14:27:31 UTC (rev 671)
@@ -41,6 +41,8 @@
import org.nuiton.jpa.api.JpaEntities;
import org.nuiton.jpa.api.JpaEntity;
import org.nuiton.jpa.api.JpaEntityIdFactoryResolver;
+import org.nuiton.jpa.api.JpaEntityVisitable;
+import org.nuiton.jpa.api.JpaEntityVisitor;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
@@ -198,8 +200,31 @@
);
}
- boolean usePCS = JpaTemplatesGeneratorUtil.useGeneratePropertyChangeListeners(getModel());
+ boolean generateVisitor =
+ JpaTemplatesGeneratorUtil.useGenerateVisitors(getModel());
+ if (generateVisitor) {
+ addInterface(output, JpaEntityVisitable.class);
+
+ // add accept method
+ ObjectModelOperation operation = addOperation(
+ output,
+ "accept",
+ void.class,
+ ObjectModelJavaModifier.PUBLIC);
+ addAnnotation(output, operation, Override.class);
+ addParameter(operation, JpaEntityVisitor.class, "visitor");
+ setOperationBody(operation, ""
+ /*{
+ visitor.visit(this);
+ }*/
+ );
+ }
+
+ boolean usePCS =
+ JpaTemplatesGeneratorUtil.useGeneratePropertyChangeListeners(
+ getModel());
+
Set<String> constantNames = addConstantsFromDependency(input, output);
// Get available properties
@@ -424,6 +449,12 @@
if (multiple) {
+ Class<?> collectionType =
+ JpaTemplatesGeneratorUtil.getCollectionType(attr);
+
+ Class<?> collectionInstanceType =
+ JpaTemplatesGeneratorUtil.getCollectionInstanceType(attr);
+
createGetChildMethod(output,
attrName,
attrType,
@@ -444,12 +475,14 @@
attrName,
attrType,
constantName,
+ collectionInstanceType,
usePCS);
createAddAllChildrenMethod(output,
attrName,
attrType,
constantName,
+ collectionInstanceType,
usePCS);
createRemoveChildMethod(output,
@@ -483,7 +516,6 @@
usePCS);
// Change type for Multiple attribute
- Class<?> collectionType = JpaTemplatesGeneratorUtil.getCollectionType(attr);
attrType = collectionType.getName() + "<" + attrType + ">";
simpleType = JpaTemplatesGeneratorUtil.getSimpleName(attrType);
@@ -635,6 +667,7 @@
String attrName,
String attrType,
String constantName,
+ Class<?> collectionInstanceType,
boolean usePCS) {
ObjectModelOperation operation = addOperation(
output,
@@ -643,11 +676,16 @@
ObjectModelJavaModifier.PUBLIC
);
addParameter(operation, attrType, attrName);
-
- String methodName = getJavaBeanMethodName("get", attrName);
+ addImport(output, collectionInstanceType);
+ String getMethodName = getJavaBeanMethodName("get", attrName);
+ String setMethodName = getJavaBeanMethodName("set", attrName);
+ String instanceName = collectionInstanceType.getSimpleName() + "<" + JpaTemplatesGeneratorUtil.getSimpleName(attrType) + ">";
StringBuilder buffer = new StringBuilder(""
/*{
- <%=methodName%>().add(<%=attrName%>);
+ if (<%=getMethodName%>() == null) {
+ <%=setMethodName%>(new <%=instanceName%>());
+ }
+ <%=getMethodName%>().add(<%=attrName%>);
}*/
);
if (usePCS) {
@@ -663,6 +701,7 @@
String attrName,
String attrType,
String constantName,
+ Class<?> collectionInstanceType,
boolean usePCS) {
ObjectModelOperation operation = addOperation(
output,
@@ -672,10 +711,15 @@
);
addParameter(operation, Collection.class.getName() + "<" + attrType + ">", attrName);
- String methodName = getJavaBeanMethodName("get", attrName);
+ String getMethodName = getJavaBeanMethodName("get", attrName);
+ String setMethodName = getJavaBeanMethodName("set", attrName);
+ String instanceName = collectionInstanceType.getSimpleName() + "<" + JpaTemplatesGeneratorUtil.getSimpleName(attrType) + ">";
StringBuilder buffer = new StringBuilder(""
/*{
- <%=methodName%>().addAll(<%=attrName%>);
+ if (<%=getMethodName%>() == null) {
+ <%=setMethodName%>(new <%=instanceName%>());
+ }
+ <%=getMethodName%>().addAll(<%=attrName%>);
}*/
);
if (usePCS) {
@@ -703,7 +747,7 @@
StringBuilder buffer = new StringBuilder();
buffer.append(""
/*{
- boolean removed = <%=methodName%>().remove(<%=attrName%>);}*/
+ boolean removed = <%=methodName%>() != null && <%=methodName%>().remove(<%=attrName%>);}*/
);
if (usePCS) {
@@ -739,7 +783,7 @@
String methodName = getJavaBeanMethodName("get", attrName);
buffer.append(""
/*{
- boolean removed = <%=methodName%>().removeAll(<%=attrName%>);}*/
+ boolean removed = <%=methodName%>() != null && <%=methodName%>().removeAll(<%=attrName%>);}*/
);
if (usePCS) {
@@ -775,7 +819,7 @@
String methodName = getJavaBeanMethodName("get", attrName);
buffer.append(""
/*{
- boolean contains = <%=methodName%>().contains(<%=attrName%>);
+ boolean contains = <%=methodName%>() != null && <%=methodName%>().contains(<%=attrName%>);
return contains;
}*/
);
@@ -796,10 +840,11 @@
);
addParameter(operation, "String", "id");
StringBuilder buffer = new StringBuilder();
+ String getMethodName = getJavaBeanMethodName("get", attrName);
String methodName = getJavaBeanMethodName("get", attrName + "ById");
buffer.append(""
/*{
- boolean contains = <%=methodName%>(id) != null;
+ boolean contains = <%=getMethodName%>() != null && <%=methodName%>(id) != null;
return contains;
}*/
);
@@ -820,10 +865,11 @@
);
addParameter(operation, Collection.class.getName() + "<" + attrType + ">", attrName);
StringBuilder buffer = new StringBuilder();
+ String getMethodName = getJavaBeanMethodName("get", attrName);
String methodName = getJavaBeanMethodName("get", attrName);
buffer.append(""
/*{
- boolean contains = <%=methodName%>().containsAll(<%=attrName%>);
+ boolean contains = <%=getMethodName%>() != null && <%=methodName%>().containsAll(<%=attrName%>);
return contains;
}*/
);
Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java 2013-06-14 09:20:52 UTC (rev 670)
+++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java 2013-06-15 14:27:31 UTC (rev 671)
@@ -36,6 +36,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -185,6 +186,35 @@
return result;
}
+ public static Class<?> getCollectionInstanceType(ObjectModelAttribute attr) {
+
+ boolean ordered = attr.isOrdered() ||
+ JpaTemplatesGeneratorUtil.hasOrderedStereotype(attr);
+ boolean unique = JpaTemplatesGeneratorUtil.hasUniqueStereotype(attr);
+
+ // Change type for Multiple attribute
+ Class<?> result;
+
+ if (ordered) {
+
+ if (unique) {
+
+ result = LinkedHashSet.class;
+ } else {
+
+ result = ArrayList.class;
+ }
+ } else {
+
+ if (unique) {
+ result = HashSet.class;
+ } else {
+ result = ArrayList.class;
+ }
+ }
+ return result;
+ }
+
public static boolean containsMutiple(Collection<ObjectModelAttribute> attributes) {
boolean result = false;
@@ -275,6 +305,26 @@
}
/**
+ * Obtain the value of the {@link JpaTemplatesTagValues#TAG_GENERATE_VISITORS}
+ * tag value on the given model.
+ *
+ * @param model model to seek
+ * @return the none empty value of the found tag value or {@code null}
+ * if not found nor empty.
+ * @see JpaTemplatesTagValues#TAG_GENERATE_VISITORS
+ * @since 0.1
+ */
+ public static String getGenerateVisitorsTagValue(ObjectModel model) {
+ String value = findTagValue(JpaTemplatesTagValues.TAG_GENERATE_VISITORS, null, model);
+ return value;
+ }
+
+ public static boolean useGenerateVisitors(ObjectModel model) {
+ String value = getGenerateVisitorsTagValue(model);
+ return ObjectUtils.equals("true", value);
+ }
+
+ /**
* Obtain the value of the {@link JpaTemplatesTagValues#TAG_ENTITY_SUPER_CLASS}
* tag value on the given model or classifier.
* <p/>
Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesTagValues.java
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesTagValues.java 2013-06-14 09:20:52 UTC (rev 670)
+++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesTagValues.java 2013-06-15 14:27:31 UTC (rev 671)
@@ -110,4 +110,15 @@
documentation = "Tag value to generate property change listeners on entities.")
String TAG_GENERATE_PROPERTY_CHANGE_LISTENERS = "generatePropertyChangeListeners";
+ /**
+ * Tag value to generate visitors on entities if setted to {@code true}.
+ *
+ * @see JpaTemplatesGeneratorUtil#getGeneratePropertyChangeListenersTagValue(ObjectModel)
+ * @since 0.1
+ */
+ @ModelPropertiesUtil.TagValueDefinition(
+ target = {ObjectModel.class},
+ documentation = "Tag value to generate visitors on entities.")
+ String TAG_GENERATE_VISITORS = "generateVisitors";
+
}
1
0
r670 - in WebTimer: . src src/angularJS src/angularJS/js src/angularJS/js/libs src/angularJS/js/libs/angular.js src/angularJS/partials src/canJs src/canJs/css src/canJs/js src/canJs/js/controls src/canJs/js/libs src/canJs/js/models src/canJs/views src/common src/common/css src/common/img
by kmorin@users.nuiton.org June 14, 2013
by kmorin@users.nuiton.org June 14, 2013
June 14, 2013
Author: kmorin
Date: 2013-06-14 11:20:52 +0200 (Fri, 14 Jun 2013)
New Revision: 670
Url: http://nuiton.org/projects/sandbox/repository/revisions/670
Log:
add sources
Added:
WebTimer/src/
WebTimer/src/angularJS/
WebTimer/src/angularJS/index.html
WebTimer/src/angularJS/js/
WebTimer/src/angularJS/js/app.js
WebTimer/src/angularJS/js/controllers.js
WebTimer/src/angularJS/js/filters.js
WebTimer/src/angularJS/js/libs/
WebTimer/src/angularJS/js/libs/angular.js/
WebTimer/src/angularJS/js/libs/angular.js/angular.min.js
WebTimer/src/angularJS/partials/
WebTimer/src/angularJS/partials/about.html
WebTimer/src/angularJS/partials/contact.html
WebTimer/src/angularJS/partials/tasks.html
WebTimer/src/canJs/
WebTimer/src/canJs/css/
WebTimer/src/canJs/css/app.css
WebTimer/src/canJs/index.html
WebTimer/src/canJs/js/
WebTimer/src/canJs/js/controls/
WebTimer/src/canJs/js/controls/content.js
WebTimer/src/canJs/js/controls/menu.js
WebTimer/src/canJs/js/libs/
WebTimer/src/canJs/js/libs/can.fixture.js
WebTimer/src/canJs/js/libs/can.jquery.js
WebTimer/src/canJs/js/libs/can.object.js
WebTimer/src/canJs/js/libs/can.observe.attributes.js
WebTimer/src/canJs/js/libs/can.observe.delegate.js
WebTimer/src/canJs/js/models/
WebTimer/src/canJs/js/models/tasks.js
WebTimer/src/canJs/views/
WebTimer/src/canJs/views/menu.ejs
WebTimer/src/canJs/views/tasks.ejs
WebTimer/src/canJs/views/tree_item_renderer_details.ejs
WebTimer/src/canJs/views/tree_item_renderer_name.ejs
WebTimer/src/common/
WebTimer/src/common/css/
WebTimer/src/common/css/app.css
WebTimer/src/common/css/bootstrap-responsive.css
WebTimer/src/common/css/bootstrap-responsive.min.css
WebTimer/src/common/css/bootstrap.css
WebTimer/src/common/css/bootstrap.min.css
WebTimer/src/common/img/
WebTimer/src/common/img/glyphicons-halflings-white.png
WebTimer/src/common/img/glyphicons-halflings.png
Modified:
WebTimer/
Property changes on: WebTimer
___________________________________________________________________
Added: svn:ignore
+ .idea
Added: WebTimer/src/angularJS/index.html
===================================================================
--- WebTimer/src/angularJS/index.html (rev 0)
+++ WebTimer/src/angularJS/index.html 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,31 @@
+<html lang="en" ng-app="webtimer">
+ <head>
+ <title></title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <link rel="stylesheet" href="../common/css/bootstrap.css">
+ <link rel="stylesheet" href="../common/css/app.css">
+
+ <script src="js/libs/angular.js/angular.min.js"></script>
+ <script src="js/app.js"></script>
+ <script src="js/controllers.js"></script>
+ <script src="js/filters.js"></script>
+ </head>
+ <body>
+ <div class="navbar navbar-inverse navbar-fixed-top">
+ <div class="navbar-inner">
+ <div class="container">
+ <a class="brand" href="#">WebTimer</a>
+ <div class="nav-collapse collapse">
+ <ul class="nav">
+ <li class="active"><a href="#">Home</a></li>
+ <li><a href="#about">About</a></li>
+ <li><a href="#contact">Contact</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div ng-view></div>
+ </body>
+</html>
Added: WebTimer/src/angularJS/js/app.js
===================================================================
--- WebTimer/src/angularJS/js/app.js (rev 0)
+++ WebTimer/src/angularJS/js/app.js 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,21 @@
+angular.module('webtimer', ['webtimerFilters'])
+ .config(['$routeProvider', function($routeProvider) {
+ $routeProvider.
+ when('/tasks', {templateUrl: 'partials/tasks.html', controller: TasksCtrl}).
+ when('/about', {templateUrl: 'partials/about.html'}).
+ when('/contact', {templateUrl: 'partials/contact.html'}).
+ otherwise({redirectTo: '/tasks'});
+ }])
+
+ .factory("$localStorage", function() {
+ return {
+ set: function(key, value) {
+ var item = angular.toJson(value);
+ window.localStorage.setItem(key, item);
+ },
+ get: function(key) {
+ var item = window.localStorage.getItem(key);
+ return angular.fromJson(item);
+ }
+ };
+ });
Added: WebTimer/src/angularJS/js/controllers.js
===================================================================
--- WebTimer/src/angularJS/js/controllers.js (rev 0)
+++ WebTimer/src/angularJS/js/controllers.js 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,98 @@
+function TasksCtrl($scope, $timeout, $localStorage) {
+ $scope.tasks = $localStorage.get("tasks");
+ if ($scope.tasks == null) {
+ $scope.tasks = [];
+ }
+
+ var save = function() {
+ $localStorage.set("tasks", $scope.tasks);
+ };
+
+ var refresh = function() {
+ $timeout(function() {
+ if ($scope.currentTask) {
+ var now = new Date();
+ $scope.currentTask.time += now - $scope.currentTaskDate;
+ $scope.currentTaskDate = now;
+ save();
+ }
+ refresh();
+ }, 100);
+ };
+ refresh();
+
+ $scope.addTask = function() {
+ $scope.tasks.push({
+ "name" : $scope.name,
+ "time" : 0,
+ "tags" : [],
+ "subtasks" : [],
+ "childrenVisibility" : true
+ });
+ $scope.name = "";
+ save();
+ };
+
+ $scope.addSubTask = function(task) {
+ if (task.subtasks == null) {
+ task.subtasks = [];
+ }
+
+ task.subtasks.push({
+ "name" : "New task",
+ "time" : 0,
+ "tags" : [],
+ "subtasks" : [],
+ "childrenVisibility" : true
+ });
+ task.childrenVisibility = true;
+ save();
+ };
+
+ $scope.removeTask = function(task, tasks) {
+ if (tasks == null) {
+ return;
+ }
+
+ for (var position = 0 ; position < tasks.length ; position ++) {
+ var current = tasks[position];
+ if (current === task) {
+ tasks.splice(position, 1);
+ break;
+ }
+ $scope.removeTask(task, current.subtasks);
+ }
+ save();
+ };
+
+ $scope.editTask = function(task, type) {
+ task.edit = type;
+ save();
+ };
+
+ $scope.saveTask = function(task) {
+ task.edit = null;
+ save();
+ };
+
+ $scope.changeTask = function(task) {
+ task.childrenVisibility = !task.childrenVisibility;
+ save();
+ };
+
+ $scope.timeTask = function(task, element) {
+ var now = new Date();
+ if ($scope.currentTask) {
+ $scope.currentTask.time += now - $scope.currentTaskDate;
+ }
+
+ if ($scope.currentTask != task) {
+ $scope.currentTask = task;
+ $scope.currentTaskDate = now;
+ } else {
+ $scope.currentTask = null;
+ $scope.currentTaskDate = null;
+ }
+ save();
+ };
+}
Added: WebTimer/src/angularJS/js/filters.js
===================================================================
--- WebTimer/src/angularJS/js/filters.js (rev 0)
+++ WebTimer/src/angularJS/js/filters.js 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,9 @@
+angular.module('webtimerFilters', []).filter('time', function() {
+ return function(input) {
+ var date = new Date(input);
+ return date.getUTCHours()
+ + ":" + date.getUTCMinutes()
+ + ":" + date.getUTCSeconds()
+ + "." + date.getUTCMilliseconds();
+ };
+});
Added: WebTimer/src/angularJS/js/libs/angular.js/angular.min.js
===================================================================
--- WebTimer/src/angularJS/js/libs/angular.js/angular.min.js (rev 0)
+++ WebTimer/src/angularJS/js/libs/angular.js/angular.min.js 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,178 @@
+/*
+ AngularJS v1.1.5
+ (c) 2010-2012 Google, Inc. http://angularjs.org
+ License: MIT
+*/
+(function(M,T,p){'use strict';function lc(){var b=M.angular;M.angular=mc;return b}function Xa(b){return!b||typeof b.length!=="number"?!1:typeof b.hasOwnProperty!="function"&&typeof b.constructor!="function"?!0:b instanceof R||ga&&b instanceof ga||Ea.call(b)!=="[object Object]"||typeof b.callee==="function"}function n(b,a,c){var d;if(b)if(H(b))for(d in b)d!="prototype"&&d!="length"&&d!="name"&&b.hasOwnProperty(d)&&a.call(c,b[d],d);else if(b.forEach&&b.forEach!==n)b.forEach(a,c);else if(Xa(b))for(d=
+0;d<b.length;d++)a.call(c,b[d],d);else for(d in b)b.hasOwnProperty(d)&&a.call(c,b[d],d);return b}function qb(b){var a=[],c;for(c in b)b.hasOwnProperty(c)&&a.push(c);return a.sort()}function nc(b,a,c){for(var d=qb(b),e=0;e<d.length;e++)a.call(c,b[d[e]],d[e]);return d}function rb(b){return function(a,c){b(c,a)}}function Fa(){for(var b=ba.length,a;b;){b--;a=ba[b].charCodeAt(0);if(a==57)return ba[b]="A",ba.join("");if(a==90)ba[b]="0";else return ba[b]=String.fromCharCode(a+1),ba.join("")}ba.unshift("0");
+return ba.join("")}function sb(b,a){a?b.$$hashKey=a:delete b.$$hashKey}function t(b){var a=b.$$hashKey;n(arguments,function(a){a!==b&&n(a,function(a,c){b[c]=a})});sb(b,a);return b}function N(b){return parseInt(b,10)}function tb(b,a){return t(new (t(function(){},{prototype:b})),a)}function q(){}function qa(b){return b}function S(b){return function(){return b}}function C(b){return typeof b=="undefined"}function B(b){return typeof b!="undefined"}function L(b){return b!=null&&typeof b=="object"}function E(b){return typeof b==
+"string"}function Ya(b){return typeof b=="number"}function ra(b){return Ea.apply(b)=="[object Date]"}function F(b){return Ea.apply(b)=="[object Array]"}function H(b){return typeof b=="function"}function sa(b){return b&&b.document&&b.location&&b.alert&&b.setInterval}function U(b){return E(b)?b.replace(/^\s*/,"").replace(/\s*$/,""):b}function oc(b){return b&&(b.nodeName||b.bind&&b.find)}function Za(b,a,c){var d=[];n(b,function(b,g,i){d.push(a.call(c,b,g,i))});return d}function Ga(b,a){if(b.indexOf)return b.indexOf(a);
+for(var c=0;c<b.length;c++)if(a===b[c])return c;return-1}function ta(b,a){var c=Ga(b,a);c>=0&&b.splice(c,1);return a}function V(b,a){if(sa(b)||b&&b.$evalAsync&&b.$watch)throw Error("Can't copy Window or Scope");if(a){if(b===a)throw Error("Can't copy equivalent objects or arrays");if(F(b))for(var c=a.length=0;c<b.length;c++)a.push(V(b[c]));else{c=a.$$hashKey;n(a,function(b,c){delete a[c]});for(var d in b)a[d]=V(b[d]);sb(a,c)}}else(a=b)&&(F(b)?a=V(b,[]):ra(b)?a=new Date(b.getTime()):L(b)&&(a=V(b,{})));
+return a}function pc(b,a){var a=a||{},c;for(c in b)b.hasOwnProperty(c)&&c.substr(0,2)!=="$$"&&(a[c]=b[c]);return a}function ia(b,a){if(b===a)return!0;if(b===null||a===null)return!1;if(b!==b&&a!==a)return!0;var c=typeof b,d;if(c==typeof a&&c=="object")if(F(b)){if((c=b.length)==a.length){for(d=0;d<c;d++)if(!ia(b[d],a[d]))return!1;return!0}}else if(ra(b))return ra(a)&&b.getTime()==a.getTime();else{if(b&&b.$evalAsync&&b.$watch||a&&a.$evalAsync&&a.$watch||sa(b)||sa(a))return!1;c={};for(d in b)if(!(d.charAt(0)===
+"$"||H(b[d]))){if(!ia(b[d],a[d]))return!1;c[d]=!0}for(d in a)if(!c[d]&&d.charAt(0)!=="$"&&a[d]!==p&&!H(a[d]))return!1;return!0}return!1}function $a(b,a){var c=arguments.length>2?ka.call(arguments,2):[];return H(a)&&!(a instanceof RegExp)?c.length?function(){return arguments.length?a.apply(b,c.concat(ka.call(arguments,0))):a.apply(b,c)}:function(){return arguments.length?a.apply(b,arguments):a.call(b)}:a}function qc(b,a){var c=a;/^\$+/.test(b)?c=p:sa(a)?c="$WINDOW":a&&T===a?c="$DOCUMENT":a&&a.$evalAsync&&
+a.$watch&&(c="$SCOPE");return c}function ha(b,a){return JSON.stringify(b,qc,a?" ":null)}function ub(b){return E(b)?JSON.parse(b):b}function ua(b){b&&b.length!==0?(b=I(""+b),b=!(b=="f"||b=="0"||b=="false"||b=="no"||b=="n"||b=="[]")):b=!1;return b}function va(b){b=w(b).clone();try{b.html("")}catch(a){}var c=w("<div>").append(b).html();try{return b[0].nodeType===3?I(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+I(b)})}catch(d){return I(c)}}function vb(b){var a={},c,d;n((b||
+"").split("&"),function(b){b&&(c=b.split("="),d=decodeURIComponent(c[0]),a[d]=B(c[1])?decodeURIComponent(c[1]):!0)});return a}function wb(b){var a=[];n(b,function(b,d){a.push(wa(d,!0)+(b===!0?"":"="+wa(b,!0)))});return a.length?a.join("&"):""}function ab(b){return wa(b,!0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function wa(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,a?"%20":"+")}function rc(b,
+a){function c(a){a&&d.push(a)}var d=[b],e,g,i=["ng:app","ng-app","x-ng-app","data-ng-app"],f=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;n(i,function(a){i[a]=!0;c(T.getElementById(a));a=a.replace(":","\\:");b.querySelectorAll&&(n(b.querySelectorAll("."+a),c),n(b.querySelectorAll("."+a+"\\:"),c),n(b.querySelectorAll("["+a+"]"),c))});n(d,function(a){if(!e){var b=f.exec(" "+a.className+" ");b?(e=a,g=(b[2]||"").replace(/\s+/g,",")):n(a.attributes,function(b){if(!e&&i[b.name])e=a,g=b.value})}});e&&a(e,g?[g]:[])}
+function xb(b,a){var c=function(){b=w(b);a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);a.unshift("ng");var c=yb(a);c.invoke(["$rootScope","$rootElement","$compile","$injector","$animator",function(a,b,c,d,e){a.$apply(function(){b.data("$injector",d);c(b)(a)});e.enabled(!0)}]);return c},d=/^NG_DEFER_BOOTSTRAP!/;if(M&&!d.test(M.name))return c();M.name=M.name.replace(d,"");Ha.resumeBootstrap=function(b){n(b,function(b){a.push(b)});c()}}function bb(b,a){a=a||"_";return b.replace(sc,
+function(b,d){return(d?a:"")+b.toLowerCase()})}function cb(b,a,c){if(!b)throw Error("Argument '"+(a||"?")+"' is "+(c||"required"));return b}function xa(b,a,c){c&&F(b)&&(b=b[b.length-1]);cb(H(b),a,"not a function, got "+(b&&typeof b=="object"?b.constructor.name||"Object":typeof b));return b}function tc(b){function a(a,b,e){return a[b]||(a[b]=e())}return a(a(b,"angular",Object),"module",function(){var b={};return function(d,e,g){e&&b.hasOwnProperty(d)&&(b[d]=null);return a(b,d,function(){function a(c,
+d,e){return function(){b[e||"push"]([c,d,arguments]);return m}}if(!e)throw Error("No module: "+d);var b=[],c=[],j=a("$injector","invoke"),m={_invokeQueue:b,_runBlocks:c,requires:e,name:d,provider:a("$provide","provider"),factory:a("$provide","factory"),service:a("$provide","service"),value:a("$provide","value"),constant:a("$provide","constant","unshift"),animation:a("$animationProvider","register"),filter:a("$filterProvider","register"),controller:a("$controllerProvider","register"),directive:a("$compileProvider",
+"directive"),config:j,run:function(a){c.push(a);return this}};g&&j(g);return m})}})}function Ia(b){return b.replace(uc,function(a,b,d,e){return e?d.toUpperCase():d}).replace(vc,"Moz$1")}function db(b,a){function c(){var e;for(var b=[this],c=a,i,f,h,j,m,k;b.length;){i=b.shift();f=0;for(h=i.length;f<h;f++){j=w(i[f]);c?j.triggerHandler("$destroy"):c=!c;m=0;for(e=(k=j.children()).length,j=e;m<j;m++)b.push(ga(k[m]))}}return d.apply(this,arguments)}var d=ga.fn[b],d=d.$original||d;c.$original=d;ga.fn[b]=
+c}function R(b){if(b instanceof R)return b;if(!(this instanceof R)){if(E(b)&&b.charAt(0)!="<")throw Error("selectors not implemented");return new R(b)}if(E(b)){var a=T.createElement("div");a.innerHTML="<div> </div>"+b;a.removeChild(a.firstChild);eb(this,a.childNodes);this.remove()}else eb(this,b)}function fb(b){return b.cloneNode(!0)}function ya(b){zb(b);for(var a=0,b=b.childNodes||[];a<b.length;a++)ya(b[a])}function Ab(b,a,c){var d=ca(b,"events");ca(b,"handle")&&(C(a)?n(d,function(a,c){gb(b,
+c,a);delete d[c]}):C(c)?(gb(b,a,d[a]),delete d[a]):ta(d[a],c))}function zb(b){var a=b[Ja],c=Ka[a];c&&(c.handle&&(c.events.$destroy&&c.handle({},"$destroy"),Ab(b)),delete Ka[a],b[Ja]=p)}function ca(b,a,c){var d=b[Ja],d=Ka[d||-1];if(B(c))d||(b[Ja]=d=++wc,d=Ka[d]={}),d[a]=c;else return d&&d[a]}function Bb(b,a,c){var d=ca(b,"data"),e=B(c),g=!e&&B(a),i=g&&!L(a);!d&&!i&&ca(b,"data",d={});if(e)d[a]=c;else if(g)if(i)return d&&d[a];else t(d,a);else return d}function La(b,a){return(" "+b.className+" ").replace(/[\n\t]/g,
+" ").indexOf(" "+a+" ")>-1}function Cb(b,a){a&&n(a.split(" "),function(a){b.className=U((" "+b.className+" ").replace(/[\n\t]/g," ").replace(" "+U(a)+" "," "))})}function Db(b,a){a&&n(a.split(" "),function(a){if(!La(b,a))b.className=U(b.className+" "+U(a))})}function eb(b,a){if(a)for(var a=!a.nodeName&&B(a.length)&&!sa(a)?a:[a],c=0;c<a.length;c++)b.push(a[c])}function Eb(b,a){return Ma(b,"$"+(a||"ngController")+"Controller")}function Ma(b,a,c){b=w(b);for(b[0].nodeType==9&&(b=b.find("html"));b.length;){if(c=
+b.data(a))return c;b=b.parent()}}function Fb(b,a){var c=Na[a.toLowerCase()];return c&&Gb[b.nodeName]&&c}function xc(b,a){var c=function(c,e){if(!c.preventDefault)c.preventDefault=function(){c.returnValue=!1};if(!c.stopPropagation)c.stopPropagation=function(){c.cancelBubble=!0};if(!c.target)c.target=c.srcElement||T;if(C(c.defaultPrevented)){var g=c.preventDefault;c.preventDefault=function(){c.defaultPrevented=!0;g.call(c)};c.defaultPrevented=!1}c.isDefaultPrevented=function(){return c.defaultPrevented||
+c.returnValue==!1};n(a[e||c.type],function(a){a.call(b,c)});Z<=8?(c.preventDefault=null,c.stopPropagation=null,c.isDefaultPrevented=null):(delete c.preventDefault,delete c.stopPropagation,delete c.isDefaultPrevented)};c.elem=b;return c}function la(b){var a=typeof b,c;if(a=="object"&&b!==null)if(typeof(c=b.$$hashKey)=="function")c=b.$$hashKey();else{if(c===p)c=b.$$hashKey=Fa()}else c=b;return a+":"+c}function za(b){n(b,this.put,this)}function Hb(b){var a,c;if(typeof b=="function"){if(!(a=b.$inject))a=
+[],c=b.toString().replace(yc,""),c=c.match(zc),n(c[1].split(Ac),function(b){b.replace(Bc,function(b,c,d){a.push(d)})}),b.$inject=a}else F(b)?(c=b.length-1,xa(b[c],"fn"),a=b.slice(0,c)):xa(b,"fn",!0);return a}function yb(b){function a(a){return function(b,c){if(L(b))n(b,rb(a));else return a(b,c)}}function c(a,b){if(H(b)||F(b))b=k.instantiate(b);if(!b.$get)throw Error("Provider "+a+" must define $get factory method.");return m[a+f]=b}function d(a,b){return c(a,{$get:b})}function e(a){var b=[];n(a,function(a){if(!j.get(a))if(j.put(a,
+!0),E(a)){var c=Aa(a);b=b.concat(e(c.requires)).concat(c._runBlocks);try{for(var d=c._invokeQueue,c=0,f=d.length;c<f;c++){var g=d[c],o=k.get(g[0]);o[g[1]].apply(o,g[2])}}catch(h){throw h.message&&(h.message+=" from "+a),h;}}else if(H(a))try{b.push(k.invoke(a))}catch(l){throw l.message&&(l.message+=" from "+a),l;}else if(F(a))try{b.push(k.invoke(a))}catch(i){throw i.message&&(i.message+=" from "+String(a[a.length-1])),i;}else xa(a,"module")});return b}function g(a,b){function c(d){if(typeof d!=="string")throw Error("Service name expected");
+if(a.hasOwnProperty(d)){if(a[d]===i)throw Error("Circular dependency: "+h.join(" <- "));return a[d]}else try{return h.unshift(d),a[d]=i,a[d]=b(d)}finally{h.shift()}}function d(a,b,e){var f=[],j=Hb(a),g,o,h;o=0;for(g=j.length;o<g;o++)h=j[o],f.push(e&&e.hasOwnProperty(h)?e[h]:c(h));a.$inject||(a=a[g]);switch(b?-1:f.length){case 0:return a();case 1:return a(f[0]);case 2:return a(f[0],f[1]);case 3:return a(f[0],f[1],f[2]);case 4:return a(f[0],f[1],f[2],f[3]);case 5:return a(f[0],f[1],f[2],f[3],f[4]);
+case 6:return a(f[0],f[1],f[2],f[3],f[4],f[5]);case 7:return a(f[0],f[1],f[2],f[3],f[4],f[5],f[6]);case 8:return a(f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7]);case 9:return a(f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8]);case 10:return a(f[0],f[1],f[2],f[3],f[4],f[5],f[6],f[7],f[8],f[9]);default:return a.apply(b,f)}}return{invoke:d,instantiate:function(a,b){var c=function(){},e;c.prototype=(F(a)?a[a.length-1]:a).prototype;c=new c;e=d(a,c,b);return L(e)?e:c},get:c,annotate:Hb,has:function(b){return m.hasOwnProperty(b+
+f)||a.hasOwnProperty(b)}}}var i={},f="Provider",h=[],j=new za,m={$provide:{provider:a(c),factory:a(d),service:a(function(a,b){return d(a,["$injector",function(a){return a.instantiate(b)}])}),value:a(function(a,b){return d(a,S(b))}),constant:a(function(a,b){m[a]=b;l[a]=b}),decorator:function(a,b){var c=k.get(a+f),d=c.$get;c.$get=function(){var a=u.invoke(d,c);return u.invoke(b,null,{$delegate:a})}}}},k=m.$injector=g(m,function(){throw Error("Unknown provider: "+h.join(" <- "));}),l={},u=l.$injector=
+g(l,function(a){a=k.get(a+f);return u.invoke(a.$get,a)});n(e(b),function(a){u.invoke(a||q)});return u}function Cc(){var b=!0;this.disableAutoScrolling=function(){b=!1};this.$get=["$window","$location","$rootScope",function(a,c,d){function e(a){var b=null;n(a,function(a){!b&&I(a.nodeName)==="a"&&(b=a)});return b}function g(){var b=c.hash(),d;b?(d=i.getElementById(b))?d.scrollIntoView():(d=e(i.getElementsByName(b)))?d.scrollIntoView():b==="top"&&a.scrollTo(0,0):a.scrollTo(0,0)}var i=a.document;b&&d.$watch(function(){return c.hash()},
+function(){d.$evalAsync(g)});return g}]}function Ib(b){this.register=function(a,c){b.factory(Ia(a)+"Animation",c)};this.$get=["$injector",function(a){return function(b){if(b&&(b=Ia(b)+"Animation",a.has(b)))return a.get(b)}}]}function Dc(b,a,c,d){function e(a){try{a.apply(null,ka.call(arguments,1))}finally{if(o--,o===0)for(;z.length;)try{z.pop()()}catch(b){c.error(b)}}}function g(a,b){(function s(){n(r,function(a){a()});y=b(s,a)})()}function i(){x!=f.url()&&(x=f.url(),n(v,function(a){a(f.url())}))}
+var f=this,h=a[0],j=b.location,m=b.history,k=b.setTimeout,l=b.clearTimeout,u={};f.isMock=!1;var o=0,z=[];f.$$completeOutstandingRequest=e;f.$$incOutstandingRequestCount=function(){o++};f.notifyWhenNoOutstandingRequests=function(a){n(r,function(a){a()});o===0?a():z.push(a)};var r=[],y;f.addPollFn=function(a){C(y)&&g(100,k);r.push(a);return a};var x=j.href,W=a.find("base");f.url=function(a,b){if(a){if(x!=a)return x=a,d.history?b?m.replaceState(null,"",a):(m.pushState(null,"",a),W.attr("href",W.attr("href"))):
+b?j.replace(a):j.href=a,f}else return j.href.replace(/%27/g,"'")};var v=[],A=!1;f.onUrlChange=function(a){A||(d.history&&w(b).bind("popstate",i),d.hashchange?w(b).bind("hashchange",i):f.addPollFn(i),A=!0);v.push(a);return a};f.baseHref=function(){var a=W.attr("href");return a?a.replace(/^https?\:\/\/[^\/]*/,""):""};var G={},D="",$=f.baseHref();f.cookies=function(a,b){var d,e,f,j;if(a)if(b===p)h.cookie=escape(a)+"=;path="+$+";expires=Thu, 01 Jan 1970 00:00:00 GMT";else{if(E(b))d=(h.cookie=escape(a)+
+"="+escape(b)+";path="+$).length+1,d>4096&&c.warn("Cookie '"+a+"' possibly not set or overflowed because it was too large ("+d+" > 4096 bytes)!")}else{if(h.cookie!==D){D=h.cookie;d=D.split("; ");G={};for(f=0;f<d.length;f++)e=d[f],j=e.indexOf("="),j>0&&(a=unescape(e.substring(0,j)),G[a]===p&&(G[a]=unescape(e.substring(j+1))))}return G}};f.defer=function(a,b){var c;o++;c=k(function(){delete u[c];e(a)},b||0);u[c]=!0;return c};f.defer.cancel=function(a){return u[a]?(delete u[a],l(a),e(q),!0):!1}}function Ec(){this.$get=
+["$window","$log","$sniffer","$document",function(b,a,c,d){return new Dc(b,d,a,c)}]}function Fc(){this.$get=function(){function b(b,d){function e(a){if(a!=k){if(l){if(l==a)l=a.n}else l=a;g(a.n,a.p);g(a,k);k=a;k.n=null}}function g(a,b){if(a!=b){if(a)a.p=b;if(b)b.n=a}}if(b in a)throw Error("cacheId "+b+" taken");var i=0,f=t({},d,{id:b}),h={},j=d&&d.capacity||Number.MAX_VALUE,m={},k=null,l=null;return a[b]={put:function(a,b){var c=m[a]||(m[a]={key:a});e(c);if(!C(b))return a in h||i++,h[a]=b,i>j&&this.remove(l.key),
+b},get:function(a){var b=m[a];if(b)return e(b),h[a]},remove:function(a){var b=m[a];if(b){if(b==k)k=b.p;if(b==l)l=b.n;g(b.n,b.p);delete m[a];delete h[a];i--}},removeAll:function(){h={};i=0;m={};k=l=null},destroy:function(){m=f=h=null;delete a[b]},info:function(){return t({},f,{size:i})}}}var a={};b.info=function(){var b={};n(a,function(a,e){b[e]=a.info()});return b};b.get=function(b){return a[b]};return b}}function Gc(){this.$get=["$cacheFactory",function(b){return b("templates")}]}function Jb(b){var a=
+{},c="Directive",d=/^\s*directive\:\s*([\d\w\-_]+)\s+(.*)$/,e=/(([\d\w\-_]+)(?:\:([^;]+))?;?)/,g="Template must have exactly one root element. was: ",i=/^\s*(https?|ftp|mailto|file):/;this.directive=function h(d,e){E(d)?(cb(e,"directive"),a.hasOwnProperty(d)||(a[d]=[],b.factory(d+c,["$injector","$exceptionHandler",function(b,c){var e=[];n(a[d],function(a){try{var g=b.invoke(a);if(H(g))g={compile:S(g)};else if(!g.compile&&g.link)g.compile=S(g.link);g.priority=g.priority||0;g.name=g.name||d;g.require=
+g.require||g.controller&&g.name;g.restrict=g.restrict||"A";e.push(g)}catch(h){c(h)}});return e}])),a[d].push(e)):n(d,rb(h));return this};this.urlSanitizationWhitelist=function(a){return B(a)?(i=a,this):i};this.$get=["$injector","$interpolate","$exceptionHandler","$http","$templateCache","$parse","$controller","$rootScope","$document",function(b,j,m,k,l,u,o,z,r){function y(a,b,c){a instanceof w||(a=w(a));n(a,function(b,c){b.nodeType==3&&b.nodeValue.match(/\S+/)&&(a[c]=w(b).wrap("<span></span>").parent()[0])});
+var d=W(a,b,a,c);return function(b,c){cb(b,"scope");for(var e=c?Ba.clone.call(a):a,j=0,g=e.length;j<g;j++){var h=e[j];(h.nodeType==1||h.nodeType==9)&&e.eq(j).data("$scope",b)}x(e,"ng-scope");c&&c(e,b);d&&d(b,e,e);return e}}function x(a,b){try{a.addClass(b)}catch(c){}}function W(a,b,c,d){function e(a,c,d,g){var h,i,k,l,o,m,u,z=[];o=0;for(m=c.length;o<m;o++)z.push(c[o]);u=o=0;for(m=j.length;o<m;u++)i=z[u],c=j[o++],h=j[o++],c?(c.scope?(k=a.$new(L(c.scope)),w(i).data("$scope",k)):k=a,(l=c.transclude)||
+!g&&b?c(h,k,i,d,function(b){return function(c){var d=a.$new();d.$$transcluded=!0;return b(d,c).bind("$destroy",$a(d,d.$destroy))}}(l||b)):c(h,k,i,p,g)):h&&h(a,i.childNodes,p,g)}for(var j=[],g,h,k,i=0;i<a.length;i++)h=new ma,g=v(a[i],[],h,d),h=(g=g.length?A(g,a[i],h,b,c):null)&&g.terminal||!a[i].childNodes||!a[i].childNodes.length?null:W(a[i].childNodes,g?g.transclude:b),j.push(g),j.push(h),k=k||g||h;return k?e:null}function v(a,b,c,j){var g=c.$attr,h;switch(a.nodeType){case 1:G(b,da(hb(a).toLowerCase()),
+"E",j);var i,k,l;h=a.attributes;for(var o=0,m=h&&h.length;o<m;o++)if(i=h[o],i.specified)k=i.name,l=da(k),Y.test(l)&&(k=l.substr(6).toLowerCase()),l=da(k.toLowerCase()),g[l]=k,c[l]=i=U(Z&&k=="href"?decodeURIComponent(a.getAttribute(k,2)):i.value),Fb(a,l)&&(c[l]=!0),s(a,b,i,l),G(b,l,"A",j);a=a.className;if(E(a)&&a!=="")for(;h=e.exec(a);)l=da(h[2]),G(b,l,"C",j)&&(c[l]=U(h[3])),a=a.substr(h.index+h[0].length);break;case 3:P(b,a.nodeValue);break;case 8:try{if(h=d.exec(a.nodeValue))l=da(h[1]),G(b,l,"M",
+j)&&(c[l]=U(h[2]))}catch(u){}}b.sort(K);return b}function A(a,b,c,d,e){function h(a,b){if(a)a.require=s.require,z.push(a);if(b)b.require=s.require,ea.push(b)}function i(a,b){var c,d="data",e=!1;if(E(a)){for(;(c=a.charAt(0))=="^"||c=="?";)a=a.substr(1),c=="^"&&(d="inheritedData"),e=e||c=="?";c=b[d]("$"+a+"Controller");if(!c&&!e)throw Error("No controller: "+a);}else F(a)&&(c=[],n(a,function(a){c.push(i(a,b))}));return c}function k(a,d,e,g,h){var l,v,r,D,x;l=b===e?c:pc(c,new ma(w(e),c.$attr));v=l.$$element;
+if(K){var y=/^\s*([@=&])(\??)\s*(\w*)\s*$/,s=d.$parent||d;n(K.scope,function(a,b){var c=a.match(y)||[],e=c[3]||b,g=c[2]=="?",c=c[1],h,k,i;d.$$isolateBindings[b]=c+e;switch(c){case "@":l.$observe(e,function(a){d[b]=a});l.$$observers[e].$$scope=s;l[e]&&(d[b]=j(l[e])(s));break;case "=":if(g&&!l[e])break;k=u(l[e]);i=k.assign||function(){h=d[b]=k(s);throw Error(Kb+l[e]+" (directive: "+K.name+")");};h=d[b]=k(s);d.$watch(function(){var a=k(s);a!==d[b]&&(a!==h?h=d[b]=a:i(s,a=h=d[b]));return a});break;case "&":k=
+u(l[e]);d[b]=function(a){return k(s,a)};break;default:throw Error("Invalid isolate scope definition for directive "+K.name+": "+a);}})}q&&n(q,function(a){var b={$scope:d,$element:v,$attrs:l,$transclude:h};x=a.controller;x=="@"&&(x=l[a.name]);v.data("$"+a.name+"Controller",o(x,b))});g=0;for(r=z.length;g<r;g++)try{D=z[g],D(d,v,l,D.require&&i(D.require,v))}catch(Hc){m(Hc,va(v))}a&&a(d,e.childNodes,p,h);g=0;for(r=ea.length;g<r;g++)try{D=ea[g],D(d,v,l,D.require&&i(D.require,v))}catch(J){m(J,va(v))}}for(var l=
+-Number.MAX_VALUE,z=[],ea=[],r=null,K=null,W=null,J=c.$$element=w(b),s,A,Y,G,P=d,q,na,t,B=0,C=a.length;B<C;B++){s=a[B];Y=p;if(l>s.priority)break;if(t=s.scope)O("isolated scope",K,s,J),L(t)&&(x(J,"ng-isolate-scope"),K=s),x(J,"ng-scope"),r=r||s;A=s.name;if(t=s.controller)q=q||{},O("'"+A+"' controller",q[A],s,J),q[A]=s;if(t=s.transclude)O("transclusion",G,s,J),G=s,l=s.priority,t=="element"?(Y=w(b),J=c.$$element=w(T.createComment(" "+A+": "+c[A]+" ")),b=J[0],ja(e,w(Y[0]),b),P=y(Y,d,l)):(Y=w(fb(b)).contents(),
+J.html(""),P=y(Y,d));if(s.template)if(O("template",W,s,J),W=s,t=H(s.template)?s.template(J,c):s.template,t=Lb(t),s.replace){Y=w("<div>"+U(t)+"</div>").contents();b=Y[0];if(Y.length!=1||b.nodeType!==1)throw Error(g+t);ja(e,J,b);A={$attr:{}};a=a.concat(v(b,a.splice(B+1,a.length-(B+1)),A));D(c,A);C=a.length}else J.html(t);if(s.templateUrl)O("template",W,s,J),W=s,k=$(a.splice(B,a.length-B),k,J,c,e,s.replace,P),C=a.length;else if(s.compile)try{na=s.compile(J,c,P),H(na)?h(null,na):na&&h(na.pre,na.post)}catch(I){m(I,
+va(J))}if(s.terminal)k.terminal=!0,l=Math.max(l,s.priority)}k.scope=r&&r.scope;k.transclude=G&&P;return k}function G(d,e,j,g){var l=!1;if(a.hasOwnProperty(e))for(var k,e=b.get(e+c),i=0,o=e.length;i<o;i++)try{if(k=e[i],(g===p||g>k.priority)&&k.restrict.indexOf(j)!=-1)d.push(k),l=!0}catch(u){m(u)}return l}function D(a,b){var c=b.$attr,d=a.$attr,e=a.$$element;n(a,function(d,e){e.charAt(0)!="$"&&(b[e]&&(d+=(e==="style"?";":" ")+b[e]),a.$set(e,d,!0,c[e]))});n(b,function(b,j){j=="class"?(x(e,b),a["class"]=
+(a["class"]?a["class"]+" ":"")+b):j=="style"?e.attr("style",e.attr("style")+";"+b):j.charAt(0)!="$"&&!a.hasOwnProperty(j)&&(a[j]=b,d[j]=c[j])})}function $(a,b,c,d,e,j,h){var i=[],o,m,u=c[0],z=a.shift(),r=t({},z,{controller:null,templateUrl:null,transclude:null,scope:null}),z=H(z.templateUrl)?z.templateUrl(c,d):z.templateUrl;c.html("");k.get(z,{cache:l}).success(function(l){var k,z,l=Lb(l);if(j){z=w("<div>"+U(l)+"</div>").contents();k=z[0];if(z.length!=1||k.nodeType!==1)throw Error(g+l);l={$attr:{}};
+ja(e,c,k);v(k,a,l);D(d,l)}else k=u,c.html(l);a.unshift(r);o=A(a,k,d,h);for(m=W(c[0].childNodes,h);i.length;){var ea=i.shift(),l=i.shift();z=i.shift();var x=i.shift(),y=k;l!==u&&(y=fb(k),ja(z,w(l),y));o(function(){b(m,ea,y,e,x)},ea,y,e,x)}i=null}).error(function(a,b,c,d){throw Error("Failed to load template: "+d.url);});return function(a,c,d,e,j){i?(i.push(c),i.push(d),i.push(e),i.push(j)):o(function(){b(m,c,d,e,j)},c,d,e,j)}}function K(a,b){return b.priority-a.priority}function O(a,b,c,d){if(b)throw Error("Multiple directives ["+
+b.name+", "+c.name+"] asking for "+a+" on: "+va(d));}function P(a,b){var c=j(b,!0);c&&a.push({priority:0,compile:S(function(a,b){var d=b.parent(),e=d.data("$binding")||[];e.push(c);x(d.data("$binding",e),"ng-binding");a.$watch(c,function(a){b[0].nodeValue=a})})})}function s(a,b,c,d){var e=j(c,!0);e&&b.push({priority:100,compile:S(function(a,b,c){b=c.$$observers||(c.$$observers={});if(e=j(c[d],!0))c[d]=e(a),(b[d]||(b[d]=[])).$$inter=!0,(c.$$observers&&c.$$observers[d].$$scope||a).$watch(e,function(a){c.$set(d,
+a)})})})}function ja(a,b,c){var d=b[0],e=d.parentNode,j,g;if(a){j=0;for(g=a.length;j<g;j++)if(a[j]==d){a[j]=c;break}}e&&e.replaceChild(c,d);c[w.expando]=d[w.expando];b[0]=c}var ma=function(a,b){this.$$element=a;this.$attr=b||{}};ma.prototype={$normalize:da,$set:function(a,b,c,d){var e=Fb(this.$$element[0],a),j=this.$$observers;e&&(this.$$element.prop(a,b),d=e);this[a]=b;d?this.$attr[a]=d:(d=this.$attr[a])||(this.$attr[a]=d=bb(a,"-"));if(hb(this.$$element[0])==="A"&&a==="href")q.setAttribute("href",
+b),e=q.href,e.match(i)||(this[a]=b="unsafe:"+e);c!==!1&&(b===null||b===p?this.$$element.removeAttr(d):this.$$element.attr(d,b));j&&n(j[a],function(a){try{a(b)}catch(c){m(c)}})},$observe:function(a,b){var c=this,d=c.$$observers||(c.$$observers={}),e=d[a]||(d[a]=[]);e.push(b);z.$evalAsync(function(){e.$$inter||b(c[a])});return b}};var q=r[0].createElement("a"),ea=j.startSymbol(),J=j.endSymbol(),Lb=ea=="{{"||J=="}}"?qa:function(a){return a.replace(/\{\{/g,ea).replace(/}}/g,J)},Y=/^ngAttr[A-Z]/;return y}]}
+function da(b){return Ia(b.replace(Ic,""))}function Jc(){var b={},a=/^(\S+)(\s+as\s+(\w+))?$/;this.register=function(a,d){L(a)?t(b,a):b[a]=d};this.$get=["$injector","$window",function(c,d){return function(e,g){var i,f;E(e)&&(f=e.match(a),i=f[1],f=f[3],e=b.hasOwnProperty(i)?b[i]:ib(g.$scope,i,!0)||ib(d,i,!0),xa(e,i,!0));i=c.instantiate(e,g);if(f){if(typeof g.$scope!=="object")throw Error('Can not export controller as "'+f+'". No scope object provided!');g.$scope[f]=i}return i}}]}function Kc(){this.$get=
+["$window",function(b){return w(b.document)}]}function Lc(){this.$get=["$log",function(b){return function(a,c){b.error.apply(b,arguments)}}]}function Mc(){var b="{{",a="}}";this.startSymbol=function(a){return a?(b=a,this):b};this.endSymbol=function(b){return b?(a=b,this):a};this.$get=["$parse","$exceptionHandler",function(c,d){function e(e,h){for(var j,m,k=0,l=[],u=e.length,o=!1,z=[];k<u;)(j=e.indexOf(b,k))!=-1&&(m=e.indexOf(a,j+g))!=-1?(k!=j&&l.push(e.substring(k,j)),l.push(k=c(o=e.substring(j+g,
+m))),k.exp=o,k=m+i,o=!0):(k!=u&&l.push(e.substring(k)),k=u);if(!(u=l.length))l.push(""),u=1;if(!h||o)return z.length=u,k=function(a){try{for(var b=0,c=u,j;b<c;b++){if(typeof(j=l[b])=="function")j=j(a),j==null||j==p?j="":typeof j!="string"&&(j=ha(j));z[b]=j}return z.join("")}catch(g){d(Error("Error while interpolating: "+e+"\n"+g.toString()))}},k.exp=e,k.parts=l,k}var g=b.length,i=a.length;e.startSymbol=function(){return b};e.endSymbol=function(){return a};return e}]}function Mb(b){for(var b=b.split("/"),
+a=b.length;a--;)b[a]=ab(b[a]);return b.join("/")}function Nb(b,a){var c=jb.exec(b);a.$$protocol=c[1];a.$$host=c[3];a.$$port=N(c[5])||Oa[c[1]]||null}function Ob(b,a){var c=Pb.exec(b);a.$$path=decodeURIComponent(c[1]);a.$$search=vb(c[3]);a.$$hash=decodeURIComponent(c[5]||"");if(a.$$path&&a.$$path.charAt(0)!="/")a.$$path="/"+a.$$path}function fa(b,a,c){return a.indexOf(b)==0?a.substr(b.length):c}function Ca(b){var a=b.indexOf("#");return a==-1?b:b.substr(0,a)}function kb(b){return b.substr(0,Ca(b).lastIndexOf("/")+
+1)}function Qb(b,a){var a=a||"",c=kb(b);this.$$parse=function(a){var b={};Nb(a,b);var g=fa(c,a);if(!E(g))throw Error('Invalid url "'+a+'", missing path prefix "'+c+'".');Ob(g,b);t(this,b);if(!this.$$path)this.$$path="/";this.$$compose()};this.$$compose=function(){var a=wb(this.$$search),b=this.$$hash?"#"+ab(this.$$hash):"";this.$$url=Mb(this.$$path)+(a?"?"+a:"")+b;this.$$absUrl=c+this.$$url.substr(1)};this.$$rewrite=function(d){var e;if((e=fa(b,d))!==p)return d=e,(e=fa(a,e))!==p?c+(fa("/",e)||e):
+b+d;else if((e=fa(c,d))!==p)return c+e;else if(c==d+"/")return c}}function lb(b,a){var c=kb(b);this.$$parse=function(d){Nb(d,this);var e=fa(b,d)||fa(c,d);if(!E(e))throw Error('Invalid url "'+d+'", does not start with "'+b+'".');e=e.charAt(0)=="#"?fa(a,e):e;if(!E(e))throw Error('Invalid url "'+d+'", missing hash prefix "'+a+'".');Ob(e,this);this.$$compose()};this.$$compose=function(){var c=wb(this.$$search),e=this.$$hash?"#"+ab(this.$$hash):"";this.$$url=Mb(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl=
+b+(this.$$url?a+this.$$url:"")};this.$$rewrite=function(a){if(Ca(b)==Ca(a))return a}}function Rb(b,a){lb.apply(this,arguments);var c=kb(b);this.$$rewrite=function(d){var e;if(b==Ca(d))return d;else if(e=fa(c,d))return b+a+e;else if(c===d+"/")return c}}function Pa(b){return function(){return this[b]}}function Sb(b,a){return function(c){if(C(c))return this[b];this[b]=a(c);this.$$compose();return this}}function Nc(){var b="",a=!1;this.hashPrefix=function(a){return B(a)?(b=a,this):b};this.html5Mode=function(b){return B(b)?
+(a=b,this):a};this.$get=["$rootScope","$browser","$sniffer","$rootElement",function(c,d,e,g){function i(a){c.$broadcast("$locationChangeSuccess",f.absUrl(),a)}var f,h=d.baseHref(),j=d.url();a?(h=h?j.substring(0,j.indexOf("/",j.indexOf("//")+2))+h:j,e=e.history?Qb:Rb):(h=Ca(j),e=lb);f=new e(h,"#"+b);f.$$parse(f.$$rewrite(j));g.bind("click",function(a){if(!a.ctrlKey&&!(a.metaKey||a.which==2)){for(var b=w(a.target);I(b[0].nodeName)!=="a";)if(b[0]===g[0]||!(b=b.parent())[0])return;var e=b.prop("href"),
+j=f.$$rewrite(e);e&&!b.attr("target")&&j&&!a.isDefaultPrevented()&&(a.preventDefault(),j!=d.url()&&(f.$$parse(j),c.$apply(),M.angular["ff-684208-preventDefault"]=!0))}});f.absUrl()!=j&&d.url(f.absUrl(),!0);d.onUrlChange(function(a){f.absUrl()!=a&&(c.$broadcast("$locationChangeStart",a,f.absUrl()).defaultPrevented?d.url(f.absUrl()):(c.$evalAsync(function(){var b=f.absUrl();f.$$parse(a);i(b)}),c.$$phase||c.$digest()))});var m=0;c.$watch(function(){var a=d.url(),b=f.$$replace;if(!m||a!=f.absUrl())m++,
+c.$evalAsync(function(){c.$broadcast("$locationChangeStart",f.absUrl(),a).defaultPrevented?f.$$parse(a):(d.url(f.absUrl(),b),i(a))});f.$$replace=!1;return m});return f}]}function Oc(){var b=!0,a=this;this.debugEnabled=function(a){return B(a)?(b=a,this):b};this.$get=["$window",function(c){function d(a){a instanceof Error&&(a.stack?a=a.message&&a.stack.indexOf(a.message)===-1?"Error: "+a.message+"\n"+a.stack:a.stack:a.sourceURL&&(a=a.message+"\n"+a.sourceURL+":"+a.line));return a}function e(a){var b=
+c.console||{},e=b[a]||b.log||q;return e.apply?function(){var a=[];n(arguments,function(b){a.push(d(b))});return e.apply(b,a)}:function(a,b){e(a,b)}}return{log:e("log"),warn:e("warn"),info:e("info"),error:e("error"),debug:function(){var c=e("debug");return function(){b&&c.apply(a,arguments)}}()}}]}function Pc(b,a){function c(a){return a.indexOf(r)!=-1}function d(a){a=a||1;return o+a<b.length?b.charAt(o+a):!1}function e(a){return"0"<=a&&a<="9"}function g(a){return a==" "||a=="\r"||a=="\t"||a=="\n"||
+a=="\u000b"||a=="\u00a0"}function i(a){return"a"<=a&&a<="z"||"A"<=a&&a<="Z"||"_"==a||a=="$"}function f(a){return a=="-"||a=="+"||e(a)}function h(a,c,d){d=d||o;throw Error("Lexer Error: "+a+" at column"+(B(c)?"s "+c+"-"+o+" ["+b.substring(c,d)+"]":" "+d)+" in expression ["+b+"].");}function j(){for(var a="",c=o;o<b.length;){var j=I(b.charAt(o));if(j=="."||e(j))a+=j;else{var g=d();if(j=="e"&&f(g))a+=j;else if(f(j)&&g&&e(g)&&a.charAt(a.length-1)=="e")a+=j;else if(f(j)&&(!g||!e(g))&&a.charAt(a.length-
+1)=="e")h("Invalid exponent");else break}o++}a*=1;l.push({index:c,text:a,json:!0,fn:function(){return a}})}function m(){for(var c="",d=o,f,j,h,k;o<b.length;){k=b.charAt(o);if(k=="."||i(k)||e(k))k=="."&&(f=o),c+=k;else break;o++}if(f)for(j=o;j<b.length;){k=b.charAt(j);if(k=="("){h=c.substr(f-d+1);c=c.substr(0,f-d);o=j;break}if(g(k))j++;else break}d={index:d,text:c};if(Da.hasOwnProperty(c))d.fn=d.json=Da[c];else{var m=Tb(c,a);d.fn=t(function(a,b){return m(a,b)},{assign:function(a,b){return Ub(a,c,b)}})}l.push(d);
+h&&(l.push({index:f,text:".",json:!1}),l.push({index:f+1,text:h,json:!1}))}function k(a){var c=o;o++;for(var d="",e=a,f=!1;o<b.length;){var j=b.charAt(o);e+=j;if(f)j=="u"?(j=b.substring(o+1,o+5),j.match(/[\da-f]{4}/i)||h("Invalid unicode escape [\\u"+j+"]"),o+=4,d+=String.fromCharCode(parseInt(j,16))):(f=Qc[j],d+=f?f:j),f=!1;else if(j=="\\")f=!0;else if(j==a){o++;l.push({index:c,text:e,string:d,json:!0,fn:function(){return d}});return}else d+=j;o++}h("Unterminated quote",c)}for(var l=[],u,o=0,z=[],
+r,y=":";o<b.length;){r=b.charAt(o);if(c("\"'"))k(r);else if(e(r)||c(".")&&e(d()))j();else if(i(r)){if(m(),"{,".indexOf(y)!=-1&&z[0]=="{"&&(u=l[l.length-1]))u.json=u.text.indexOf(".")==-1}else if(c("(){}[].,;:?"))l.push({index:o,text:r,json:":[,".indexOf(y)!=-1&&c("{[")||c("}]:,")}),c("{[")&&z.unshift(r),c("}]")&&z.shift(),o++;else if(g(r)){o++;continue}else{var x=r+d(),n=x+d(2),v=Da[r],A=Da[x],G=Da[n];G?(l.push({index:o,text:n,fn:G}),o+=3):A?(l.push({index:o,text:x,fn:A}),o+=2):v?(l.push({index:o,
+text:r,fn:v,json:"[,:".indexOf(y)!=-1&&c("+-")}),o+=1):h("Unexpected next character ",o,o+1)}y=r}return l}function Rc(b,a,c,d){function e(a,c){throw Error("Syntax Error: Token '"+c.text+"' "+a+" at column "+(c.index+1)+" of the expression ["+b+"] starting at ["+b.substring(c.index)+"].");}function g(){if(O.length===0)throw Error("Unexpected end of expression: "+b);return O[0]}function i(a,b,c,d){if(O.length>0){var e=O[0],f=e.text;if(f==a||f==b||f==c||f==d||!a&&!b&&!c&&!d)return e}return!1}function f(b,
+c,d,f){return(b=i(b,c,d,f))?(a&&!b.json&&e("is not valid json",b),O.shift(),b):!1}function h(a){f(a)||e("is unexpected, expecting ["+a+"]",i())}function j(a,b){return t(function(c,d){return a(c,d,b)},{constant:b.constant})}function m(a,b,c){return t(function(d,e){return a(d,e)?b(d,e):c(d,e)},{constant:a.constant&&b.constant&&c.constant})}function k(a,b,c){return t(function(d,e){return b(d,e,a,c)},{constant:a.constant&&c.constant})}function l(){for(var a=[];;)if(O.length>0&&!i("}",")",";","]")&&a.push(w()),
+!f(";"))return a.length==1?a[0]:function(b,c){for(var d,e=0;e<a.length;e++){var f=a[e];f&&(d=f(b,c))}return d}}function u(){for(var a=f(),b=c(a.text),d=[];;)if(a=f(":"))d.push(P());else{var e=function(a,c,e){for(var e=[e],f=0;f<d.length;f++)e.push(d[f](a,c));return b.apply(a,e)};return function(){return e}}}function o(){var a=z(),b,c;if(f("?"))if(b=o(),c=f(":"))return m(a,b,o());else e("expected :",c);else return a}function z(){for(var a=r(),b;;)if(b=f("||"))a=k(a,b.fn,r());else return a}function r(){var a=
+y(),b;if(b=f("&&"))a=k(a,b.fn,r());return a}function y(){var a=x(),b;if(b=f("==","!=","===","!=="))a=k(a,b.fn,y());return a}function x(){var a;a=n();for(var b;b=f("+","-");)a=k(a,b.fn,n());if(b=f("<",">","<=",">="))a=k(a,b.fn,x());return a}function n(){for(var a=v(),b;b=f("*","/","%");)a=k(a,b.fn,v());return a}function v(){var a;return f("+")?A():(a=f("-"))?k($,a.fn,v()):(a=f("!"))?j(a.fn,v()):A()}function A(){var a;if(f("("))a=w(),h(")");else if(f("["))a=G();else if(f("{"))a=D();else{var b=f();(a=
+b.fn)||e("not a primary expression",b);if(b.json)a.constant=a.literal=!0}for(var c;b=f("(","[",".");)b.text==="("?(a=s(a,c),c=null):b.text==="["?(c=a,a=ma(a)):b.text==="."?(c=a,a=ja(a)):e("IMPOSSIBLE");return a}function G(){var a=[],b=!0;if(g().text!="]"){do{var c=P();a.push(c);c.constant||(b=!1)}while(f(","))}h("]");return t(function(b,c){for(var d=[],e=0;e<a.length;e++)d.push(a[e](b,c));return d},{literal:!0,constant:b})}function D(){var a=[],b=!0;if(g().text!="}"){do{var c=f(),c=c.string||c.text;
+h(":");var d=P();a.push({key:c,value:d});d.constant||(b=!1)}while(f(","))}h("}");return t(function(b,c){for(var d={},e=0;e<a.length;e++){var f=a[e];d[f.key]=f.value(b,c)}return d},{literal:!0,constant:b})}var $=S(0),K,O=Pc(b,d),P=function(){var a=o(),c,d;return(d=f("="))?(a.assign||e("implies assignment but ["+b.substring(0,d.index)+"] can not be assigned to",d),c=o(),function(b,d){return a.assign(b,c(b,d),d)}):a},s=function(a,b){var c=[];if(g().text!=")"){do c.push(P());while(f(","))}h(")");return function(d,
+e){for(var f=[],j=b?b(d,e):d,g=0;g<c.length;g++)f.push(c[g](d,e));g=a(d,e,j)||q;return g.apply?g.apply(j,f):g(f[0],f[1],f[2],f[3],f[4])}},ja=function(a){var b=f().text,c=Tb(b,d);return t(function(b,d,e){return c(e||a(b,d),d)},{assign:function(c,d,e){return Ub(a(c,e),b,d)}})},ma=function(a){var b=P();h("]");return t(function(c,d){var e=a(c,d),f=b(c,d),j;if(!e)return p;if((e=e[f])&&e.then){j=e;if(!("$$v"in e))j.$$v=p,j.then(function(a){j.$$v=a});e=e.$$v}return e},{assign:function(c,d,e){return a(c,
+e)[b(c,e)]=d}})},w=function(){for(var a=P(),b;;)if(b=f("|"))a=k(a,b.fn,u());else return a};a?(P=z,s=ja=ma=w=function(){e("is not valid json",{text:b,index:0})},K=A()):K=l();O.length!==0&&e("is an unexpected token",O[0]);K.literal=!!K.literal;K.constant=!!K.constant;return K}function Ub(b,a,c){for(var a=a.split("."),d=0;a.length>1;d++){var e=a.shift(),g=b[e];g||(g={},b[e]=g);b=g}return b[a.shift()]=c}function ib(b,a,c){if(!a)return b;for(var a=a.split("."),d,e=b,g=a.length,i=0;i<g;i++)d=a[i],b&&(b=
+(e=b)[d]);return!c&&H(b)?$a(e,b):b}function Vb(b,a,c,d,e){return function(g,i){var f=i&&i.hasOwnProperty(b)?i:g,h;if(f===null||f===p)return f;if((f=f[b])&&f.then){if(!("$$v"in f))h=f,h.$$v=p,h.then(function(a){h.$$v=a});f=f.$$v}if(!a||f===null||f===p)return f;if((f=f[a])&&f.then){if(!("$$v"in f))h=f,h.$$v=p,h.then(function(a){h.$$v=a});f=f.$$v}if(!c||f===null||f===p)return f;if((f=f[c])&&f.then){if(!("$$v"in f))h=f,h.$$v=p,h.then(function(a){h.$$v=a});f=f.$$v}if(!d||f===null||f===p)return f;if((f=
+f[d])&&f.then){if(!("$$v"in f))h=f,h.$$v=p,h.then(function(a){h.$$v=a});f=f.$$v}if(!e||f===null||f===p)return f;if((f=f[e])&&f.then){if(!("$$v"in f))h=f,h.$$v=p,h.then(function(a){h.$$v=a});f=f.$$v}return f}}function Tb(b,a){if(mb.hasOwnProperty(b))return mb[b];var c=b.split("."),d=c.length,e;if(a)e=d<6?Vb(c[0],c[1],c[2],c[3],c[4]):function(a,b){var e=0,j;do j=Vb(c[e++],c[e++],c[e++],c[e++],c[e++])(a,b),b=p,a=j;while(e<d);return j};else{var g="var l, fn, p;\n";n(c,function(a,b){g+="if(s === null || s === undefined) return s;\nl=s;\ns="+
+(b?"s":'((k&&k.hasOwnProperty("'+a+'"))?k:s)')+'["'+a+'"];\nif (s && s.then) {\n if (!("$$v" in s)) {\n p=s;\n p.$$v = undefined;\n p.then(function(v) {p.$$v=v;});\n}\n s=s.$$v\n}\n'});g+="return s;";e=Function("s","k",g);e.toString=function(){return g}}return mb[b]=e}function Sc(){var b={};this.$get=["$filter","$sniffer",function(a,c){return function(d){switch(typeof d){case "string":return b.hasOwnProperty(d)?b[d]:b[d]=Rc(d,!1,a,c.csp);case "function":return d;default:return q}}}]}function Tc(){this.$get=
+["$rootScope","$exceptionHandler",function(b,a){return Uc(function(a){b.$evalAsync(a)},a)}]}function Uc(b,a){function c(a){return a}function d(a){return i(a)}var e=function(){var f=[],h,j;return j={resolve:function(a){if(f){var c=f;f=p;h=g(a);c.length&&b(function(){for(var a,b=0,d=c.length;b<d;b++)a=c[b],h.then(a[0],a[1])})}},reject:function(a){j.resolve(i(a))},promise:{then:function(b,j){var g=e(),i=function(d){try{g.resolve((b||c)(d))}catch(e){a(e),g.reject(e)}},o=function(b){try{g.resolve((j||
+d)(b))}catch(c){a(c),g.reject(c)}};f?f.push([i,o]):h.then(i,o);return g.promise},always:function(a){function b(a,c){var d=e();c?d.resolve(a):d.reject(a);return d.promise}function d(e,f){var j=null;try{j=(a||c)()}catch(g){return b(g,!1)}return j&&j.then?j.then(function(){return b(e,f)},function(a){return b(a,!1)}):b(e,f)}return this.then(function(a){return d(a,!0)},function(a){return d(a,!1)})}}}},g=function(a){return a&&a.then?a:{then:function(c){var d=e();b(function(){d.resolve(c(a))});return d.promise}}},
+i=function(a){return{then:function(c,j){var g=e();b(function(){g.resolve((j||d)(a))});return g.promise}}};return{defer:e,reject:i,when:function(f,h,j){var m=e(),k,l=function(b){try{return(h||c)(b)}catch(d){return a(d),i(d)}},u=function(b){try{return(j||d)(b)}catch(c){return a(c),i(c)}};b(function(){g(f).then(function(a){k||(k=!0,m.resolve(g(a).then(l,u)))},function(a){k||(k=!0,m.resolve(u(a)))})});return m.promise},all:function(a){var b=e(),c=0,d=F(a)?[]:{};n(a,function(a,e){c++;g(a).then(function(a){d.hasOwnProperty(e)||
+(d[e]=a,--c||b.resolve(d))},function(a){d.hasOwnProperty(e)||b.reject(a)})});c===0&&b.resolve(d);return b.promise}}}function Vc(){var b={};this.when=function(a,c){b[a]=t({reloadOnSearch:!0,caseInsensitiveMatch:!1},c);if(a){var d=a[a.length-1]=="/"?a.substr(0,a.length-1):a+"/";b[d]={redirectTo:a}}return this};this.otherwise=function(a){this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$http","$templateCache",function(a,c,d,e,g,i,f){function h(a,b,c){for(var b=
+"^"+b.replace(/[-\/\\^$:*+?.()|[\]{}]/g,"\\$&")+"$",d="",e=[],f={},j=/\\([:*])(\w+)/g,g,i=0;(g=j.exec(b))!==null;){d+=b.slice(i,g.index);switch(g[1]){case ":":d+="([^\\/]*)";break;case "*":d+="(.*)"}e.push(g[2]);i=j.lastIndex}d+=b.substr(i);var h=a.match(RegExp(d,c.caseInsensitiveMatch?"i":""));h&&n(e,function(a,b){f[a]=h[b+1]});return h?f:null}function j(){var b=m(),j=u.current;if(b&&j&&b.$$route===j.$$route&&ia(b.pathParams,j.pathParams)&&!b.reloadOnSearch&&!l)j.params=b.params,V(j.params,d),a.$broadcast("$routeUpdate",
+j);else if(b||j)l=!1,a.$broadcast("$routeChangeStart",b,j),(u.current=b)&&b.redirectTo&&(E(b.redirectTo)?c.path(k(b.redirectTo,b.params)).search(b.params).replace():c.url(b.redirectTo(b.pathParams,c.path(),c.search())).replace()),e.when(b).then(function(){if(b){var a=t({},b.resolve),c;n(a,function(b,c){a[c]=E(b)?g.get(b):g.invoke(b)});if(B(c=b.template))H(c)&&(c=c(b.params));else if(B(c=b.templateUrl))if(H(c)&&(c=c(b.params)),B(c))b.loadedTemplateUrl=c,c=i.get(c,{cache:f}).then(function(a){return a.data});
+B(c)&&(a.$template=c);return e.all(a)}}).then(function(c){if(b==u.current){if(b)b.locals=c,V(b.params,d);a.$broadcast("$routeChangeSuccess",b,j)}},function(c){b==u.current&&a.$broadcast("$routeChangeError",b,j,c)})}function m(){var a,d;n(b,function(b,e){if(!d&&(a=h(c.path(),e,b)))d=tb(b,{params:t({},c.search(),a),pathParams:a}),d.$$route=b});return d||b[null]&&tb(b[null],{params:{},pathParams:{}})}function k(a,b){var c=[];n((a||"").split(":"),function(a,d){if(d==0)c.push(a);else{var e=a.match(/(\w+)(.*)/),
+f=e[1];c.push(b[f]);c.push(e[2]||"");delete b[f]}});return c.join("")}var l=!1,u={routes:b,reload:function(){l=!0;a.$evalAsync(j)}};a.$on("$locationChangeSuccess",j);return u}]}function Wc(){this.$get=S({})}function Xc(){var b=10;this.digestTtl=function(a){arguments.length&&(b=a);return b};this.$get=["$injector","$exceptionHandler","$parse",function(a,c,d){function e(){this.$id=Fa();this.$$phase=this.$parent=this.$$watchers=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=null;
+this["this"]=this.$root=this;this.$$destroyed=!1;this.$$asyncQueue=[];this.$$listeners={};this.$$isolateBindings={}}function g(a){if(h.$$phase)throw Error(h.$$phase+" already in progress");h.$$phase=a}function i(a,b){var c=d(a);xa(c,b);return c}function f(){}e.prototype={$new:function(a){if(H(a))throw Error("API-CHANGE: Use $controller to instantiate controllers.");a?(a=new e,a.$root=this.$root):(a=function(){},a.prototype=this,a=new a,a.$id=Fa());a["this"]=a;a.$$listeners={};a.$parent=this;a.$$watchers=
+a.$$nextSibling=a.$$childHead=a.$$childTail=null;a.$$prevSibling=this.$$childTail;this.$$childHead?this.$$childTail=this.$$childTail.$$nextSibling=a:this.$$childHead=this.$$childTail=a;return a},$watch:function(a,b,c){var d=i(a,"watch"),e=this.$$watchers,g={fn:b,last:f,get:d,exp:a,eq:!!c};if(!H(b)){var h=i(b||q,"listener");g.fn=function(a,b,c){h(c)}}if(typeof a=="string"&&d.constant){var r=g.fn;g.fn=function(a,b,c){r.call(this,a,b,c);ta(e,g)}}if(!e)e=this.$$watchers=[];e.unshift(g);return function(){ta(e,
+g)}},$watchCollection:function(a,b){var c=this,e,f,g=0,i=d(a),h=[],n={},x=0;return this.$watch(function(){f=i(c);var a,b;if(L(f))if(Xa(f)){if(e!==h)e=h,x=e.length=0,g++;a=f.length;if(x!==a)g++,e.length=x=a;for(b=0;b<a;b++)e[b]!==f[b]&&(g++,e[b]=f[b])}else{e!==n&&(e=n={},x=0,g++);a=0;for(b in f)f.hasOwnProperty(b)&&(a++,e.hasOwnProperty(b)?e[b]!==f[b]&&(g++,e[b]=f[b]):(x++,e[b]=f[b],g++));if(x>a)for(b in g++,e)e.hasOwnProperty(b)&&!f.hasOwnProperty(b)&&(x--,delete e[b])}else e!==f&&(e=f,g++);return g},
+function(){b(f,e,c)})},$digest:function(){var a,d,e,i,u=this.$$asyncQueue,o,z,r=b,n,x=[],p,v;g("$digest");do{z=!1;for(n=this;u.length;)try{n.$eval(u.shift())}catch(A){c(A)}do{if(i=n.$$watchers)for(o=i.length;o--;)try{if(a=i[o],(d=a.get(n))!==(e=a.last)&&!(a.eq?ia(d,e):typeof d=="number"&&typeof e=="number"&&isNaN(d)&&isNaN(e)))z=!0,a.last=a.eq?V(d):d,a.fn(d,e===f?d:e,n),r<5&&(p=4-r,x[p]||(x[p]=[]),v=H(a.exp)?"fn: "+(a.exp.name||a.exp.toString()):a.exp,v+="; newVal: "+ha(d)+"; oldVal: "+ha(e),x[p].push(v))}catch(G){c(G)}if(!(i=
+n.$$childHead||n!==this&&n.$$nextSibling))for(;n!==this&&!(i=n.$$nextSibling);)n=n.$parent}while(n=i);if(z&&!r--)throw h.$$phase=null,Error(b+" $digest() iterations reached. Aborting!\nWatchers fired in the last 5 iterations: "+ha(x));}while(z||u.length);h.$$phase=null},$destroy:function(){if(!(h==this||this.$$destroyed)){var a=this.$parent;this.$broadcast("$destroy");this.$$destroyed=!0;if(a.$$childHead==this)a.$$childHead=this.$$nextSibling;if(a.$$childTail==this)a.$$childTail=this.$$prevSibling;
+if(this.$$prevSibling)this.$$prevSibling.$$nextSibling=this.$$nextSibling;if(this.$$nextSibling)this.$$nextSibling.$$prevSibling=this.$$prevSibling;this.$parent=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=null}},$eval:function(a,b){return d(a)(this,b)},$evalAsync:function(a){this.$$asyncQueue.push(a)},$apply:function(a){try{return g("$apply"),this.$eval(a)}catch(b){c(b)}finally{h.$$phase=null;try{h.$digest()}catch(d){throw c(d),d;}}},$on:function(a,b){var c=this.$$listeners[a];
+c||(this.$$listeners[a]=c=[]);c.push(b);return function(){c[Ga(c,b)]=null}},$emit:function(a,b){var d=[],e,f=this,g=!1,i={name:a,targetScope:f,stopPropagation:function(){g=!0},preventDefault:function(){i.defaultPrevented=!0},defaultPrevented:!1},h=[i].concat(ka.call(arguments,1)),n,x;do{e=f.$$listeners[a]||d;i.currentScope=f;n=0;for(x=e.length;n<x;n++)if(e[n])try{if(e[n].apply(null,h),g)return i}catch(p){c(p)}else e.splice(n,1),n--,x--;f=f.$parent}while(f);return i},$broadcast:function(a,b){var d=
+this,e=this,f={name:a,targetScope:this,preventDefault:function(){f.defaultPrevented=!0},defaultPrevented:!1},g=[f].concat(ka.call(arguments,1)),i,h;do{d=e;f.currentScope=d;e=d.$$listeners[a]||[];i=0;for(h=e.length;i<h;i++)if(e[i])try{e[i].apply(null,g)}catch(n){c(n)}else e.splice(i,1),i--,h--;if(!(e=d.$$childHead||d!==this&&d.$$nextSibling))for(;d!==this&&!(e=d.$$nextSibling);)d=d.$parent}while(d=e);return f}};var h=new e;return h}]}function Yc(){this.$get=["$window","$document",function(b,a){var c=
+{},d=N((/android (\d+)/.exec(I((b.navigator||{}).userAgent))||[])[1]),e=a[0]||{},g,i=/^(Moz|webkit|O|ms)(?=[A-Z])/,f=e.body&&e.body.style,h=!1,j=!1;if(f){for(var m in f)if(h=i.exec(m)){g=h[0];g=g.substr(0,1).toUpperCase()+g.substr(1);break}h=!!("transition"in f||g+"Transition"in f);j=!!("animation"in f||g+"Animation"in f)}return{history:!(!b.history||!b.history.pushState||d<4),hashchange:"onhashchange"in b&&(!e.documentMode||e.documentMode>7),hasEvent:function(a){if(a=="input"&&Z==9)return!1;if(C(c[a])){var b=
+e.createElement("div");c[a]="on"+a in b}return c[a]},csp:e.securityPolicy?e.securityPolicy.isActive:!1,vendorPrefix:g,transitions:h,animations:j}}]}function Zc(){this.$get=S(M)}function Wb(b){var a={},c,d,e;if(!b)return a;n(b.split("\n"),function(b){e=b.indexOf(":");c=I(U(b.substr(0,e)));d=U(b.substr(e+1));c&&(a[c]?a[c]+=", "+d:a[c]=d)});return a}function $c(b,a){var c=ad.exec(b);if(c==null)return!0;var d={protocol:c[2],host:c[4],port:N(c[6])||Oa[c[2]]||null,relativeProtocol:c[2]===p||c[2]===""},
+c=jb.exec(a),c={protocol:c[1],host:c[3],port:N(c[5])||Oa[c[1]]||null};return(d.protocol==c.protocol||d.relativeProtocol)&&d.host==c.host&&(d.port==c.port||d.relativeProtocol&&c.port==Oa[c.protocol])}function Xb(b){var a=L(b)?b:p;return function(c){a||(a=Wb(b));return c?a[I(c)]||null:a}}function Yb(b,a,c){if(H(c))return c(b,a);n(c,function(c){b=c(b,a)});return b}function bd(){var b=/^\s*(\[|\{[^\{])/,a=/[\}\]]\s*$/,c=/^\)\]\}',?\n/,d={"Content-Type":"application/json;charset=utf-8"},e=this.defaults=
+{transformResponse:[function(d){E(d)&&(d=d.replace(c,""),b.test(d)&&a.test(d)&&(d=ub(d,!0)));return d}],transformRequest:[function(a){return L(a)&&Ea.apply(a)!=="[object File]"?ha(a):a}],headers:{common:{Accept:"application/json, text/plain, */*"},post:d,put:d,patch:d},xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN"},g=this.interceptors=[],i=this.responseInterceptors=[];this.$get=["$httpBackend","$browser","$cacheFactory","$rootScope","$q","$injector",function(a,b,c,d,k,l){function u(a){function c(a){var b=
+t({},a,{data:Yb(a.data,a.headers,d.transformResponse)});return 200<=a.status&&a.status<300?b:k.reject(b)}var d={transformRequest:e.transformRequest,transformResponse:e.transformResponse},f={};t(d,a);d.headers=f;d.method=oa(d.method);t(f,e.headers.common,e.headers[I(d.method)],a.headers);(a=$c(d.url,b.url())?b.cookies()[d.xsrfCookieName||e.xsrfCookieName]:p)&&(f[d.xsrfHeaderName||e.xsrfHeaderName]=a);var g=[function(a){var b=Yb(a.data,Xb(f),a.transformRequest);C(a.data)&&delete f["Content-Type"];if(C(a.withCredentials)&&
+!C(e.withCredentials))a.withCredentials=e.withCredentials;return o(a,b,f).then(c,c)},p],j=k.when(d);for(n(y,function(a){(a.request||a.requestError)&&g.unshift(a.request,a.requestError);(a.response||a.responseError)&&g.push(a.response,a.responseError)});g.length;)var a=g.shift(),i=g.shift(),j=j.then(a,i);j.success=function(a){j.then(function(b){a(b.data,b.status,b.headers,d)});return j};j.error=function(a){j.then(null,function(b){a(b.data,b.status,b.headers,d)});return j};return j}function o(b,c,g){function j(a,
+b,c){n&&(200<=a&&a<300?n.put(s,[a,b,Wb(c)]):n.remove(s));i(b,a,c);d.$$phase||d.$apply()}function i(a,c,d){c=Math.max(c,0);(200<=c&&c<300?l.resolve:l.reject)({data:a,status:c,headers:Xb(d),config:b})}function h(){var a=Ga(u.pendingRequests,b);a!==-1&&u.pendingRequests.splice(a,1)}var l=k.defer(),o=l.promise,n,p,s=z(b.url,b.params);u.pendingRequests.push(b);o.then(h,h);if((b.cache||e.cache)&&b.cache!==!1&&b.method=="GET")n=L(b.cache)?b.cache:L(e.cache)?e.cache:r;if(n)if(p=n.get(s))if(p.then)return p.then(h,
+h),p;else F(p)?i(p[1],p[0],V(p[2])):i(p,200,{});else n.put(s,o);p||a(b.method,s,c,j,g,b.timeout,b.withCredentials,b.responseType);return o}function z(a,b){if(!b)return a;var c=[];nc(b,function(a,b){a==null||a==p||(F(a)||(a=[a]),n(a,function(a){L(a)&&(a=ha(a));c.push(wa(b)+"="+wa(a))}))});return a+(a.indexOf("?")==-1?"?":"&")+c.join("&")}var r=c("$http"),y=[];n(g,function(a){y.unshift(E(a)?l.get(a):l.invoke(a))});n(i,function(a,b){var c=E(a)?l.get(a):l.invoke(a);y.splice(b,0,{response:function(a){return c(k.when(a))},
+responseError:function(a){return c(k.reject(a))}})});u.pendingRequests=[];(function(a){n(arguments,function(a){u[a]=function(b,c){return u(t(c||{},{method:a,url:b}))}})})("get","delete","head","jsonp");(function(a){n(arguments,function(a){u[a]=function(b,c,d){return u(t(d||{},{method:a,url:b,data:c}))}})})("post","put");u.defaults=e;return u}]}function cd(){this.$get=["$browser","$window","$document",function(b,a,c){return dd(b,ed,b.defer,a.angular.callbacks,c[0],a.location.protocol.replace(":",""))}]}
+function dd(b,a,c,d,e,g){function i(a,b){var c=e.createElement("script"),d=function(){e.body.removeChild(c);b&&b()};c.type="text/javascript";c.src=a;Z?c.onreadystatechange=function(){/loaded|complete/.test(c.readyState)&&d()}:c.onload=c.onerror=d;e.body.appendChild(c);return d}return function(e,h,j,m,k,l,u,o){function z(){p=-1;t&&t();v&&v.abort()}function r(a,d,e,f){var j=(h.match(jb)||["",g])[1];A&&c.cancel(A);t=v=null;d=j=="file"?e?200:404:d;a(d==1223?204:d,e,f);b.$$completeOutstandingRequest(q)}
+var p;b.$$incOutstandingRequestCount();h=h||b.url();if(I(e)=="jsonp"){var x="_"+(d.counter++).toString(36);d[x]=function(a){d[x].data=a};var t=i(h.replace("JSON_CALLBACK","angular.callbacks."+x),function(){d[x].data?r(m,200,d[x].data):r(m,p||-2);delete d[x]})}else{var v=new a;v.open(e,h,!0);n(k,function(a,b){a&&v.setRequestHeader(b,a)});v.onreadystatechange=function(){if(v.readyState==4){var a=v.getAllResponseHeaders(),b=["Cache-Control","Content-Language","Content-Type","Expires","Last-Modified",
+"Pragma"];a||(a="",n(b,function(b){var c=v.getResponseHeader(b);c&&(a+=b+": "+c+"\n")}));r(m,p||v.status,v.responseType?v.response:v.responseText,a)}};if(u)v.withCredentials=!0;if(o)v.responseType=o;v.send(j||"")}if(l>0)var A=c(z,l);else l&&l.then&&l.then(z)}}function fd(){this.$get=function(){return{id:"en-us",NUMBER_FORMATS:{DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{minInt:1,minFrac:0,maxFrac:3,posPre:"",posSuf:"",negPre:"-",negSuf:"",gSize:3,lgSize:3},{minInt:1,minFrac:2,maxFrac:2,posPre:"\u00a4",
+posSuf:"",negPre:"(\u00a4",negSuf:")",gSize:3,lgSize:3}],CURRENCY_SYM:"$"},DATETIME_FORMATS:{MONTH:"January,February,March,April,May,June,July,August,September,October,November,December".split(","),SHORTMONTH:"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),DAY:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),SHORTDAY:"Sun,Mon,Tue,Wed,Thu,Fri,Sat".split(","),AMPMS:["AM","PM"],medium:"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a",fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",
+mediumDate:"MMM d, y",shortDate:"M/d/yy",mediumTime:"h:mm:ss a",shortTime:"h:mm a"},pluralCat:function(b){return b===1?"one":"other"}}}}function gd(){this.$get=["$rootScope","$browser","$q","$exceptionHandler",function(b,a,c,d){function e(e,f,h){var j=c.defer(),m=j.promise,k=B(h)&&!h,f=a.defer(function(){try{j.resolve(e())}catch(a){j.reject(a),d(a)}k||b.$apply()},f),h=function(){delete g[m.$$timeoutId]};m.$$timeoutId=f;g[f]=j;m.then(h,h);return m}var g={};e.cancel=function(b){return b&&b.$$timeoutId in
+g?(g[b.$$timeoutId].reject("canceled"),a.defer.cancel(b.$$timeoutId)):!1};return e}]}function Zb(b){function a(a,e){return b.factory(a+c,e)}var c="Filter";this.register=a;this.$get=["$injector",function(a){return function(b){return a.get(b+c)}}];a("currency",$b);a("date",ac);a("filter",hd);a("json",id);a("limitTo",jd);a("lowercase",kd);a("number",bc);a("orderBy",cc);a("uppercase",ld)}function hd(){return function(b,a,c){if(!F(b))return b;var d=[];d.check=function(a){for(var b=0;b<d.length;b++)if(!d[b](a))return!1;
+return!0};switch(typeof c){case "function":break;case "boolean":if(c==!0){c=function(a,b){return Ha.equals(a,b)};break}default:c=function(a,b){b=(""+b).toLowerCase();return(""+a).toLowerCase().indexOf(b)>-1}}var e=function(a,b){if(typeof b=="string"&&b.charAt(0)==="!")return!e(a,b.substr(1));switch(typeof a){case "boolean":case "number":case "string":return c(a,b);case "object":switch(typeof b){case "object":return c(a,b);default:for(var d in a)if(d.charAt(0)!=="$"&&e(a[d],b))return!0}return!1;case "array":for(d=
+0;d<a.length;d++)if(e(a[d],b))return!0;return!1;default:return!1}};switch(typeof a){case "boolean":case "number":case "string":a={$:a};case "object":for(var g in a)g=="$"?function(){if(a[g]){var b=g;d.push(function(c){return e(c,a[b])})}}():function(){if(a[g]){var b=g;d.push(function(c){return e(ib(c,b),a[b])})}}();break;case "function":d.push(a);break;default:return b}for(var i=[],f=0;f<b.length;f++){var h=b[f];d.check(h)&&i.push(h)}return i}}function $b(b){var a=b.NUMBER_FORMATS;return function(b,
+d){if(C(d))d=a.CURRENCY_SYM;return dc(b,a.PATTERNS[1],a.GROUP_SEP,a.DECIMAL_SEP,2).replace(/\u00A4/g,d)}}function bc(b){var a=b.NUMBER_FORMATS;return function(b,d){return dc(b,a.PATTERNS[0],a.GROUP_SEP,a.DECIMAL_SEP,d)}}function dc(b,a,c,d,e){if(isNaN(b)||!isFinite(b))return"";var g=b<0,b=Math.abs(b),i=b+"",f="",h=[],j=!1;if(i.indexOf("e")!==-1){var m=i.match(/([\d\.]+)e(-?)(\d+)/);m&&m[2]=="-"&&m[3]>e+1?i="0":(f=i,j=!0)}if(!j){i=(i.split(ec)[1]||"").length;C(e)&&(e=Math.min(Math.max(a.minFrac,i),
+a.maxFrac));var i=Math.pow(10,e),b=Math.round(b*i)/i,b=(""+b).split(ec),i=b[0],b=b[1]||"",j=0,m=a.lgSize,k=a.gSize;if(i.length>=m+k)for(var j=i.length-m,l=0;l<j;l++)(j-l)%k===0&&l!==0&&(f+=c),f+=i.charAt(l);for(l=j;l<i.length;l++)(i.length-l)%m===0&&l!==0&&(f+=c),f+=i.charAt(l);for(;b.length<e;)b+="0";e&&e!=="0"&&(f+=d+b.substr(0,e))}h.push(g?a.negPre:a.posPre);h.push(f);h.push(g?a.negSuf:a.posSuf);return h.join("")}function nb(b,a,c){var d="";b<0&&(d="-",b=-b);for(b=""+b;b.length<a;)b="0"+b;c&&(b=
+b.substr(b.length-a));return d+b}function Q(b,a,c,d){c=c||0;return function(e){e=e["get"+b]();if(c>0||e>-c)e+=c;e===0&&c==-12&&(e=12);return nb(e,a,d)}}function Qa(b,a){return function(c,d){var e=c["get"+b](),g=oa(a?"SHORT"+b:b);return d[g][e]}}function ac(b){function a(a){var b;if(b=a.match(c)){var a=new Date(0),g=0,i=0,f=b[8]?a.setUTCFullYear:a.setFullYear,h=b[8]?a.setUTCHours:a.setHours;b[9]&&(g=N(b[9]+b[10]),i=N(b[9]+b[11]));f.call(a,N(b[1]),N(b[2])-1,N(b[3]));g=N(b[4]||0)-g;i=N(b[5]||0)-i;f=
+N(b[6]||0);b=Math.round(parseFloat("0."+(b[7]||0))*1E3);h.call(a,g,i,f,b)}return a}var c=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;return function(c,e){var g="",i=[],f,h,e=e||"mediumDate",e=b.DATETIME_FORMATS[e]||e;E(c)&&(c=md.test(c)?N(c):a(c));Ya(c)&&(c=new Date(c));if(!ra(c))return c;for(;e;)(h=nd.exec(e))?(i=i.concat(ka.call(h,1)),e=i.pop()):(i.push(e),e=null);n(i,function(a){f=od[a];g+=f?f(c,b.DATETIME_FORMATS):a.replace(/(^'|'$)/g,
+"").replace(/''/g,"'")});return g}}function id(){return function(b){return ha(b,!0)}}function jd(){return function(b,a){if(!F(b)&&!E(b))return b;a=N(a);if(E(b))return a?a>=0?b.slice(0,a):b.slice(a,b.length):"";var c=[],d,e;a>b.length?a=b.length:a<-b.length&&(a=-b.length);a>0?(d=0,e=a):(d=b.length+a,e=b.length);for(;d<e;d++)c.push(b[d]);return c}}function cc(b){return function(a,c,d){function e(a,b){return ua(b)?function(b,c){return a(c,b)}:a}if(!F(a))return a;if(!c)return a;for(var c=F(c)?c:[c],c=
+Za(c,function(a){var c=!1,d=a||qa;if(E(a)){if(a.charAt(0)=="+"||a.charAt(0)=="-")c=a.charAt(0)=="-",a=a.substring(1);d=b(a)}return e(function(a,b){var c;c=d(a);var e=d(b),f=typeof c,g=typeof e;f==g?(f=="string"&&(c=c.toLowerCase()),f=="string"&&(e=e.toLowerCase()),c=c===e?0:c<e?-1:1):c=f<g?-1:1;return c},c)}),g=[],i=0;i<a.length;i++)g.push(a[i]);return g.sort(e(function(a,b){for(var d=0;d<c.length;d++){var e=c[d](a,b);if(e!==0)return e}return 0},d))}}function aa(b){H(b)&&(b={link:b});b.restrict=b.restrict||
+"AC";return S(b)}function fc(b,a){function c(a,c){c=c?"-"+bb(c,"-"):"";b.removeClass((a?Ra:Sa)+c).addClass((a?Sa:Ra)+c)}var d=this,e=b.parent().controller("form")||Ta,g=0,i=d.$error={},f=[];d.$name=a.name;d.$dirty=!1;d.$pristine=!0;d.$valid=!0;d.$invalid=!1;e.$addControl(d);b.addClass(pa);c(!0);d.$addControl=function(a){f.push(a);a.$name&&!d.hasOwnProperty(a.$name)&&(d[a.$name]=a)};d.$removeControl=function(a){a.$name&&d[a.$name]===a&&delete d[a.$name];n(i,function(b,c){d.$setValidity(c,!0,a)});ta(f,
+a)};d.$setValidity=function(a,b,f){var k=i[a];if(b){if(k&&(ta(k,f),!k.length)){g--;if(!g)c(b),d.$valid=!0,d.$invalid=!1;i[a]=!1;c(!0,a);e.$setValidity(a,!0,d)}}else{g||c(b);if(k){if(Ga(k,f)!=-1)return}else i[a]=k=[],g++,c(!1,a),e.$setValidity(a,!1,d);k.push(f);d.$valid=!1;d.$invalid=!0}};d.$setDirty=function(){b.removeClass(pa).addClass(Ua);d.$dirty=!0;d.$pristine=!1;e.$setDirty()};d.$setPristine=function(){b.removeClass(Ua).addClass(pa);d.$dirty=!1;d.$pristine=!0;n(f,function(a){a.$setPristine()})}}
+function X(b){return C(b)||b===""||b===null||b!==b}function Va(b,a,c,d,e,g){var i=function(){var e=a.val();if(ua(c.ngTrim||"T"))e=U(e);d.$viewValue!==e&&b.$apply(function(){d.$setViewValue(e)})};if(e.hasEvent("input"))a.bind("input",i);else{var f,h=function(){f||(f=g.defer(function(){i();f=null}))};a.bind("keydown",function(a){a=a.keyCode;a===91||15<a&&a<19||37<=a&&a<=40||h()});a.bind("change",i);e.hasEvent("paste")&&a.bind("paste cut",h)}d.$render=function(){a.val(X(d.$viewValue)?"":d.$viewValue)};
+var j=c.ngPattern,m=function(a,b){return X(b)||a.test(b)?(d.$setValidity("pattern",!0),b):(d.$setValidity("pattern",!1),p)};j&&((e=j.match(/^\/(.*)\/([gim]*)$/))?(j=RegExp(e[1],e[2]),e=function(a){return m(j,a)}):e=function(a){var c=b.$eval(j);if(!c||!c.test)throw Error("Expected "+j+" to be a RegExp but was "+c);return m(c,a)},d.$formatters.push(e),d.$parsers.push(e));if(c.ngMinlength){var k=N(c.ngMinlength),e=function(a){return!X(a)&&a.length<k?(d.$setValidity("minlength",!1),p):(d.$setValidity("minlength",
+!0),a)};d.$parsers.push(e);d.$formatters.push(e)}if(c.ngMaxlength){var l=N(c.ngMaxlength),e=function(a){return!X(a)&&a.length>l?(d.$setValidity("maxlength",!1),p):(d.$setValidity("maxlength",!0),a)};d.$parsers.push(e);d.$formatters.push(e)}}function ob(b,a){b="ngClass"+b;return aa(function(c,d,e){function g(b){if(a===!0||c.$index%2===a)h&&!ia(b,h)&&i(h),f(b);h=V(b)}function i(a){L(a)&&!F(a)&&(a=Za(a,function(a,b){if(a)return b}));d.removeClass(F(a)?a.join(" "):a)}function f(a){L(a)&&!F(a)&&(a=Za(a,
+function(a,b){if(a)return b}));a&&d.addClass(F(a)?a.join(" "):a)}var h=p;c.$watch(e[b],g,!0);e.$observe("class",function(){var a=c.$eval(e[b]);g(a,a)});b!=="ngClass"&&c.$watch("$index",function(d,g){var h=d&1;h!==g&1&&(h===a?f(c.$eval(e[b])):i(c.$eval(e[b])))})})}var I=function(b){return E(b)?b.toLowerCase():b},oa=function(b){return E(b)?b.toUpperCase():b},Z=N((/msie (\d+)/.exec(I(navigator.userAgent))||[])[1]),w,ga,ka=[].slice,Wa=[].push,Ea=Object.prototype.toString,mc=M.angular,Ha=M.angular||(M.angular=
+{}),Aa,hb,ba=["0","0","0"];q.$inject=[];qa.$inject=[];hb=Z<9?function(b){b=b.nodeName?b:b[0];return b.scopeName&&b.scopeName!="HTML"?oa(b.scopeName+":"+b.nodeName):b.nodeName}:function(b){return b.nodeName?b.nodeName:b[0].nodeName};var sc=/[A-Z]/g,pd={full:"1.1.5",major:1,minor:1,dot:5,codeName:"triangle-squarification"},Ka=R.cache={},Ja=R.expando="ng-"+(new Date).getTime(),wc=1,gc=M.document.addEventListener?function(b,a,c){b.addEventListener(a,c,!1)}:function(b,a,c){b.attachEvent("on"+a,c)},gb=
+M.document.removeEventListener?function(b,a,c){b.removeEventListener(a,c,!1)}:function(b,a,c){b.detachEvent("on"+a,c)},uc=/([\:\-\_]+(.))/g,vc=/^moz([A-Z])/,Ba=R.prototype={ready:function(b){function a(){c||(c=!0,b())}var c=!1;T.readyState==="complete"?setTimeout(a):(this.bind("DOMContentLoaded",a),R(M).bind("load",a))},toString:function(){var b=[];n(this,function(a){b.push(""+a)});return"["+b.join(", ")+"]"},eq:function(b){return b>=0?w(this[b]):w(this[this.length+b])},length:0,push:Wa,sort:[].sort,
+splice:[].splice},Na={};n("multiple,selected,checked,disabled,readOnly,required,open".split(","),function(b){Na[I(b)]=b});var Gb={};n("input,select,option,textarea,button,form,details".split(","),function(b){Gb[oa(b)]=!0});n({data:Bb,inheritedData:Ma,scope:function(b){return Ma(b,"$scope")},controller:Eb,injector:function(b){return Ma(b,"$injector")},removeAttr:function(b,a){b.removeAttribute(a)},hasClass:La,css:function(b,a,c){a=Ia(a);if(B(c))b.style[a]=c;else{var d;Z<=8&&(d=b.currentStyle&&b.currentStyle[a],
+d===""&&(d="auto"));d=d||b.style[a];Z<=8&&(d=d===""?p:d);return d}},attr:function(b,a,c){var d=I(a);if(Na[d])if(B(c))c?(b[a]=!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d));else return b[a]||(b.attributes.getNamedItem(a)||q).specified?d:p;else if(B(c))b.setAttribute(a,c);else if(b.getAttribute)return b=b.getAttribute(a,2),b===null?p:b},prop:function(b,a,c){if(B(c))b[a]=c;else return b[a]},text:t(Z<9?function(b,a){if(b.nodeType==1){if(C(a))return b.innerText;b.innerText=a}else{if(C(a))return b.nodeValue;
+b.nodeValue=a}}:function(b,a){if(C(a))return b.textContent;b.textContent=a},{$dv:""}),val:function(b,a){if(C(a))return b.value;b.value=a},html:function(b,a){if(C(a))return b.innerHTML;for(var c=0,d=b.childNodes;c<d.length;c++)ya(d[c]);b.innerHTML=a}},function(b,a){R.prototype[a]=function(a,d){var e,g;if((b.length==2&&b!==La&&b!==Eb?a:d)===p)if(L(a)){for(e=0;e<this.length;e++)if(b===Bb)b(this[e],a);else for(g in a)b(this[e],g,a[g]);return this}else{if(this.length)return b(this[0],a,d)}else{for(e=0;e<
+this.length;e++)b(this[e],a,d);return this}return b.$dv}});n({removeData:zb,dealoc:ya,bind:function a(c,d,e){var g=ca(c,"events"),i=ca(c,"handle");g||ca(c,"events",g={});i||ca(c,"handle",i=xc(c,g));n(d.split(" "),function(d){var h=g[d];if(!h){if(d=="mouseenter"||d=="mouseleave"){var j=T.body.contains||T.body.compareDocumentPosition?function(a,c){var d=a.nodeType===9?a.documentElement:a,e=c&&c.parentNode;return a===e||!(!e||!(e.nodeType===1&&(d.contains?d.contains(e):a.compareDocumentPosition&&a.compareDocumentPosition(e)&
+16)))}:function(a,c){if(c)for(;c=c.parentNode;)if(c===a)return!0;return!1};g[d]=[];a(c,{mouseleave:"mouseout",mouseenter:"mouseover"}[d],function(a){var c=a.relatedTarget;(!c||c!==this&&!j(this,c))&&i(a,d)})}else gc(c,d,i),g[d]=[];h=g[d]}h.push(e)})},unbind:Ab,replaceWith:function(a,c){var d,e=a.parentNode;ya(a);n(new R(c),function(c){d?e.insertBefore(c,d.nextSibling):e.replaceChild(c,a);d=c})},children:function(a){var c=[];n(a.childNodes,function(a){a.nodeType===1&&c.push(a)});return c},contents:function(a){return a.childNodes||
+[]},append:function(a,c){n(new R(c),function(c){(a.nodeType===1||a.nodeType===11)&&a.appendChild(c)})},prepend:function(a,c){if(a.nodeType===1){var d=a.firstChild;n(new R(c),function(c){d?a.insertBefore(c,d):(a.appendChild(c),d=c)})}},wrap:function(a,c){var c=w(c)[0],d=a.parentNode;d&&d.replaceChild(c,a);c.appendChild(a)},remove:function(a){ya(a);var c=a.parentNode;c&&c.removeChild(a)},after:function(a,c){var d=a,e=a.parentNode;n(new R(c),function(a){e.insertBefore(a,d.nextSibling);d=a})},addClass:Db,
+removeClass:Cb,toggleClass:function(a,c,d){C(d)&&(d=!La(a,c));(d?Db:Cb)(a,c)},parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},next:function(a){if(a.nextElementSibling)return a.nextElementSibling;for(a=a.nextSibling;a!=null&&a.nodeType!==1;)a=a.nextSibling;return a},find:function(a,c){return a.getElementsByTagName(c)},clone:fb,triggerHandler:function(a,c){var d=(ca(a,"events")||{})[c];n(d,function(c){c.call(a,{preventDefault:q})})}},function(a,c){R.prototype[c]=function(c,e){for(var g,
+i=0;i<this.length;i++)g==p?(g=a(this[i],c,e),g!==p&&(g=w(g))):eb(g,a(this[i],c,e));return g==p?this:g}});za.prototype={put:function(a,c){this[la(a)]=c},get:function(a){return this[la(a)]},remove:function(a){var c=this[a=la(a)];delete this[a];return c}};var zc=/^function\s*[^\(]*\(\s*([^\)]*)\)/m,Ac=/,/,Bc=/^\s*(_?)(\S+?)\1\s*$/,yc=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;Ib.$inject=["$provide"];var qd=function(){var a="$ngAnimateController",c={running:!0};this.$get=["$animation","$window","$sniffer","$rootElement",
+"$rootScope",function(d,e,g,i){i.data(a,c);i=function(c,i){function j(j,k,o){return function(m,r,p){function x(a){var c=0,a=E(a)?a.split(/\s*,\s*/):[];n(a,function(a){c=Math.max(parseFloat(a)||0,c)});return c}function t(){m.addClass(K);if($)$(m,v,P);else if(H(e.getComputedStyle)){var a=g.vendorPrefix+"Animation",c=g.vendorPrefix+"Transition",d=0;n(m,function(f){if(f.nodeType==1){var g="transition",i=c,j=1,h=e.getComputedStyle(f)||{};if(parseFloat(h.animationDuration)>0||parseFloat(h[a+"Duration"])>
+0)g="animation",i=a,j=Math.max(parseInt(h[g+"IterationCount"])||0,parseInt(h[i+"IterationCount"])||0,j);f=Math.max(x(h[g+"Delay"]),x(h[i+"Delay"]));g=Math.max(x(h[g+"Duration"]),x(h[i+"Duration"]));d=Math.max(f+j*g,d)}});e.setTimeout(v,d*1E3)}else v()}function v(){if(!v.run)v.run=!0,o(m,r,p),m.removeClass(w),m.removeClass(K),m.removeData(a)}var A=c.$eval(i.ngAnimate),w=A?L(A)?A[j]:A+"-"+j:"",D=d(w),A=D&&D.setup,$=D&&D.start,D=D&&D.cancel;if(w){var K=w+"-active";r||(r=p?p.parent():m.parent());if(!g.transitions&&
+!A&&!$||(r.inheritedData(a)||q).running)k(m,r,p),o(m,r,p);else{var O=m.data(a)||{};O.running&&((D||q)(m),O.done());m.data(a,{running:!0,done:v});m.addClass(w);k(m,r,p);if(m.length==0)return v();var P=(A||q)(m);e.setTimeout(t,1)}}else k(m,r,p),o(m,r,p)}}function m(a,c,d){d?d.after(a):c.append(a)}var k={};k.enter=j("enter",m,q);k.leave=j("leave",q,function(a){a.remove()});k.move=j("move",function(a,c,d){m(a,c,d)},q);k.show=j("show",function(a){a.css("display","")},q);k.hide=j("hide",q,function(a){a.css("display",
+"none")});k.animate=function(a,c){j(a,q,q)(c)};return k};i.enabled=function(a){if(arguments.length)c.running=!a;return!c.running};return i}]},Kb="Non-assignable model expression: ";Jb.$inject=["$provide"];var Ic=/^(x[\:\-_]|data[\:\-_])/i,jb=/^([^:]+):\/\/(\w+:{0,1}\w*@)?(\{?[\w\.-]*\}?)(:([0-9]+))?(\/[^\?#]*)?(\?([^#]*))?(#(.*))?$/,Pb=/^([^\?#]*)(\?([^#]*))?(#(.*))?$/,Oa={http:80,https:443,ftp:21};Rb.prototype=lb.prototype=Qb.prototype={$$replace:!1,absUrl:Pa("$$absUrl"),url:function(a,c){if(C(a))return this.$$url;
+var d=Pb.exec(a);d[1]&&this.path(decodeURIComponent(d[1]));if(d[2]||d[1])this.search(d[3]||"");this.hash(d[5]||"",c);return this},protocol:Pa("$$protocol"),host:Pa("$$host"),port:Pa("$$port"),path:Sb("$$path",function(a){return a.charAt(0)=="/"?a:"/"+a}),search:function(a,c){if(C(a))return this.$$search;B(c)?c===null?delete this.$$search[a]:this.$$search[a]=c:this.$$search=E(a)?vb(a):a;this.$$compose();return this},hash:Sb("$$hash",qa),replace:function(){this.$$replace=!0;return this}};var Da={"null":function(){return null},
+"true":function(){return!0},"false":function(){return!1},undefined:q,"+":function(a,c,d,e){d=d(a,c);e=e(a,c);return B(d)?B(e)?d+e:d:B(e)?e:p},"-":function(a,c,d,e){d=d(a,c);e=e(a,c);return(B(d)?d:0)-(B(e)?e:0)},"*":function(a,c,d,e){return d(a,c)*e(a,c)},"/":function(a,c,d,e){return d(a,c)/e(a,c)},"%":function(a,c,d,e){return d(a,c)%e(a,c)},"^":function(a,c,d,e){return d(a,c)^e(a,c)},"=":q,"===":function(a,c,d,e){return d(a,c)===e(a,c)},"!==":function(a,c,d,e){return d(a,c)!==e(a,c)},"==":function(a,
+c,d,e){return d(a,c)==e(a,c)},"!=":function(a,c,d,e){return d(a,c)!=e(a,c)},"<":function(a,c,d,e){return d(a,c)<e(a,c)},">":function(a,c,d,e){return d(a,c)>e(a,c)},"<=":function(a,c,d,e){return d(a,c)<=e(a,c)},">=":function(a,c,d,e){return d(a,c)>=e(a,c)},"&&":function(a,c,d,e){return d(a,c)&&e(a,c)},"||":function(a,c,d,e){return d(a,c)||e(a,c)},"&":function(a,c,d,e){return d(a,c)&e(a,c)},"|":function(a,c,d,e){return e(a,c)(a,c,d(a,c))},"!":function(a,c,d){return!d(a,c)}},Qc={n:"\n",f:"\u000c",r:"\r",
+t:"\t",v:"\u000b","'":"'",'"':'"'},mb={},ad=/^(([^:]+):)?\/\/(\w+:{0,1}\w*@)?([\w\.-]*)?(:([0-9]+))?(.*)$/,ed=M.XMLHttpRequest||function(){try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(a){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(c){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(d){}throw Error("This browser does not support XMLHttpRequest.");};Zb.$inject=["$provide"];$b.$inject=["$locale"];bc.$inject=["$locale"];var ec=".",od={yyyy:Q("FullYear",4),yy:Q("FullYear",
+2,0,!0),y:Q("FullYear",1),MMMM:Qa("Month"),MMM:Qa("Month",!0),MM:Q("Month",2,1),M:Q("Month",1,1),dd:Q("Date",2),d:Q("Date",1),HH:Q("Hours",2),H:Q("Hours",1),hh:Q("Hours",2,-12),h:Q("Hours",1,-12),mm:Q("Minutes",2),m:Q("Minutes",1),ss:Q("Seconds",2),s:Q("Seconds",1),sss:Q("Milliseconds",3),EEEE:Qa("Day"),EEE:Qa("Day",!0),a:function(a,c){return a.getHours()<12?c.AMPMS[0]:c.AMPMS[1]},Z:function(a){var a=-1*a.getTimezoneOffset(),c=a>=0?"+":"";c+=nb(Math[a>0?"floor":"ceil"](a/60),2)+nb(Math.abs(a%60),
+2);return c}},nd=/((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z))(.*)/,md=/^\d+$/;ac.$inject=["$locale"];var kd=S(I),ld=S(oa);cc.$inject=["$parse"];var rd=S({restrict:"E",compile:function(a,c){Z<=8&&(!c.href&&!c.name&&c.$set("href",""),a.append(T.createComment("IE fix")));return function(a,c){c.bind("click",function(a){c.attr("href")||a.preventDefault()})}}}),pb={};n(Na,function(a,c){var d=da("ng-"+c);pb[d]=function(){return{priority:100,compile:function(){return function(a,
+g,i){a.$watch(i[d],function(a){i.$set(c,!!a)})}}}}});n(["src","srcset","href"],function(a){var c=da("ng-"+a);pb[c]=function(){return{priority:99,link:function(d,e,g){g.$observe(c,function(c){c&&(g.$set(a,c),Z&&e.prop(a,g[a]))})}}}});var Ta={$addControl:q,$removeControl:q,$setValidity:q,$setDirty:q,$setPristine:q};fc.$inject=["$element","$attrs","$scope"];var Wa=function(a){return["$timeout",function(c){var d={name:"form",restrict:"E",controller:fc,compile:function(){return{pre:function(a,d,i,f){if(!i.action){var h=
+function(a){a.preventDefault?a.preventDefault():a.returnValue=!1};gc(d[0],"submit",h);d.bind("$destroy",function(){c(function(){gb(d[0],"submit",h)},0,!1)})}var j=d.parent().controller("form"),m=i.name||i.ngForm;m&&(a[m]=f);j&&d.bind("$destroy",function(){j.$removeControl(f);m&&(a[m]=p);t(f,Ta)})}}}};return a?t(V(d),{restrict:"EAC"}):d}]},sd=Wa(),td=Wa(!0),ud=/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/,vd=/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/,
+wd=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/,hc={text:Va,number:function(a,c,d,e,g,i){Va(a,c,d,e,g,i);e.$parsers.push(function(a){var c=X(a);return c||wd.test(a)?(e.$setValidity("number",!0),a===""?null:c?a:parseFloat(a)):(e.$setValidity("number",!1),p)});e.$formatters.push(function(a){return X(a)?"":""+a});if(d.min){var f=parseFloat(d.min),a=function(a){return!X(a)&&a<f?(e.$setValidity("min",!1),p):(e.$setValidity("min",!0),a)};e.$parsers.push(a);e.$formatters.push(a)}if(d.max){var h=parseFloat(d.max),
+d=function(a){return!X(a)&&a>h?(e.$setValidity("max",!1),p):(e.$setValidity("max",!0),a)};e.$parsers.push(d);e.$formatters.push(d)}e.$formatters.push(function(a){return X(a)||Ya(a)?(e.$setValidity("number",!0),a):(e.$setValidity("number",!1),p)})},url:function(a,c,d,e,g,i){Va(a,c,d,e,g,i);a=function(a){return X(a)||ud.test(a)?(e.$setValidity("url",!0),a):(e.$setValidity("url",!1),p)};e.$formatters.push(a);e.$parsers.push(a)},email:function(a,c,d,e,g,i){Va(a,c,d,e,g,i);a=function(a){return X(a)||vd.test(a)?
+(e.$setValidity("email",!0),a):(e.$setValidity("email",!1),p)};e.$formatters.push(a);e.$parsers.push(a)},radio:function(a,c,d,e){C(d.name)&&c.attr("name",Fa());c.bind("click",function(){c[0].checked&&a.$apply(function(){e.$setViewValue(d.value)})});e.$render=function(){c[0].checked=d.value==e.$viewValue};d.$observe("value",e.$render)},checkbox:function(a,c,d,e){var g=d.ngTrueValue,i=d.ngFalseValue;E(g)||(g=!0);E(i)||(i=!1);c.bind("click",function(){a.$apply(function(){e.$setViewValue(c[0].checked)})});
+e.$render=function(){c[0].checked=e.$viewValue};e.$formatters.push(function(a){return a===g});e.$parsers.push(function(a){return a?g:i})},hidden:q,button:q,submit:q,reset:q},ic=["$browser","$sniffer",function(a,c){return{restrict:"E",require:"?ngModel",link:function(d,e,g,i){i&&(hc[I(g.type)]||hc.text)(d,e,g,i,c,a)}}}],Sa="ng-valid",Ra="ng-invalid",pa="ng-pristine",Ua="ng-dirty",xd=["$scope","$exceptionHandler","$attrs","$element","$parse",function(a,c,d,e,g){function i(a,c){c=c?"-"+bb(c,"-"):"";
+e.removeClass((a?Ra:Sa)+c).addClass((a?Sa:Ra)+c)}this.$modelValue=this.$viewValue=Number.NaN;this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$pristine=!0;this.$dirty=!1;this.$valid=!0;this.$invalid=!1;this.$name=d.name;var f=g(d.ngModel),h=f.assign;if(!h)throw Error(Kb+d.ngModel+" ("+va(e)+")");this.$render=q;var j=e.inheritedData("$formController")||Ta,m=0,k=this.$error={};e.addClass(pa);i(!0);this.$setValidity=function(a,c){if(k[a]!==!c){if(c){if(k[a]&&m--,!m)i(!0),this.$valid=
+!0,this.$invalid=!1}else i(!1),this.$invalid=!0,this.$valid=!1,m++;k[a]=!c;i(c,a);j.$setValidity(a,c,this)}};this.$setPristine=function(){this.$dirty=!1;this.$pristine=!0;e.removeClass(Ua).addClass(pa)};this.$setViewValue=function(d){this.$viewValue=d;if(this.$pristine)this.$dirty=!0,this.$pristine=!1,e.removeClass(pa).addClass(Ua),j.$setDirty();n(this.$parsers,function(a){d=a(d)});if(this.$modelValue!==d)this.$modelValue=d,h(a,d),n(this.$viewChangeListeners,function(a){try{a()}catch(d){c(d)}})};
+var l=this;a.$watch(function(){var c=f(a);if(l.$modelValue!==c){var d=l.$formatters,e=d.length;for(l.$modelValue=c;e--;)c=d[e](c);if(l.$viewValue!==c)l.$viewValue=c,l.$render()}})}],yd=function(){return{require:["ngModel","^?form"],controller:xd,link:function(a,c,d,e){var g=e[0],i=e[1]||Ta;i.$addControl(g);c.bind("$destroy",function(){i.$removeControl(g)})}}},zd=S({require:"ngModel",link:function(a,c,d,e){e.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}),jc=function(){return{require:"?ngModel",
+link:function(a,c,d,e){if(e){d.required=!0;var g=function(a){if(d.required&&(X(a)||a===!1))e.$setValidity("required",!1);else return e.$setValidity("required",!0),a};e.$formatters.push(g);e.$parsers.unshift(g);d.$observe("required",function(){g(e.$viewValue)})}}}},Ad=function(){return{require:"ngModel",link:function(a,c,d,e){var g=(a=/\/(.*)\//.exec(d.ngList))&&RegExp(a[1])||d.ngList||",";e.$parsers.push(function(a){var c=[];a&&n(a.split(g),function(a){a&&c.push(U(a))});return c});e.$formatters.push(function(a){return F(a)?
+a.join(", "):p})}}},Bd=/^(true|false|\d+)$/,Cd=function(){return{priority:100,compile:function(a,c){return Bd.test(c.ngValue)?function(a,c,g){g.$set("value",a.$eval(g.ngValue))}:function(a,c,g){a.$watch(g.ngValue,function(a){g.$set("value",a,!1)})}}}},Dd=aa(function(a,c,d){c.addClass("ng-binding").data("$binding",d.ngBind);a.$watch(d.ngBind,function(a){c.text(a==p?"":a)})}),Ed=["$interpolate",function(a){return function(c,d,e){c=a(d.attr(e.$attr.ngBindTemplate));d.addClass("ng-binding").data("$binding",
+c);e.$observe("ngBindTemplate",function(a){d.text(a)})}}],Fd=[function(){return function(a,c,d){c.addClass("ng-binding").data("$binding",d.ngBindHtmlUnsafe);a.$watch(d.ngBindHtmlUnsafe,function(a){c.html(a||"")})}}],Gd=ob("",!0),Hd=ob("Odd",0),Id=ob("Even",1),Jd=aa({compile:function(a,c){c.$set("ngCloak",p);a.removeClass("ng-cloak")}}),Kd=[function(){return{scope:!0,controller:"@"}}],Ld=["$sniffer",function(a){return{priority:1E3,compile:function(){a.csp=!0}}}],kc={};n("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress".split(" "),
+function(a){var c=da("ng-"+a);kc[c]=["$parse",function(d){return function(e,g,i){var f=d(i[c]);g.bind(I(a),function(a){e.$apply(function(){f(e,{$event:a})})})}}]});var Md=aa(function(a,c,d){c.bind("submit",function(){a.$apply(d.ngSubmit)})}),Nd=["$animator",function(a){return{transclude:"element",priority:1E3,terminal:!0,restrict:"A",compile:function(c,d,e){return function(c,d,f){var h=a(c,f),j,m;c.$watch(f.ngIf,function(a){j&&(h.leave(j),j=p);m&&(m.$destroy(),m=p);ua(a)&&(m=c.$new(),e(m,function(a){j=
+a;h.enter(a,d.parent(),d)}))})}}}}],Od=["$http","$templateCache","$anchorScroll","$compile","$animator",function(a,c,d,e,g){return{restrict:"ECA",terminal:!0,compile:function(i,f){var h=f.ngInclude||f.src,j=f.onload||"",m=f.autoscroll;return function(f,i,n){var o=g(f,n),p=0,r,t=function(){r&&(r.$destroy(),r=null);o.leave(i.contents(),i)};f.$watch(h,function(g){var h=++p;g?(a.get(g,{cache:c}).success(function(a){h===p&&(r&&r.$destroy(),r=f.$new(),o.leave(i.contents(),i),a=w("<div/>").html(a).contents(),
+o.enter(a,i),e(a)(r),B(m)&&(!m||f.$eval(m))&&d(),r.$emit("$includeContentLoaded"),f.$eval(j))}).error(function(){h===p&&t()}),f.$emit("$includeContentRequested")):t()})}}}}],Pd=aa({compile:function(){return{pre:function(a,c,d){a.$eval(d.ngInit)}}}}),Qd=aa({terminal:!0,priority:1E3}),Rd=["$locale","$interpolate",function(a,c){var d=/{}/g;return{restrict:"EA",link:function(e,g,i){var f=i.count,h=g.attr(i.$attr.when),j=i.offset||0,m=e.$eval(h),k={},l=c.startSymbol(),p=c.endSymbol();n(m,function(a,e){k[e]=
+c(a.replace(d,l+f+"-"+j+p))});e.$watch(function(){var c=parseFloat(e.$eval(f));return isNaN(c)?"":(c in m||(c=a.pluralCat(c-j)),k[c](e,g,!0))},function(a){g.text(a)})}}}],Sd=["$parse","$animator",function(a,c){return{transclude:"element",priority:1E3,terminal:!0,compile:function(d,e,g){return function(d,e,h){var j=c(d,h),m=h.ngRepeat,k=m.match(/^\s*(.+)\s+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$/),l,p,o,z,r,t={$id:la};if(!k)throw Error("Expected ngRepeat in form of '_item_ in _collection_[ track by _id_]' but got '"+
+m+"'.");h=k[1];o=k[2];(k=k[4])?(l=a(k),p=function(a,c,e){r&&(t[r]=a);t[z]=c;t.$index=e;return l(d,t)}):p=function(a,c){return la(c)};k=h.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);if(!k)throw Error("'item' in 'item in collection' should be identifier or (key, value) but got '"+h+"'.");z=k[3]||k[1];r=k[2];var x={};d.$watchCollection(o,function(a){var c,h,k=e,l,o={},t,q,w,s,B,y,C=[];if(Xa(a))B=a;else{B=[];for(w in a)a.hasOwnProperty(w)&&w.charAt(0)!="$"&&B.push(w);B.sort()}t=B.length;h=
+C.length=B.length;for(c=0;c<h;c++)if(w=a===B?c:B[c],s=a[w],l=p(w,s,c),x.hasOwnProperty(l))y=x[l],delete x[l],o[l]=y,C[c]=y;else if(o.hasOwnProperty(l))throw n(C,function(a){a&&a.element&&(x[a.id]=a)}),Error("Duplicates in a repeater are not allowed. Repeater: "+m+" key: "+l);else C[c]={id:l},o[l]=!1;for(w in x)if(x.hasOwnProperty(w))y=x[w],j.leave(y.element),y.element[0].$$NG_REMOVED=!0,y.scope.$destroy();c=0;for(h=B.length;c<h;c++){w=a===B?c:B[c];s=a[w];y=C[c];if(y.element){q=y.scope;l=k[0];do l=
+l.nextSibling;while(l&&l.$$NG_REMOVED);y.element[0]!=l&&j.move(y.element,null,k);k=y.element}else q=d.$new();q[z]=s;r&&(q[r]=w);q.$index=c;q.$first=c===0;q.$last=c===t-1;q.$middle=!(q.$first||q.$last);y.element||g(q,function(a){j.enter(a,null,k);k=a;y.scope=q;y.element=a;o[y.id]=y})}x=o})}}}}],Td=["$animator",function(a){return function(c,d,e){var g=a(c,e);c.$watch(e.ngShow,function(a){g[ua(a)?"show":"hide"](d)})}}],Ud=["$animator",function(a){return function(c,d,e){var g=a(c,e);c.$watch(e.ngHide,
+function(a){g[ua(a)?"hide":"show"](d)})}}],Vd=aa(function(a,c,d){a.$watch(d.ngStyle,function(a,d){d&&a!==d&&n(d,function(a,d){c.css(d,"")});a&&c.css(a)},!0)}),Wd=["$animator",function(a){return{restrict:"EA",require:"ngSwitch",controller:["$scope",function(){this.cases={}}],link:function(c,d,e,g){var i=a(c,e),f,h,j=[];c.$watch(e.ngSwitch||e.on,function(a){for(var d=0,l=j.length;d<l;d++)j[d].$destroy(),i.leave(h[d]);h=[];j=[];if(f=g.cases["!"+a]||g.cases["?"])c.$eval(e.change),n(f,function(a){var d=
+c.$new();j.push(d);a.transclude(d,function(c){var d=a.element;h.push(c);i.enter(c,d.parent(),d)})})})}}}],Xd=aa({transclude:"element",priority:500,require:"^ngSwitch",compile:function(a,c,d){return function(a,g,i,f){f.cases["!"+c.ngSwitchWhen]=f.cases["!"+c.ngSwitchWhen]||[];f.cases["!"+c.ngSwitchWhen].push({transclude:d,element:g})}}}),Yd=aa({transclude:"element",priority:500,require:"^ngSwitch",compile:function(a,c,d){return function(a,c,i,f){f.cases["?"]=f.cases["?"]||[];f.cases["?"].push({transclude:d,
+element:c})}}}),Zd=aa({controller:["$transclude","$element",function(a,c){a(function(a){c.append(a)})}]}),$d=["$http","$templateCache","$route","$anchorScroll","$compile","$controller","$animator",function(a,c,d,e,g,i,f){return{restrict:"ECA",terminal:!0,link:function(a,c,m){function k(){var f=d.current&&d.current.locals,k=f&&f.$template;if(k){o.leave(c.contents(),c);l&&(l.$destroy(),l=null);k=w("<div></div>").html(k).contents();o.enter(k,c);var k=g(k),m=d.current;l=m.scope=a.$new();if(m.controller)f.$scope=
+l,f=i(m.controller,f),m.controllerAs&&(l[m.controllerAs]=f),c.children().data("$ngControllerController",f);k(l);l.$emit("$viewContentLoaded");l.$eval(n);e()}else o.leave(c.contents(),c),l&&(l.$destroy(),l=null)}var l,n=m.onload||"",o=f(a,m);a.$on("$routeChangeSuccess",k);k()}}}],ae=["$templateCache",function(a){return{restrict:"E",terminal:!0,compile:function(c,d){d.type=="text/ng-template"&&a.put(d.id,c[0].text)}}}],be=S({terminal:!0}),ce=["$compile","$parse",function(a,c){var d=/^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w\d]*)|(?:\(\s*([\$\w][\$\w\d]*)\s*,\s*([\$\w][\$\w\d]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/,
+e={$setViewValue:q};return{restrict:"E",require:["select","?ngModel"],controller:["$element","$scope","$attrs",function(a,c,d){var h=this,j={},m=e,k;h.databound=d.ngModel;h.init=function(a,c,d){m=a;k=d};h.addOption=function(c){j[c]=!0;m.$viewValue==c&&(a.val(c),k.parent()&&k.remove())};h.removeOption=function(a){this.hasOption(a)&&(delete j[a],m.$viewValue==a&&this.renderUnknownOption(a))};h.renderUnknownOption=function(c){c="? "+la(c)+" ?";k.val(c);a.prepend(k);a.val(c);k.prop("selected",!0)};h.hasOption=
+function(a){return j.hasOwnProperty(a)};c.$on("$destroy",function(){h.renderUnknownOption=q})}],link:function(e,i,f,h){function j(a,c,d,e){d.$render=function(){var a=d.$viewValue;e.hasOption(a)?(v.parent()&&v.remove(),c.val(a),a===""&&t.prop("selected",!0)):C(a)&&t?c.val(""):e.renderUnknownOption(a)};c.bind("change",function(){a.$apply(function(){v.parent()&&v.remove();d.$setViewValue(c.val())})})}function m(a,c,d){var e;d.$render=function(){var a=new za(d.$viewValue);n(c.find("option"),function(c){c.selected=
+B(a.get(c.value))})};a.$watch(function(){ia(e,d.$viewValue)||(e=V(d.$viewValue),d.$render())});c.bind("change",function(){a.$apply(function(){var a=[];n(c.find("option"),function(c){c.selected&&a.push(c.value)});d.$setViewValue(a)})})}function k(e,f,g){function i(){var a={"":[]},c=[""],d,h,q,v,s;q=g.$modelValue;v=u(e)||[];var z=l?qb(v):v,B,y,A;y={};s=!1;var C,D;if(o)if(t&&F(q)){s=new za([]);for(h=0;h<q.length;h++)y[k]=q[h],s.put(t(e,y),q[h])}else s=new za(q);for(A=0;B=z.length,A<B;A++){y[k]=v[l?y[l]=
+z[A]:A];d=m(e,y)||"";if(!(h=a[d]))h=a[d]=[],c.push(d);o?d=s.remove(t?t(e,y):n(e,y))!=p:(t?(d={},d[k]=q,d=t(e,d)===t(e,y)):d=q===n(e,y),s=s||d);C=j(e,y);C=C===p?"":C;h.push({id:t?t(e,y):l?z[A]:A,label:C,selected:d})}o||(r||q===null?a[""].unshift({id:"",label:"",selected:!s}):s||a[""].unshift({id:"?",label:"",selected:!0}));y=0;for(z=c.length;y<z;y++){d=c[y];h=a[d];if(w.length<=y)q={element:E.clone().attr("label",d),label:h.label},v=[q],w.push(v),f.append(q.element);else if(v=w[y],q=v[0],q.label!=d)q.element.attr("label",
+q.label=d);C=null;A=0;for(B=h.length;A<B;A++)if(d=h[A],s=v[A+1]){C=s.element;if(s.label!==d.label)C.text(s.label=d.label);if(s.id!==d.id)C.val(s.id=d.id);if(C[0].selected!==d.selected)C.prop("selected",s.selected=d.selected)}else d.id===""&&r?D=r:(D=x.clone()).val(d.id).attr("selected",d.selected).text(d.label),v.push({element:D,label:d.label,id:d.id,selected:d.selected}),C?C.after(D):q.element.append(D),C=D;for(A++;v.length>A;)v.pop().element.remove()}for(;w.length>y;)w.pop()[0].element.remove()}
+var h;if(!(h=q.match(d)))throw Error("Expected ngOptions in form of '_select_ (as _label_)? for (_key_,)?_value_ in _collection_ (track by _expr_)?' but got '"+q+"'.");var j=c(h[2]||h[1]),k=h[4]||h[6],l=h[5],m=c(h[3]||""),n=c(h[2]?h[1]:k),u=c(h[7]),t=h[8]?c(h[8]):null,w=[[{element:f,label:""}]];r&&(a(r)(e),r.removeClass("ng-scope"),r.remove());f.html("");f.bind("change",function(){e.$apply(function(){var a,c=u(e)||[],d={},h,i,j,m,q,r;if(o){i=[];m=0;for(r=w.length;m<r;m++){a=w[m];j=1;for(q=a.length;j<
+q;j++)if((h=a[j].element)[0].selected){h=h.val();l&&(d[l]=h);if(t)for(var s=0;s<c.length;s++){if(d[k]=c[s],t(e,d)==h)break}else d[k]=c[h];i.push(n(e,d))}}}else if(h=f.val(),h=="?")i=p;else if(h=="")i=null;else if(t)for(s=0;s<c.length;s++){if(d[k]=c[s],t(e,d)==h){i=n(e,d);break}}else d[k]=c[h],l&&(d[l]=h),i=n(e,d);g.$setViewValue(i)})});g.$render=i;e.$watch(i)}if(h[1]){for(var l=h[0],u=h[1],o=f.multiple,q=f.ngOptions,r=!1,t,x=w(T.createElement("option")),E=w(T.createElement("optgroup")),v=x.clone(),
+h=0,A=i.children(),G=A.length;h<G;h++)if(A[h].value==""){t=r=A.eq(h);break}l.init(u,r,v);if(o&&(f.required||f.ngRequired)){var D=function(a){u.$setValidity("required",!f.required||a&&a.length);return a};u.$parsers.push(D);u.$formatters.unshift(D);f.$observe("required",function(){D(u.$viewValue)})}q?k(e,i,u):o?m(e,i,u):j(e,i,u,l)}}}}],de=["$interpolate",function(a){var c={addOption:q,removeOption:q};return{restrict:"E",priority:100,compile:function(d,e){if(C(e.value)){var g=a(d.text(),!0);g||e.$set("value",
+d.text())}return function(a,d,e){var j=d.parent(),m=j.data("$selectController")||j.parent().data("$selectController");m&&m.databound?d.prop("selected",!1):m=c;g?a.$watch(g,function(a,c){e.$set("value",a);a!==c&&m.removeOption(c);m.addOption(a)}):m.addOption(e.value);d.bind("$destroy",function(){m.removeOption(e.value)})}}}}],ee=S({restrict:"E",terminal:!0});(ga=M.jQuery)?(w=ga,t(ga.fn,{scope:Ba.scope,controller:Ba.controller,injector:Ba.injector,inheritedData:Ba.inheritedData}),db("remove",!0),db("empty"),
+db("html")):w=R;Ha.element=w;(function(a){t(a,{bootstrap:xb,copy:V,extend:t,equals:ia,element:w,forEach:n,injector:yb,noop:q,bind:$a,toJson:ha,fromJson:ub,identity:qa,isUndefined:C,isDefined:B,isString:E,isFunction:H,isObject:L,isNumber:Ya,isElement:oc,isArray:F,version:pd,isDate:ra,lowercase:I,uppercase:oa,callbacks:{counter:0},noConflict:lc});Aa=tc(M);try{Aa("ngLocale")}catch(c){Aa("ngLocale",[]).provider("$locale",fd)}Aa("ng",["ngLocale"],["$provide",function(a){a.provider("$compile",Jb).directive({a:rd,
+input:ic,textarea:ic,form:sd,script:ae,select:ce,style:ee,option:de,ngBind:Dd,ngBindHtmlUnsafe:Fd,ngBindTemplate:Ed,ngClass:Gd,ngClassEven:Id,ngClassOdd:Hd,ngCsp:Ld,ngCloak:Jd,ngController:Kd,ngForm:td,ngHide:Ud,ngIf:Nd,ngInclude:Od,ngInit:Pd,ngNonBindable:Qd,ngPluralize:Rd,ngRepeat:Sd,ngShow:Td,ngSubmit:Md,ngStyle:Vd,ngSwitch:Wd,ngSwitchWhen:Xd,ngSwitchDefault:Yd,ngOptions:be,ngView:$d,ngTransclude:Zd,ngModel:yd,ngList:Ad,ngChange:zd,required:jc,ngRequired:jc,ngValue:Cd}).directive(pb).directive(kc);
+a.provider({$anchorScroll:Cc,$animation:Ib,$animator:qd,$browser:Ec,$cacheFactory:Fc,$controller:Jc,$document:Kc,$exceptionHandler:Lc,$filter:Zb,$interpolate:Mc,$http:bd,$httpBackend:cd,$location:Nc,$log:Oc,$parse:Sc,$route:Vc,$routeParams:Wc,$rootScope:Xc,$q:Tc,$sniffer:Yc,$templateCache:Gc,$timeout:gd,$window:Zc})}])})(Ha);w(T).ready(function(){rc(T,xb)})})(window,document);angular.element(document).find("head").append('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak{display:none;}ng\\:form{display:block;}</style>');
Added: WebTimer/src/angularJS/partials/about.html
===================================================================
--- WebTimer/src/angularJS/partials/about.html (rev 0)
+++ WebTimer/src/angularJS/partials/about.html 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1 @@
+WebTimer 1.0
Added: WebTimer/src/angularJS/partials/contact.html
===================================================================
--- WebTimer/src/angularJS/partials/contact.html (rev 0)
+++ WebTimer/src/angularJS/partials/contact.html 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1 @@
+jruchaud(a)codelutin.com
Added: WebTimer/src/angularJS/partials/tasks.html
===================================================================
--- WebTimer/src/angularJS/partials/tasks.html (rev 0)
+++ WebTimer/src/angularJS/partials/tasks.html 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,80 @@
+<script type="text/ng-template" id="tree_item_renderer_name.html">
+ <div>
+ <i class="icon-plus-sign" ng-click="changeTask(task)" ng-show="!task.childrenVisibility && task.subtasks.length != 0"></i>
+ <i class="icon-minus-sign" ng-click="changeTask(task)" ng-show="task.childrenVisibility && task.subtasks.length != 0"></i>
+
+ <form ng-submit="saveTask(task)" ng-show="task.edit == 'name'">
+ <input ng-model="task.name">
+ </form>
+
+ <span ng-click="editTask(task, 'name')" ng-show="task.edit != 'name'">{{task.name}} </span>
+
+ <div class="btn-group">
+ <a class="btn" href="" ng-click="removeTask(task, tasks)"><i class="icon-minus"></i></a>
+ <a class="btn" href="" ng-click="addSubTask(task)"><i class="icon-plus"></i></a>
+ <a class="btn" href="" ng-click="timeTask(task)">
+ <i ng-class="{'icon-play' : (task != currentTask), 'icon-stop' : (task == currentTask)}"></i>
+ </a>
+ </div>
+ </div>
+
+ <ul class="tasks subtasks" ng-show="task.childrenVisibility">
+ <li class="task subtasks" ng-repeat="task in task.subtasks | filter:query" ng-animate="'filtering'" ng-include="'tree_item_renderer_name.html'"></li>
+ </ul>
+</script>
+
+<script type="text/ng-template" id="tree_item_renderer_details.html">
+ <div>{{task.time | time}}</div>
+
+ <div ng-click="editTask(task, 'tags')">
+ <form ng-submit="saveTask(task)" ng-show="task.edit == 'tags'">
+ <input ng-model="task.tags" ng-list>
+ </form>
+
+ <span class="label label-info" ng-repeat="tag in task.tags" style="margin-right: 10px;" ng-show="task.edit != 'tags'">
+ {{tag}}
+ </span>
+
+ <span ng-show="task.tags.length == 0 && task.edit != 'tags'">No tag</span>
+ </div>
+
+ <ul class="tasks subtasks" ng-show="task.childrenVisibility">
+ <li class="task subtasks" ng-repeat="task in task.subtasks | filter:query" ng-animate="'filtering'" ng-include="'tree_item_renderer_details.html'"></li>
+ </ul>
+</script>
+
+<div class="container-fluid">
+ <div class="row-fluid">
+ <div class="span6">
+ Filter <input ng-model="query">
+ </div>
+ <div class="span6">
+ <form ng-submit="addTask()">
+ Add project <input ng-model="name"><a class="btn" href="" ng-click="addTask()"><i class="icon-plus"></i></a>
+ </form>
+ </div>
+ </div>
+
+ <div class="row-fluid">
+ <div class="span4 names">
+ <ul class="tasks">
+ <li class="task title">
+ <div>Name</div>
+ </li>
+
+ <li class="task" ng-repeat="task in tasks | filter:query" ng-animate="'filtering'" ng-include="'tree_item_renderer_name.html'"></li>
+ </ul>
+ </div>
+
+ <div class="span8 details">
+ <ul class="tasks">
+ <li class="task title">
+ <div>Time</div>
+ <div>Tags</div>
+ </li>
+
+ <li class="task" ng-repeat="task in tasks | filter:query" ng-animate="'filtering'" ng-include="'tree_item_renderer_details.html'"></li>
+ </ul>
+ </div>
+ </div>
+</div>
\ No newline at end of file
Added: WebTimer/src/canJs/css/app.css
===================================================================
--- WebTimer/src/canJs/css/app.css (rev 0)
+++ WebTimer/src/canJs/css/app.css 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,7 @@
+#content >div {
+ display: none;
+}
+
+.hidden {
+ display:none;
+}
\ No newline at end of file
Added: WebTimer/src/canJs/index.html
===================================================================
--- WebTimer/src/canJs/index.html (rev 0)
+++ WebTimer/src/canJs/index.html 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,65 @@
+<html lang="en" ng-app="webtimer">
+ <head>
+ <title></title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+ <link rel="stylesheet" href="../common/css/bootstrap.css">
+ <link rel="stylesheet" href="../common/css/app.css">
+ <link rel="stylesheet" href="css/app.css">
+
+ </head>
+ <body>
+ <div class="navbar navbar-inverse navbar-fixed-top">
+ <div class="navbar-inner">
+ <div class="container">
+ <a class="brand" href="#">WebTimer</a>
+ <div class="nav-collapse collapse">
+ <ul class="nav" id='menu'>
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div id="content">
+
+ <!--Body content-->
+ <div id="tasks"></div>
+ <div id="about">WebTimer 1.0</div>
+ <div id="contact">kmorin(a)codelutin.com</div>
+
+ </div>
+
+ <script type="text/javascript">
+ var formatDuration = function(time) {
+ var remainingTime = Math.floor(time / 1000);
+ var seconds = Math.floor(remainingTime % 60);
+ remainingTime = Math.floor(remainingTime / 60)
+ var minutes = Math.floor(remainingTime % 60);
+ remainingTime = Math.floor(remainingTime / 60);
+ return remainingTime + ":" + (minutes >= 10 ? "" : "0") + minutes + ":" + (seconds >= 10 ? "" : "0") + seconds;
+ }
+ </script>
+
+ <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.js"></script>
+ <script src="js/libs/can.jquery.min.js"></script>
+ <script src="js/libs/can.object.js"></script>
+ <script src="js/libs/can.fixture.js"></script>
+ <script src="js/libs/can.observe.attributes.js"></script>
+ <script src="js/libs/can.observe.delegate.js"></script>
+
+ <script src="js/models/tasks.js"></script>
+
+ <script src="js/controls/menu.js"></script>
+ <script src="js/controls/content.js"></script>
+
+ <script type="text/javascript">
+
+ var menu = new Menu('#menu');
+ var content = new Content('#content');
+
+ can.route(':page');
+
+ </script>
+ </body>
+</html>
Added: WebTimer/src/canJs/js/controls/content.js
===================================================================
--- WebTimer/src/canJs/js/controls/content.js (rev 0)
+++ WebTimer/src/canJs/js/controls/content.js 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,185 @@
+var Content = can.Control({
+
+ init: function() {
+ var self = this;
+
+ var refresh = function() {
+ setInterval(function() {
+ var now = new Date().getTime();
+ var currentTask = self.options.currentTask;
+ if (currentTask.task) {
+ currentTask.attr('task.time', currentTask.task.time + now - currentTask.date);
+ currentTask.attr('date', now);
+ currentTask.task.save();
+ }
+ }, 500);
+ };
+ refresh();
+ },
+
+ setModelListsRecursively: function(tasks) {
+ var taskList = new Task.List([]);
+ for (var i = 0 ; i < tasks.length ; i++) {
+ var task = tasks[i];
+ if (!task._data) {
+ task = new Task(task);
+ } else {
+ task = new Task(task._data);
+ }
+ task.attr('subtasks', this.setModelListsRecursively(task.subtasks));
+ taskList.push(task);
+ }
+ return taskList;
+ },
+
+ 'route': function(data) {
+ if (!data.page) {
+ this.showTasks();
+ }
+ },
+
+ 'contact route': function() {
+ var contact = this.element.find("#contact");
+ contact.siblings().hide();
+ contact.show();
+ },
+
+ 'about route': function() {
+ var about = this.element.find("#about");
+ about.siblings().hide();
+ about.show();
+ },
+
+ 'tasks route': function() {
+ this.showTasks();
+ },
+
+ 'tasks/:filter route': function() {
+ this.showTasks();
+ },
+
+ showTasks: function(filter) {
+ var tasksElement = this.element.find("#tasks");
+ var self = this;
+ this.options.currentTask = new can.Observe();
+ this.options.state = new can.Observe();
+ $.when(Task.findAll()).then(
+ function(tasks) {
+ tasks = self.setModelListsRecursively(tasks);
+ self.computeTaskMatchFilter(tasks);
+ self.options.tasks = tasks;
+ self.element.find("#tasks").html(can.view('views/tasks.ejs', {tasks: tasks, currentTask: self.options.currentTask}));
+ tasksElement.siblings().hide();
+ tasksElement.show();
+ });
+ },
+
+ '#addTaskForm submit': function(form) {
+ var taskName = form.find("[name='name']").val();
+ if (taskName) {
+ var task = new Task({
+ name: taskName,
+ time: 0,
+ tags: [],
+ subtasks: [],
+ childrenVisibility:true
+ });
+ var self = this;
+ task.save(function(data) {
+ task.attr('id', data.id);
+ self.options.tasks.push(task);
+ form[0].reset();
+ });
+ }
+ return false;
+ },
+
+ ".toggleChildrenVisibilityButton click": function(el) {
+ var task = el.data('task');
+ task.attr('childrenVisibility', !task.childrenVisibility);
+ task.save();
+ },
+
+ ".taskNameLabel click": function(el) {
+ var task = el.data('task');
+ task.attr('edit', el.data('edit'));
+ },
+
+ ".taskTags click": function(el) {
+ var task = el.data('task');
+ task.attr('edit', el.data('edit'));
+ },
+
+ '.saveTaskForm submit': function(form) {
+ var task = form.data('task');
+ var taskName = form.find("[name='name']").val();
+ if (taskName) {
+ task.attr('name', taskName);
+ }
+ var tags = form.find("[name='tags']").val();
+ if (tags) {
+ task.attr('tags', tags.split(','));
+ }
+ task.attr('edit', null);
+ task.save();
+ return false;
+ },
+
+ '.removeTask click': function(el) {
+ var task = el.data('task');
+ task.destroy();
+ },
+
+ '.addSubTask click': function(el) {
+ var task = el.data('task');
+ if (task.subtasks == null) {
+ task.att('subtasks', []);
+ }
+ var subtask = new Task({
+ name: "New task",
+ time: 0,
+ tags: [],
+ subtasks: [],
+ parentTask: task.id,
+ childrenVisibility:true
+ });
+ subtask.save(function(data) {
+ subtask.attr('id', data.id);
+ task.subtasks.push(subtask);
+ });
+ task.attr('childrenVisibility', true);
+ },
+
+ '.startTiming click': function(el) {
+ var now = new Date().getTime();
+ var task = el.data('task');
+
+ if (this.options.currentTask.task != task) {
+ this.options.currentTask.attr('task', task);
+ this.options.currentTask.attr('date', now);
+
+ } else {
+ task.save();
+ this.options.currentTask.attr('task', null);
+ this.options.currentTask.attr('date', null);
+ }
+ },
+
+ '#filterInput keyup': function(el) {
+ this.computeTaskMatchFilter(this.options.tasks, el.val());
+ },
+
+ computeTaskMatchFilter: function(tasks, filter) {
+ var taskMatch = false;
+ for (var i = 0 ; i < tasks.length ; i++) {
+ var task = tasks[i];
+ var childMatch = false;
+ if (task.subtasks) {
+ childMatch = this.computeTaskMatchFilter(task.subtasks, filter);
+ }
+ task.attr('matchFilter', !filter || childMatch || task.name.indexOf(filter) !== -1);
+ taskMatch |= task.matchFilter;
+ }
+ return taskMatch;
+ }
+});
\ No newline at end of file
Added: WebTimer/src/canJs/js/controls/menu.js
===================================================================
--- WebTimer/src/canJs/js/controls/menu.js (rev 0)
+++ WebTimer/src/canJs/js/controls/menu.js 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,23 @@
+var Menu = can.Control({
+ init: function() {
+ this.element.html(can.view('views/menu.ejs'));
+ },
+
+ 'route': function() {
+ var homeMenu = $("#homeMenu");
+ homeMenu.siblings().removeClass("active");
+ homeMenu.addClass("active");
+ },
+
+ 'contact route': function() {
+ var contactMenu = $("#contactMenu");
+ contactMenu.siblings().removeClass("active");
+ contactMenu.addClass("active");
+ },
+
+ 'about route': function() {
+ var aboutMenu = $("#aboutMenu");
+ aboutMenu.siblings().removeClass("active");
+ aboutMenu.addClass("active");
+ }
+});
\ No newline at end of file
Added: WebTimer/src/canJs/js/libs/can.fixture.js
===================================================================
--- WebTimer/src/canJs/js/libs/can.fixture.js (rev 0)
+++ WebTimer/src/canJs/js/libs/can.fixture.js 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,614 @@
+/*!
+ * CanJS - 1.1.6
+ * http://canjs.us/
+ * Copyright (c) 2013 Bitovi
+ * Wed, 29 May 2013 18:59:29 GMT
+ * Licensed MIT
+ * Includes: can/util/fixture
+ * Download from: http://canjs.com
+ */
+(function(can) {
+
+ // Get the URL from old Steal root, new Steal config or can.fixture.rootUrl
+ var getUrl = function(url) {
+ if (typeof steal !== 'undefined') {
+ if (can.isFunction(steal.config)) {
+ return steal.config().root.mapJoin(url).toString();
+ }
+ return steal.root.join(url).toString();
+ }
+ return (can.fixture.rootUrl || '') + url;
+ }
+
+ var updateSettings = function(settings, originalOptions) {
+ if (!can.fixture.on) {
+ return;
+ }
+
+ //simple wrapper for logging
+ var _logger = function(type, arr) {
+ if (console.log.apply) {
+ Function.prototype.call.apply(console[type], [console].concat(arr));
+ // console[type].apply(console, arr)
+ } else {
+ console[type](arr)
+ }
+ },
+ log = function() {
+ if (typeof steal !== 'undefined' && steal.dev) {
+ steal.dev.log('fixture INFO: ' + Array.prototype.slice.call(arguments).join(' '));
+ }
+ }
+
+ // We always need the type which can also be called method, default to GET
+ settings.type = settings.type || settings.method || 'GET';
+
+ // add the fixture option if programmed in
+ var data = overwrite(settings);
+
+ // if we don't have a fixture, do nothing
+ if (!settings.fixture) {
+ if (window.location.protocol === "file:") {
+ log("ajax request to " + settings.url + ", no fixture found");
+ }
+ return;
+ }
+
+ //if referencing something else, update the fixture option
+ if (typeof settings.fixture === "string" && can.fixture[settings.fixture]) {
+ settings.fixture = can.fixture[settings.fixture];
+ }
+
+ // if a string, we just point to the right url
+ if (typeof settings.fixture == "string") {
+ var url = settings.fixture;
+
+ if (/^\/\//.test(url)) {
+ // this lets us use rootUrl w/o having steal...
+ url = getUrl(settings.fixture.substr(2));
+ }
+
+ if (data) {
+ // Template static fixture URLs
+ url = can.sub(url, data);
+ }
+
+ delete settings.fixture;
+
+
+
+ settings.url = url;
+ settings.data = null;
+ settings.type = "GET";
+ if (!settings.error) {
+ settings.error = function(xhr, error, message) {
+ throw "fixtures.js Error " + error + " " + message;
+ };
+ }
+ } else {
+
+
+ //it's a function ... add the fixture datatype so our fixture transport handles it
+ // TODO: make everything go here for timing and other fun stuff
+ // add to settings data from fixture ...
+ settings.dataTypes && settings.dataTypes.splice(0, 0, "fixture");
+
+ if (data && originalOptions) {
+ can.extend(originalOptions.data, data)
+ }
+ }
+ },
+ // A helper function that takes what's called with response
+ // and moves some common args around to make it easier to call
+ extractResponse = function(status, statusText, responses, headers) {
+ // if we get response(RESPONSES, HEADERS)
+ if (typeof status != "number") {
+ headers = statusText;
+ responses = status;
+ statusText = "success"
+ status = 200;
+ }
+ // if we get response(200, RESPONSES, HEADERS)
+ if (typeof statusText != "string") {
+ headers = responses;
+ responses = statusText;
+ statusText = "success";
+ }
+ if (status >= 400 && status <= 599) {
+ this.dataType = "text"
+ }
+ return [status, statusText, extractResponses(this, responses), headers];
+ },
+ // If we get data instead of responses,
+ // make sure we provide a response type that matches the first datatype (typically json)
+ extractResponses = function(settings, responses) {
+ var next = settings.dataTypes ? settings.dataTypes[0] : (settings.dataType || 'json');
+ if (!responses || !responses[next]) {
+ var tmp = {}
+ tmp[next] = responses;
+ responses = tmp;
+ }
+ return responses;
+ };
+
+ //used to check urls
+ // check if jQuery
+ if (can.ajaxPrefilter && can.ajaxTransport) {
+
+ // the pre-filter needs to re-route the url
+ can.ajaxPrefilter(updateSettings);
+
+ can.ajaxTransport("fixture", function(s, original) {
+ // remove the fixture from the datatype
+ s.dataTypes.shift();
+
+ //we'll return the result of the next data type
+ var timeout, stopped = false;
+
+ return {
+ send: function(headers, callback) {
+ // we'll immediately wait the delay time for all fixtures
+ timeout = setTimeout(function() {
+ // if the user wants to call success on their own, we allow it ...
+ var success = function() {
+ if (stopped === false) {
+ callback.apply(null, extractResponse.apply(s, arguments));
+ }
+ },
+ // get the result form the fixture
+ result = s.fixture(original, success, headers, s);
+ if (result !== undefined) {
+ // make sure the result has the right dataType
+ callback(200, "success", extractResponses(s, result), {});
+ }
+ }, can.fixture.delay);
+ },
+ abort: function() {
+ stopped = true;
+ clearTimeout(timeout)
+ }
+ };
+ });
+ } else {
+ var AJAX = can.ajax;
+ can.ajax = function(settings) {
+ updateSettings(settings, settings);
+ if (settings.fixture) {
+ var timeout, d = new can.Deferred(),
+ stopped = false;
+
+ //TODO this should work with response
+ d.getResponseHeader = function() {}
+
+ // call success and fail
+ d.then(settings.success, settings.fail);
+
+ // abort should stop the timeout and calling success
+ d.abort = function() {
+ clearTimeout(timeout);
+ stopped = true;
+ d.reject(d)
+ }
+ // set a timeout that simulates making a request ....
+ timeout = setTimeout(function() {
+ // if the user wants to call success on their own, we allow it ...
+ var success = function() {
+ var response = extractResponse.apply(settings, arguments),
+ status = response[0];
+
+ if ((status >= 200 && status < 300 || status === 304) && stopped === false) {
+ d.resolve(response[2][settings.dataType])
+ } else {
+ // TODO probably resolve better
+ d.reject(d, 'error', response[1]);
+ }
+ },
+ // get the result form the fixture
+ result = settings.fixture(settings, success, settings.headers, settings);
+ if (result !== undefined) {
+ d.resolve(result)
+ }
+ }, can.fixture.delay);
+
+ return d;
+ } else {
+ return AJAX(settings);
+ }
+ }
+ }
+
+ var typeTest = /^(script|json|text|jsonp)$/,
+ // a list of 'overwrite' settings object
+ overwrites = [],
+ // returns the index of an overwrite function
+ find = function(settings, exact) {
+ for (var i = 0; i < overwrites.length; i++) {
+ if ($fixture._similar(settings, overwrites[i], exact)) {
+ return i;
+ }
+ }
+ return -1;
+ },
+ // overwrites the settings fixture if an overwrite matches
+ overwrite = function(settings) {
+ var index = find(settings);
+ if (index > -1) {
+ settings.fixture = overwrites[index].fixture;
+ return $fixture._getData(overwrites[index].url, settings.url)
+ }
+
+ },
+ // Makes an attempt to guess where the id is at in the url and returns it.
+ getId = function(settings) {
+ var id = settings.data.id;
+
+ if (id === undefined && typeof settings.data === "number") {
+ id = settings.data;
+ }
+
+
+
+ if (id === undefined) {
+ settings.url.replace(/\/(\d+)(\/|$|\.)/g, function(all, num) {
+ id = num;
+ });
+ }
+
+ if (id === undefined) {
+ id = settings.url.replace(/\/(\w+)(\/|$|\.)/g, function(all, num) {
+ if (num != 'update') {
+ id = num;
+ }
+ })
+ }
+
+ if (id === undefined) { // if still not set, guess a random number
+ id = Math.round(Math.random() * 1000)
+ }
+
+ return id;
+ };
+
+ var $fixture = can.fixture = function(settings, fixture) {
+ // if we provide a fixture ...
+ if (fixture !== undefined) {
+ if (typeof settings == 'string') {
+ // handle url strings
+ var matches = settings.match(/(GET|POST|PUT|DELETE) (.+)/i);
+ if (!matches) {
+ settings = {
+ url: settings
+ };
+ } else {
+ settings = {
+ url: matches[2],
+ type: matches[1]
+ };
+ }
+
+ }
+
+ //handle removing. An exact match if fixture was provided, otherwise, anything similar
+ var index = find(settings, !! fixture);
+ if (index > -1) {
+ overwrites.splice(index, 1)
+ }
+ if (fixture == null) {
+ return
+ }
+ settings.fixture = fixture;
+ overwrites.push(settings)
+ } else {
+ can.each(settings, function(fixture, url) {
+ $fixture(url, fixture);
+ })
+ }
+ };
+ var replacer = can.replacer;
+
+ can.extend(can.fixture, {
+ // given ajax settings, find an overwrite
+ _similar: function(settings, overwrite, exact) {
+ if (exact) {
+ return can.Object.same(settings, overwrite, {
+ fixture: null
+ })
+ } else {
+ return can.Object.subset(settings, overwrite, can.fixture._compare)
+ }
+ },
+ _compare: {
+ url: function(a, b) {
+ return !!$fixture._getData(b, a)
+ },
+ fixture: null,
+ type: "i"
+ },
+ // gets data from a url like "/todo/{id}" given "todo/5"
+ _getData: function(fixtureUrl, url) {
+ var order = [],
+ fixtureUrlAdjusted = fixtureUrl.replace('.', '\\.').replace('?', '\\?'),
+ res = new RegExp(fixtureUrlAdjusted.replace(replacer, function(whole, part) {
+ order.push(part)
+ return "([^\/]+)"
+ }) + "$").exec(url),
+ data = {};
+
+ if (!res) {
+ return null;
+ }
+ res.shift();
+ can.each(order, function(name) {
+ data[name] = res.shift()
+ })
+ return data;
+ },
+
+ store: function(types, count, make, filter) {
+
+ var items = [], // TODO: change this to a hash
+ currentId = 0,
+ findOne = function(id) {
+ for (var i = 0; i < items.length; i++) {
+ if (id == items[i].id) {
+ return items[i];
+ }
+ }
+ },
+ methods = {};
+
+ if (typeof types === "string") {
+ types = [types + "s", types]
+ } else if (!can.isArray(types)) {
+ filter = make;
+ make = count;
+ count = types;
+ }
+
+ // make all items
+ can.extend(methods, {
+
+ findAll: function(request) {
+ request = request || {}
+ //copy array of items
+ var retArr = items.slice(0);
+ request.data = request.data || {};
+ //sort using order
+ //order looks like ["age ASC","gender DESC"]
+ can.each((request.data.order || []).slice(0).reverse(), function(name) {
+ var split = name.split(" ");
+ retArr = retArr.sort(function(a, b) {
+ if (split[1].toUpperCase() !== "ASC") {
+ if (a[split[0]] < b[split[0]]) {
+ return 1;
+ } else if (a[split[0]] == b[split[0]]) {
+ return 0
+ } else {
+ return -1;
+ }
+ } else {
+ if (a[split[0]] < b[split[0]]) {
+ return -1;
+ } else if (a[split[0]] == b[split[0]]) {
+ return 0
+ } else {
+ return 1;
+ }
+ }
+ });
+ });
+
+ //group is just like a sort
+ can.each((request.data.group || []).slice(0).reverse(), function(name) {
+ var split = name.split(" ");
+ retArr = retArr.sort(function(a, b) {
+ return a[split[0]] > b[split[0]];
+ });
+ });
+
+ var offset = parseInt(request.data.offset, 10) || 0,
+ limit = parseInt(request.data.limit, 10) || (items.length - offset),
+ i = 0;
+
+ //filter results if someone added an attr like parentId
+ for (var param in request.data) {
+ i = 0;
+ if (request.data[param] !== undefined && // don't do this if the value of the param is null (ignore it)
+ (param.indexOf("Id") != -1 || param.indexOf("_id") != -1)) {
+ while (i < retArr.length) {
+ if (request.data[param] != retArr[i][param]) {
+ retArr.splice(i, 1);
+ } else {
+ i++;
+ }
+ }
+ }
+ }
+
+ if (filter) {
+ i = 0;
+ while (i < retArr.length) {
+ if (!filter(retArr[i], request)) {
+ retArr.splice(i, 1);
+ } else {
+ i++;
+ }
+ }
+ }
+
+ //return data spliced with limit and offset
+ return {
+ "count": retArr.length,
+ "limit": request.data.limit,
+ "offset": request.data.offset,
+ "data": retArr.slice(offset, offset + limit)
+ };
+ },
+
+ findOne: function(request, response) {
+ var item = findOne(getId(request));
+ response(item ? item : undefined);
+ },
+
+ update: function(request, response) {
+ var id = getId(request);
+
+ // TODO: make it work with non-linear ids ..
+ can.extend(findOne(id), request.data);
+ response({
+ id: getId(request)
+ }, {
+ location: request.url || "/" + getId(request)
+ });
+ },
+
+ destroy: function(request) {
+ var id = getId(request);
+ for (var i = 0; i < items.length; i++) {
+ if (items[i].id == id) {
+ items.splice(i, 1);
+ break;
+ }
+ }
+
+ // TODO: make it work with non-linear ids ..
+ can.extend(findOne(id) || {}, request.data);
+ return {};
+ },
+
+ create: function(settings, response) {
+ var item = make(items.length, items);
+
+ can.extend(item, settings.data);
+
+ if (!item.id) {
+ item.id = currentId++;
+ }
+
+ items.push(item);
+ response({
+ id: item.id
+ }, {
+ location: settings.url + "/" + item.id
+ })
+ }
+ });
+
+ var reset = function() {
+ items = [];
+ for (var i = 0; i < (count); i++) {
+ //call back provided make
+ var item = make(i, items);
+
+ if (!item.id) {
+ item.id = i;
+ }
+ currentId = Math.max(item.id + 1, currentId + 1) || items.length;
+ items.push(item);
+ }
+ if (can.isArray(types)) {
+ can.fixture["~" + types[0]] = items;
+ can.fixture["-" + types[0]] = methods.findAll;
+ can.fixture["-" + types[1]] = methods.findOne;
+ can.fixture["-" + types[1] + "Update"] = methods.update;
+ can.fixture["-" + types[1] + "Destroy"] = methods.destroy;
+ can.fixture["-" + types[1] + "Create"] = methods.create;
+ }
+
+ }
+ reset()
+ // if we have types given add them to can.fixture
+
+
+ return can.extend({
+ getId: getId,
+
+ find: function(settings) {
+ return findOne(getId(settings));
+ },
+
+ reset: reset
+ }, methods);
+ },
+
+ rand: function(arr, min, max) {
+ if (typeof arr == 'number') {
+ if (typeof min == 'number') {
+ return arr + Math.floor(Math.random() * (min - arr));
+ } else {
+ return Math.floor(Math.random() * arr);
+ }
+
+ }
+ var rand = arguments.callee;
+ // get a random set
+ if (min === undefined) {
+ return rand(arr, rand(arr.length + 1))
+ }
+ // get a random selection of arr
+ var res = [];
+ arr = arr.slice(0);
+ // set max
+ if (!max) {
+ max = min;
+ }
+ //random max
+ max = min + Math.round(rand(max - min))
+ for (var i = 0; i < max; i++) {
+ res.push(arr.splice(rand(arr.length), 1)[0])
+ }
+ return res;
+ },
+
+ xhr: function(xhr) {
+ return can.extend({}, {
+ abort: can.noop,
+ getAllResponseHeaders: function() {
+ return "";
+ },
+ getResponseHeader: function() {
+ return "";
+ },
+ open: can.noop,
+ overrideMimeType: can.noop,
+ readyState: 4,
+ responseText: "",
+ responseXML: null,
+ send: can.noop,
+ setRequestHeader: can.noop,
+ status: 200,
+ statusText: "OK"
+ }, xhr);
+ },
+
+ on: true
+ });
+
+ can.fixture.delay = 200;
+
+
+ can.fixture.rootUrl = getUrl('');
+
+ can.fixture["-handleFunction"] = function(settings) {
+ if (typeof settings.fixture === "string" && can.fixture[settings.fixture]) {
+ settings.fixture = can.fixture[settings.fixture];
+ }
+ if (typeof settings.fixture == "function") {
+ setTimeout(function() {
+ if (settings.success) {
+ settings.success.apply(null, settings.fixture(settings, "success"));
+ }
+ if (settings.complete) {
+ settings.complete.apply(null, settings.fixture(settings, "complete"));
+ }
+ }, can.fixture.delay);
+ return true;
+ }
+ return false;
+ };
+
+ //Expose this for fixture debugging
+ can.fixture.overwrites = overwrites;
+ can.fixture.make = can.fixture.store;
+ return can.fixture;
+ })(can);
\ No newline at end of file
Added: WebTimer/src/canJs/js/libs/can.jquery.js
===================================================================
--- WebTimer/src/canJs/js/libs/can.jquery.js (rev 0)
+++ WebTimer/src/canJs/js/libs/can.jquery.js 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,4367 @@
+/*!
+ * CanJS - 1.1.6
+ * http://canjs.us/
+ * Copyright (c) 2013 Bitovi
+ * Wed, 29 May 2013 18:59:27 GMT
+ * Licensed MIT
+ * Includes: can/construct,can/observe,can/observe/compute,can/model,can/view,can/view/ejs,can/control,can/route,can/control/route
+ * Download from: http://canjs.com
+ */
+(function(undefined) {
+
+ // ## util/can.js
+ var __m5 = (function() {
+ var can = window.can || {};
+ if (typeof GLOBALCAN === 'undefined' || GLOBALCAN !== false) {
+ window.can = can;
+ }
+
+ can.isDeferred = function(obj) {
+ var isFunction = this.isFunction;
+ // Returns `true` if something looks like a deferred.
+ return obj && isFunction(obj.then) && isFunction(obj.pipe);
+ };
+
+ var cid = 0;
+ can.cid = function(object, name) {
+ if (object._cid) {
+ return object._cid
+ } else {
+ return object._cid = (name || "") + (++cid)
+ }
+ }
+ can.VERSION = '@EDGE';
+ return can;
+ })();
+
+ // ## util/array/each.js
+ var __m6 = (function(can) {
+ can.each = function(elements, callback, context) {
+ var i = 0,
+ key;
+ if (elements) {
+ if (typeof elements.length === 'number' && elements.pop) {
+ if (elements.attr) {
+ elements.attr('length');
+ }
+ for (key = elements.length; i < key; i++) {
+ if (callback.call(context || elements[i], elements[i], i, elements) === false) {
+ break;
+ }
+ }
+ } else if (elements.hasOwnProperty) {
+ for (key in elements) {
+ if (elements.hasOwnProperty(key)) {
+ if (callback.call(context || elements[key], elements[key], key, elements) === false) {
+ break;
+ }
+ }
+ }
+ }
+ }
+ return elements;
+ };
+
+ return can;
+ })(__m5);
+
+ // ## util/jquery/jquery.js
+ var __m3 = (function($, can) {
+ // _jQuery node list._
+ $.extend(can, $, {
+ trigger: function(obj, event, args) {
+ if (obj.trigger) {
+ obj.trigger(event, args);
+ } else {
+ $.event.trigger(event, args, obj, true);
+ }
+ },
+ addEvent: function(ev, cb) {
+ $([this]).bind(ev, cb);
+ return this;
+ },
+ removeEvent: function(ev, cb) {
+ $([this]).unbind(ev, cb);
+ return this;
+ },
+ // jquery caches fragments, we always needs a new one
+ buildFragment: function(elems, context) {
+ var oldFragment = $.buildFragment,
+ ret;
+
+ elems = [elems];
+ // Set context per 1.8 logic
+ context = context || document;
+ context = !context.nodeType && context[0] || context;
+ context = context.ownerDocument || context;
+
+ ret = oldFragment.call(jQuery, elems, context);
+
+ return ret.cacheable ? $.clone(ret.fragment) : ret.fragment || ret;
+ },
+ $: $,
+ each: can.each
+ });
+
+ // Wrap binding functions.
+ $.each(['bind', 'unbind', 'undelegate', 'delegate'], function(i, func) {
+ can[func] = function() {
+ var t = this[func] ? this : $([this]);
+ t[func].apply(t, arguments);
+ return this;
+ };
+ });
+
+ // Wrap modifier functions.
+ $.each(["append", "filter", "addClass", "remove", "data", "get"], function(i, name) {
+ can[name] = function(wrapped) {
+ return wrapped[name].apply(wrapped, can.makeArray(arguments).slice(1));
+ };
+ });
+
+ // Memory safe destruction.
+ var oldClean = $.cleanData;
+
+ $.cleanData = function(elems) {
+ $.each(elems, function(i, elem) {
+ if (elem) {
+ can.trigger(elem, "destroyed", [], false);
+ }
+ });
+ oldClean(elems);
+ };
+
+ return can;
+ })(jQuery, __m5, __m6);
+
+ // ## util/string/string.js
+ var __m2 = (function(can) {
+ // ##string.js
+ // _Miscellaneous string utility functions._
+
+ // Several of the methods in this plugin use code adapated from Prototype
+ // Prototype JavaScript framework, version 1.6.0.1.
+ // © 2005-2007 Sam Stephenson
+ var strUndHash = /_|-/,
+ strColons = /\=\=/,
+ strWords = /([A-Z]+)([A-Z][a-z])/g,
+ strLowUp = /([a-z\d])([A-Z])/g,
+ strDash = /([a-z\d])([A-Z])/g,
+ strReplacer = /\{([^\}]+)\}/g,
+ strQuote = /"/g,
+ strSingleQuote = /'/g,
+
+ // Returns the `prop` property from `obj`.
+ // If `add` is true and `prop` doesn't exist in `obj`, create it as an
+ // empty object.
+ getNext = function(obj, prop, add) {
+ var result = obj[prop];
+
+ if (result === undefined && add === true) {
+ result = obj[prop] = {}
+ }
+ return result
+ },
+
+ // Returns `true` if the object can have properties (no `null`s).
+ isContainer = function(current) {
+ return (/^f|^o/).test(typeof current);
+ };
+
+ can.extend(can, {
+ // Escapes strings for HTML.
+
+ esc: function(content) {
+ // Convert bad values into empty strings
+ var isInvalid = content === null || content === undefined || (isNaN(content) && ("" + content === 'NaN'));
+ return ("" + (isInvalid ? '' : content))
+ .replace(/&/g, '&')
+ .replace(/</g, '<')
+ .replace(/>/g, '>')
+ .replace(strQuote, '"')
+ .replace(strSingleQuote, "'");
+ },
+
+
+ getObject: function(name, roots, add) {
+
+ // The parts of the name we are looking up
+ // `['App','Models','Recipe']`
+ var parts = name ? name.split('.') : [],
+ length = parts.length,
+ current,
+ r = 0,
+ i, container, rootsLength;
+
+ // Make sure roots is an `array`.
+ roots = can.isArray(roots) ? roots : [roots || window];
+
+ rootsLength = roots.length
+
+ if (!length) {
+ return roots[0];
+ }
+
+ // For each root, mark it as current.
+ for (r; r < rootsLength; r++) {
+ current = roots[r];
+ container = undefined;
+
+ // Walk current to the 2nd to last object or until there
+ // is not a container.
+ for (i = 0; i < length && isContainer(current); i++) {
+ container = current;
+ current = getNext(container, parts[i]);
+ }
+
+ // If we found property break cycle
+ if (container !== undefined && current !== undefined) {
+ break
+ }
+ }
+
+ // Remove property from found container
+ if (add === false && current !== undefined) {
+ delete container[parts[i - 1]]
+ }
+
+ // When adding property add it to the first root
+ if (add === true && current === undefined) {
+ current = roots[0]
+
+ for (i = 0; i < length && isContainer(current); i++) {
+ current = getNext(current, parts[i], true);
+ }
+ }
+
+ return current;
+ },
+ // Capitalizes a string.
+
+ capitalize: function(s, cache) {
+ // Used to make newId.
+ return s.charAt(0).toUpperCase() + s.slice(1);
+ },
+
+ // Underscores a string.
+
+ underscore: function(s) {
+ return s
+ .replace(strColons, '/')
+ .replace(strWords, '$1_$2')
+ .replace(strLowUp, '$1_$2')
+ .replace(strDash, '_')
+ .toLowerCase();
+ },
+ // Micro-templating.
+
+ sub: function(str, data, remove) {
+ var obs = [];
+
+ str = str || '';
+
+ obs.push(str.replace(strReplacer, function(whole, inside) {
+
+ // Convert inside to type.
+ var ob = can.getObject(inside, data, remove === true ? false : undefined);
+
+ if (ob === undefined) {
+ obs = null;
+ return "";
+ }
+
+ // If a container, push into objs (which will return objects found).
+ if (isContainer(ob) && obs) {
+ obs.push(ob);
+ return "";
+ }
+
+ return "" + ob;
+ }));
+
+ return obs === null ? obs : (obs.length <= 1 ? obs[0] : obs);
+ },
+
+ // These regex's are used throughout the rest of can, so let's make
+ // them available.
+ replacer: strReplacer,
+ undHash: strUndHash
+ });
+ return can;
+ })(__m3);
+
+ // ## construct/construct.js
+ var __m1 = (function(can) {
+
+ // ## construct.js
+ // `can.Construct`
+ // _This is a modified version of
+ // [John Resig's class](http://ejohn.org/blog/simple-javascript-inheritance/).
+ // It provides class level inheritance and callbacks._
+
+ // A private flag used to initialize a new class instance without
+ // initializing it's bindings.
+ var initializing = 0;
+
+
+ can.Construct = function() {
+ if (arguments.length) {
+ return can.Construct.extend.apply(can.Construct, arguments);
+ }
+ };
+
+
+ can.extend(can.Construct, {
+
+ newInstance: function() {
+ // Get a raw instance object (`init` is not called).
+ var inst = this.instance(),
+ arg = arguments,
+ args;
+
+ // Call `setup` if there is a `setup`
+ if (inst.setup) {
+ args = inst.setup.apply(inst, arguments);
+ }
+
+ // Call `init` if there is an `init`
+ // If `setup` returned `args`, use those as the arguments
+ if (inst.init) {
+ inst.init.apply(inst, args || arguments);
+ }
+
+ return inst;
+ },
+ // Overwrites an object with methods. Used in the `super` plugin.
+ // `newProps` - New properties to add.
+ // `oldProps` - Where the old properties might be (used with `super`).
+ // `addTo` - What we are adding to.
+ _inherit: function(newProps, oldProps, addTo) {
+ can.extend(addTo || newProps, newProps || {})
+ },
+ // used for overwriting a single property.
+ // this should be used for patching other objects
+ // the super plugin overwrites this
+ _overwrite: function(what, oldProps, propName, val) {
+ what[propName] = val;
+ },
+ // Set `defaults` as the merger of the parent `defaults` and this
+ // object's `defaults`. If you overwrite this method, make sure to
+ // include option merging logic.
+
+ setup: function(base, fullName) {
+ this.defaults = can.extend(true, {}, base.defaults, this.defaults);
+ },
+ // Create's a new `class` instance without initializing by setting the
+ // `initializing` flag.
+ instance: function() {
+
+ // Prevents running `init`.
+ initializing = 1;
+
+ var inst = new this();
+
+ // Allow running `init`.
+ initializing = 0;
+
+ return inst;
+ },
+ // Extends classes.
+
+ extend: function(fullName, klass, proto) {
+ // Figure out what was passed and normalize it.
+ if (typeof fullName != 'string') {
+ proto = klass;
+ klass = fullName;
+ fullName = null;
+ }
+
+ if (!proto) {
+ proto = klass;
+ klass = null;
+ }
+ proto = proto || {};
+
+ var _super_class = this,
+ _super = this.prototype,
+ name, shortName, namespace, prototype;
+
+ // Instantiate a base class (but only create the instance,
+ // don't run the init constructor).
+ prototype = this.instance();
+
+ // Copy the properties over onto the new prototype.
+ can.Construct._inherit(proto, _super, prototype);
+
+ // The dummy class constructor.
+
+ function Constructor() {
+ // All construction is actually done in the init method.
+ if (!initializing) {
+ return this.constructor !== Constructor && arguments.length ?
+ // We are being called without `new` or we are extending.
+ arguments.callee.extend.apply(arguments.callee, arguments) :
+ // We are being called with `new`.
+ this.constructor.newInstance.apply(this.constructor, arguments);
+ }
+ }
+
+ // Copy old stuff onto class (can probably be merged w/ inherit)
+ for (name in _super_class) {
+ if (_super_class.hasOwnProperty(name)) {
+ Constructor[name] = _super_class[name];
+ }
+ }
+
+ // Copy new static properties on class.
+ can.Construct._inherit(klass, _super_class, Constructor);
+
+ // Setup namespaces.
+ if (fullName) {
+
+ var parts = fullName.split('.'),
+ shortName = parts.pop(),
+ current = can.getObject(parts.join('.'), window, true),
+ namespace = current,
+ _fullName = can.underscore(fullName.replace(/\./g, "_")),
+ _shortName = can.underscore(shortName);
+
+
+
+ current[shortName] = Constructor;
+ }
+
+ // Set things that shouldn't be overwritten.
+ can.extend(Constructor, {
+ constructor: Constructor,
+ prototype: prototype,
+
+ namespace: namespace,
+
+ _shortName: _shortName,
+
+ fullName: fullName,
+ _fullName: _fullName
+ });
+
+ // Dojo and YUI extend undefined
+ if (shortName !== undefined) {
+ Constructor.shortName = shortName;
+ }
+
+ // Make sure our prototype looks nice.
+ Constructor.prototype.constructor = Constructor;
+
+
+ // Call the class `setup` and `init`
+ var t = [_super_class].concat(can.makeArray(arguments)),
+ args = Constructor.setup.apply(Constructor, t);
+
+ if (Constructor.init) {
+ Constructor.init.apply(Constructor, args || t);
+ }
+
+
+ return Constructor;
+
+ }
+
+ });
+ return can.Construct;
+ })(__m2);
+
+ // ## util/bind/bind.js
+ var __m8 = (function(can) {
+
+
+ // ## Bind helpers
+ can.bindAndSetup = function() {
+ // Add the event to this object
+ can.addEvent.apply(this, arguments);
+ // If not initializing, and the first binding
+ // call bindsetup if the function exists.
+ if (!this._init) {
+ if (!this._bindings) {
+ this._bindings = 1;
+ // setup live-binding
+ this._bindsetup && this._bindsetup();
+
+ } else {
+ this._bindings++;
+ }
+
+ }
+
+ return this;
+ };
+
+ can.unbindAndTeardown = function(ev, handler) {
+ // Remove the event handler
+ can.removeEvent.apply(this, arguments);
+
+ this._bindings--;
+ // If there are no longer any bindings and
+ // there is a bindteardown method, call it.
+ if (!this._bindings) {
+ this._bindteardown && this._bindteardown();
+ }
+ return this;
+ }
+
+ return can;
+
+ })(__m3);
+
+ // ## observe/observe.js
+ var __m7 = (function(can, bind) {
+ // ## observe.js
+ // `can.Observe`
+ // _Provides the observable pattern for JavaScript Objects._
+ // Returns `true` if something is an object with properties of its own.
+ var canMakeObserve = function(obj) {
+ return obj && !can.isDeferred(obj) && (can.isArray(obj) || can.isPlainObject(obj) || (obj instanceof can.Observe));
+ },
+
+ // Removes all listeners.
+ unhookup = function(items, namespace) {
+ return can.each(items, function(item) {
+ if (item && item.unbind) {
+ item.unbind("change" + namespace);
+ }
+ });
+ },
+ // Listens to changes on `child` and "bubbles" the event up.
+ // `child` - The object to listen for changes on.
+ // `prop` - The property name is at on.
+ // `parent` - The parent object of prop.
+ // `ob` - (optional) The Observe object constructor
+ // `list` - (optional) The observable list constructor
+ hookupBubble = function(child, prop, parent, Ob, List) {
+ Ob = Ob || Observe;
+ List = List || Observe.List;
+
+ // If it's an `array` make a list, otherwise a child.
+ if (child instanceof Observe) {
+ // We have an `observe` already...
+ // Make sure it is not listening to this already
+ // It's only listening if it has bindings already.
+ parent._bindings && unhookup([child], parent._cid);
+ } else if (can.isArray(child)) {
+ child = new List(child);
+ } else {
+ child = new Ob(child);
+ }
+ // only listen if something is listening to you
+ if (parent._bindings) {
+ // Listen to all changes and `batchTrigger` upwards.
+ bindToChildAndBubbleToParent(child, prop, parent)
+ }
+
+
+ return child;
+ },
+ bindToChildAndBubbleToParent = function(child, prop, parent) {
+ child.bind("change" + parent._cid, function() {
+ // `batchTrigger` the type on this...
+ var args = can.makeArray(arguments),
+ ev = args.shift();
+ args[0] = (prop === "*" ? [parent.indexOf(child), args[0]] : [prop, args[0]]).join(".");
+
+ // track objects dispatched on this observe
+ ev.triggeredNS = ev.triggeredNS || {};
+
+ // if it has already been dispatched exit
+ if (ev.triggeredNS[parent._cid]) {
+ return;
+ }
+
+ ev.triggeredNS[parent._cid] = true;
+ // send change event with modified attr to parent
+ can.trigger(parent, ev, args);
+ // send modified attr event to parent
+ //can.trigger(parent, args[0], args);
+ });
+ }
+ // An `id` to track events for a given observe.
+ observeId = 0,
+ // A helper used to serialize an `Observe` or `Observe.List`.
+ // `observe` - The observable.
+ // `how` - To serialize with `attr` or `serialize`.
+ // `where` - To put properties, in an `{}` or `[]`.
+ serialize = function(observe, how, where) {
+ // Go through each property.
+ observe.each(function(val, name) {
+ // If the value is an `object`, and has an `attrs` or `serialize` function.
+ where[name] = canMakeObserve(val) && can.isFunction(val[how]) ?
+ // Call `attrs` or `serialize` to get the original data back.
+ val[how]() :
+ // Otherwise return the value.
+ val;
+ });
+ return where;
+ },
+ attrParts = function(attr, keepKey) {
+ if (keepKey) {
+ return [attr];
+ }
+ return can.isArray(attr) ? attr : ("" + attr).split(".");
+ },
+ // Which batch of events this is for -- might not want to send multiple
+ // messages on the same batch. This is mostly for event delegation.
+ batchNum = 1,
+ // how many times has start been called without a stop
+ transactions = 0,
+ // an array of events within a transaction
+ batchEvents = [],
+ stopCallbacks = [],
+ makeBindSetup = function(wildcard) {
+ return function() {
+ var parent = this;
+ this._each(function(child, prop) {
+ if (child && child.bind) {
+ bindToChildAndBubbleToParent(child, wildcard || prop, parent)
+ }
+ })
+ };
+ };
+
+
+ var Observe = can.Map = can.Observe = can.Construct({
+
+ // keep so it can be overwritten
+ bind: can.bindAndSetup,
+ unbind: can.unbindAndTeardown,
+ id: "id",
+ canMakeObserve: canMakeObserve,
+ // starts collecting events
+ // takes a callback for after they are updated
+ // how could you hook into after ejs
+
+ startBatch: function(batchStopHandler) {
+ transactions++;
+ batchStopHandler && stopCallbacks.push(batchStopHandler);
+ },
+
+ stopBatch: function(force, callStart) {
+ if (force) {
+ transactions = 0;
+ } else {
+ transactions--;
+ }
+
+ if (transactions == 0) {
+ var items = batchEvents.slice(0),
+ callbacks = stopCallbacks.slice(0);
+ batchEvents = [];
+ stopCallbacks = [];
+ batchNum++;
+ callStart && this.startBatch();
+ can.each(items, function(args) {
+ can.trigger.apply(can, args);
+ });
+ can.each(callbacks, function(cb) {
+ cb();
+ });
+ }
+ },
+
+ triggerBatch: function(item, event, args) {
+ // Don't send events if initalizing.
+ if (!item._init) {
+ if (transactions == 0) {
+ return can.trigger(item, event, args);
+ } else {
+ event = typeof event === "string" ? {
+ type: event
+ } :
+ event;
+ event.batchNum = batchNum;
+ batchEvents.push([
+ item,
+ event,
+ args
+ ]);
+ }
+ }
+ },
+
+ keys: function(observe) {
+ var keys = [];
+ Observe.__reading && Observe.__reading(observe, '__keys');
+ for (var keyName in observe._data) {
+ keys.push(keyName);
+ }
+ return keys;
+ }
+ },
+
+ {
+ setup: function(obj) {
+ // `_data` is where we keep the properties.
+ this._data = {};
+
+ // The namespace this `object` uses to listen to events.
+ can.cid(this, ".observe");
+ // Sets all `attrs`.
+ this._init = 1;
+ this.attr(obj);
+ this.bind('change' + this._cid, can.proxy(this._changes, this));
+ delete this._init;
+ },
+ _bindsetup: makeBindSetup(),
+ _bindteardown: function() {
+ var cid = this._cid;
+ this._each(function(child) {
+ unhookup([child], cid)
+ })
+ },
+ _changes: function(ev, attr, how, newVal, oldVal) {
+ Observe.triggerBatch(this, {
+ type: attr,
+ batchNum: ev.batchNum
+ }, [newVal, oldVal]);
+ },
+ _triggerChange: function(attr, how, newVal, oldVal) {
+ Observe.triggerBatch(this, "change", can.makeArray(arguments))
+ },
+ // no live binding iterator
+ _each: function(callback) {
+ var data = this.__get();
+ for (var prop in data) {
+ if (data.hasOwnProperty(prop)) {
+ callback(data[prop], prop)
+ }
+ }
+ },
+
+ attr: function(attr, val) {
+ // This is super obfuscated for space -- basically, we're checking
+ // if the type of the attribute is not a `number` or a `string`.
+ var type = typeof attr;
+ if (type !== "string" && type !== "number") {
+ return this._attrs(attr, val)
+ } else if (val === undefined) { // If we are getting a value.
+ // Let people know we are reading.
+ Observe.__reading && Observe.__reading(this, attr)
+ return this._get(attr)
+ } else {
+ // Otherwise we are setting.
+ this._set(attr, val);
+ return this;
+ }
+ },
+
+ each: function() {
+ Observe.__reading && Observe.__reading(this, '__keys');
+ return can.each.apply(undefined, [this.__get()].concat(can.makeArray(arguments)))
+ },
+
+ removeAttr: function(attr) {
+ // Info if this is List or not
+ var isList = this instanceof can.Observe.List,
+ // Convert the `attr` into parts (if nested).
+ parts = attrParts(attr),
+ // The actual property to remove.
+ prop = parts.shift(),
+ // The current value.
+ current = isList ? this[prop] : this._data[prop];
+
+ // If we have more parts, call `removeAttr` on that part.
+ if (parts.length) {
+ return current.removeAttr(parts)
+ } else {
+ if (isList) {
+ this.splice(prop, 1)
+ } else if (prop in this._data) {
+ // Otherwise, `delete`.
+ delete this._data[prop];
+ // Create the event.
+ if (!(prop in this.constructor.prototype)) {
+ delete this[prop]
+ }
+ // Let others know the number of keys have changed
+ Observe.triggerBatch(this, "__keys");
+ this._triggerChange(prop, "remove", undefined, current);
+
+ }
+ return current;
+ }
+ },
+ // Reads a property from the `object`.
+ _get: function(attr) {
+ var value = typeof attr === 'string' && !! ~attr.indexOf('.') && this.__get(attr);
+ if (value) {
+ return value;
+ }
+
+ // break up the attr (`"foo.bar"`) into `["foo","bar"]`
+ var parts = attrParts(attr),
+ // get the value of the first attr name (`"foo"`)
+ current = this.__get(parts.shift());
+ // if there are other attributes to read
+ return parts.length ?
+ // and current has a value
+ current ?
+ // lookup the remaining attrs on current
+ current._get(parts) :
+ // or if there's no current, return undefined
+ undefined :
+ // if there are no more parts, return current
+ current;
+ },
+ // Reads a property directly if an `attr` is provided, otherwise
+ // returns the "real" data object itself.
+ __get: function(attr) {
+ return attr ? this._data[attr] : this._data;
+ },
+ // Sets `attr` prop as value on this object where.
+ // `attr` - Is a string of properties or an array of property values.
+ // `value` - The raw value to set.
+ _set: function(attr, value, keepKey) {
+ // Convert `attr` to attr parts (if it isn't already).
+ var parts = attrParts(attr, keepKey),
+ // The immediate prop we are setting.
+ prop = parts.shift(),
+ // The current value.
+ current = this.__get(prop);
+
+ // If we have an `object` and remaining parts.
+ if (canMakeObserve(current) && parts.length) {
+ // That `object` should set it (this might need to call attr).
+ current._set(parts, value)
+ } else if (!parts.length) {
+ // We're in "real" set territory.
+ if (this.__convert) {
+ value = this.__convert(prop, value)
+ }
+ this.__set(prop, value, current)
+ } else {
+ throw "can.Observe: Object does not exist"
+ }
+ },
+ __set: function(prop, value, current) {
+
+ // Otherwise, we are setting it on this `object`.
+ // TODO: Check if value is object and transform
+ // are we changing the value.
+ if (value !== current) {
+ // Check if we are adding this for the first time --
+ // if we are, we need to create an `add` event.
+ var changeType = this.__get().hasOwnProperty(prop) ? "set" : "add";
+
+ // Set the value on data.
+ this.___set(prop,
+
+ // If we are getting an object.
+ canMakeObserve(value) ?
+
+ // Hook it up to send event.
+ hookupBubble(value, prop, this) :
+ // Value is normal.
+ value);
+
+ if (changeType == "add") {
+ // If there is no current value, let others know that
+ // the the number of keys have changed
+
+ Observe.triggerBatch(this, "__keys", undefined);
+
+ }
+ // `batchTrigger` the change event.
+ this._triggerChange(prop, changeType, value, current);
+
+ //Observe.triggerBatch(this, prop, [value, current]);
+ // If we can stop listening to our old value, do it.
+ current && unhookup([current], this._cid);
+ }
+
+ },
+ // Directly sets a property on this `object`.
+ ___set: function(prop, val) {
+ this._data[prop] = val;
+ // Add property directly for easy writing.
+ // Check if its on the `prototype` so we don't overwrite methods like `attrs`.
+ if (!(prop in this.constructor.prototype)) {
+ this[prop] = val
+ }
+ },
+
+
+ bind: can.bindAndSetup,
+
+ unbind: can.unbindAndTeardown,
+
+ serialize: function() {
+ return serialize(this, 'serialize', {});
+ },
+
+ _attrs: function(props, remove) {
+
+ if (props === undefined) {
+ return serialize(this, 'attr', {})
+ }
+
+ props = can.extend({}, props);
+ var prop,
+ self = this,
+ newVal;
+ Observe.startBatch();
+ this.each(function(curVal, prop) {
+ newVal = props[prop];
+
+ // If we are merging...
+ if (newVal === undefined) {
+ remove && self.removeAttr(prop);
+ return;
+ }
+
+ if (self.__convert) {
+ newVal = self.__convert(prop, newVal)
+ }
+
+ // if we're dealing with models, want to call _set to let converter run
+ if (newVal instanceof can.Observe) {
+ self.__set(prop, newVal, curVal)
+ // if its an object, let attr merge
+ } else if (canMakeObserve(curVal) && canMakeObserve(newVal) && curVal.attr) {
+ curVal.attr(newVal, remove)
+ // otherwise just set
+ } else if (curVal != newVal) {
+ self.__set(prop, newVal, curVal)
+ }
+
+ delete props[prop];
+ })
+ // Add remaining props.
+ for (var prop in props) {
+ newVal = props[prop];
+ this._set(prop, newVal, true)
+ }
+ Observe.stopBatch()
+ return this;
+ },
+
+
+ compute: function(prop) {
+ return can.compute(this, prop);
+ }
+ });
+ // Helpers for `observable` lists.
+ var splice = [].splice,
+
+ list = Observe(
+
+ {
+ setup: function(instances, options) {
+ this.length = 0;
+ can.cid(this, ".observe")
+ this._init = 1;
+ if (can.isDeferred(instances)) {
+ this.replace(instances)
+ } else {
+ this.push.apply(this, can.makeArray(instances || []));
+ }
+ // this change needs to be ignored
+ this.bind('change' + this._cid, can.proxy(this._changes, this));
+ can.extend(this, options);
+ delete this._init;
+ },
+ _triggerChange: function(attr, how, newVal, oldVal) {
+
+ Observe.prototype._triggerChange.apply(this, arguments)
+ // `batchTrigger` direct add and remove events...
+ if (!~attr.indexOf('.')) {
+
+ if (how === 'add') {
+ Observe.triggerBatch(this, how, [newVal, +attr]);
+ Observe.triggerBatch(this, 'length', [this.length]);
+ } else if (how === 'remove') {
+ Observe.triggerBatch(this, how, [oldVal, +attr]);
+ Observe.triggerBatch(this, 'length', [this.length]);
+ } else {
+ Observe.triggerBatch(this, how, [newVal, +attr])
+ }
+
+ }
+
+ },
+ __get: function(attr) {
+ return attr ? this[attr] : this;
+ },
+ ___set: function(attr, val) {
+ this[attr] = val;
+ if (+attr >= this.length) {
+ this.length = (+attr + 1)
+ }
+ },
+ _each: function(callback) {
+ var data = this.__get();
+ for (var i = 0; i < data.length; i++) {
+ callback(data[i], i)
+ }
+ },
+ _bindsetup: makeBindSetup("*"),
+ // Returns the serialized form of this list.
+
+ serialize: function() {
+ return serialize(this, 'serialize', []);
+ },
+
+ splice: function(index, howMany) {
+ var args = can.makeArray(arguments),
+ i;
+
+ for (i = 2; i < args.length; i++) {
+ var val = args[i];
+ if (canMakeObserve(val)) {
+ args[i] = hookupBubble(val, "*", this, this.constructor.Observe, this.constructor)
+ }
+ }
+ if (howMany === undefined) {
+ howMany = args[1] = this.length - index;
+ }
+ var removed = splice.apply(this, args);
+ can.Observe.startBatch();
+ if (howMany > 0) {
+ this._triggerChange("" + index, "remove", undefined, removed);
+ unhookup(removed, this._cid);
+ }
+ if (args.length > 2) {
+ this._triggerChange("" + index, "add", args.slice(2), removed);
+ }
+ can.Observe.stopBatch();
+ return removed;
+ },
+
+ _attrs: function(items, remove) {
+ if (items === undefined) {
+ return serialize(this, 'attr', []);
+ }
+
+ // Create a copy.
+ items = can.makeArray(items);
+
+ Observe.startBatch();
+ this._updateAttrs(items, remove);
+ Observe.stopBatch()
+ },
+
+ _updateAttrs: function(items, remove) {
+ var len = Math.min(items.length, this.length);
+
+ for (var prop = 0; prop < len; prop++) {
+ var curVal = this[prop],
+ newVal = items[prop];
+
+ if (canMakeObserve(curVal) && canMakeObserve(newVal)) {
+ curVal.attr(newVal, remove)
+ } else if (curVal != newVal) {
+ this._set(prop, newVal)
+ } else {
+
+ }
+ }
+ if (items.length > this.length) {
+ // Add in the remaining props.
+ this.push.apply(this, items.slice(this.length));
+ } else if (items.length < this.length && remove) {
+ this.splice(items.length)
+ }
+ }
+ }),
+
+ // Converts to an `array` of arguments.
+ getArgs = function(args) {
+ return args[0] && can.isArray(args[0]) ?
+ args[0] :
+ can.makeArray(args);
+ };
+ // Create `push`, `pop`, `shift`, and `unshift`
+ can.each({
+
+ push: "length",
+
+ unshift: 0
+ },
+ // Adds a method
+ // `name` - The method name.
+ // `where` - Where items in the `array` should be added.
+
+ function(where, name) {
+ var orig = [][name]
+ list.prototype[name] = function() {
+ // Get the items being added.
+ var args = [],
+ // Where we are going to add items.
+ len = where ? this.length : 0,
+ i = arguments.length,
+ res,
+ val,
+ constructor = this.constructor;
+
+ // Go through and convert anything to an `observe` that needs to be converted.
+ while (i--) {
+ val = arguments[i];
+ args[i] = canMakeObserve(val) ?
+ hookupBubble(val, "*", this, this.constructor.Observe, this.constructor) :
+ val;
+ }
+
+ // Call the original method.
+ res = orig.apply(this, args);
+
+ if (!this.comparator || args.length) {
+
+ this._triggerChange("" + len, "add", args, undefined);
+ }
+
+ return res;
+ }
+ });
+
+ can.each({
+
+ pop: "length",
+
+ shift: 0
+ },
+ // Creates a `remove` type method
+
+ function(where, name) {
+ list.prototype[name] = function() {
+
+ var args = getArgs(arguments),
+ len = where && this.length ? this.length - 1 : 0;
+
+ var res = [][name].apply(this, args)
+
+ // Create a change where the args are
+ // `len` - Where these items were removed.
+ // `remove` - Items removed.
+ // `undefined` - The new values (there are none).
+ // `res` - The old, removed values (should these be unbound).
+ this._triggerChange("" + len, "remove", undefined, [res])
+
+ if (res && res.unbind) {
+ res.unbind("change" + this._cid)
+ }
+ return res;
+ }
+ });
+
+ can.extend(list.prototype, {
+
+ indexOf: function(item) {
+ this.attr('length')
+ return can.inArray(item, this)
+ },
+
+
+ join: [].join,
+
+
+ reverse: [].reverse,
+
+
+ slice: function() {
+ var temp = Array.prototype.slice.apply(this, arguments);
+ return new this.constructor(temp);
+ },
+
+
+ concat: function() {
+ var args = [];
+ can.each(can.makeArray(arguments), function(arg, i) {
+ args[i] = arg instanceof can.Observe.List ? arg.serialize() : arg;
+ });
+ return new this.constructor(Array.prototype.concat.apply(this.serialize(), args));
+ },
+
+
+ forEach: function(cb, thisarg) {
+ can.each(this, cb, thisarg || this);
+ },
+
+
+ replace: function(newList) {
+ if (can.isDeferred(newList)) {
+ newList.then(can.proxy(this.replace, this));
+ } else {
+ this.splice.apply(this, [0, this.length].concat(can.makeArray(newList || [])));
+ }
+
+ return this;
+ }
+ });
+
+ can.List = Observe.List = list;
+ Observe.setup = function() {
+ can.Construct.setup.apply(this, arguments);
+ // I would prefer not to do it this way. It should
+ // be using the attributes plugin to do this type of conversion.
+ this.List = Observe.List({
+ Observe: this
+ }, {});
+ }
+ return Observe;
+ })(__m3, __m8, __m1);
+
+ // ## observe/compute/compute.js
+ var __m9 = (function(can, bind) {
+
+ // returns the
+ // - observes and attr methods are called by func
+ // - the value returned by func
+ // ex: `{value: 100, observed: [{obs: o, attr: "completed"}]}`
+ var getValueAndObserved = function(func, self) {
+
+ var oldReading;
+ if (can.Observe) {
+ // Set a callback on can.Observe to know
+ // when an attr is read.
+ // Keep a reference to the old reader
+ // if there is one. This is used
+ // for nested live binding.
+ oldReading = can.Observe.__reading;
+ can.Observe.__reading = function(obj, attr) {
+ // Add the observe and attr that was read
+ // to `observed`
+ observed.push({
+ obj: obj,
+ attr: attr + ""
+ });
+ };
+ }
+
+ var observed = [],
+ // Call the "wrapping" function to get the value. `observed`
+ // will have the observe/attribute pairs that were read.
+ value = func.call(self);
+
+ // Set back so we are no longer reading.
+ if (can.Observe) {
+ can.Observe.__reading = oldReading;
+ }
+ return {
+ value: value,
+ observed: observed
+ };
+ },
+ // Calls `callback(newVal, oldVal)` everytime an observed property
+ // called within `getterSetter` is changed and creates a new result of `getterSetter`.
+ // Also returns an object that can teardown all event handlers.
+ computeBinder = function(getterSetter, context, callback, computeState) {
+ // track what we are observing
+ var observing = {},
+ // a flag indicating if this observe/attr pair is already bound
+ matched = true,
+ // the data to return
+ data = {
+ // we will maintain the value while live-binding is taking place
+ value: undefined,
+ // a teardown method that stops listening
+ teardown: function() {
+ for (var name in observing) {
+ var ob = observing[name];
+ ob.observe.obj.unbind(ob.observe.attr, onchanged);
+ delete observing[name];
+ }
+ }
+ },
+ batchNum;
+
+ // when a property value is changed
+ var onchanged = function(ev) {
+ // If the compute is no longer bound (because the same change event led to an unbind)
+ // then do not call getValueAndBind, or we will leak bindings.
+ if (computeState && !computeState.bound) {
+ return;
+ }
+ if (ev.batchNum === undefined || ev.batchNum !== batchNum) {
+ // store the old value
+ var oldValue = data.value,
+ // get the new value
+ newvalue = getValueAndBind();
+
+ // update the value reference (in case someone reads)
+ data.value = newvalue;
+ // if a change happened
+ if (newvalue !== oldValue) {
+ callback(newvalue, oldValue);
+ }
+ batchNum = batchNum = ev.batchNum;
+ }
+
+
+ };
+
+ // gets the value returned by `getterSetter` and also binds to any attributes
+ // read by the call
+ var getValueAndBind = function() {
+ var info = getValueAndObserved(getterSetter, context),
+ newObserveSet = info.observed;
+
+ var value = info.value;
+ matched = !matched;
+
+ // go through every attribute read by this observe
+ can.each(newObserveSet, function(ob) {
+ // if the observe/attribute pair is being observed
+ if (observing[ob.obj._cid + "|" + ob.attr]) {
+ // mark at as observed
+ observing[ob.obj._cid + "|" + ob.attr].matched = matched;
+ } else {
+ // otherwise, set the observe/attribute on oldObserved, marking it as being observed
+ observing[ob.obj._cid + "|" + ob.attr] = {
+ matched: matched,
+ observe: ob
+ };
+ ob.obj.bind(ob.attr, onchanged);
+ }
+ });
+
+ // Iterate through oldObserved, looking for observe/attributes
+ // that are no longer being bound and unbind them
+ for (var name in observing) {
+ var ob = observing[name];
+ if (ob.matched !== matched) {
+ ob.observe.obj.unbind(ob.observe.attr, onchanged);
+ delete observing[name];
+ }
+ }
+ return value;
+ };
+ // set the initial value
+ data.value = getValueAndBind();
+
+ data.isListening = !can.isEmptyObject(observing);
+ return data;
+ }
+
+ // if no one is listening ... we can not calculate every time
+
+ can.compute = function(getterSetter, context, eventName) {
+ if (getterSetter && getterSetter.isComputed) {
+ return getterSetter;
+ }
+ // stores the result of computeBinder
+ var computedData,
+ // how many listeners to this this compute
+ bindings = 0,
+ // the computed object
+ computed,
+ // an object that keeps track if the computed is bound
+ // onchanged needs to know this. It's possible a change happens and results in
+ // something that unbinds the compute, it needs to not to try to recalculate who it
+ // is listening to
+ computeState = {
+ bound: false,
+ // true if this compute is calculated from other computes and observes
+ hasDependencies: false
+ },
+ // The following functions are overwritten depending on how compute() is called
+ // a method to setup listening
+ on = function() {},
+ // a method to teardown listening
+ off = function() {},
+ // the current cached value (only valid if bound = true)
+ value,
+ // how to read the value
+ get = function() {
+ return value
+ },
+ // sets the value
+ set = function(newVal) {
+ value = newVal;
+ },
+ // this compute can be a dependency of other computes
+ canReadForChangeEvent = true;
+
+ computed = function(newVal) {
+ // setting ...
+ if (arguments.length) {
+ // save a reference to the old value
+ var old = value;
+
+ // setter may return a value if
+ // setter is for a value maintained exclusively by this compute
+ var setVal = set.call(context, newVal, old);
+
+ // if this has dependencies return the current value
+ if (computed.hasDependencies) {
+ return get.call(context);
+ }
+
+ if (setVal === undefined) {
+ // it's possible, like with the DOM, setting does not
+ // fire a change event, so we must read
+ value = get.call(context);
+ } else {
+ value = setVal;
+ }
+ // fire the change
+ if (old !== value) {
+ can.Observe.triggerBatch(computed, "change", [value, old]);
+ }
+ return value;
+ } else {
+ // Let others know to listen to changes in this compute
+ if (can.Observe.__reading && canReadForChangeEvent) {
+ can.Observe.__reading(computed, 'change');
+ }
+ // if we are bound, use the cached value
+ if (computeState.bound) {
+ return value;
+ } else {
+ return get.call(context);
+ }
+ }
+ }
+ if (typeof getterSetter === "function") {
+ set = getterSetter;
+ get = getterSetter;
+ canReadForChangeEvent = eventName === false ? false : true;
+ computed.hasDependencies = false;
+ on = function(update) {
+ computedData = computeBinder(getterSetter, context || this, update, computeState);
+ computed.hasDependencies = computedData.isListening
+ value = computedData.value;
+ }
+ off = function() {
+ computedData.teardown();
+ }
+ } else if (context) {
+
+ if (typeof context == "string") {
+ // `can.compute(obj, "propertyName", [eventName])`
+
+ var propertyName = context,
+ isObserve = getterSetter instanceof can.Observe;
+ if (isObserve) {
+ computed.hasDependencies = true;
+ }
+ get = function() {
+ if (isObserve) {
+ return getterSetter.attr(propertyName);
+ } else {
+ return getterSetter[propertyName];
+ }
+ }
+ set = function(newValue) {
+ if (isObserve) {
+ getterSetter.attr(propertyName, newValue)
+ } else {
+ getterSetter[propertyName] = newValue;
+ }
+ }
+ var handler;
+ on = function(update) {
+ handler = function() {
+ update(get(), value)
+ };
+ can.bind.call(getterSetter, eventName || propertyName, handler)
+
+ // use getValueAndObserved because
+ // we should not be indicating that some parent
+ // reads this property if it happens to be binding on it
+ value = getValueAndObserved(get).value
+ }
+ off = function() {
+ can.unbind.call(getterSetter, eventName || propertyName, handler)
+ }
+
+ } else {
+ // `can.compute(initialValue, setter)`
+ if (typeof context === "function") {
+ value = getterSetter;
+ set = context;
+ } else {
+ // `can.compute(initialValue,{get:, set:, on:, off:})`
+ value = getterSetter;
+ var options = context;
+ get = options.get || get;
+ set = options.set || set;
+ on = options.on || on;
+ off = options.off || off;
+ }
+
+ }
+
+
+
+ } else {
+ // `can.compute(5)`
+ value = getterSetter;
+ }
+
+ computed.isComputed = true;
+
+ can.cid(computed, "compute")
+
+ var updater = function(newValue, oldValue) {
+ value = newValue;
+ // might need a way to look up new and oldVal
+ can.Observe.triggerBatch(computed, "change", [newValue, oldValue])
+ }
+
+ return can.extend(computed, {
+ _bindsetup: function() {
+ computeState.bound = true;
+ // setup live-binding
+ on.call(this, updater)
+ },
+ _bindteardown: function() {
+ off.call(this, updater)
+ computeState.bound = false;
+ },
+
+ bind: can.bindAndSetup,
+
+ unbind: can.unbindAndTeardown
+ });
+ };
+ can.compute.binder = computeBinder;
+ return can.compute;
+ })(__m3, __m8);
+
+ // ## model/model.js
+ var __m10 = (function(can) {
+
+ // ## model.js
+ // `can.Model`
+ // _A `can.Observe` that connects to a RESTful interface._
+ // Generic deferred piping function
+
+ var pipe = function(def, model, func) {
+ var d = new can.Deferred();
+ def.then(function() {
+ var args = can.makeArray(arguments);
+ args[0] = model[func](args[0]);
+ d.resolveWith(d, args);
+ }, function() {
+ d.rejectWith(this, arguments);
+ });
+
+ if (typeof def.abort === 'function') {
+ d.abort = function() {
+ return def.abort();
+ }
+ }
+
+ return d;
+ },
+ modelNum = 0,
+ ignoreHookup = /change.observe\d+/,
+ getId = function(inst) {
+ // Instead of using attr, use __get for performance.
+ // Need to set reading
+ can.Observe.__reading && can.Observe.__reading(inst, inst.constructor.id)
+ return inst.__get(inst.constructor.id);
+ },
+ // Ajax `options` generator function
+ ajax = function(ajaxOb, data, type, dataType, success, error) {
+
+ var params = {};
+
+ // If we get a string, handle it.
+ if (typeof ajaxOb == "string") {
+ // If there's a space, it's probably the type.
+ var parts = ajaxOb.split(/\s+/);
+ params.url = parts.pop();
+ if (parts.length) {
+ params.type = parts.pop();
+ }
+ } else {
+ can.extend(params, ajaxOb);
+ }
+
+ // If we are a non-array object, copy to a new attrs.
+ params.data = typeof data == "object" && !can.isArray(data) ?
+ can.extend(params.data || {}, data) : data;
+
+ // Get the url with any templated values filled out.
+ params.url = can.sub(params.url, params.data, true);
+
+ return can.ajax(can.extend({
+ type: type || "post",
+ dataType: dataType || "json",
+ success: success,
+ error: error
+ }, params));
+ },
+ makeRequest = function(self, type, success, error, method) {
+ var args;
+ // if we pass an array as `self` it it means we are coming from
+ // the queued request, and we're passing already serialized data
+ // self's signature will be: [self, serializedData]
+ if (can.isArray(self)) {
+ args = self[1];
+ self = self[0];
+ } else {
+ args = self.serialize();
+ }
+ args = [args];
+ var deferred,
+ // The model.
+ model = self.constructor,
+ jqXHR;
+
+ // `destroy` does not need data.
+ if (type == 'destroy') {
+ args.shift();
+ }
+ // `update` and `destroy` need the `id`.
+ if (type !== 'create') {
+ args.unshift(getId(self));
+ }
+
+
+ jqXHR = model[type].apply(model, args);
+
+ deferred = jqXHR.pipe(function(data) {
+ self[method || type + "d"](data, jqXHR);
+ return self;
+ });
+
+ // Hook up `abort`
+ if (jqXHR.abort) {
+ deferred.abort = function() {
+ jqXHR.abort();
+ };
+ }
+
+ deferred.then(success, error);
+ return deferred;
+ },
+
+ // This object describes how to make an ajax request for each ajax method.
+ // The available properties are:
+ // `url` - The default url to use as indicated as a property on the model.
+ // `type` - The default http request type
+ // `data` - A method that takes the `arguments` and returns `data` used for ajax.
+
+ ajaxMethods = {
+
+ create: {
+ url: "_shortName",
+ type: "post"
+ },
+
+ update: {
+ data: function(id, attrs) {
+ attrs = attrs || {};
+ var identity = this.id;
+ if (attrs[identity] && attrs[identity] !== id) {
+ attrs["new" + can.capitalize(id)] = attrs[identity];
+ delete attrs[identity];
+ }
+ attrs[identity] = id;
+ return attrs;
+ },
+ type: "put"
+ },
+
+ destroy: {
+ type: "delete",
+ data: function(id) {
+ var args = {};
+ args.id = args[this.id] = id;
+ return args;
+ }
+ },
+
+ findAll: {
+ url: "_shortName"
+ },
+
+ findOne: {}
+ },
+ // Makes an ajax request `function` from a string.
+ // `ajaxMethod` - The `ajaxMethod` object defined above.
+ // `str` - The string the user provided. Ex: `findAll: "/recipes.json"`.
+ ajaxMaker = function(ajaxMethod, str) {
+ // Return a `function` that serves as the ajax method.
+ return function(data) {
+ // If the ajax method has it's own way of getting `data`, use that.
+ data = ajaxMethod.data ?
+ ajaxMethod.data.apply(this, arguments) :
+ // Otherwise use the data passed in.
+ data;
+ // Return the ajax method with `data` and the `type` provided.
+ return ajax(str || this[ajaxMethod.url || "_url"], data, ajaxMethod.type || "get")
+ }
+ }
+
+
+
+ can.Model = can.Observe({
+ fullName: "can.Model",
+ _reqs: 0,
+ setup: function(base) {
+ // create store here if someone wants to use model without inheriting from it
+ this.store = {};
+ can.Observe.setup.apply(this, arguments);
+ // Set default list as model list
+ if (!can.Model) {
+ return;
+ }
+ this.List = ML({
+ Observe: this
+ }, {});
+ var self = this,
+ clean = can.proxy(this._clean, self);
+
+
+ // go through ajax methods and set them up
+ can.each(ajaxMethods, function(method, name) {
+ // if an ajax method is not a function, it's either
+ // a string url like findAll: "/recipes" or an
+ // ajax options object like {url: "/recipes"}
+ if (!can.isFunction(self[name])) {
+ // use ajaxMaker to convert that into a function
+ // that returns a deferred with the data
+ self[name] = ajaxMaker(method, self[name]);
+ }
+ // check if there's a make function like makeFindAll
+ // these take deferred function and can do special
+ // behavior with it (like look up data in a store)
+ if (self["make" + can.capitalize(name)]) {
+ // pass the deferred method to the make method to get back
+ // the "findAll" method.
+ var newMethod = self["make" + can.capitalize(name)](self[name]);
+ can.Construct._overwrite(self, base, name, function() {
+ // increment the numer of requests
+ can.Model._reqs++;
+ var def = newMethod.apply(this, arguments);
+ var then = def.then(clean, clean);
+ then.abort = def.abort;
+
+ // attach abort to our then and return it
+ return then;
+ })
+ }
+ });
+
+ if (self.fullName == "can.Model" || !self.fullName) {
+ self.fullName = "Model" + (++modelNum);
+ }
+ // Add ajax converters.
+ can.Model._reqs = 0;
+ this._url = this._shortName + "/{" + this.id + "}"
+ },
+ _ajax: ajaxMaker,
+ _makeRequest: makeRequest,
+ _clean: function() {
+ can.Model._reqs--;
+ if (!can.Model._reqs) {
+ for (var id in this.store) {
+ if (!this.store[id]._bindings) {
+ delete this.store[id];
+ }
+ }
+ }
+ return arguments[0];
+ },
+
+ models: function(instancesRawData, oldList) {
+ // until "end of turn", increment reqs counter so instances will be added to the store
+ can.Model._reqs++;
+ if (!instancesRawData) {
+ return;
+ }
+
+ if (instancesRawData instanceof this.List) {
+ return instancesRawData;
+ }
+
+ // Get the list type.
+ var self = this,
+ tmp = [],
+ res = oldList instanceof can.Observe.List ? oldList : new(self.List || ML),
+ // Did we get an `array`?
+ arr = can.isArray(instancesRawData),
+
+ // Did we get a model list?
+ ml = (instancesRawData instanceof ML),
+
+ // Get the raw `array` of objects.
+ raw = arr ?
+
+ // If an `array`, return the `array`.
+ instancesRawData :
+
+ // Otherwise if a model list.
+ (ml ?
+
+ // Get the raw objects from the list.
+ instancesRawData.serialize() :
+
+ // Get the object's data.
+ instancesRawData.data),
+ i = 0;
+
+
+
+ if (res.length) {
+ res.splice(0);
+ }
+
+ can.each(raw, function(rawPart) {
+ tmp.push(self.model(rawPart));
+ });
+
+ // We only want one change event so push everything at once
+ res.push.apply(res, tmp);
+
+ if (!arr) { // Push other stuff onto `array`.
+ can.each(instancesRawData, function(val, prop) {
+ if (prop !== 'data') {
+ res.attr(prop, val);
+ }
+ })
+ }
+ // at "end of turn", clean up the store
+ setTimeout(can.proxy(this._clean, this), 1);
+ return res;
+ },
+
+ model: function(attributes) {
+ if (!attributes) {
+ return;
+ }
+ if (attributes instanceof this) {
+ attributes = attributes.serialize();
+ }
+ var id = attributes[this.id],
+ model = (id || id === 0) && this.store[id] ?
+ this.store[id].attr(attributes, this.removeAttr || false) : new this(attributes);
+ if (can.Model._reqs) {
+ this.store[attributes[this.id]] = model;
+ }
+ return model;
+ }
+ },
+
+
+ {
+
+ isNew: function() {
+ var id = getId(this);
+ return !(id || id === 0); // If `null` or `undefined`
+ },
+
+ save: function(success, error) {
+ return makeRequest(this, this.isNew() ? 'create' : 'update', success, error);
+ },
+
+ destroy: function(success, error) {
+ if (this.isNew()) {
+ var self = this;
+ var def = can.Deferred();
+ def.then(success, error);
+ return def.done(function(data) {
+ self.destroyed(data)
+ }).resolve(self);
+ }
+ return makeRequest(this, 'destroy', success, error, 'destroyed');
+ },
+
+ _bindsetup: function() {
+ this.constructor.store[this.__get(this.constructor.id)] = this;
+ return can.Observe.prototype._bindsetup.apply(this, arguments);
+ },
+
+ _bindteardown: function() {
+ delete this.constructor.store[getId(this)];
+ return can.Observe.prototype._bindteardown.apply(this, arguments)
+ },
+ // Change `id`.
+ ___set: function(prop, val) {
+ can.Observe.prototype.___set.call(this, prop, val)
+ // If we add an `id`, move it to the store.
+ if (prop === this.constructor.id && this._bindings) {
+ this.constructor.store[getId(this)] = this;
+ }
+ }
+ });
+
+ can.each({
+ makeFindAll: "models",
+ makeFindOne: "model",
+ makeCreate: "model",
+ makeUpdate: "model"
+ }, function(method, name) {
+ can.Model[name] = function(oldMethod) {
+ return function() {
+ var args = can.makeArray(arguments),
+ oldArgs = can.isFunction(args[1]) ? args.splice(0, 1) : args.splice(0, 2),
+ def = pipe(oldMethod.apply(this, oldArgs), this, method);
+ def.then(args[0], args[1]);
+ // return the original promise
+ return def;
+ };
+ };
+ });
+
+ can.each([
+
+ "created",
+
+ "updated",
+
+ "destroyed"
+ ], function(funcName) {
+ can.Model.prototype[funcName] = function(attrs) {
+ var stub,
+ constructor = this.constructor;
+
+ // Update attributes if attributes have been passed
+ stub = attrs && typeof attrs == 'object' && this.attr(attrs.attr ? attrs.attr() : attrs);
+
+ // triggers change event that bubble's like
+ // handler( 'change','1.destroyed' ). This is used
+ // to remove items on destroyed from Model Lists.
+ // but there should be a better way.
+ can.trigger(this, "change", funcName)
+
+
+ // Call event on the instance's Class
+ can.trigger(constructor, funcName, this);
+ };
+ });
+
+ // Model lists are just like `Observe.List` except that when their items are
+ // destroyed, it automatically gets removed from the list.
+
+ var ML = can.Model.List = can.Observe.List({
+ setup: function(params) {
+ if (can.isPlainObject(params) && !can.isArray(params)) {
+ can.Observe.List.prototype.setup.apply(this);
+ this.replace(this.constructor.Observe.findAll(params))
+ } else {
+ can.Observe.List.prototype.setup.apply(this, arguments);
+ }
+ },
+ _changes: function(ev, attr) {
+ can.Observe.List.prototype._changes.apply(this, arguments);
+ if (/\w+\.destroyed/.test(attr)) {
+ var index = this.indexOf(ev.target);
+ if (index != -1) {
+ this.splice(index, 1);
+ }
+ }
+ }
+ })
+
+ return can.Model;
+ })(__m3, __m7);
+
+ // ## view/view.js
+ var __m11 = (function(can) {
+ // ## view.js
+ // `can.view`
+ // _Templating abstraction._
+
+ var isFunction = can.isFunction,
+ makeArray = can.makeArray,
+ // Used for hookup `id`s.
+ hookupId = 1,
+
+ $view = can.view = can.template = function(view, data, helpers, callback) {
+ // If helpers is a `function`, it is actually a callback.
+ if (isFunction(helpers)) {
+ callback = helpers;
+ helpers = undefined;
+ }
+
+ var pipe = function(result) {
+ return $view.frag(result);
+ },
+ // In case we got a callback, we need to convert the can.view.render
+ // result to a document fragment
+ wrapCallback = isFunction(callback) ? function(frag) {
+ callback(pipe(frag));
+ } : null,
+ // Get the result.
+ result = $view.render(view, data, helpers, wrapCallback),
+ deferred = can.Deferred();
+
+ if (isFunction(result)) {
+ return result;
+ }
+
+ if (can.isDeferred(result)) {
+ result.then(function(result, data) {
+ deferred.resolve.call(deferred, pipe(result), data);
+ }, function() {
+ deferred.fail.apply(deferred, arguments);
+ });
+ return deferred;
+ }
+
+ // Convert it into a dom frag.
+ return pipe(result);
+ };
+
+ can.extend($view, {
+ // creates a frag and hooks it up all at once
+ frag: function(result, parentNode) {
+ return $view.hookup($view.fragment(result), parentNode);
+ },
+
+ // simply creates a frag
+ // this is used internally to create a frag
+ // insert it
+ // then hook it up
+ fragment: function(result) {
+ var frag = can.buildFragment(result, document.body);
+ // If we have an empty frag...
+ if (!frag.childNodes.length) {
+ frag.appendChild(document.createTextNode(''));
+ }
+ return frag;
+ },
+
+ // Convert a path like string into something that's ok for an `element` ID.
+ toId: function(src) {
+ return can.map(src.toString().split(/\/|\./g), function(part) {
+ // Dont include empty strings in toId functions
+ if (part) {
+ return part;
+ }
+ }).join("_");
+ },
+
+ hookup: function(fragment, parentNode) {
+ var hookupEls = [],
+ id,
+ func;
+
+ // Get all `childNodes`.
+ can.each(fragment.childNodes ? can.makeArray(fragment.childNodes) : fragment, function(node) {
+ if (node.nodeType === 1) {
+ hookupEls.push(node);
+ hookupEls.push.apply(hookupEls, can.makeArray(node.getElementsByTagName('*')));
+ }
+ });
+
+ // Filter by `data-view-id` attribute.
+ can.each(hookupEls, function(el) {
+ if (el.getAttribute && (id = el.getAttribute('data-view-id')) && (func = $view.hookups[id])) {
+ func(el, parentNode, id);
+ delete $view.hookups[id];
+ el.removeAttribute('data-view-id');
+ }
+ });
+
+ return fragment;
+ },
+
+
+ hookups: {},
+
+
+ hook: function(cb) {
+ $view.hookups[++hookupId] = cb;
+ return " data-view-id='" + hookupId + "'";
+ },
+
+
+ cached: {},
+
+ cachedRenderers: {},
+
+
+ cache: true,
+
+
+ register: function(info) {
+ this.types["." + info.suffix] = info;
+ },
+
+ types: {},
+
+
+ ext: ".ejs",
+
+
+ registerScript: function() {},
+
+
+ preload: function() {},
+
+
+ render: function(view, data, helpers, callback) {
+ // If helpers is a `function`, it is actually a callback.
+ if (isFunction(helpers)) {
+ callback = helpers;
+ helpers = undefined;
+ }
+
+ // See if we got passed any deferreds.
+ var deferreds = getDeferreds(data);
+
+ if (deferreds.length) { // Does data contain any deferreds?
+ // The deferred that resolves into the rendered content...
+ var deferred = new can.Deferred(),
+ dataCopy = can.extend({}, data);
+
+ // Add the view request to the list of deferreds.
+ deferreds.push(get(view, true))
+
+ // Wait for the view and all deferreds to finish...
+ can.when.apply(can, deferreds).then(function(resolved) {
+ // Get all the resolved deferreds.
+ var objs = makeArray(arguments),
+ // Renderer is the last index of the data.
+ renderer = objs.pop(),
+ // The result of the template rendering with data.
+ result;
+
+ // Make data look like the resolved deferreds.
+ if (can.isDeferred(data)) {
+ dataCopy = usefulPart(resolved);
+ } else {
+ // Go through each prop in data again and
+ // replace the defferreds with what they resolved to.
+ for (var prop in data) {
+ if (can.isDeferred(data[prop])) {
+ dataCopy[prop] = usefulPart(objs.shift());
+ }
+ }
+ }
+
+ // Get the rendered result.
+ result = renderer(dataCopy, helpers);
+
+ // Resolve with the rendered view.
+ deferred.resolve(result, dataCopy);
+
+ // If there's a `callback`, call it back with the result.
+ callback && callback(result, dataCopy);
+ }, function() {
+ deferred.reject.apply(deferred, arguments)
+ });
+ // Return the deferred...
+ return deferred;
+ } else {
+ // No deferreds! Render this bad boy.
+ var response,
+ // If there's a `callback` function
+ async = isFunction(callback),
+ // Get the `view` type
+ deferred = get(view, async);
+
+ // If we are `async`...
+ if (async) {
+ // Return the deferred
+ response = deferred;
+ // And fire callback with the rendered result.
+ deferred.then(function(renderer) {
+ callback(data ? renderer(data, helpers) : renderer);
+ })
+ } else {
+ // if the deferred is resolved, call the cached renderer instead
+ // this is because it's possible, with recursive deferreds to
+ // need to render a view while its deferred is _resolving_. A _resolving_ deferred
+ // is a deferred that was just resolved and is calling back it's success callbacks.
+ // If a new success handler is called while resoliving, it does not get fired by
+ // jQuery's deferred system. So instead of adding a new callback
+ // we use the cached renderer.
+ // We also add __view_id on the deferred so we can look up it's cached renderer.
+ // In the future, we might simply store either a deferred or the cached result.
+ if (deferred.state() === "resolved" && deferred.__view_id) {
+ var currentRenderer = $view.cachedRenderers[deferred.__view_id];
+ return data ? currentRenderer(data, helpers) : currentRenderer;
+ } else {
+ // Otherwise, the deferred is complete, so
+ // set response to the result of the rendering.
+ deferred.then(function(renderer) {
+ response = data ? renderer(data, helpers) : renderer;
+ });
+ }
+ }
+
+ return response;
+ }
+ },
+
+
+ registerView: function(id, text, type, def) {
+ // Get the renderer function.
+ var func = (type || $view.types[$view.ext]).renderer(id, text);
+ def = def || new can.Deferred();
+
+ // Cache if we are caching.
+ if ($view.cache) {
+ $view.cached[id] = def;
+ def.__view_id = id;
+ $view.cachedRenderers[id] = func;
+ }
+
+ // Return the objects for the response's `dataTypes`
+ // (in this case view).
+ return def.resolve(func);
+ }
+ });
+
+ // Makes sure there's a template, if not, have `steal` provide a warning.
+ var checkText = function(text, url) {
+ if (!text.length) {
+
+ throw "can.view: No template or empty template:" + url;
+ }
+ },
+ // `Returns a `view` renderer deferred.
+ // `url` - The url to the template.
+ // `async` - If the ajax request should be asynchronous.
+ // Returns a deferred.
+ get = function(url, async) {
+ var suffix = url.match(/\.[\w\d]+$/),
+ type,
+ // If we are reading a script element for the content of the template,
+ // `el` will be set to that script element.
+ el,
+ // A unique identifier for the view (used for caching).
+ // This is typically derived from the element id or
+ // the url for the template.
+ id,
+ // The ajax request used to retrieve the template content.
+ jqXHR;
+
+ //If the url has a #, we assume we want to use an inline template
+ //from a script element and not current page's HTML
+ if (url.match(/^#/)) {
+ url = url.substr(1);
+ }
+ // If we have an inline template, derive the suffix from the `text/???` part.
+ // This only supports `<script>` tags.
+ if (el = document.getElementById(url)) {
+ suffix = "." + el.type.match(/\/(x\-)?(.+)/)[2];
+ }
+
+ // If there is no suffix, add one.
+ if (!suffix && !$view.cached[url]) {
+ url += (suffix = $view.ext);
+ }
+
+ if (can.isArray(suffix)) {
+ suffix = suffix[0]
+ }
+
+ // Convert to a unique and valid id.
+ id = $view.toId(url);
+
+ // If an absolute path, use `steal` to get it.
+ // You should only be using `//` if you are using `steal`.
+ if (url.match(/^\/\//)) {
+ var sub = url.substr(2);
+ url = !window.steal ?
+ sub :
+ steal.config().root.mapJoin("" + steal.id(sub));
+ }
+
+ // Set the template engine type.
+ type = $view.types[suffix];
+
+ // If it is cached,
+ if ($view.cached[id]) {
+ // Return the cached deferred renderer.
+ return $view.cached[id];
+
+ // Otherwise if we are getting this from a `<script>` element.
+ } else if (el) {
+ // Resolve immediately with the element's `innerHTML`.
+ return $view.registerView(id, el.innerHTML, type);
+ } else {
+ // Make an ajax request for text.
+ var d = new can.Deferred();
+ can.ajax({
+ async: async,
+ url: url,
+ dataType: "text",
+ error: function(jqXHR) {
+ checkText("", url);
+ d.reject(jqXHR);
+ },
+ success: function(text) {
+ // Make sure we got some text back.
+ checkText(text, url);
+ $view.registerView(id, text, type, d)
+ }
+ });
+ return d;
+ }
+ },
+ // Gets an `array` of deferreds from an `object`.
+ // This only goes one level deep.
+ getDeferreds = function(data) {
+ var deferreds = [];
+
+ // pull out deferreds
+ if (can.isDeferred(data)) {
+ return [data]
+ } else {
+ for (var prop in data) {
+ if (can.isDeferred(data[prop])) {
+ deferreds.push(data[prop]);
+ }
+ }
+ }
+ return deferreds;
+ },
+ // Gets the useful part of a resolved deferred.
+ // This is for `model`s and `can.ajax` that resolve to an `array`.
+ usefulPart = function(resolved) {
+ return can.isArray(resolved) && resolved[1] === 'success' ? resolved[0] : resolved
+ };
+
+ //!steal-pluginify-remove-start
+ if (window.steal) {
+ steal.type("view js", function(options, success, error) {
+ var type = $view.types["." + options.type],
+ id = $view.toId(options.id);
+
+ options.text = "steal('" + (type.plugin || "can/view/" + options.type) + "',function(can){return " + "can.view.preload('" + id + "'," + options.text + ");\n})";
+ success();
+ })
+ }
+ //!steal-pluginify-remove-end
+
+ can.extend($view, {
+ register: function(info) {
+ this.types["." + info.suffix] = info;
+
+ //!steal-pluginify-remove-start
+ if (window.steal) {
+ steal.type(info.suffix + " view js", function(options, success, error) {
+ var type = $view.types["." + options.type],
+ id = $view.toId(options.id + '');
+
+ options.text = type.script(id, options.text)
+ success();
+ })
+ };
+ //!steal-pluginify-remove-end
+
+ $view[info.suffix] = function(id, text) {
+ if (!text) {
+ // Return a nameless renderer
+ var renderer = function() {
+ return $view.frag(renderer.render.apply(this, arguments));
+ }
+ renderer.render = function() {
+ var renderer = info.renderer(null, id);
+ return renderer.apply(renderer, arguments);
+ }
+ return renderer;
+ }
+
+ $view.preload(id, info.renderer(id, text));
+ return can.view(id);
+ }
+ },
+ registerScript: function(type, id, src) {
+ return "can.view.preload('" + id + "'," + $view.types["." + type].script(id, src) + ");";
+ },
+ preload: function(id, renderer) {
+ $view.cached[id] = new can.Deferred().resolve(function(data, helpers) {
+ return renderer.call(data, data, helpers);
+ });
+
+ function frag() {
+ return $view.frag(renderer.apply(this, arguments));
+ }
+ // expose the renderer for mustache
+ frag.render = renderer;
+ return frag;
+ }
+
+ });
+
+ return can;
+ })(__m3);
+
+ // ## view/elements.js
+ var __m14 = (function() {
+
+ var elements = {
+ tagToContentPropMap: {
+ option: "textContent" in document.createElement("option") ? "textContent" : "innerText",
+ textarea: "value"
+ },
+
+ attrMap: {
+ "class": "className",
+ "value": "value",
+ "innerText": "innerText",
+ "textContent": "textContent",
+ "checked": true,
+ "disabled": true,
+ "readonly": true,
+ "required": true
+ },
+ // elements whos default value we should set
+ defaultValue: ["input", "textarea"],
+ // a map of parent element to child elements
+ tagMap: {
+ "": "span",
+ table: "tbody",
+ tr: "td",
+ ol: "li",
+ ul: "li",
+ tbody: "tr",
+ thead: "tr",
+ tfoot: "tr",
+ select: "option",
+ optgroup: "option"
+ },
+ // a tag's parent element
+ reverseTagMap: {
+ tr: "tbody",
+ option: "select",
+ td: "tr",
+ th: "tr",
+ li: "ul"
+ },
+
+ getParentNode: function(el, defaultParentNode) {
+ return defaultParentNode && el.parentNode.nodeType === 11 ? defaultParentNode : el.parentNode;
+ },
+ // set an attribute on an element
+ setAttr: function(el, attrName, val) {
+ var tagName = el.nodeName.toString().toLowerCase(),
+ prop = elements.attrMap[attrName];
+ // if this is a special property
+ if (prop === true) {
+ el[attrName] = true;
+ } else if (prop) {
+ // set the value as true / false
+ el[prop] = val;
+ if (prop === "value" && can.inArray(tagName, elements.defaultValue) >= 0) {
+ el.defaultValue = val;
+ }
+ } else {
+ el.setAttribute(attrName, val);
+ }
+ },
+ // gets the value of an attribute
+ getAttr: function(el, attrName) {
+ // Default to a blank string for IE7/8
+ return (elements.attrMap[attrName] && el[elements.attrMap[attrName]] ?
+ el[elements.attrMap[attrName]] :
+ el.getAttribute(attrName)) || '';
+ },
+ // removes the attribute
+ removeAttr: function(el, attrName) {
+ if (elements.attrMap[attrName] === true) {
+ el[attrName] = false;
+ } else {
+ el.removeAttribute(attrName);
+ }
+ },
+ contentText: function(text) {
+ if (typeof text == 'string') {
+ return text;
+ }
+ // If has no value, return an empty string.
+ if (!text && text !== 0) {
+ return '';
+ }
+ return "" + text;
+ }
+ };
+
+ return elements;
+ })();
+
+ // ## view/scanner.js
+ var __m13 = (function(can, elements) {
+
+ var newLine = /(\r|\n)+/g,
+ // Escapes characters starting with `\`.
+ clean = function(content) {
+ return content
+ .split('\\').join("\\\\")
+ .split("\n").join("\\n")
+ .split('"').join('\\"')
+ .split("\t").join("\\t");
+ },
+ // Returns a tagName to use as a temporary placeholder for live content
+ // looks forward ... could be slow, but we only do it when necessary
+ getTag = function(tagName, tokens, i) {
+ // if a tagName is provided, use that
+ if (tagName) {
+ return tagName;
+ } else {
+ // otherwise go searching for the next two tokens like "<",TAG
+ while (i < tokens.length) {
+ if (tokens[i] == "<" && elements.reverseTagMap[tokens[i + 1]]) {
+ return elements.reverseTagMap[tokens[i + 1]];
+ }
+ i++;
+ }
+ }
+ return '';
+ },
+ bracketNum = function(content) {
+ return (--content.split("{").length) - (--content.split("}").length);
+ },
+ myEval = function(script) {
+ try {
+ eval(script);
+ } catch(e) {
+ console.log(script)
+ }
+ },
+ attrReg = /([^\s]+)[\s]*=[\s]*$/,
+ // Commands for caching.
+ startTxt = 'var ___v1ew = [];',
+ finishTxt = "return ___v1ew.join('')",
+ put_cmd = "___v1ew.push(",
+ insert_cmd = put_cmd,
+ // Global controls (used by other functions to know where we are).
+ // Are we inside a tag?
+ htmlTag = null,
+ // Are we within a quote within a tag?
+ quote = null,
+ // What was the text before the current quote? (used to get the `attr` name)
+ beforeQuote = null,
+ // Whether a rescan is in progress
+ rescan = null,
+ // Used to mark where the element is.
+ status = function() {
+ // `t` - `1`.
+ // `h` - `0`.
+ // `q` - String `beforeQuote`.
+ return quote ? "'" + beforeQuote.match(attrReg)[1] + "'" : (htmlTag ? 1 : 0);
+ };
+
+ can.view.Scanner = Scanner = function(options) {
+ // Set options on self
+ can.extend(this, {
+ text: {},
+ tokens: []
+ }, options);
+
+ // Cache a token lookup
+ this.tokenReg = [];
+ this.tokenSimple = {
+ "<": "<",
+ ">": ">",
+ '"': '"',
+ "'": "'"
+ };
+ this.tokenComplex = [];
+ this.tokenMap = {};
+ for (var i = 0, token; token = this.tokens[i]; i++) {
+
+
+ // Save complex mappings (custom regexp)
+ if (token[2]) {
+ this.tokenReg.push(token[2]);
+ this.tokenComplex.push({
+ abbr: token[1],
+ re: new RegExp(token[2]),
+ rescan: token[3]
+ });
+ }
+ // Save simple mappings (string only, no regexp)
+ else {
+ this.tokenReg.push(token[1]);
+ this.tokenSimple[token[1]] = token[0];
+ }
+ this.tokenMap[token[0]] = token[1];
+ }
+
+ // Cache the token registry.
+ this.tokenReg = new RegExp("(" + this.tokenReg.slice(0).concat(["<", ">", '"', "'"]).join("|") + ")", "g");
+ };
+
+ Scanner.prototype = {
+
+ helpers: [
+
+ {
+ name: /\s*\(([\$\w]+)\)\s*->([^\n]*)/,
+ fn: function(content) {
+ var quickFunc = /\s*\(([\$\w]+)\)\s*->([^\n]*)/,
+ parts = content.match(quickFunc);
+
+ return "can.proxy(function(__){var " + parts[1] + "=can.$(__);" + parts[2] + "}, this);";
+ }
+ }
+ ],
+
+ scan: function(source, name) {
+ var tokens = [],
+ last = 0,
+ simple = this.tokenSimple,
+ complex = this.tokenComplex;
+
+ source = source.replace(newLine, "\n");
+ if (this.transform) {
+ source = this.transform(source);
+ }
+ source.replace(this.tokenReg, function(whole, part) {
+ // offset is the second to last argument
+ var offset = arguments[arguments.length - 2];
+
+ // if the next token starts after the last token ends
+ // push what's in between
+ if (offset > last) {
+ tokens.push(source.substring(last, offset));
+ }
+
+ // push the simple token (if there is one)
+ if (simple[whole]) {
+ tokens.push(whole);
+ }
+ // otherwise lookup complex tokens
+ else {
+ for (var i = 0, token; token = complex[i]; i++) {
+ if (token.re.test(whole)) {
+ tokens.push(token.abbr);
+ // Push a rescan function if one exists
+ if (token.rescan) {
+ tokens.push(token.rescan(part));
+ }
+ break;
+ }
+ }
+ }
+
+ // update the position of the last part of the last token
+ last = offset + part.length;
+ });
+
+ // if there's something at the end, add it
+ if (last < source.length) {
+ tokens.push(source.substr(last));
+ }
+
+ var content = '',
+ buff = [startTxt + (this.text.start || '')],
+ // Helper `function` for putting stuff in the view concat.
+ put = function(content, bonus) {
+ buff.push(put_cmd, '"', clean(content), '"' + (bonus || '') + ');');
+ },
+ // A stack used to keep track of how we should end a bracket
+ // `}`.
+ // Once we have a `<%= %>` with a `leftBracket`,
+ // we store how the file should end here (either `))` or `;`).
+ endStack = [],
+ // The last token, used to remember which tag we are in.
+ lastToken,
+ // The corresponding magic tag.
+ startTag = null,
+ // Was there a magic tag inside an html tag?
+ magicInTag = false,
+ // The current tag name.
+ tagName = '',
+ // stack of tagNames
+ tagNames = [],
+ // Pop from tagNames?
+ popTagName = false,
+ // Declared here.
+ bracketCount,
+ i = 0,
+ token,
+ tmap = this.tokenMap;
+
+ // Reinitialize the tag state goodness.
+ htmlTag = quote = beforeQuote = null;
+
+ for (;
+ (token = tokens[i++]) !== undefined;) {
+ if (startTag === null) {
+ switch (token) {
+ case tmap.left:
+ case tmap.escapeLeft:
+ case tmap.returnLeft:
+ magicInTag = htmlTag && 1;
+ case tmap.commentLeft:
+ // A new line -- just add whatever content within a clean.
+ // Reset everything.
+ startTag = token;
+ if (content.length) {
+ put(content);
+ }
+ content = '';
+ break;
+ case tmap.escapeFull:
+ // This is a full line escape (a line that contains only whitespace and escaped logic)
+ // Break it up into escape left and right
+ magicInTag = htmlTag && 1;
+ rescan = 1;
+ startTag = tmap.escapeLeft;
+ if (content.length) {
+ put(content);
+ }
+ rescan = tokens[i++];
+ content = rescan.content || rescan;
+ if (rescan.before) {
+ put(rescan.before);
+ }
+ tokens.splice(i, 0, tmap.right);
+ break;
+ case tmap.commentFull:
+ // Ignore full line comments.
+ break;
+ case tmap.templateLeft:
+ content += tmap.left;
+ break;
+ case '<':
+ // Make sure we are not in a comment.
+ if (tokens[i].indexOf("!--") !== 0) {
+ htmlTag = 1;
+ magicInTag = 0;
+ }
+ content += token;
+ break;
+ case '>':
+ htmlTag = 0;
+ // content.substr(-1) doesn't work in IE7/8
+ var emptyElement = content.substr(content.length - 1) == "/" || content.substr(content.length - 2) == "--";
+ // if there was a magic tag
+ // or it's an element that has text content between its tags,
+ // but content is not other tags add a hookup
+ // TODO: we should only add `can.EJS.pending()` if there's a magic tag
+ // within the html tags.
+ if (magicInTag || !popTagName && elements.tagToContentPropMap[tagNames[tagNames.length - 1]]) {
+ // make sure / of /> is on the left of pending
+ if (emptyElement) {
+ put(content.substr(0, content.length - 1), ",can.view.pending(),\"/>\"");
+ } else {
+ put(content, ",can.view.pending(),\">\"");
+ }
+ content = '';
+ magicInTag = 0;
+ } else {
+ content += token;
+ }
+ // if it's a tag like <input/>
+ if (emptyElement || popTagName) {
+ // remove the current tag in the stack
+ tagNames.pop();
+ // set the current tag to the previous parent
+ tagName = tagNames[tagNames.length - 1];
+ // Don't pop next time
+ popTagName = false;
+ }
+ break;
+ case "'":
+ case '"':
+ // If we are in an html tag, finding matching quotes.
+ if (htmlTag) {
+ // We have a quote and it matches.
+ if (quote && quote === token) {
+ // We are exiting the quote.
+ quote = null;
+ // Otherwise we are creating a quote.
+ // TODO: does this handle `\`?
+ } else if (quote === null) {
+ quote = token;
+ beforeQuote = lastToken;
+ }
+ }
+ default:
+ // Track the current tag
+ if (lastToken === '<') {
+ tagName = token.split(/\s/)[0];
+ if (tagName.indexOf("/") === 0 && tagNames[tagNames.length - 1] === tagName.substr(1)) {
+ // set tagName to the last tagName
+ // if there are no more tagNames, we'll rely on getTag.
+ tagName = tagNames[tagNames.length - 1];
+ popTagName = true;
+ } else {
+ tagNames.push(tagName);
+ }
+ }
+ content += token;
+ break;
+ }
+ } else {
+ // We have a start tag.
+ switch (token) {
+ case tmap.right:
+ case tmap.returnRight:
+ switch (startTag) {
+ case tmap.left:
+ // Get the number of `{ minus }`
+ bracketCount = bracketNum(content);
+
+ // We are ending a block.
+ if (bracketCount == 1) {
+
+ // We are starting on.
+ buff.push(insert_cmd, "can.view.txt(0,'" + getTag(tagName, tokens, i) + "'," + status() + ",this,function(){", startTxt, content);
+
+ endStack.push({
+ before: "",
+ after: finishTxt + "}));\n"
+ });
+ } else {
+
+ // How are we ending this statement?
+ last = // If the stack has value and we are ending a block...
+ endStack.length && bracketCount == -1 ? // Use the last item in the block stack.
+ endStack.pop() : // Or use the default ending.
+ {
+ after: ";"
+ };
+
+ // If we are ending a returning block,
+ // add the finish text which returns the result of the
+ // block.
+ if (last.before) {
+ buff.push(last.before);
+ }
+ // Add the remaining content.
+ buff.push(content, ";", last.after);
+ }
+ break;
+ case tmap.escapeLeft:
+ case tmap.returnLeft:
+ // We have an extra `{` -> `block`.
+ // Get the number of `{ minus }`.
+ bracketCount = bracketNum(content);
+ // If we have more `{`, it means there is a block.
+ if (bracketCount) {
+ // When we return to the same # of `{` vs `}` end with a `doubleParent`.
+ endStack.push({
+ before: finishTxt,
+ after: "}));"
+ });
+ }
+
+ var escaped = startTag === tmap.escapeLeft ? 1 : 0,
+ commands = {
+ insert: insert_cmd,
+ tagName: getTag(tagName, tokens, i),
+ status: status()
+ };
+
+ for (var ii = 0; ii < this.helpers.length; ii++) {
+ // Match the helper based on helper
+ // regex name value
+ var helper = this.helpers[ii];
+ if (helper.name.test(content)) {
+ content = helper.fn(content, commands);
+
+ // dont escape partials
+ if (helper.name.source == /^>[\s]*\w*/.source) {
+ escaped = 0;
+ }
+ break;
+ }
+ }
+
+ // Handle special cases
+ if (typeof content == 'object') {
+ if (content.raw) {
+ buff.push(content.raw);
+ }
+ } else {
+ // If we have `<%== a(function(){ %>` then we want
+ // `can.EJS.text(0,this, function(){ return a(function(){ var _v1ew = [];`.
+ buff.push(insert_cmd, "can.view.txt(" + escaped + ",'" + tagName + "'," + status() + ",this,function(){ " + (this.text.escape || '') + "return ", content,
+ // If we have a block.
+ bracketCount ?
+ // Start with startTxt `"var _v1ew = [];"`.
+ startTxt :
+ // If not, add `doubleParent` to close push and text.
+ "}));");
+ }
+
+ if (rescan && rescan.after && rescan.after.length) {
+ put(rescan.after.length);
+ rescan = null;
+ }
+ break;
+ }
+ startTag = null;
+ content = '';
+ break;
+ case tmap.templateLeft:
+ content += tmap.left;
+ break;
+ default:
+ content += token;
+ break;
+ }
+ }
+ lastToken = token;
+ }
+
+ // Put it together...
+ if (content.length) {
+ // Should be `content.dump` in Ruby.
+ put(content);
+ }
+ buff.push(";");
+
+ var template = buff.join(''),
+ out = {
+ out: 'with(_VIEW) { with (_CONTEXT) {' + template + " " + finishTxt + "}}"
+ };
+ // Use `eval` instead of creating a function, because it is easier to debug.
+ myEval.call(out, 'this.fn = (function(_CONTEXT,_VIEW){' + out.out + '});\r\n//@ sourceURL=' + name + ".js");
+
+ return out;
+ }
+ };
+
+ return Scanner;
+ })(__m11, __m14);
+
+ // ## view/node_lists.js
+ var __m17 = (function(can) {
+
+ // text node expando test
+ var canExpando = true;
+ try {
+ document.createTextNode('')._ = 0;
+ } catch (ex) {
+ canExpando = false;
+ }
+
+ // a mapping of element ids to nodeList ids
+ var nodeMap = {},
+ // a mapping of ids to text nodes
+ textNodeMap = {},
+ // a mapping of nodeList ids to nodeList
+ nodeListMap = {},
+ expando = "ejs_" + Math.random(),
+ _id = 0,
+ id = function(node) {
+ if (canExpando || node.nodeType !== 3) {
+ if (node[expando]) {
+ return node[expando];
+ } else {
+ return node[expando] = (node.nodeName ? "element_" : "obj_") + (++_id);
+ }
+ } else {
+ for (var textNodeID in textNodeMap) {
+ if (textNodeMap[textNodeID] === node) {
+ return textNodeID;
+ }
+ }
+
+ textNodeMap["text_" + (++_id)] = node;
+ return "text_" + _id;
+ }
+ },
+ // removes a nodeListId from a node's nodeListIds
+ removeNodeListId = function(node, nodeListId) {
+ var nodeListIds = nodeMap[id(node)];
+ if (nodeListIds) {
+ var index = can.inArray(nodeListId, nodeListIds);
+
+ if (index >= 0) {
+ nodeListIds.splice(index, 1);
+ }
+ if (!nodeListIds.length) {
+ delete nodeMap[id(node)];
+ }
+ }
+ },
+ addNodeListId = function(node, nodeListId) {
+ var nodeListIds = nodeMap[id(node)];
+ if (!nodeListIds) {
+ nodeListIds = nodeMap[id(node)] = [];
+ }
+ nodeListIds.push(nodeListId);
+ };
+
+ var nodeLists = {
+ id: id,
+ // replaces the contents of one node list with the nodes in another list
+ replace: function(oldNodeList, newNodes) {
+ // for each node in the node list
+ oldNodeList = can.makeArray(oldNodeList);
+
+ // try every set
+ //can.each( oldNodeList, function(node){
+ var node = oldNodeList[0]
+ // for each nodeList the node is in
+ can.each(can.makeArray(nodeMap[id(node)]), function(nodeListId) {
+
+ // if startNode to endNode is
+ // within list, replace that list
+ // I think the problem is not the WHOLE part is being
+ // matched
+ var nodeList = nodeListMap[nodeListId],
+ startIndex = can.inArray(node, nodeList),
+ endIndex = can.inArray(oldNodeList[oldNodeList.length - 1], nodeList);
+
+
+ // remove this nodeListId from each node
+ if (startIndex >= 0 && endIndex >= 0) {
+ for (var i = startIndex; i <= endIndex; i++) {
+ var n = nodeList[i];
+ removeNodeListId(n, nodeListId);
+ }
+ // swap in new nodes into the nodeLIst
+ nodeList.splice.apply(nodeList, [startIndex, endIndex - startIndex + 1].concat(newNodes));
+
+ // tell these new nodes they belong to the nodeList
+ can.each(newNodes, function(node) {
+ addNodeListId(node, nodeListId);
+ });
+ } else {
+ nodeLists.unregister(nodeList);
+ }
+ });
+ //});
+ },
+ // registers a list of nodes
+ register: function(nodeList) {
+ var nLId = id(nodeList);
+ nodeListMap[nLId] = nodeList;
+
+ can.each(nodeList, function(node) {
+ addNodeListId(node, nLId);
+ });
+
+ },
+ // removes mappings
+ unregister: function(nodeList) {
+ var nLId = id(nodeList);
+ can.each(nodeList, function(node) {
+ removeNodeListId(node, nLId);
+ });
+ delete nodeListMap[nLId];
+ },
+ nodeMap: nodeMap,
+ nodeListMap: nodeListMap
+ }
+ var ids = function(nodeList) {
+ return nodeList.map(function(n) {
+ return id(n) + ":" + (n.innerHTML || n.nodeValue)
+ })
+ }
+ return nodeLists;
+
+ })(__m3);
+
+ // ## view/live.js
+ var __m16 = (function(can, elements, view, nodeLists) {
+ // ## live.js
+ // The live module provides live binding for computes
+ // and can.Observe.List.
+ // Currently, it's API is designed for `can/view/render`, but
+ // it could easily be used for other purposes.
+
+ // ### Helper methods
+ // #### setup
+ // `setup(HTMLElement, bind(data), unbind(data)) -> data`
+ // Calls bind right away, but will call unbind
+ // if the element is "destroyed" (removed from the DOM).
+ var setup = function(el, bind, unbind) {
+ var teardown = function() {
+ unbind(data)
+ can.unbind.call(el, 'destroyed', teardown);
+ },
+ data = {
+ teardownCheck: function(parent) {
+ if (!parent) {
+ teardown();
+ }
+ }
+ }
+
+ can.bind.call(el, 'destroyed', teardown);
+ bind(data)
+ return data;
+ },
+ // #### listen
+ // Calls setup, but presets bind and unbind to
+ // operate on a compute
+ listen = function(el, compute, change) {
+ return setup(el, function() {
+ compute.bind("change", change);
+ }, function(data) {
+ compute.unbind("change", change);
+ if (data.nodeList) {
+ nodeLists.unregister(data.nodeList);
+ }
+ });
+ },
+ // #### getAttributeParts
+ // Breaks up a string like foo='bar' into ["foo","'bar'""]
+ getAttributeParts = function(newVal) {
+ return (newVal || "").replace(/['"]/g, '').split('=')
+ }
+ // #### insertElementsAfter
+ // Appends elements after the last item in oldElements.
+ insertElementsAfter = function(oldElements, newFrag) {
+ var last = oldElements[oldElements.length - 1];
+
+ // Insert it in the `document` or `documentFragment`
+ if (last.nextSibling) {
+ last.parentNode.insertBefore(newFrag, last.nextSibling);
+ } else {
+ last.parentNode.appendChild(newFrag);
+ }
+ };
+
+ var live = {
+ nodeLists: nodeLists,
+ list: function(el, list, func, context, parentNode) {
+ // A mapping of the index to an array
+ // of elements that represent the item.
+ // Each array is registered so child or parent
+ // live structures can update the elements
+ var nodesMap = [],
+
+ add = function(ev, items, index) {
+
+ // Collect new html and mappings
+ var frag = document.createDocumentFragment(),
+ newMappings = [];
+ can.each(items, function(item) {
+ var itemHTML = func.call(context, item),
+ itemFrag = can.view.frag(itemHTML, parentNode);
+
+ newMappings.push(can.makeArray(itemFrag.childNodes));
+ frag.appendChild(itemFrag);
+ })
+
+ // Inserting at the end of the list
+ if (!nodesMap[index]) {
+ insertElementsAfter(
+ index == 0 ? [text] :
+ nodesMap[index - 1], frag)
+ } else {
+ var el = nodesMap[index][0];
+ el.parentNode.insertBefore(frag, el)
+ }
+ // register each item
+ can.each(newMappings, function(nodeList) {
+ nodeLists.register(nodeList)
+ });
+ [].splice.apply(nodesMap, [index, 0].concat(newMappings));
+ },
+ remove = function(ev, items, index) {
+ var removedMappings = nodesMap.splice(index, items.length),
+ itemsToRemove = [];
+
+ can.each(removedMappings, function(nodeList) {
+ // add items that we will remove all at once
+ [].push.apply(itemsToRemove, nodeList)
+ // Update any parent lists to remove these items
+ nodeLists.replace(nodeList, []);
+ // unregister the list
+ nodeLists.unregister(nodeList);
+
+ });
+ can.remove(can.$(itemsToRemove));
+ },
+ parentNode = elements.getParentNode(el, parentNode),
+ text = document.createTextNode("");
+
+ // Setup binding and teardown to add and remove events
+ setup(parentNode, function() {
+ list.bind("add", add).bind("remove", remove)
+ }, function() {
+ list.unbind("add", add).unbind("remove", remove);
+ can.each(nodesMap, function(nodeList) {
+ nodeLists.unregister(nodeList);
+ })
+ })
+
+ insertElementsAfter([el], text);
+ can.remove(can.$(el));
+ add({}, list, 0);
+
+ },
+ html: function(el, compute, parentNode) {
+ var parentNode = elements.getParentNode(el, parentNode),
+
+ data = listen(parentNode, compute, function(ev, newVal, oldVal) {
+ var attached = nodes[0].parentNode;
+ // update the nodes in the DOM with the new rendered value
+ if (attached) {
+ makeAndPut(newVal);
+ }
+ data.teardownCheck(nodes[0].parentNode);
+ });
+
+ var nodes,
+ makeAndPut = function(val) {
+ // create the fragment, but don't hook it up
+ // we need to insert it into the document first
+ var frag = can.view.frag(val, parentNode),
+ // keep a reference to each node
+ newNodes = can.makeArray(frag.childNodes);
+ // Insert it in the `document` or `documentFragment`
+ insertElementsAfter(nodes || [el], frag)
+ // nodes hasn't been set yet
+ if (!nodes) {
+ can.remove(can.$(el));
+ nodes = newNodes;
+ // set the teardown nodeList
+ data.nodeList = nodes;
+ nodeLists.register(nodes);
+ } else {
+ // Update node Array's to point to new nodes
+ // and then remove the old nodes.
+ // It has to be in this order for Mootools
+ // and IE because somehow, after an element
+ // is removed from the DOM, it loses its
+ // expando values.
+ var nodesToRemove = can.makeArray(nodes);
+ nodeLists.replace(nodes, newNodes);
+ can.remove(can.$(nodesToRemove));
+ }
+ };
+ makeAndPut(compute(), [el]);
+
+ },
+ text: function(el, compute, parentNode) {
+ var parent = elements.getParentNode(el, parentNode);
+
+ // setup listening right away so we don't have to re-calculate value
+ var data = listen(el.parentNode !== parent ? el.parentNode : parent, compute, function(ev, newVal, oldVal) {
+ // Sometimes this is 'unknown' in IE and will throw an exception if it is
+ if (typeof node.nodeValue != 'unknown') {
+ node.nodeValue = "" + newVal;
+ }
+ data.teardownCheck(node.parentNode);
+ });
+
+ var node = document.createTextNode(compute());
+
+ if (el.parentNode !== parent) {
+ parent = el.parentNode;
+ parent.insertBefore(node, el);
+ parent.removeChild(el);
+ } else {
+ parent.insertBefore(node, el);
+ parent.removeChild(el);
+ }
+ },
+ attributes: function(el, compute, currentValue) {
+ var setAttrs = function(newVal) {
+ var parts = getAttributeParts(newVal),
+ newAttrName = parts.shift();
+
+ // Remove if we have a change and used to have an `attrName`.
+ if ((newAttrName != attrName) && attrName) {
+ elements.removeAttr(el, attrName);
+ }
+ // Set if we have a new `attrName`.
+ if (newAttrName) {
+ elements.setAttr(el, newAttrName, parts.join('='));
+ attrName = newAttrName;
+ }
+ }
+
+ listen(el, compute, function(ev, newVal) {
+ setAttrs(newVal)
+ })
+ // current value has been set
+ if (arguments.length >= 3) {
+ var attrName = getAttributeParts(currentValue)[0]
+ } else {
+ setAttrs(compute())
+ }
+ },
+ attributePlaceholder: '__!!__',
+ attributeReplace: /__!!__/g,
+ attribute: function(el, attributeName, compute) {
+ listen(el, compute, function(ev, newVal) {
+ elements.setAttr(el, attributeName, hook.render());
+ })
+
+ var wrapped = can.$(el),
+ hooks;
+
+ // Get the list of hookups or create one for this element.
+ // Hooks is a map of attribute names to hookup `data`s.
+ // Each hookup data has:
+ // `render` - A `function` to render the value of the attribute.
+ // `funcs` - A list of hookup `function`s on that attribute.
+ // `batchNum` - The last event `batchNum`, used for performance.
+ hooks = can.data(wrapped, 'hooks');
+ if (!hooks) {
+ can.data(wrapped, 'hooks', hooks = {});
+ }
+
+ // Get the attribute value.
+ var attr = elements.getAttr(el, attributeName),
+ // Split the attribute value by the template.
+ // Only split out the first __!!__ so if we have multiple hookups in the same attribute,
+ // they will be put in the right spot on first render
+ parts = attr.split(live.attributePlaceholder),
+ goodParts = [],
+ hook;
+ goodParts.push(parts.shift(),
+ parts.join(live.attributePlaceholder));
+
+ // If we already had a hookup for this attribute...
+ if (hooks[attributeName]) {
+ // Just add to that attribute's list of `function`s.
+ hooks[attributeName].computes.push(compute);
+ } else {
+ // Create the hookup data.
+ hooks[attributeName] = {
+ render: function() {
+ var i = 0,
+ // attr doesn't have a value in IE
+ newAttr = attr ? attr.replace(live.attributeReplace, function() {
+ return elements.contentText(hook.computes[i++]());
+ }) : elements.contentText(hook.computes[i++]());
+ return newAttr;
+ },
+ computes: [compute],
+ batchNum: undefined
+ };
+ }
+
+ // Save the hook for slightly faster performance.
+ hook = hooks[attributeName];
+
+ // Insert the value in parts.
+ goodParts.splice(1, 0, compute());
+
+ // Set the attribute.
+ elements.setAttr(el, attributeName, goodParts.join(""));
+
+ }
+ }
+ return live;
+
+ })(__m3, __m14, __m11, __m17);
+
+ // ## view/render.js
+ var __m15 = (function(can, elements, live) {
+
+ var pendingHookups = [],
+ tagChildren = function(tagName) {
+ var newTag = elements.tagMap[tagName] || "span";
+ if (newTag === "span") {
+ //innerHTML in IE doesn't honor leading whitespace after empty elements
+ return "@@!!@@";
+ }
+ return "<" + newTag + ">" + tagChildren(newTag) + "</" + newTag + ">";
+ },
+ contentText = function(input, tag) {
+
+ // If it's a string, return.
+ if (typeof input == 'string') {
+ return input;
+ }
+ // If has no value, return an empty string.
+ if (!input && input !== 0) {
+ return '';
+ }
+
+ // If it's an object, and it has a hookup method.
+ var hook = (input.hookup &&
+
+ // Make a function call the hookup method.
+
+ function(el, id) {
+ input.hookup.call(input, el, id);
+ }) ||
+
+ // Or if it's a `function`, just use the input.
+ (typeof input == 'function' && input);
+
+ // Finally, if there is a `function` to hookup on some dom,
+ // add it to pending hookups.
+ if (hook) {
+ if (tag) {
+ return "<" + tag + " " + can.view.hook(hook) + "></" + tag + ">"
+ } else {
+ pendingHookups.push(hook);
+ }
+
+ return '';
+ }
+
+ // Finally, if all else is `false`, `toString()` it.
+ return "" + input;
+ },
+ // Returns escaped/sanatized content for anything other than a live-binding
+ contentEscape = function(txt) {
+ return (typeof txt == 'string' || typeof txt == 'number') ?
+ can.esc(txt) :
+ contentText(txt);
+ };
+
+ var current;
+
+ can.extend(can.view, {
+ live: live,
+ setupLists: function() {
+
+ var old = can.view.lists,
+ data;
+
+ can.view.lists = function(list, renderer) {
+ data = {
+ list: list,
+ renderer: renderer
+ }
+ }
+ return function() {
+ can.view.lists = old;
+ return data;
+ }
+ },
+ pending: function() {
+ // TODO, make this only run for the right tagName
+ var hooks = pendingHookups.slice(0);
+ lastHookups = hooks;
+ pendingHookups = [];
+ return can.view.hook(function(el) {
+ can.each(hooks, function(fn) {
+ fn(el);
+ });
+ });
+ },
+
+
+ txt: function(escape, tagName, status, self, func) {
+ var listTeardown = can.view.setupLists(),
+ emptyHandler = function() {},
+ unbind = function() {
+ compute.unbind("change", emptyHandler)
+ };
+
+ var compute = can.compute(func, self, false);
+ // bind to get and temporarily cache the value
+ compute.bind("change", emptyHandler);
+ // call the "wrapping" function and get the binding information
+ var tag = (elements.tagMap[tagName] || "span"),
+ listData = listTeardown(),
+ value = compute();
+
+
+ if (listData) {
+ return "<" + tag + can.view.hook(function(el, parentNode) {
+ live.list(el, listData.list, listData.renderer, self, parentNode);
+ }) + "></" + tag + ">";
+ }
+
+ // If we had no observes just return the value returned by func.
+ if (!compute.hasDependencies) {
+ unbind();
+ return (escape || status !== 0 ? contentEscape : contentText)(value, status === 0 && tag);
+ }
+
+ // the property (instead of innerHTML elements) to adjust. For
+ // example options should use textContent
+ var contentProp = elements.tagToContentPropMap[tagName];
+
+
+ // The magic tag is outside or between tags.
+ if (status === 0 && !contentProp) {
+ // Return an element tag with a hookup in place of the content
+ return "<" + tag + can.view.hook(
+ escape ?
+ // If we are escaping, replace the parentNode with
+ // a text node who's value is `func`'s return value.
+
+ function(el, parentNode) {
+ live.text(el, compute, parentNode);
+ unbind();
+ } :
+ // If we are not escaping, replace the parentNode with a
+ // documentFragment created as with `func`'s return value.
+
+ function(el, parentNode) {
+ live.html(el, compute, parentNode);
+ unbind();
+ //children have to be properly nested HTML for buildFragment to work properly
+ }) + ">" + tagChildren(tag) + "</" + tag + ">";
+ // In a tag, but not in an attribute
+ } else if (status === 1) {
+ // remember the old attr name
+ pendingHookups.push(function(el) {
+ live.attributes(el, compute, compute());
+ unbind();
+ });
+ return compute();
+ } else { // In an attribute...
+ var attributeName = status === 0 ? contentProp : status;
+ // if the magic tag is inside the element, like `<option><% TAG %></option>`,
+ // we add this hookup to the last element (ex: `option`'s) hookups.
+ // Otherwise, the magic tag is in an attribute, just add to the current element's
+ // hookups.
+ (status === 0 ? lastHookups : pendingHookups).push(function(el) {
+ live.attribute(el, attributeName, compute);
+ unbind();
+ });
+ return live.attributePlaceholder;
+ }
+ }
+ });
+
+ return can;
+ })(__m11, __m14, __m16, __m2);
+
+ // ## view/ejs/ejs.js
+ var __m12 = (function(can) {
+ // ## ejs.js
+ // `can.EJS`
+ // _Embedded JavaScript Templates._
+
+ // Helper methods.
+ var extend = can.extend,
+ EJS = function(options) {
+ // Supports calling EJS without the constructor
+ // This returns a function that renders the template.
+ if (this.constructor != EJS) {
+ var ejs = new EJS(options);
+ return function(data, helpers) {
+ return ejs.render(data, helpers);
+ };
+ }
+ // If we get a `function` directly, it probably is coming from
+ // a `steal`-packaged view.
+ if (typeof options == "function") {
+ this.template = {
+ fn: options
+ };
+ return;
+ }
+ // Set options on self.
+ extend(this, options);
+ this.template = this.scanner.scan(this.text, this.name);
+ };
+
+ can.EJS = EJS;
+
+
+ EJS.prototype.
+
+ render = function(object, extraHelpers) {
+ object = object || {};
+ return this.template.fn.call(object, object, new EJS.Helpers(object, extraHelpers || {}));
+ };
+
+ extend(EJS.prototype, {
+
+ scanner: new can.view.Scanner({
+
+ tokens: [
+ ["templateLeft", "<%%"], // Template
+ ["templateRight", "%>"], // Right Template
+ ["returnLeft", "<%=="], // Return Unescaped
+ ["escapeLeft", "<%="], // Return Escaped
+ ["commentLeft", "<%#"], // Comment
+ ["left", "<%"], // Run --- this is hack for now
+ ["right", "%>"], // Right -> All have same FOR Mustache ...
+ ["returnRight", "%>"]
+ ],
+
+
+ transform: function(source) {
+ return source.replace(/<%([\s\S]+?)%>/gm, function(whole, part) {
+ var brackets = [],
+ foundBracketPair,
+ i;
+
+ // Look for brackets (for removing self-contained blocks)
+ part.replace(/[{}]/gm, function(bracket, offset) {
+ brackets.push([bracket, offset]);
+ });
+
+ // Remove bracket pairs from the list of replacements
+ do {
+ foundBracketPair = false;
+ for (i = brackets.length - 2; i >= 0; i--) {
+ if (brackets[i][0] == '{' && brackets[i + 1][0] == '}') {
+ brackets.splice(i, 2);
+ foundBracketPair = true;
+ break;
+ }
+ }
+ } while (foundBracketPair);
+
+ // Unmatched brackets found, inject EJS tags
+ if (brackets.length >= 2) {
+ var result = ['<%'],
+ bracket,
+ last = 0;
+ for (i = 0; bracket = brackets[i]; i++) {
+ result.push(part.substring(last, last = bracket[1]));
+ if ((bracket[0] == '{' && i < brackets.length - 1) || (bracket[0] == '}' && i > 0)) {
+ result.push(bracket[0] == '{' ? '{ %><% ' : ' %><% }');
+ } else {
+ result.push(bracket[0]);
+ }
+ ++last;
+ }
+ result.push(part.substring(last), '%>');
+ return result.join('');
+ }
+ // Otherwise return the original
+ else {
+ return '<%' + part + '%>';
+ }
+ });
+ }
+ })
+ });
+
+ EJS.Helpers = function(data, extras) {
+ this._data = data;
+ this._extras = extras;
+ extend(this, extras);
+ };
+
+
+ EJS.Helpers.prototype = {
+ // TODO Deprecated!!
+ list: function(list, cb) {
+
+ can.each(list, function(item, i) {
+ cb(item, i, list)
+ })
+ },
+ each: function(list, cb) {
+ // Normal arrays don't get live updated
+ if (can.isArray(list)) {
+ this.list(list, cb);
+ } else {
+ can.view.lists(list, cb);
+ }
+ }
+ };
+
+ // Options for `steal`'s build.
+ can.view.register({
+ suffix: "ejs",
+ // returns a `function` that renders the view.
+ script: function(id, src) {
+ return "can.EJS(function(_CONTEXT,_VIEW) { " + new EJS({
+ text: src,
+ name: id
+ }).template.out + " })";
+ },
+ renderer: function(id, text) {
+ return EJS({
+ text: text,
+ name: id
+ });
+ }
+ });
+
+ return can;
+ })(__m3, __m11, __m2, __m9, __m13, __m15);
+
+ // ## control/control.js
+ var __m18 = (function(can) {
+ // ## control.js
+ // `can.Control`
+ // _Controller_
+
+ // Binds an element, returns a function that unbinds.
+ var bind = function(el, ev, callback) {
+
+ can.bind.call(el, ev, callback);
+
+ return function() {
+ can.unbind.call(el, ev, callback);
+ };
+ },
+ isFunction = can.isFunction,
+ extend = can.extend,
+ each = can.each,
+ slice = [].slice,
+ paramReplacer = /\{([^\}]+)\}/g,
+ special = can.getObject("$.event.special", [can]) || {},
+
+ // Binds an element, returns a function that unbinds.
+ delegate = function(el, selector, ev, callback) {
+ can.delegate.call(el, selector, ev, callback);
+ return function() {
+ can.undelegate.call(el, selector, ev, callback);
+ };
+ },
+
+ // Calls bind or unbind depending if there is a selector.
+ binder = function(el, ev, callback, selector) {
+ return selector ?
+ delegate(el, can.trim(selector), ev, callback) :
+ bind(el, ev, callback);
+ },
+
+ basicProcessor;
+
+ var Control = can.Control = can.Construct(
+
+ {
+ // Setup pre-processes which methods are event listeners.
+
+ setup: function() {
+
+ // Allow contollers to inherit "defaults" from super-classes as it
+ // done in `can.Construct`
+ can.Construct.setup.apply(this, arguments);
+
+ // If you didn't provide a name, or are `control`, don't do anything.
+ if (can.Control) {
+
+ // Cache the underscored names.
+ var control = this,
+ funcName;
+
+ // Calculate and cache actions.
+ control.actions = {};
+ for (funcName in control.prototype) {
+ if (control._isAction(funcName)) {
+ control.actions[funcName] = control._action(funcName);
+ }
+ }
+ }
+ },
+
+ // Moves `this` to the first argument, wraps it with `jQuery` if it's an element
+ _shifter: function(context, name) {
+
+ var method = typeof name == "string" ? context[name] : name;
+
+ if (!isFunction(method)) {
+ method = context[method];
+ }
+
+ return function() {
+ context.called = name;
+ return method.apply(context, [this.nodeName ? can.$(this) : this].concat(slice.call(arguments, 0)));
+ };
+ },
+
+ // Return `true` if is an action.
+
+ _isAction: function(methodName) {
+
+ var val = this.prototype[methodName],
+ type = typeof val;
+ // if not the constructor
+ return (methodName !== 'constructor') &&
+ // and is a function or links to a function
+ (type == "function" || (type == "string" && isFunction(this.prototype[val]))) &&
+ // and is in special, a processor, or has a funny character
+ !! (special[methodName] || processors[methodName] || /[^\w]/.test(methodName));
+ },
+ // Takes a method name and the options passed to a control
+ // and tries to return the data necessary to pass to a processor
+ // (something that binds things).
+
+ _action: function(methodName, options) {
+
+ // If we don't have options (a `control` instance), we'll run this
+ // later.
+ paramReplacer.lastIndex = 0;
+ if (options || !paramReplacer.test(methodName)) {
+ // If we have options, run sub to replace templates `{}` with a
+ // value from the options or the window
+ var convertedName = options ? can.sub(methodName, [options, window]) : methodName;
+ if (!convertedName) {
+ return null;
+ }
+ // If a `{}` template resolves to an object, `convertedName` will be
+ // an array
+ var arr = can.isArray(convertedName),
+
+ // Get the name
+ name = arr ? convertedName[1] : convertedName,
+
+ // Grab the event off the end
+ parts = name.split(/\s+/g),
+ event = parts.pop();
+
+ return {
+ processor: processors[event] || basicProcessor,
+ parts: [name, parts.join(" "), event],
+ delegate: arr ? convertedName[0] : undefined
+ };
+ }
+ },
+ // An object of `{eventName : function}` pairs that Control uses to
+ // hook up events auto-magically.
+
+ processors: {},
+ // A object of name-value pairs that act as default values for a
+ // control instance
+ defaults: {}
+
+ }, {
+
+ // Sets `this.element`, saves the control in `data, binds event
+ // handlers.
+
+ setup: function(element, options) {
+
+ var cls = this.constructor,
+ pluginname = cls.pluginName || cls._fullName,
+ arr;
+
+ // Want the raw element here.
+ this.element = can.$(element)
+
+ if (pluginname && pluginname !== 'can_control') {
+ // Set element and `className` on element.
+ this.element.addClass(pluginname);
+ }
+
+ (arr = can.data(this.element, "controls")) || can.data(this.element, "controls", arr = []);
+ arr.push(this);
+
+ // Option merging.
+
+ this.options = extend({}, cls.defaults, options);
+
+ // Bind all event handlers.
+ this.on();
+
+ // Gets passed into `init`.
+
+ return [this.element, this.options];
+ },
+
+ on: function(el, selector, eventName, func) {
+ if (!el) {
+
+ // Adds bindings.
+ this.off();
+
+ // Go through the cached list of actions and use the processor
+ // to bind
+ var cls = this.constructor,
+ bindings = this._bindings,
+ actions = cls.actions,
+ element = this.element,
+ destroyCB = can.Control._shifter(this, "destroy"),
+ funcName, ready;
+
+ for (funcName in actions) {
+ // Only push if we have the action and no option is `undefined`
+ if (actions.hasOwnProperty(funcName) &&
+ (ready = actions[funcName] || cls._action(funcName, this.options))) {
+ bindings.push(ready.processor(ready.delegate || element,
+ ready.parts[2], ready.parts[1], funcName, this));
+ }
+ }
+
+
+ // Setup to be destroyed...
+ // don't bind because we don't want to remove it.
+ can.bind.call(element, "destroyed", destroyCB);
+ bindings.push(function(el) {
+ can.unbind.call(el, "destroyed", destroyCB);
+ });
+ return bindings.length;
+ }
+
+ if (typeof el == 'string') {
+ func = eventName;
+ eventName = selector;
+ selector = el;
+ el = this.element;
+ }
+
+ if (func === undefined) {
+ func = eventName;
+ eventName = selector;
+ selector = null;
+ }
+
+ if (typeof func == 'string') {
+ func = can.Control._shifter(this, func);
+ }
+
+ this._bindings.push(binder(el, eventName, func, selector));
+
+ return this._bindings.length;
+ },
+ // Unbinds all event handlers on the controller.
+
+ off: function() {
+ var el = this.element[0]
+ each(this._bindings || [], function(value) {
+ value(el);
+ });
+ // Adds bindings.
+ this._bindings = [];
+ },
+ // Prepares a `control` for garbage collection
+
+ destroy: function() {
+ //Control already destroyed
+ if (this.element === null) {
+
+ return;
+ }
+ var Class = this.constructor,
+ pluginName = Class.pluginName || Class._fullName,
+ controls;
+
+ // Unbind bindings.
+ this.off();
+
+ if (pluginName && pluginName !== 'can_control') {
+ // Remove the `className`.
+ this.element.removeClass(pluginName);
+ }
+
+ // Remove from `data`.
+ controls = can.data(this.element, "controls");
+ controls.splice(can.inArray(this, controls), 1);
+
+ can.trigger(this, "destroyed"); // In case we want to know if the `control` is removed.
+
+ this.element = null;
+ }
+ });
+
+ var processors = can.Control.processors,
+ // Processors do the binding.
+ // They return a function that unbinds when called.
+ // The basic processor that binds events.
+ basicProcessor = function(el, event, selector, methodName, control) {
+ return binder(el, event, can.Control._shifter(control, methodName), selector);
+ };
+
+ // Set common events to be processed as a `basicProcessor`
+ each(["change", "click", "contextmenu", "dblclick", "keydown", "keyup",
+ "keypress", "mousedown", "mousemove", "mouseout", "mouseover",
+ "mouseup", "reset", "resize", "scroll", "select", "submit", "focusin",
+ "focusout", "mouseenter", "mouseleave",
+ // #104 - Add touch events as default processors
+ // TOOD feature detect?
+ "touchstart", "touchmove", "touchcancel", "touchend", "touchleave"
+ ], function(v) {
+ processors[v] = basicProcessor;
+ });
+
+ return Control;
+ })(__m3, __m1);
+
+ // ## util/string/deparam/deparam.js
+ var __m20 = (function(can) {
+
+ // ## deparam.js
+ // `can.deparam`
+ // _Takes a string of name value pairs and returns a Object literal that represents those params._
+ var digitTest = /^\d+$/,
+ keyBreaker = /([^\[\]]+)|(\[\])/g,
+ paramTest = /([^?#]*)(#.*)?$/,
+ prep = function(str) {
+ return decodeURIComponent(str.replace(/\+/g, " "));
+ };
+
+
+ can.extend(can, {
+
+ deparam: function(params) {
+
+ var data = {},
+ pairs, lastPart;
+
+ if (params && paramTest.test(params)) {
+
+ pairs = params.split('&'),
+
+ can.each(pairs, function(pair) {
+
+ var parts = pair.split('='),
+ key = prep(parts.shift()),
+ value = prep(parts.join("=")),
+ current = data;
+
+ if (key) {
+ parts = key.match(keyBreaker);
+
+ for (var j = 0, l = parts.length - 1; j < l; j++) {
+ if (!current[parts[j]]) {
+ // If what we are pointing to looks like an `array`
+ current[parts[j]] = digitTest.test(parts[j + 1]) || parts[j + 1] == "[]" ? [] : {};
+ }
+ current = current[parts[j]];
+ }
+ lastPart = parts.pop();
+ if (lastPart == "[]") {
+ current.push(value);
+ } else {
+ current[lastPart] = value;
+ }
+ }
+ });
+ }
+ return data;
+ }
+ });
+ return can;
+ })(__m3, __m2);
+
+ // ## route/route.js
+ var __m19 = (function(can) {
+
+ // ## route.js
+ // `can.route`
+ // _Helps manage browser history (and client state) by synchronizing the
+ // `window.location.hash` with a `can.Observe`._
+ // Helper methods used for matching routes.
+ var
+ // `RegExp` used to match route variables of the type ':name'.
+ // Any word character or a period is matched.
+ matcher = /\:([\w\.]+)/g,
+ // Regular expression for identifying &key=value lists.
+ paramsMatcher = /^(?:&[^=]+=[^&]*)+/,
+ // Converts a JS Object into a list of parameters that can be
+ // inserted into an html element tag.
+ makeProps = function(props) {
+ var tags = [];
+ can.each(props, function(val, name) {
+ tags.push((name === 'className' ? 'class' : name) + '="' +
+ (name === "href" ? val : can.esc(val)) + '"');
+ });
+ return tags.join(" ");
+ },
+ // Checks if a route matches the data provided. If any route variable
+ // is not present in the data, the route does not match. If all route
+ // variables are present in the data, the number of matches is returned
+ // to allow discerning between general and more specific routes.
+ matchesData = function(route, data) {
+ var count = 0,
+ i = 0,
+ defaults = {};
+ // look at default values, if they match ...
+ for (var name in route.defaults) {
+ if (route.defaults[name] === data[name]) {
+ // mark as matched
+ defaults[name] = 1;
+ count++;
+ }
+ }
+ for (; i < route.names.length; i++) {
+ if (!data.hasOwnProperty(route.names[i])) {
+ return -1;
+ }
+ if (!defaults[route.names[i]]) {
+ count++;
+ }
+
+ }
+
+ return count;
+ },
+ onready = !0,
+ location = window.location,
+ wrapQuote = function(str) {
+ return (str + '').replace(/([.?*+\^$\[\]\\(){}|\-])/g, "\\$1");
+ },
+ each = can.each,
+ extend = can.extend;
+
+ can.route = function(url, defaults) {
+ defaults = defaults || {};
+ // Extract the variable names and replace with `RegExp` that will match
+ // an atual URL with values.
+ var names = [],
+ test = url.replace(matcher, function(whole, name, i) {
+ names.push(name);
+ var next = "\\" + (url.substr(i + whole.length, 1) || can.route._querySeparator);
+ // a name without a default value HAS to have a value
+ // a name that has a default value can be empty
+ // The `\\` is for string-escaping giving single `\` for `RegExp` escaping.
+ return "([^" + next + "]" + (defaults[name] ? "*" : "+") + ")";
+ });
+
+ // Add route in a form that can be easily figured out.
+ can.route.routes[url] = {
+ // A regular expression that will match the route when variable values
+ // are present; i.e. for `:page/:type` the `RegExp` is `/([\w\.]*)/([\w\.]*)/` which
+ // will match for any value of `:page` and `:type` (word chars or period).
+ test: new RegExp("^" + test + "($|" + wrapQuote(can.route._querySeparator) + ")"),
+ // The original URL, same as the index for this entry in routes.
+ route: url,
+ // An `array` of all the variable names in this route.
+ names: names,
+ // Default values provided for the variables.
+ defaults: defaults,
+ // The number of parts in the URL separated by `/`.
+ length: url.split('/').length
+ };
+ return can.route;
+ };
+
+
+ extend(can.route, {
+
+ _querySeparator: '&',
+ _paramsMatcher: paramsMatcher,
+
+
+ param: function(data, _setRoute) {
+ // Check if the provided data keys match the names in any routes;
+ // Get the one with the most matches.
+ var route,
+ // Need to have at least 1 match.
+ matches = 0,
+ matchCount,
+ routeName = data.route,
+ propCount = 0;
+
+ delete data.route;
+
+ each(data, function() {
+ propCount++;
+ });
+ // Otherwise find route.
+ each(can.route.routes, function(temp, name) {
+ // best route is the first with all defaults matching
+
+
+ matchCount = matchesData(temp, data);
+ if (matchCount > matches) {
+ route = temp;
+ matches = matchCount;
+ }
+ if (matchCount >= propCount) {
+ return false;
+ }
+ });
+ // If we have a route name in our `can.route` data, and it's
+ // just as good as what currently matches, use that
+ if (can.route.routes[routeName] && matchesData(can.route.routes[routeName], data) === matches) {
+ route = can.route.routes[routeName];
+ }
+ // If this is match...
+ if (route) {
+ var cpy = extend({}, data),
+ // Create the url by replacing the var names with the provided data.
+ // If the default value is found an empty string is inserted.
+ res = route.route.replace(matcher, function(whole, name) {
+ delete cpy[name];
+ return data[name] === route.defaults[name] ? "" : encodeURIComponent(data[name]);
+ }),
+ after;
+ // Remove matching default values
+ each(route.defaults, function(val, name) {
+ if (cpy[name] === val) {
+ delete cpy[name];
+ }
+ });
+
+ // The remaining elements of data are added as
+ // `&` separated parameters to the url.
+ after = can.param(cpy);
+ // if we are paraming for setting the hash
+ // we also want to make sure the route value is updated
+ if (_setRoute) {
+ can.route.attr('route', route.route);
+ }
+ return res + (after ? can.route._querySeparator + after : "");
+ }
+ // If no route was found, there is no hash URL, only paramters.
+ return can.isEmptyObject(data) ? "" : can.route._querySeparator + can.param(data);
+ },
+
+ deparam: function(url) {
+ // See if the url matches any routes by testing it against the `route.test` `RegExp`.
+ // By comparing the URL length the most specialized route that matches is used.
+ var route = {
+ length: -1
+ };
+ each(can.route.routes, function(temp, name) {
+ if (temp.test.test(url) && temp.length > route.length) {
+ route = temp;
+ }
+ });
+ // If a route was matched.
+ if (route.length > -1) {
+
+ var // Since `RegExp` backreferences are used in `route.test` (parens)
+ // the parts will contain the full matched string and each variable (back-referenced) value.
+ parts = url.match(route.test),
+ // Start will contain the full matched string; parts contain the variable values.
+ start = parts.shift(),
+ // The remainder will be the `&key=value` list at the end of the URL.
+ remainder = url.substr(start.length - (parts[parts.length - 1] === can.route._querySeparator ? 1 : 0)),
+ // If there is a remainder and it contains a `&key=value` list deparam it.
+ obj = (remainder && can.route._paramsMatcher.test(remainder)) ? can.deparam(remainder.slice(1)) : {};
+
+ // Add the default values for this route.
+ obj = extend(true, {}, route.defaults, obj);
+ // Overwrite each of the default values in `obj` with those in
+ // parts if that part is not empty.
+ each(parts, function(part, i) {
+ if (part && part !== can.route._querySeparator) {
+ obj[route.names[i]] = decodeURIComponent(part);
+ }
+ });
+ obj.route = route.route;
+ return obj;
+ }
+ // If no route was matched, it is parsed as a `&key=value` list.
+ if (url.charAt(0) !== can.route._querySeparator) {
+ url = can.route._querySeparator + url;
+ }
+ return can.route._paramsMatcher.test(url) ? can.deparam(url.slice(1)) : {};
+ },
+
+ data: new can.Observe({}),
+
+ routes: {},
+
+ ready: function(val) {
+ if (val === false) {
+ onready = val;
+ }
+ if (val === true || onready === true) {
+ can.route._setup();
+ setState();
+ }
+ return can.route;
+ },
+
+ url: function(options, merge) {
+ if (merge) {
+ options = extend({}, curParams, options)
+ }
+ return "#!" + can.route.param(options);
+ },
+
+ link: function(name, options, props, merge) {
+ return "<a " + makeProps(
+ extend({
+ href: can.route.url(options, merge)
+ }, props)) + ">" + name + "</a>";
+ },
+
+ current: function(options) {
+ return location.hash == "#!" + can.route.param(options)
+ },
+ _setup: function() {
+ // If the hash changes, update the `can.route.data`.
+ can.bind.call(window, 'hashchange', setState);
+ },
+ _getHash: function() {
+ return location.href.split(/#!?/)[1] || "";
+ },
+ _setHash: function(serialized) {
+ var path = (can.route.param(serialized, true));
+ location.hash = "#!" + path;
+ return path;
+ }
+ });
+
+
+ // The functions in the following list applied to `can.route` (e.g. `can.route.attr('...')`) will
+ // instead act on the `can.route.data` observe.
+ each(['bind', 'unbind', 'delegate', 'undelegate', 'attr', 'removeAttr'], function(name) {
+ can.route[name] = function() {
+ // `delegate` and `undelegate` require
+ // the `can/observe/delegate` plugin
+ if (!can.route.data[name]) {
+ return;
+ }
+
+ return can.route.data[name].apply(can.route.data, arguments);
+ }
+ })
+
+ var // A ~~throttled~~ debounced function called multiple times will only fire once the
+ // timer runs down. Each call resets the timer.
+ timer,
+ // Intermediate storage for `can.route.data`.
+ curParams,
+ // Deparameterizes the portion of the hash of interest and assign the
+ // values to the `can.route.data` removing existing values no longer in the hash.
+ // setState is called typically by hashchange which fires asynchronously
+ // So it's possible that someone started changing the data before the
+ // hashchange event fired. For this reason, it will not set the route data
+ // if the data is changing or the hash already matches the hash that was set.
+ setState = can.route.setState = function() {
+ var hash = can.route._getHash();
+ curParams = can.route.deparam(hash);
+
+ // if the hash data is currently changing, or
+ // the hash is what we set it to anyway, do NOT change the hash
+ if (!changingData || hash !== lastHash) {
+ can.route.attr(curParams, true);
+ }
+ },
+ // The last hash caused by a data change
+ lastHash,
+ // Are data changes pending that haven't yet updated the hash
+ changingData;
+
+ // If the `can.route.data` changes, update the hash.
+ // Using `.serialize()` retrieves the raw data contained in the `observable`.
+ // This function is ~~throttled~~ debounced so it only updates once even if multiple values changed.
+ // This might be able to use batchNum and avoid this.
+ can.route.bind("change", function(ev, attr) {
+ // indicate that data is changing
+ changingData = 1;
+ clearTimeout(timer);
+ timer = setTimeout(function() {
+ // indicate that the hash is set to look like the data
+ changingData = 0;
+ var serialized = can.route.data.serialize();
+
+ lastHash = can.route._setHash(serialized);
+ }, 1);
+ });
+ // `onready` event...
+ can.bind.call(document, "ready", can.route.ready);
+
+ // Libraries other than jQuery don't execute the document `ready` listener
+ // if we are already DOM ready
+ if ((document.readyState === 'complete' || document.readyState === "interactive") && onready) {
+ can.route.ready();
+ }
+
+ // extend route to have a similar property
+ // that is often checked in mustache to determine
+ // an object's observability
+ can.route.constructor.canMakeObserve = can.Observe.canMakeObserve;
+
+ return can.route;
+ })(__m3, __m7, __m20);
+
+ // ## control/route/route.js
+ var __m21 = (function(can) {
+
+ // ## control/route.js
+ // _Controller route integration._
+
+ can.Control.processors.route = function(el, event, selector, funcName, controller) {
+ selector = selector || "";
+ can.route(selector);
+ var batchNum,
+ check = function(ev, attr, how) {
+ if (can.route.attr('route') === (selector) &&
+ (ev.batchNum === undefined || ev.batchNum !== batchNum)) {
+
+ batchNum = ev.batchNum;
+
+ var d = can.route.attr();
+ delete d.route;
+ if (can.isFunction(controller[funcName])) {
+ controller[funcName](d);
+ } else {
+ controller[controller[funcName]](d);
+ }
+
+ }
+ };
+ can.route.bind('change', check);
+ return function() {
+ can.route.unbind('change', check);
+ };
+ };
+
+ return can;
+ })(__m3, __m19, __m18);
+
+ window['can'] = __m5;
+ })();
\ No newline at end of file
Added: WebTimer/src/canJs/js/libs/can.object.js
===================================================================
--- WebTimer/src/canJs/js/libs/can.object.js (rev 0)
+++ WebTimer/src/canJs/js/libs/can.object.js 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,137 @@
+/*!
+ * CanJS - 1.1.6
+ * http://canjs.us/
+ * Copyright (c) 2013 Bitovi
+ * Wed, 29 May 2013 18:59:29 GMT
+ * Licensed MIT
+ * Includes: can/util/object
+ * Download from: http://canjs.com
+ */
+(function(can) {
+
+ var isArray = can.isArray,
+ // essentially returns an object that has all the must have comparisons ...
+ // must haves, do not return true when provided undefined
+ cleanSet = function(obj, compares) {
+ var copy = can.extend({}, obj);
+ for (var prop in copy) {
+ var compare = compares[prop] === undefined ? compares["*"] : compares[prop];
+ if (same(copy[prop], undefined, compare)) {
+ delete copy[prop]
+ }
+ }
+ return copy;
+ },
+ propCount = function(obj) {
+ var count = 0;
+ for (var prop in obj) count++;
+ return count;
+ };
+
+ can.Object = {};
+
+ var same = can.Object.same = function(a, b, compares, aParent, bParent, deep) {
+ var aType = typeof a,
+ aArray = isArray(a),
+ comparesType = typeof compares,
+ compare;
+
+ if (comparesType == 'string' || compares === null) {
+ compares = compareMethods[compares];
+ comparesType = 'function'
+ }
+ if (comparesType == 'function') {
+ return compares(a, b, aParent, bParent)
+ }
+ compares = compares || {};
+
+ if (a instanceof Date) {
+ return a === b;
+ }
+ if (deep === -1) {
+ return aType === 'object' || a === b;
+ }
+ if (aType !== typeof b || aArray !== isArray(b)) {
+ return false;
+ }
+ if (a === b) {
+ return true;
+ }
+ if (aArray) {
+ if (a.length !== b.length) {
+ return false;
+ }
+ for (var i = 0; i < a.length; i++) {
+ compare = compares[i] === undefined ? compares["*"] : compares[i]
+ if (!same(a[i], b[i], a, b, compare)) {
+ return false;
+ }
+ };
+ return true;
+ } else if (aType === "object" || aType === 'function') {
+ var bCopy = can.extend({}, b);
+ for (var prop in a) {
+ compare = compares[prop] === undefined ? compares["*"] : compares[prop];
+ if (!same(a[prop], b[prop], compare, a, b, deep === false ? -1 : undefined)) {
+ return false;
+ }
+ delete bCopy[prop];
+ }
+ // go through bCopy props ... if there is no compare .. return false
+ for (prop in bCopy) {
+ if (compares[prop] === undefined || !same(undefined, b[prop], compares[prop], a, b, deep === false ? -1 : undefined)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ };
+
+ can.Object.subsets = function(checkSet, sets, compares) {
+ var len = sets.length,
+ subsets = [],
+ checkPropCount = propCount(checkSet),
+ setLength;
+
+ for (var i = 0; i < len; i++) {
+ //check this subset
+ var set = sets[i];
+ if (can.Object.subset(checkSet, set, compares)) {
+ subsets.push(set)
+ }
+ }
+ return subsets;
+ };
+
+ can.Object.subset = function(subset, set, compares) {
+ // go through set {type: 'folder'} and make sure every property
+ // is in subset {type: 'folder', parentId :5}
+ // then make sure that set has fewer properties
+ // make sure we are only checking 'important' properties
+ // in subset (ones that have to have a value)
+
+ var setPropCount = 0,
+ compares = compares || {};
+
+ for (var prop in set) {
+
+ if (!same(subset[prop], set[prop], compares[prop], subset, set)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ var compareMethods = {
+ "null": function() {
+ return true;
+ },
+ i: function(a, b) {
+ return ("" + a).toLowerCase() == ("" + b).toLowerCase()
+ }
+ }
+
+ return can.Object;
+
+ })(can);
\ No newline at end of file
Added: WebTimer/src/canJs/js/libs/can.observe.attributes.js
===================================================================
--- WebTimer/src/canJs/js/libs/can.observe.attributes.js (rev 0)
+++ WebTimer/src/canJs/js/libs/can.observe.attributes.js 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,174 @@
+/*!
+ * CanJS - 1.1.6
+ * http://canjs.us/
+ * Copyright (c) 2013 Bitovi
+ * Wed, 29 May 2013 18:59:29 GMT
+ * Licensed MIT
+ * Includes: can/observe/attributes
+ * Download from: http://canjs.com
+ */
+(function(can, Observe) {
+
+ can.each([can.Observe, can.Model], function(clss) {
+ // in some cases model might not be defined quite yet.
+ if (clss === undefined) {
+ return;
+ }
+ var isObject = function(obj) {
+ return typeof obj === 'object' && obj !== null && obj;
+ };
+
+ can.extend(clss, {
+
+ attributes: {},
+
+
+ convert: {
+ "date": function(str) {
+ var type = typeof str;
+ if (type === "string") {
+ return isNaN(Date.parse(str)) ? null : Date.parse(str)
+ } else if (type === 'number') {
+ return new Date(str)
+ } else {
+ return str
+ }
+ },
+ "number": function(val) {
+ return parseFloat(val);
+ },
+ "boolean": function(val) {
+ if (val === 'false' || val === '0' || !val) {
+ return false;
+ }
+ return true;
+ },
+ "default": function(val, oldVal, error, type) {
+ var construct = can.getObject(type),
+ context = window,
+ realType;
+ // if type has a . we need to look it up
+ if (type.indexOf(".") >= 0) {
+ // get everything before the last .
+ realType = type.substring(0, type.lastIndexOf("."));
+ // get the object before the last .
+ context = can.getObject(realType);
+ }
+ return typeof construct == "function" ? construct.call(context, val, oldVal) : val;
+ }
+ },
+
+ serialize: {
+ "default": function(val, type) {
+ return isObject(val) && val.serialize ? val.serialize() : val;
+ },
+ "date": function(val) {
+ return val && val.getTime()
+ }
+ }
+ });
+
+ // overwrite setup to do this stuff
+ var oldSetup = clss.setup;
+
+
+ clss.setup = function(superClass, stat, proto) {
+ var self = this;
+ oldSetup.call(self, superClass, stat, proto);
+
+ can.each(["attributes"], function(name) {
+ if (!self[name] || superClass[name] === self[name]) {
+ self[name] = {};
+ }
+ });
+
+ can.each(["convert", "serialize"], function(name) {
+ if (superClass[name] != self[name]) {
+ self[name] = can.extend({}, superClass[name], self[name]);
+ }
+ });
+ };
+ });
+
+ var oldSetup = can.Observe.prototype.setup;
+
+ can.Observe.prototype.setup = function(obj) {
+
+ var diff = {};
+
+ oldSetup.call(this, obj);
+
+ can.each(this.constructor.defaults, function(value, key) {
+ if (!this.hasOwnProperty(key)) {
+ diff[key] = value;
+ }
+ }, this);
+
+ this._init = 1;
+ this.attr(diff);
+ delete this._init;
+ };
+
+ can.Observe.prototype.__convert = function(prop, value) {
+ // check if there is a
+
+ var Class = this.constructor,
+ oldVal = this.attr(prop),
+ type, converter;
+
+ if (Class.attributes) {
+ // the type of the attribute
+ type = Class.attributes[prop];
+ converter = Class.convert[type] || Class.convert['default'];
+ }
+
+ return value === null || !type ?
+ // just use the value
+ value :
+ // otherwise, pass to the converter
+ converter.call(Class, value, oldVal, function() {}, type);
+ };
+
+ can.Observe.prototype.serialize = function(attrName, stack) {
+ var where = {},
+ Class = this.constructor,
+ attrs = {};
+
+ stack = can.isArray(stack) ? stack : [];
+ stack.push(this._cid);
+
+ if (attrName !== undefined) {
+ attrs[attrName] = this[attrName];
+ } else {
+ attrs = this.__get();
+ }
+
+ can.each(attrs, function(val, name) {
+ var type, converter;
+
+ // If this is an observe, check that it wasn't serialized earlier in the stack.
+ if (val instanceof can.Observe && can.inArray(val._cid, stack) > -1) {
+ // Since this object has already been serialized once,
+ // just reference the id (or undefined if it doesn't exist).
+ where[name] = val.attr('id');
+ } else {
+ type = Class.attributes ? Class.attributes[name] : 0;
+ converter = Class.serialize ? Class.serialize[type] : 0;
+
+ // if the value is an object, and has a attrs or serialize function
+ where[name] = val && typeof val.serialize == 'function' ?
+ // call attrs or serialize to get the original data back
+ val.serialize(undefined, stack) :
+ // otherwise if we have a converter
+ converter ?
+ // use the converter
+ converter(val, type) :
+ // or return the val
+ val;
+ }
+ });
+
+ return attrName != undefined ? where[attrName] : where;
+ };
+ return can.Observe;
+ })(can);
\ No newline at end of file
Added: WebTimer/src/canJs/js/libs/can.observe.delegate.js
===================================================================
--- WebTimer/src/canJs/js/libs/can.observe.delegate.js (rev 0)
+++ WebTimer/src/canJs/js/libs/can.observe.delegate.js 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,215 @@
+/*!
+ * CanJS - 1.1.6
+ * http://canjs.us/
+ * Copyright (c) 2013 Bitovi
+ * Wed, 29 May 2013 18:59:29 GMT
+ * Licensed MIT
+ * Includes: can/observe/delegate
+ * Download from: http://canjs.com
+ */
+(function(can) {
+
+
+
+ // ** - 'this' will be the deepest item changed
+ // * - 'this' will be any changes within *, but * will be the
+ // this returned
+
+ // tells if the parts part of a delegate matches the broken up props of the event
+ // gives the prop to use as 'this'
+ // - parts - the attribute name of the delegate split in parts ['foo','*']
+ // - props - the split props of the event that happened ['foo','bar','0']
+ // - returns - the attribute to delegate too ('foo.bar'), or null if not a match
+ var delegateMatches = function(parts, props) {
+ //check props parts are the same or
+ var len = parts.length,
+ i = 0,
+ // keeps the matched props we will use
+ matchedProps = [],
+ prop;
+
+ // if the event matches
+ for (i; i < len; i++) {
+ prop = props[i]
+ // if no more props (but we should be matching them)
+ // return null
+ if (typeof prop !== 'string') {
+ return null;
+ } else
+ // if we have a "**", match everything
+ if (parts[i] == "**") {
+ return props.join(".");
+ } else
+ // a match, but we want to delegate to "*"
+ if (parts[i] == "*") {
+ // only do this if there is nothing after ...
+ matchedProps.push(prop);
+ } else if (prop === parts[i]) {
+ matchedProps.push(prop);
+ } else {
+ return null;
+ }
+ }
+ return matchedProps.join(".");
+ },
+ // gets a change event and tries to figure out which
+ // delegates to call
+ delegateHandler = function(event, prop, how, newVal, oldVal) {
+ // pre-split properties to save some regexp time
+ var props = prop.split("."),
+ delegates = (this._observe_delegates || []).slice(0),
+ delegate,
+ attr,
+ matchedAttr,
+ hasMatch,
+ valuesEqual;
+ event.attr = prop;
+ event.lastAttr = props[props.length - 1];
+
+ // for each delegate
+ for (var i = 0; delegate = delegates[i++];) {
+
+ // if there is a batchNum, this means that this
+ // event is part of a series of events caused by a single
+ // attrs call. We don't want to issue the same event
+ // multiple times
+ // setting the batchNum happens later
+ if ((event.batchNum && delegate.batchNum === event.batchNum) || delegate.undelegated) {
+ continue;
+ }
+
+ // reset match and values tests
+ hasMatch = undefined;
+ valuesEqual = true;
+
+ // yeah, all this under here has to be redone v
+
+ // for each attr in a delegate
+ for (var a = 0; a < delegate.attrs.length; a++) {
+
+ attr = delegate.attrs[a];
+
+ // check if it is a match
+ if (matchedAttr = delegateMatches(attr.parts, props)) {
+ hasMatch = matchedAttr;
+ }
+ // if it has a value, make sure it's the right value
+ // if it's set, we should probably check that it has a
+ // value no matter what
+ if (attr.value && valuesEqual) {
+ valuesEqual = attr.value === "" + this.attr(attr.attr)
+ } else if (valuesEqual && delegate.attrs.length > 1) {
+ // if there are multiple attributes, each has to at
+ // least have some value
+ valuesEqual = this.attr(attr.attr) !== undefined
+ }
+ }
+
+
+ // if there is a match and valuesEqual ... call back
+ if (hasMatch && valuesEqual) {
+ // how to get to the changed property from the delegate
+ var from = prop.replace(hasMatch + ".", "");
+
+ // if this event is part of a batch, set it on the delegate
+ // to only send one event
+ if (event.batchNum) {
+ delegate.batchNum = event.batchNum
+ }
+
+ // if we listen to change, fire those with the same attrs
+ // TODO: the attrs should probably be using from
+ if (delegate.event === 'change') {
+ arguments[1] = from;
+ event.curAttr = hasMatch;
+ delegate.callback.apply(this.attr(hasMatch), can.makeArray(arguments));
+ } else if (delegate.event === how) {
+
+ // if it's a match, callback with the location of the match
+ delegate.callback.apply(this.attr(hasMatch), [event, newVal, oldVal, from]);
+ } else if (delegate.event === 'set' &&
+ how == 'add') {
+ // if we are listening to set, we should also listen to add
+ delegate.callback.apply(this.attr(hasMatch), [event, newVal, oldVal, from]);
+ }
+ }
+
+ }
+ };
+
+ can.extend(can.Observe.prototype, {
+
+ delegate: function(selector, event, handler) {
+ selector = can.trim(selector);
+ var delegates = this._observe_delegates || (this._observe_delegates = []),
+ attrs = [],
+ selectorRegex = /([^\s=,]+)(?:=("[^",]*"|'[^',]*'|[^\s"',]*))?(,?)\s*/g,
+ matches;
+
+ // parse each property in the selector
+ while (matches = selectorRegex.exec(selector)) {
+ // we need to do a little doctoring to make up for the quotes.
+ if (matches[2] && can.inArray(matches[2].substr(0, 1), ['"', "'"]) >= 0) {
+ matches[2] = matches[2].substr(1, -1);
+ }
+
+ attrs.push({
+ // the attribute name
+ attr: matches[1],
+ // the attribute name, pre-split for speed
+ parts: matches[1].split('.'),
+ // the value associated with this property (if there was one given)
+ value: matches[2],
+ // whether this selector combines with the one after it with AND or OR
+ or: matches[3] === ','
+ });
+ }
+
+ // delegates has pre-processed info about the event
+ delegates.push({
+ // the attrs name for unbinding
+ selector: selector,
+ // an object of attribute names and values {type: 'recipe',id: undefined}
+ // undefined means a value was not defined
+ attrs: attrs,
+ callback: handler,
+ event: event
+ });
+ if (delegates.length === 1) {
+ this.bind("change", delegateHandler)
+ }
+ return this;
+ },
+
+ undelegate: function(selector, event, handler) {
+ selector = selector && can.trim(selector);
+
+ var i = 0,
+ delegates = this._observe_delegates || [],
+ delegateOb;
+ if (selector) {
+ while (i < delegates.length) {
+ delegateOb = delegates[i];
+ if (delegateOb.callback === handler ||
+ (!handler && delegateOb.selector === selector)) {
+ delegateOb.undelegated = true;
+ delegates.splice(i, 1)
+ } else {
+ i++;
+ }
+ }
+ } else {
+ // remove all delegates
+ delegates = [];
+ }
+ if (!delegates.length) {
+ //can.removeData(this, "_observe_delegates");
+ this.unbind("change", delegateHandler)
+ }
+ return this;
+ }
+ });
+ // add helpers for testing ..
+ can.Observe.prototype.delegate.matches = delegateMatches;
+ return can.Observe;
+ })(can);
\ No newline at end of file
Added: WebTimer/src/canJs/js/models/tasks.js
===================================================================
--- WebTimer/src/canJs/js/models/tasks.js (rev 0)
+++ WebTimer/src/canJs/js/models/tasks.js 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,78 @@
+var Task = can.Model({
+ findAll: 'GET /tasks',
+ create : "POST /tasks",
+ update : "PUT /tasks/{id}",
+ destroy : "DELETE /tasks/{id}"
+
+}, {});
+
+can.fixture('GET /tasks', function() {
+ var storedTasks = window.localStorage.getItem('tasks');
+ var tasks = new Array();
+ if (storedTasks) {
+ storedTasks = JSON.parse(storedTasks);
+ var taskMap = {};
+ for (var i = 0 ; i < storedTasks.length ; i++) {
+ var task = storedTasks[i];
+ taskMap[task.id]= task;
+ if (!task.parentTask) {
+ tasks.push(task);
+ } else {
+ var parent = taskMap[task.parentTask];
+ parent.subtasks.push(task);
+ }
+ }
+ }
+ return tasks;
+});
+
+can.fixture("POST /tasks", function(orig) {
+ console.log("create task " + orig.data);
+ var tasks = window.localStorage.getItem('tasks');
+ if (!tasks) {
+ tasks = new Array();
+ } else {
+ tasks = JSON.parse(tasks);
+ }
+ var task = orig.data;
+ var id = new Date().getTime();
+ task.id = id;
+ task.subtasks = [];
+ tasks.push(task);
+ window.localStorage.setItem('tasks', JSON.stringify(tasks));
+ return { id: id };
+});
+
+can.fixture("PUT /tasks/{id}", function(orig) {
+ var tasks = window.localStorage.getItem('tasks');
+ if (tasks) {
+ tasks = JSON.parse(tasks);
+ var task = orig.data;
+ for (var i = 0 ; i < tasks.length ; i++) {
+ if (tasks[i].id == orig.data.id) {
+ tasks[i] = task;
+ tasks[i].subtasks = [];
+ break;
+ }
+ }
+ window.localStorage.setItem('tasks', JSON.stringify(tasks));
+ }
+ return {};
+});
+
+can.fixture("DELETE /tasks/{id}", function(orig){
+ console.log("delete task " + orig.data.id);
+ var tasks = window.localStorage.getItem('tasks');
+ if (tasks) {
+ tasks = JSON.parse(tasks);
+ var task = orig.data;
+ for (var i = 0 ; i < tasks.length ; i++) {
+ if (tasks[i].id == orig.data.id) {
+ tasks.splice(i, 1);
+ break;
+ }
+ }
+ window.localStorage.setItem('tasks', JSON.stringify(tasks));
+ }
+ return {};
+});
\ No newline at end of file
Added: WebTimer/src/canJs/views/menu.ejs
===================================================================
--- WebTimer/src/canJs/views/menu.ejs (rev 0)
+++ WebTimer/src/canJs/views/menu.ejs 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,3 @@
+<li id='homeMenu'><%== can.route.link('Home', {}) %></li>
+<li id='aboutMenu'><%== can.route.link('About', { page: 'about' }) %></li>
+<li id='contactMenu'><%== can.route.link('Contact', { page: 'contact' }) %></li>
\ No newline at end of file
Added: WebTimer/src/canJs/views/tasks.ejs
===================================================================
--- WebTimer/src/canJs/views/tasks.ejs (rev 0)
+++ WebTimer/src/canJs/views/tasks.ejs 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,41 @@
+<div class="container-fluid">
+ <div class="row-fluid">
+ <div class="span6">
+ Filter <input id="filterInput"/>
+ </div>
+ <div class="span6">
+ <form id="addTaskForm">
+ Add project
+ <input name="name"/>
+ <button type="submit" class="btn"><i class="icon-plus"></i></button>
+ </form>
+ </div>
+ </div>
+
+ <div class="row-fluid">
+ <div class="span4 names">
+ <ul class="tasks">
+ <li class="task title">
+ <div>Name</div>
+ </li>
+
+ <% tasks.each(function(task) { %>
+ <li class="task"><%== can.view.render('views/tree_item_renderer_name', {task: task, currentTask: currentTask}); %></li>
+ <% }) %>
+ </ul>
+ </div>
+
+ <div class="span8 details">
+ <ul class="tasks">
+ <li class="task title">
+ <div>Time</div>
+ <div>Tags</div>
+ </li>
+
+ <% tasks.each(function(task) { %>
+ <li class="task"><%== can.view.render('views/tree_item_renderer_details', {task: task, currentTask: currentTask}); %></li>
+ <% }) %>
+ </ul>
+ </div>
+ </div>
+</div>
\ No newline at end of file
Added: WebTimer/src/canJs/views/tree_item_renderer_details.ejs
===================================================================
--- WebTimer/src/canJs/views/tree_item_renderer_details.ejs (rev 0)
+++ WebTimer/src/canJs/views/tree_item_renderer_details.ejs 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,33 @@
+<div class="<%= task.attr('matchFilter') ? '' : 'hidden' %>">
+ <%= formatDuration(task.attr('time')) %>
+</div>
+
+<div class="taskTags <%= task.attr('matchFilter') ? '' : 'hidden' %>"
+ <%= (el) -> can.data(el, 'task', task) %>
+ <%= (el) -> can.data(el, 'edit', 'tags') %>>
+ <form class='saveTaskForm'
+ style="display: <%= task.attr('edit') == 'tags' ? 'inherit' : 'none' %>"
+ <%= (el) -> can.data(el, 'task', task) %>>
+ <input name='tags' value="<%= task.attr('tags').join() %>"/>
+ </form>
+ <% task.attr('tags').each(function(tag) { %>
+ <span class="label label-info"
+ style="margin-right: 10px; display: <%= task.attr('edit') != 'tags' ? 'inline' : 'none' %>">
+ <%= tag.trim() %>
+ </span>
+ <% }) %>
+
+ <% if (task.attr('tags').length == 0 && task.attr('edit') != 'tags') { %>
+ <span>No tag</span>
+ <% } %>
+</div>
+
+<ul class="tasks subtasks">
+<% if (task.attr('childrenVisibility')) {
+ task.attr('subtasks').each(function(subtask) { %>
+ <li class="task subtasks">
+ <%== can.view.render('views/tree_item_renderer_details', { task: subtask, currentTask: currentTask }); %>
+ </li>
+ <% })
+ }%>
+</ul>
\ No newline at end of file
Added: WebTimer/src/canJs/views/tree_item_renderer_name.ejs
===================================================================
--- WebTimer/src/canJs/views/tree_item_renderer_name.ejs (rev 0)
+++ WebTimer/src/canJs/views/tree_item_renderer_name.ejs 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,34 @@
+<div class="<%= task.attr('matchFilter') ? '' : 'hidden' %>">
+ <i class="toggleChildrenVisibilityButton
+ <%= task.attr('childrenVisibility') ? 'icon-minus-sign' : 'icon-plus-sign' %>
+ <%= task.attr('subtasks').attr('length') != 0 ? '' : 'hidden' %>"
+ <%= (el) -> can.data(el, 'task', task) %>></i>
+
+ <form class="saveTaskForm
+ <%= task.attr('edit') == 'name' ? '' : 'hidden' %>"
+ <%= (el) -> can.data(el, 'task', task) %>>
+ <input name='name' value="<%= task.name %>"/>
+ </form>
+
+ <span class="taskNameLabel
+ <%= task.attr('edit') != 'name' ? '' : 'hidden' %>"
+ <%= (el) -> can.data(el, 'task', task) %>
+ <%= (el) -> can.data(el, 'edit', 'name') %>><%= task.attr('name') %> </span>
+
+ <div class="btn-group">
+ <button class="btn removeTask" <%= (el) -> can.data(el, 'task', task) %>><i class="icon-minus"></i></button>
+ <button class="btn addSubTask" <%= (el) -> can.data(el, 'task', task) %>><i class="icon-plus"></i></button>
+ <button class="btn startTiming" <%= (el) -> can.data(el, 'task', task) %>>
+ <i class="<%= currentTask.attr('task') === task ? 'icon-stop' : 'icon-play' %>"></i>
+ </button>
+ </div>
+</div>
+<ul class="tasks subtasks">
+ <% if (task.attr('childrenVisibility')) {
+ task.attr('subtasks').each(function(subtask) { %>
+ <li class="task subtasks">
+ <%== can.view.render('views/tree_item_renderer_name', { task: subtask, currentTask: currentTask }); %>
+ </li>
+ <% })
+ } %>
+</ul>
\ No newline at end of file
Added: WebTimer/src/common/css/app.css
===================================================================
--- WebTimer/src/common/css/app.css (rev 0)
+++ WebTimer/src/common/css/app.css 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,90 @@
+body {
+ position: relative;
+ padding-top: 60px;
+}
+
+ul.tasks {
+ display : block;
+ width : 100%;
+ list-style: none;
+}
+
+li.task {
+ display : block;
+ width : 100%;
+ height: 32px;
+}
+
+li.task.title {
+ font-weight: bold;
+ font-size: medium;
+}
+
+li.task div {
+ width : 25%;
+ height: 32px;
+ float: left;
+}
+
+.names li.task div {
+ width : 100%;
+}
+
+.details li.task div {
+ width : 50%;
+}
+
+.names ul.tasks {
+ margin: 0 0 0 25px;
+}
+
+.details ul.tasks {
+ margin: 0 0 0 0;
+}
+
+form {
+ display : inline-block;
+ margin : 0px;
+}
+
+.filtering-enter {
+ -webkit-transition : all linear 0.2s;
+ -moz-transition : all linear 0.2s;
+ -o-transition : all linear 0.2s;
+ transition : all linear 0.2s;
+
+ /* The animation preparation code */
+ opacity : 0;
+ height : 0;
+}
+
+.filtering-enter.filtering-enter-active {
+ /* The animation code itself */
+ opacity : 1;
+ height : 42px;
+}
+
+.filtering-leave {
+ -webkit-transition : all linear 0.2s;
+ -moz-transition : all linear 0.2s;
+ -o-transition : all linear 0.2s;
+ transition : all linear 0.2s;
+
+ /* The animation preparation code */
+ opacity : 1;
+ height : 42px;
+}
+
+.filtering-leave.filtering-leave-active {
+ /* The animation code itself */
+ opacity : 0;
+ height : 0;
+}
+
+.btn-group {
+ display: none;
+}
+
+div:hover > .btn-group {
+ display: block;
+}
Added: WebTimer/src/common/css/bootstrap-responsive.css
===================================================================
--- WebTimer/src/common/css/bootstrap-responsive.css (rev 0)
+++ WebTimer/src/common/css/bootstrap-responsive.css 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,1109 @@
+/*!
+ * Bootstrap Responsive v2.3.2
+ *
+ * Copyright 2012 Twitter, Inc
+ * Licensed under the Apache License v2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Designed and built with all the love in the world @twitter by @mdo and @fat.
+ */
+
+.clearfix {
+ *zoom: 1;
+}
+
+.clearfix:before,
+.clearfix:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.clearfix:after {
+ clear: both;
+}
+
+.hide-text {
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0;
+}
+
+.input-block-level {
+ display: block;
+ width: 100%;
+ min-height: 30px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+@-ms-viewport {
+ width: device-width;
+}
+
+.hidden {
+ display: none;
+ visibility: hidden;
+}
+
+.visible-phone {
+ display: none !important;
+}
+
+.visible-tablet {
+ display: none !important;
+}
+
+.hidden-desktop {
+ display: none !important;
+}
+
+.visible-desktop {
+ display: inherit !important;
+}
+
+@media (min-width: 768px) and (max-width: 979px) {
+ .hidden-desktop {
+ display: inherit !important;
+ }
+ .visible-desktop {
+ display: none !important ;
+ }
+ .visible-tablet {
+ display: inherit !important;
+ }
+ .hidden-tablet {
+ display: none !important;
+ }
+}
+
+@media (max-width: 767px) {
+ .hidden-desktop {
+ display: inherit !important;
+ }
+ .visible-desktop {
+ display: none !important;
+ }
+ .visible-phone {
+ display: inherit !important;
+ }
+ .hidden-phone {
+ display: none !important;
+ }
+}
+
+.visible-print {
+ display: none !important;
+}
+
+@media print {
+ .visible-print {
+ display: inherit !important;
+ }
+ .hidden-print {
+ display: none !important;
+ }
+}
+
+@media (min-width: 1200px) {
+ .row {
+ margin-left: -30px;
+ *zoom: 1;
+ }
+ .row:before,
+ .row:after {
+ display: table;
+ line-height: 0;
+ content: "";
+ }
+ .row:after {
+ clear: both;
+ }
+ [class*="span"] {
+ float: left;
+ min-height: 1px;
+ margin-left: 30px;
+ }
+ .container,
+ .navbar-static-top .container,
+ .navbar-fixed-top .container,
+ .navbar-fixed-bottom .container {
+ width: 1170px;
+ }
+ .span12 {
+ width: 1170px;
+ }
+ .span11 {
+ width: 1070px;
+ }
+ .span10 {
+ width: 970px;
+ }
+ .span9 {
+ width: 870px;
+ }
+ .span8 {
+ width: 770px;
+ }
+ .span7 {
+ width: 670px;
+ }
+ .span6 {
+ width: 570px;
+ }
+ .span5 {
+ width: 470px;
+ }
+ .span4 {
+ width: 370px;
+ }
+ .span3 {
+ width: 270px;
+ }
+ .span2 {
+ width: 170px;
+ }
+ .span1 {
+ width: 70px;
+ }
+ .offset12 {
+ margin-left: 1230px;
+ }
+ .offset11 {
+ margin-left: 1130px;
+ }
+ .offset10 {
+ margin-left: 1030px;
+ }
+ .offset9 {
+ margin-left: 930px;
+ }
+ .offset8 {
+ margin-left: 830px;
+ }
+ .offset7 {
+ margin-left: 730px;
+ }
+ .offset6 {
+ margin-left: 630px;
+ }
+ .offset5 {
+ margin-left: 530px;
+ }
+ .offset4 {
+ margin-left: 430px;
+ }
+ .offset3 {
+ margin-left: 330px;
+ }
+ .offset2 {
+ margin-left: 230px;
+ }
+ .offset1 {
+ margin-left: 130px;
+ }
+ .row-fluid {
+ width: 100%;
+ *zoom: 1;
+ }
+ .row-fluid:before,
+ .row-fluid:after {
+ display: table;
+ line-height: 0;
+ content: "";
+ }
+ .row-fluid:after {
+ clear: both;
+ }
+ .row-fluid [class*="span"] {
+ display: block;
+ float: left;
+ width: 100%;
+ min-height: 30px;
+ margin-left: 2.564102564102564%;
+ *margin-left: 2.5109110747408616%;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ }
+ .row-fluid [class*="span"]:first-child {
+ margin-left: 0;
+ }
+ .row-fluid .controls-row [class*="span"] + [class*="span"] {
+ margin-left: 2.564102564102564%;
+ }
+ .row-fluid .span12 {
+ width: 100%;
+ *width: 99.94680851063829%;
+ }
+ .row-fluid .span11 {
+ width: 91.45299145299145%;
+ *width: 91.39979996362975%;
+ }
+ .row-fluid .span10 {
+ width: 82.90598290598291%;
+ *width: 82.8527914166212%;
+ }
+ .row-fluid .span9 {
+ width: 74.35897435897436%;
+ *width: 74.30578286961266%;
+ }
+ .row-fluid .span8 {
+ width: 65.81196581196582%;
+ *width: 65.75877432260411%;
+ }
+ .row-fluid .span7 {
+ width: 57.26495726495726%;
+ *width: 57.21176577559556%;
+ }
+ .row-fluid .span6 {
+ width: 48.717948717948715%;
+ *width: 48.664757228587014%;
+ }
+ .row-fluid .span5 {
+ width: 40.17094017094017%;
+ *width: 40.11774868157847%;
+ }
+ .row-fluid .span4 {
+ width: 31.623931623931625%;
+ *width: 31.570740134569924%;
+ }
+ .row-fluid .span3 {
+ width: 23.076923076923077%;
+ *width: 23.023731587561375%;
+ }
+ .row-fluid .span2 {
+ width: 14.52991452991453%;
+ *width: 14.476723040552828%;
+ }
+ .row-fluid .span1 {
+ width: 5.982905982905983%;
+ *width: 5.929714493544281%;
+ }
+ .row-fluid .offset12 {
+ margin-left: 105.12820512820512%;
+ *margin-left: 105.02182214948171%;
+ }
+ .row-fluid .offset12:first-child {
+ margin-left: 102.56410256410257%;
+ *margin-left: 102.45771958537915%;
+ }
+ .row-fluid .offset11 {
+ margin-left: 96.58119658119658%;
+ *margin-left: 96.47481360247316%;
+ }
+ .row-fluid .offset11:first-child {
+ margin-left: 94.01709401709402%;
+ *margin-left: 93.91071103837061%;
+ }
+ .row-fluid .offset10 {
+ margin-left: 88.03418803418803%;
+ *margin-left: 87.92780505546462%;
+ }
+ .row-fluid .offset10:first-child {
+ margin-left: 85.47008547008548%;
+ *margin-left: 85.36370249136206%;
+ }
+ .row-fluid .offset9 {
+ margin-left: 79.48717948717949%;
+ *margin-left: 79.38079650845607%;
+ }
+ .row-fluid .offset9:first-child {
+ margin-left: 76.92307692307693%;
+ *margin-left: 76.81669394435352%;
+ }
+ .row-fluid .offset8 {
+ margin-left: 70.94017094017094%;
+ *margin-left: 70.83378796144753%;
+ }
+ .row-fluid .offset8:first-child {
+ margin-left: 68.37606837606839%;
+ *margin-left: 68.26968539734497%;
+ }
+ .row-fluid .offset7 {
+ margin-left: 62.393162393162385%;
+ *margin-left: 62.28677941443899%;
+ }
+ .row-fluid .offset7:first-child {
+ margin-left: 59.82905982905982%;
+ *margin-left: 59.72267685033642%;
+ }
+ .row-fluid .offset6 {
+ margin-left: 53.84615384615384%;
+ *margin-left: 53.739770867430444%;
+ }
+ .row-fluid .offset6:first-child {
+ margin-left: 51.28205128205128%;
+ *margin-left: 51.175668303327875%;
+ }
+ .row-fluid .offset5 {
+ margin-left: 45.299145299145295%;
+ *margin-left: 45.1927623204219%;
+ }
+ .row-fluid .offset5:first-child {
+ margin-left: 42.73504273504273%;
+ *margin-left: 42.62865975631933%;
+ }
+ .row-fluid .offset4 {
+ margin-left: 36.75213675213675%;
+ *margin-left: 36.645753773413354%;
+ }
+ .row-fluid .offset4:first-child {
+ margin-left: 34.18803418803419%;
+ *margin-left: 34.081651209310785%;
+ }
+ .row-fluid .offset3 {
+ margin-left: 28.205128205128204%;
+ *margin-left: 28.0987452264048%;
+ }
+ .row-fluid .offset3:first-child {
+ margin-left: 25.641025641025642%;
+ *margin-left: 25.53464266230224%;
+ }
+ .row-fluid .offset2 {
+ margin-left: 19.65811965811966%;
+ *margin-left: 19.551736679396257%;
+ }
+ .row-fluid .offset2:first-child {
+ margin-left: 17.094017094017094%;
+ *margin-left: 16.98763411529369%;
+ }
+ .row-fluid .offset1 {
+ margin-left: 11.11111111111111%;
+ *margin-left: 11.004728132387708%;
+ }
+ .row-fluid .offset1:first-child {
+ margin-left: 8.547008547008547%;
+ *margin-left: 8.440625568285142%;
+ }
+ input,
+ textarea,
+ .uneditable-input {
+ margin-left: 0;
+ }
+ .controls-row [class*="span"] + [class*="span"] {
+ margin-left: 30px;
+ }
+ input.span12,
+ textarea.span12,
+ .uneditable-input.span12 {
+ width: 1156px;
+ }
+ input.span11,
+ textarea.span11,
+ .uneditable-input.span11 {
+ width: 1056px;
+ }
+ input.span10,
+ textarea.span10,
+ .uneditable-input.span10 {
+ width: 956px;
+ }
+ input.span9,
+ textarea.span9,
+ .uneditable-input.span9 {
+ width: 856px;
+ }
+ input.span8,
+ textarea.span8,
+ .uneditable-input.span8 {
+ width: 756px;
+ }
+ input.span7,
+ textarea.span7,
+ .uneditable-input.span7 {
+ width: 656px;
+ }
+ input.span6,
+ textarea.span6,
+ .uneditable-input.span6 {
+ width: 556px;
+ }
+ input.span5,
+ textarea.span5,
+ .uneditable-input.span5 {
+ width: 456px;
+ }
+ input.span4,
+ textarea.span4,
+ .uneditable-input.span4 {
+ width: 356px;
+ }
+ input.span3,
+ textarea.span3,
+ .uneditable-input.span3 {
+ width: 256px;
+ }
+ input.span2,
+ textarea.span2,
+ .uneditable-input.span2 {
+ width: 156px;
+ }
+ input.span1,
+ textarea.span1,
+ .uneditable-input.span1 {
+ width: 56px;
+ }
+ .thumbnails {
+ margin-left: -30px;
+ }
+ .thumbnails > li {
+ margin-left: 30px;
+ }
+ .row-fluid .thumbnails {
+ margin-left: 0;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 979px) {
+ .row {
+ margin-left: -20px;
+ *zoom: 1;
+ }
+ .row:before,
+ .row:after {
+ display: table;
+ line-height: 0;
+ content: "";
+ }
+ .row:after {
+ clear: both;
+ }
+ [class*="span"] {
+ float: left;
+ min-height: 1px;
+ margin-left: 20px;
+ }
+ .container,
+ .navbar-static-top .container,
+ .navbar-fixed-top .container,
+ .navbar-fixed-bottom .container {
+ width: 724px;
+ }
+ .span12 {
+ width: 724px;
+ }
+ .span11 {
+ width: 662px;
+ }
+ .span10 {
+ width: 600px;
+ }
+ .span9 {
+ width: 538px;
+ }
+ .span8 {
+ width: 476px;
+ }
+ .span7 {
+ width: 414px;
+ }
+ .span6 {
+ width: 352px;
+ }
+ .span5 {
+ width: 290px;
+ }
+ .span4 {
+ width: 228px;
+ }
+ .span3 {
+ width: 166px;
+ }
+ .span2 {
+ width: 104px;
+ }
+ .span1 {
+ width: 42px;
+ }
+ .offset12 {
+ margin-left: 764px;
+ }
+ .offset11 {
+ margin-left: 702px;
+ }
+ .offset10 {
+ margin-left: 640px;
+ }
+ .offset9 {
+ margin-left: 578px;
+ }
+ .offset8 {
+ margin-left: 516px;
+ }
+ .offset7 {
+ margin-left: 454px;
+ }
+ .offset6 {
+ margin-left: 392px;
+ }
+ .offset5 {
+ margin-left: 330px;
+ }
+ .offset4 {
+ margin-left: 268px;
+ }
+ .offset3 {
+ margin-left: 206px;
+ }
+ .offset2 {
+ margin-left: 144px;
+ }
+ .offset1 {
+ margin-left: 82px;
+ }
+ .row-fluid {
+ width: 100%;
+ *zoom: 1;
+ }
+ .row-fluid:before,
+ .row-fluid:after {
+ display: table;
+ line-height: 0;
+ content: "";
+ }
+ .row-fluid:after {
+ clear: both;
+ }
+ .row-fluid [class*="span"] {
+ display: block;
+ float: left;
+ width: 100%;
+ min-height: 30px;
+ margin-left: 2.7624309392265194%;
+ *margin-left: 2.709239449864817%;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ }
+ .row-fluid [class*="span"]:first-child {
+ margin-left: 0;
+ }
+ .row-fluid .controls-row [class*="span"] + [class*="span"] {
+ margin-left: 2.7624309392265194%;
+ }
+ .row-fluid .span12 {
+ width: 100%;
+ *width: 99.94680851063829%;
+ }
+ .row-fluid .span11 {
+ width: 91.43646408839778%;
+ *width: 91.38327259903608%;
+ }
+ .row-fluid .span10 {
+ width: 82.87292817679558%;
+ *width: 82.81973668743387%;
+ }
+ .row-fluid .span9 {
+ width: 74.30939226519337%;
+ *width: 74.25620077583166%;
+ }
+ .row-fluid .span8 {
+ width: 65.74585635359117%;
+ *width: 65.69266486422946%;
+ }
+ .row-fluid .span7 {
+ width: 57.18232044198895%;
+ *width: 57.12912895262725%;
+ }
+ .row-fluid .span6 {
+ width: 48.61878453038674%;
+ *width: 48.56559304102504%;
+ }
+ .row-fluid .span5 {
+ width: 40.05524861878453%;
+ *width: 40.00205712942283%;
+ }
+ .row-fluid .span4 {
+ width: 31.491712707182323%;
+ *width: 31.43852121782062%;
+ }
+ .row-fluid .span3 {
+ width: 22.92817679558011%;
+ *width: 22.87498530621841%;
+ }
+ .row-fluid .span2 {
+ width: 14.3646408839779%;
+ *width: 14.311449394616199%;
+ }
+ .row-fluid .span1 {
+ width: 5.801104972375691%;
+ *width: 5.747913483013988%;
+ }
+ .row-fluid .offset12 {
+ margin-left: 105.52486187845304%;
+ *margin-left: 105.41847889972962%;
+ }
+ .row-fluid .offset12:first-child {
+ margin-left: 102.76243093922652%;
+ *margin-left: 102.6560479605031%;
+ }
+ .row-fluid .offset11 {
+ margin-left: 96.96132596685082%;
+ *margin-left: 96.8549429881274%;
+ }
+ .row-fluid .offset11:first-child {
+ margin-left: 94.1988950276243%;
+ *margin-left: 94.09251204890089%;
+ }
+ .row-fluid .offset10 {
+ margin-left: 88.39779005524862%;
+ *margin-left: 88.2914070765252%;
+ }
+ .row-fluid .offset10:first-child {
+ margin-left: 85.6353591160221%;
+ *margin-left: 85.52897613729868%;
+ }
+ .row-fluid .offset9 {
+ margin-left: 79.8342541436464%;
+ *margin-left: 79.72787116492299%;
+ }
+ .row-fluid .offset9:first-child {
+ margin-left: 77.07182320441989%;
+ *margin-left: 76.96544022569647%;
+ }
+ .row-fluid .offset8 {
+ margin-left: 71.2707182320442%;
+ *margin-left: 71.16433525332079%;
+ }
+ .row-fluid .offset8:first-child {
+ margin-left: 68.50828729281768%;
+ *margin-left: 68.40190431409427%;
+ }
+ .row-fluid .offset7 {
+ margin-left: 62.70718232044199%;
+ *margin-left: 62.600799341718584%;
+ }
+ .row-fluid .offset7:first-child {
+ margin-left: 59.94475138121547%;
+ *margin-left: 59.838368402492065%;
+ }
+ .row-fluid .offset6 {
+ margin-left: 54.14364640883978%;
+ *margin-left: 54.037263430116376%;
+ }
+ .row-fluid .offset6:first-child {
+ margin-left: 51.38121546961326%;
+ *margin-left: 51.27483249088986%;
+ }
+ .row-fluid .offset5 {
+ margin-left: 45.58011049723757%;
+ *margin-left: 45.47372751851417%;
+ }
+ .row-fluid .offset5:first-child {
+ margin-left: 42.81767955801105%;
+ *margin-left: 42.71129657928765%;
+ }
+ .row-fluid .offset4 {
+ margin-left: 37.01657458563536%;
+ *margin-left: 36.91019160691196%;
+ }
+ .row-fluid .offset4:first-child {
+ margin-left: 34.25414364640884%;
+ *margin-left: 34.14776066768544%;
+ }
+ .row-fluid .offset3 {
+ margin-left: 28.45303867403315%;
+ *margin-left: 28.346655695309746%;
+ }
+ .row-fluid .offset3:first-child {
+ margin-left: 25.69060773480663%;
+ *margin-left: 25.584224756083227%;
+ }
+ .row-fluid .offset2 {
+ margin-left: 19.88950276243094%;
+ *margin-left: 19.783119783707537%;
+ }
+ .row-fluid .offset2:first-child {
+ margin-left: 17.12707182320442%;
+ *margin-left: 17.02068884448102%;
+ }
+ .row-fluid .offset1 {
+ margin-left: 11.32596685082873%;
+ *margin-left: 11.219583872105325%;
+ }
+ .row-fluid .offset1:first-child {
+ margin-left: 8.56353591160221%;
+ *margin-left: 8.457152932878806%;
+ }
+ input,
+ textarea,
+ .uneditable-input {
+ margin-left: 0;
+ }
+ .controls-row [class*="span"] + [class*="span"] {
+ margin-left: 20px;
+ }
+ input.span12,
+ textarea.span12,
+ .uneditable-input.span12 {
+ width: 710px;
+ }
+ input.span11,
+ textarea.span11,
+ .uneditable-input.span11 {
+ width: 648px;
+ }
+ input.span10,
+ textarea.span10,
+ .uneditable-input.span10 {
+ width: 586px;
+ }
+ input.span9,
+ textarea.span9,
+ .uneditable-input.span9 {
+ width: 524px;
+ }
+ input.span8,
+ textarea.span8,
+ .uneditable-input.span8 {
+ width: 462px;
+ }
+ input.span7,
+ textarea.span7,
+ .uneditable-input.span7 {
+ width: 400px;
+ }
+ input.span6,
+ textarea.span6,
+ .uneditable-input.span6 {
+ width: 338px;
+ }
+ input.span5,
+ textarea.span5,
+ .uneditable-input.span5 {
+ width: 276px;
+ }
+ input.span4,
+ textarea.span4,
+ .uneditable-input.span4 {
+ width: 214px;
+ }
+ input.span3,
+ textarea.span3,
+ .uneditable-input.span3 {
+ width: 152px;
+ }
+ input.span2,
+ textarea.span2,
+ .uneditable-input.span2 {
+ width: 90px;
+ }
+ input.span1,
+ textarea.span1,
+ .uneditable-input.span1 {
+ width: 28px;
+ }
+}
+
+@media (max-width: 767px) {
+ body {
+ padding-right: 20px;
+ padding-left: 20px;
+ }
+ .navbar-fixed-top,
+ .navbar-fixed-bottom,
+ .navbar-static-top {
+ margin-right: -20px;
+ margin-left: -20px;
+ }
+ .container-fluid {
+ padding: 0;
+ }
+ .dl-horizontal dt {
+ float: none;
+ width: auto;
+ clear: none;
+ text-align: left;
+ }
+ .dl-horizontal dd {
+ margin-left: 0;
+ }
+ .container {
+ width: auto;
+ }
+ .row-fluid {
+ width: 100%;
+ }
+ .row,
+ .thumbnails {
+ margin-left: 0;
+ }
+ .thumbnails > li {
+ float: none;
+ margin-left: 0;
+ }
+ [class*="span"],
+ .uneditable-input[class*="span"],
+ .row-fluid [class*="span"] {
+ display: block;
+ float: none;
+ width: 100%;
+ margin-left: 0;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ }
+ .span12,
+ .row-fluid .span12 {
+ width: 100%;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ }
+ .row-fluid [class*="offset"]:first-child {
+ margin-left: 0;
+ }
+ .input-large,
+ .input-xlarge,
+ .input-xxlarge,
+ input[class*="span"],
+ select[class*="span"],
+ textarea[class*="span"],
+ .uneditable-input {
+ display: block;
+ width: 100%;
+ min-height: 30px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ }
+ .input-prepend input,
+ .input-append input,
+ .input-prepend input[class*="span"],
+ .input-append input[class*="span"] {
+ display: inline-block;
+ width: auto;
+ }
+ .controls-row [class*="span"] + [class*="span"] {
+ margin-left: 0;
+ }
+ .modal {
+ position: fixed;
+ top: 20px;
+ right: 20px;
+ left: 20px;
+ width: auto;
+ margin: 0;
+ }
+ .modal.fade {
+ top: -100px;
+ }
+ .modal.fade.in {
+ top: 20px;
+ }
+}
+
+@media (max-width: 480px) {
+ .nav-collapse {
+ -webkit-transform: translate3d(0, 0, 0);
+ }
+ .page-header h1 small {
+ display: block;
+ line-height: 20px;
+ }
+ input[type="checkbox"],
+ input[type="radio"] {
+ border: 1px solid #ccc;
+ }
+ .form-horizontal .control-label {
+ float: none;
+ width: auto;
+ padding-top: 0;
+ text-align: left;
+ }
+ .form-horizontal .controls {
+ margin-left: 0;
+ }
+ .form-horizontal .control-list {
+ padding-top: 0;
+ }
+ .form-horizontal .form-actions {
+ padding-right: 10px;
+ padding-left: 10px;
+ }
+ .media .pull-left,
+ .media .pull-right {
+ display: block;
+ float: none;
+ margin-bottom: 10px;
+ }
+ .media-object {
+ margin-right: 0;
+ margin-left: 0;
+ }
+ .modal {
+ top: 10px;
+ right: 10px;
+ left: 10px;
+ }
+ .modal-header .close {
+ padding: 10px;
+ margin: -10px;
+ }
+ .carousel-caption {
+ position: static;
+ }
+}
+
+@media (max-width: 979px) {
+ body {
+ padding-top: 0;
+ }
+ .navbar-fixed-top,
+ .navbar-fixed-bottom {
+ position: static;
+ }
+ .navbar-fixed-top {
+ margin-bottom: 20px;
+ }
+ .navbar-fixed-bottom {
+ margin-top: 20px;
+ }
+ .navbar-fixed-top .navbar-inner,
+ .navbar-fixed-bottom .navbar-inner {
+ padding: 5px;
+ }
+ .navbar .container {
+ width: auto;
+ padding: 0;
+ }
+ .navbar .brand {
+ padding-right: 10px;
+ padding-left: 10px;
+ margin: 0 0 0 -5px;
+ }
+ .nav-collapse {
+ clear: both;
+ }
+ .nav-collapse .nav {
+ float: none;
+ margin: 0 0 10px;
+ }
+ .nav-collapse .nav > li {
+ float: none;
+ }
+ .nav-collapse .nav > li > a {
+ margin-bottom: 2px;
+ }
+ .nav-collapse .nav > .divider-vertical {
+ display: none;
+ }
+ .nav-collapse .nav .nav-header {
+ color: #777777;
+ text-shadow: none;
+ }
+ .nav-collapse .nav > li > a,
+ .nav-collapse .dropdown-menu a {
+ padding: 9px 15px;
+ font-weight: bold;
+ color: #777777;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+ }
+ .nav-collapse .btn {
+ padding: 4px 10px 4px;
+ font-weight: normal;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ }
+ .nav-collapse .dropdown-menu li + li a {
+ margin-bottom: 2px;
+ }
+ .nav-collapse .nav > li > a:hover,
+ .nav-collapse .nav > li > a:focus,
+ .nav-collapse .dropdown-menu a:hover,
+ .nav-collapse .dropdown-menu a:focus {
+ background-color: #f2f2f2;
+ }
+ .navbar-inverse .nav-collapse .nav > li > a,
+ .navbar-inverse .nav-collapse .dropdown-menu a {
+ color: #999999;
+ }
+ .navbar-inverse .nav-collapse .nav > li > a:hover,
+ .navbar-inverse .nav-collapse .nav > li > a:focus,
+ .navbar-inverse .nav-collapse .dropdown-menu a:hover,
+ .navbar-inverse .nav-collapse .dropdown-menu a:focus {
+ background-color: #111111;
+ }
+ .nav-collapse.in .btn-group {
+ padding: 0;
+ margin-top: 5px;
+ }
+ .nav-collapse .dropdown-menu {
+ position: static;
+ top: auto;
+ left: auto;
+ display: none;
+ float: none;
+ max-width: none;
+ padding: 0;
+ margin: 0 15px;
+ background-color: transparent;
+ border: none;
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+ }
+ .nav-collapse .open > .dropdown-menu {
+ display: block;
+ }
+ .nav-collapse .dropdown-menu:before,
+ .nav-collapse .dropdown-menu:after {
+ display: none;
+ }
+ .nav-collapse .dropdown-menu .divider {
+ display: none;
+ }
+ .nav-collapse .nav > li > .dropdown-menu:before,
+ .nav-collapse .nav > li > .dropdown-menu:after {
+ display: none;
+ }
+ .nav-collapse .navbar-form,
+ .nav-collapse .navbar-search {
+ float: none;
+ padding: 10px 15px;
+ margin: 10px 0;
+ border-top: 1px solid #f2f2f2;
+ border-bottom: 1px solid #f2f2f2;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
+ }
+ .navbar-inverse .nav-collapse .navbar-form,
+ .navbar-inverse .nav-collapse .navbar-search {
+ border-top-color: #111111;
+ border-bottom-color: #111111;
+ }
+ .navbar .nav-collapse .nav.pull-right {
+ float: none;
+ margin-left: 0;
+ }
+ .nav-collapse,
+ .nav-collapse.collapse {
+ height: 0;
+ overflow: hidden;
+ }
+ .navbar .btn-navbar {
+ display: block;
+ }
+ .navbar-static .navbar-inner {
+ padding-right: 10px;
+ padding-left: 10px;
+ }
+}
+
+@media (min-width: 980px) {
+ .nav-collapse.collapse {
+ height: auto !important;
+ overflow: visible !important;
+ }
+}
Added: WebTimer/src/common/css/bootstrap-responsive.min.css
===================================================================
--- WebTimer/src/common/css/bootstrap-responsive.min.css (rev 0)
+++ WebTimer/src/common/css/bootstrap-responsive.min.css 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,9 @@
+/*!
+ * Bootstrap Responsive v2.3.2
+ *
+ * Copyright 2012 Twitter, Inc
+ * Licensed under the Apache License v2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Designed and built with all the love in the world @twitter by @mdo and @fat.
+ */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:inherit!important}.hidden-print{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}}
Added: WebTimer/src/common/css/bootstrap.css
===================================================================
--- WebTimer/src/common/css/bootstrap.css (rev 0)
+++ WebTimer/src/common/css/bootstrap.css 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,6167 @@
+/*!
+ * Bootstrap v2.3.2
+ *
+ * Copyright 2012 Twitter, Inc
+ * Licensed under the Apache License v2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Designed and built with all the love in the world @twitter by @mdo and @fat.
+ */
+
+.clearfix {
+ *zoom: 1;
+}
+
+.clearfix:before,
+.clearfix:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.clearfix:after {
+ clear: both;
+}
+
+.hide-text {
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0;
+}
+
+.input-block-level {
+ display: block;
+ width: 100%;
+ min-height: 30px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+nav,
+section {
+ display: block;
+}
+
+audio,
+canvas,
+video {
+ display: inline-block;
+ *display: inline;
+ *zoom: 1;
+}
+
+audio:not([controls]) {
+ display: none;
+}
+
+html {
+ font-size: 100%;
+ -webkit-text-size-adjust: 100%;
+ -ms-text-size-adjust: 100%;
+}
+
+a:focus {
+ outline: thin dotted #333;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
+a:hover,
+a:active {
+ outline: 0;
+}
+
+sub,
+sup {
+ position: relative;
+ font-size: 75%;
+ line-height: 0;
+ vertical-align: baseline;
+}
+
+sup {
+ top: -0.5em;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+img {
+ width: auto\9;
+ height: auto;
+ max-width: 100%;
+ vertical-align: middle;
+ border: 0;
+ -ms-interpolation-mode: bicubic;
+}
+
+#map_canvas img,
+.google-maps img {
+ max-width: none;
+}
+
+button,
+input,
+select,
+textarea {
+ margin: 0;
+ font-size: 100%;
+ vertical-align: middle;
+}
+
+button,
+input {
+ *overflow: visible;
+ line-height: normal;
+}
+
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+}
+
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ cursor: pointer;
+ -webkit-appearance: button;
+}
+
+label,
+select,
+button,
+input[type="button"],
+input[type="reset"],
+input[type="submit"],
+input[type="radio"],
+input[type="checkbox"] {
+ cursor: pointer;
+}
+
+input[type="search"] {
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ -webkit-appearance: textfield;
+}
+
+input[type="search"]::-webkit-search-decoration,
+input[type="search"]::-webkit-search-cancel-button {
+ -webkit-appearance: none;
+}
+
+textarea {
+ overflow: auto;
+ vertical-align: top;
+}
+
+@media print {
+ * {
+ color: #000 !important;
+ text-shadow: none !important;
+ background: transparent !important;
+ box-shadow: none !important;
+ }
+ a,
+ a:visited {
+ text-decoration: underline;
+ }
+ a[href]:after {
+ content: " (" attr(href) ")";
+ }
+ abbr[title]:after {
+ content: " (" attr(title) ")";
+ }
+ .ir a:after,
+ a[href^="javascript:"]:after,
+ a[href^="#"]:after {
+ content: "";
+ }
+ pre,
+ blockquote {
+ border: 1px solid #999;
+ page-break-inside: avoid;
+ }
+ thead {
+ display: table-header-group;
+ }
+ tr,
+ img {
+ page-break-inside: avoid;
+ }
+ img {
+ max-width: 100% !important;
+ }
+ @page {
+ margin: 0.5cm;
+ }
+ p,
+ h2,
+ h3 {
+ orphans: 3;
+ widows: 3;
+ }
+ h2,
+ h3 {
+ page-break-after: avoid;
+ }
+}
+
+body {
+ margin: 0;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ line-height: 20px;
+ color: #333333;
+ background-color: #ffffff;
+}
+
+a {
+ color: #0088cc;
+ text-decoration: none;
+}
+
+a:hover,
+a:focus {
+ color: #005580;
+ text-decoration: underline;
+}
+
+.img-rounded {
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+}
+
+.img-polaroid {
+ padding: 4px;
+ background-color: #fff;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+ -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+}
+
+.img-circle {
+ -webkit-border-radius: 500px;
+ -moz-border-radius: 500px;
+ border-radius: 500px;
+}
+
+.row {
+ margin-left: -20px;
+ *zoom: 1;
+}
+
+.row:before,
+.row:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.row:after {
+ clear: both;
+}
+
+[class*="span"] {
+ float: left;
+ min-height: 1px;
+ margin-left: 20px;
+}
+
+.container,
+.navbar-static-top .container,
+.navbar-fixed-top .container,
+.navbar-fixed-bottom .container {
+ width: 940px;
+}
+
+.span12 {
+ width: 940px;
+}
+
+.span11 {
+ width: 860px;
+}
+
+.span10 {
+ width: 780px;
+}
+
+.span9 {
+ width: 700px;
+}
+
+.span8 {
+ width: 620px;
+}
+
+.span7 {
+ width: 540px;
+}
+
+.span6 {
+ width: 460px;
+}
+
+.span5 {
+ width: 380px;
+}
+
+.span4 {
+ width: 300px;
+}
+
+.span3 {
+ width: 220px;
+}
+
+.span2 {
+ width: 140px;
+}
+
+.span1 {
+ width: 60px;
+}
+
+.offset12 {
+ margin-left: 980px;
+}
+
+.offset11 {
+ margin-left: 900px;
+}
+
+.offset10 {
+ margin-left: 820px;
+}
+
+.offset9 {
+ margin-left: 740px;
+}
+
+.offset8 {
+ margin-left: 660px;
+}
+
+.offset7 {
+ margin-left: 580px;
+}
+
+.offset6 {
+ margin-left: 500px;
+}
+
+.offset5 {
+ margin-left: 420px;
+}
+
+.offset4 {
+ margin-left: 340px;
+}
+
+.offset3 {
+ margin-left: 260px;
+}
+
+.offset2 {
+ margin-left: 180px;
+}
+
+.offset1 {
+ margin-left: 100px;
+}
+
+.row-fluid {
+ width: 100%;
+ *zoom: 1;
+}
+
+.row-fluid:before,
+.row-fluid:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.row-fluid:after {
+ clear: both;
+}
+
+.row-fluid [class*="span"] {
+ display: block;
+ float: left;
+ width: 100%;
+ min-height: 30px;
+ margin-left: 2.127659574468085%;
+ *margin-left: 2.074468085106383%;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+.row-fluid [class*="span"]:first-child {
+ margin-left: 0;
+}
+
+.row-fluid .controls-row [class*="span"] + [class*="span"] {
+ margin-left: 2.127659574468085%;
+}
+
+.row-fluid .span12 {
+ width: 100%;
+ *width: 99.94680851063829%;
+}
+
+.row-fluid .span11 {
+ width: 91.48936170212765%;
+ *width: 91.43617021276594%;
+}
+
+.row-fluid .span10 {
+ width: 82.97872340425532%;
+ *width: 82.92553191489361%;
+}
+
+.row-fluid .span9 {
+ width: 74.46808510638297%;
+ *width: 74.41489361702126%;
+}
+
+.row-fluid .span8 {
+ width: 65.95744680851064%;
+ *width: 65.90425531914893%;
+}
+
+.row-fluid .span7 {
+ width: 57.44680851063829%;
+ *width: 57.39361702127659%;
+}
+
+.row-fluid .span6 {
+ width: 48.93617021276595%;
+ *width: 48.88297872340425%;
+}
+
+.row-fluid .span5 {
+ width: 40.42553191489362%;
+ *width: 40.37234042553192%;
+}
+
+.row-fluid .span4 {
+ width: 31.914893617021278%;
+ *width: 31.861702127659576%;
+}
+
+.row-fluid .span3 {
+ width: 23.404255319148934%;
+ *width: 23.351063829787233%;
+}
+
+.row-fluid .span2 {
+ width: 14.893617021276595%;
+ *width: 14.840425531914894%;
+}
+
+.row-fluid .span1 {
+ width: 6.382978723404255%;
+ *width: 6.329787234042553%;
+}
+
+.row-fluid .offset12 {
+ margin-left: 104.25531914893617%;
+ *margin-left: 104.14893617021275%;
+}
+
+.row-fluid .offset12:first-child {
+ margin-left: 102.12765957446808%;
+ *margin-left: 102.02127659574467%;
+}
+
+.row-fluid .offset11 {
+ margin-left: 95.74468085106382%;
+ *margin-left: 95.6382978723404%;
+}
+
+.row-fluid .offset11:first-child {
+ margin-left: 93.61702127659574%;
+ *margin-left: 93.51063829787232%;
+}
+
+.row-fluid .offset10 {
+ margin-left: 87.23404255319149%;
+ *margin-left: 87.12765957446807%;
+}
+
+.row-fluid .offset10:first-child {
+ margin-left: 85.1063829787234%;
+ *margin-left: 84.99999999999999%;
+}
+
+.row-fluid .offset9 {
+ margin-left: 78.72340425531914%;
+ *margin-left: 78.61702127659572%;
+}
+
+.row-fluid .offset9:first-child {
+ margin-left: 76.59574468085106%;
+ *margin-left: 76.48936170212764%;
+}
+
+.row-fluid .offset8 {
+ margin-left: 70.2127659574468%;
+ *margin-left: 70.10638297872339%;
+}
+
+.row-fluid .offset8:first-child {
+ margin-left: 68.08510638297872%;
+ *margin-left: 67.9787234042553%;
+}
+
+.row-fluid .offset7 {
+ margin-left: 61.70212765957446%;
+ *margin-left: 61.59574468085106%;
+}
+
+.row-fluid .offset7:first-child {
+ margin-left: 59.574468085106375%;
+ *margin-left: 59.46808510638297%;
+}
+
+.row-fluid .offset6 {
+ margin-left: 53.191489361702125%;
+ *margin-left: 53.085106382978715%;
+}
+
+.row-fluid .offset6:first-child {
+ margin-left: 51.063829787234035%;
+ *margin-left: 50.95744680851063%;
+}
+
+.row-fluid .offset5 {
+ margin-left: 44.68085106382979%;
+ *margin-left: 44.57446808510638%;
+}
+
+.row-fluid .offset5:first-child {
+ margin-left: 42.5531914893617%;
+ *margin-left: 42.4468085106383%;
+}
+
+.row-fluid .offset4 {
+ margin-left: 36.170212765957444%;
+ *margin-left: 36.06382978723405%;
+}
+
+.row-fluid .offset4:first-child {
+ margin-left: 34.04255319148936%;
+ *margin-left: 33.93617021276596%;
+}
+
+.row-fluid .offset3 {
+ margin-left: 27.659574468085104%;
+ *margin-left: 27.5531914893617%;
+}
+
+.row-fluid .offset3:first-child {
+ margin-left: 25.53191489361702%;
+ *margin-left: 25.425531914893618%;
+}
+
+.row-fluid .offset2 {
+ margin-left: 19.148936170212764%;
+ *margin-left: 19.04255319148936%;
+}
+
+.row-fluid .offset2:first-child {
+ margin-left: 17.02127659574468%;
+ *margin-left: 16.914893617021278%;
+}
+
+.row-fluid .offset1 {
+ margin-left: 10.638297872340425%;
+ *margin-left: 10.53191489361702%;
+}
+
+.row-fluid .offset1:first-child {
+ margin-left: 8.51063829787234%;
+ *margin-left: 8.404255319148938%;
+}
+
+[class*="span"].hide,
+.row-fluid [class*="span"].hide {
+ display: none;
+}
+
+[class*="span"].pull-right,
+.row-fluid [class*="span"].pull-right {
+ float: right;
+}
+
+.container {
+ margin-right: auto;
+ margin-left: auto;
+ *zoom: 1;
+}
+
+.container:before,
+.container:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.container:after {
+ clear: both;
+}
+
+.container-fluid {
+ padding-right: 20px;
+ padding-left: 20px;
+ *zoom: 1;
+}
+
+.container-fluid:before,
+.container-fluid:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.container-fluid:after {
+ clear: both;
+}
+
+p {
+ margin: 0 0 10px;
+}
+
+.lead {
+ margin-bottom: 20px;
+ font-size: 21px;
+ font-weight: 200;
+ line-height: 30px;
+}
+
+small {
+ font-size: 85%;
+}
+
+strong {
+ font-weight: bold;
+}
+
+em {
+ font-style: italic;
+}
+
+cite {
+ font-style: normal;
+}
+
+.muted {
+ color: #999999;
+}
+
+a.muted:hover,
+a.muted:focus {
+ color: #808080;
+}
+
+.text-warning {
+ color: #c09853;
+}
+
+a.text-warning:hover,
+a.text-warning:focus {
+ color: #a47e3c;
+}
+
+.text-error {
+ color: #b94a48;
+}
+
+a.text-error:hover,
+a.text-error:focus {
+ color: #953b39;
+}
+
+.text-info {
+ color: #3a87ad;
+}
+
+a.text-info:hover,
+a.text-info:focus {
+ color: #2d6987;
+}
+
+.text-success {
+ color: #468847;
+}
+
+a.text-success:hover,
+a.text-success:focus {
+ color: #356635;
+}
+
+.text-left {
+ text-align: left;
+}
+
+.text-right {
+ text-align: right;
+}
+
+.text-center {
+ text-align: center;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ margin: 10px 0;
+ font-family: inherit;
+ font-weight: bold;
+ line-height: 20px;
+ color: inherit;
+ text-rendering: optimizelegibility;
+}
+
+h1 small,
+h2 small,
+h3 small,
+h4 small,
+h5 small,
+h6 small {
+ font-weight: normal;
+ line-height: 1;
+ color: #999999;
+}
+
+h1,
+h2,
+h3 {
+ line-height: 40px;
+}
+
+h1 {
+ font-size: 38.5px;
+}
+
+h2 {
+ font-size: 31.5px;
+}
+
+h3 {
+ font-size: 24.5px;
+}
+
+h4 {
+ font-size: 17.5px;
+}
+
+h5 {
+ font-size: 14px;
+}
+
+h6 {
+ font-size: 11.9px;
+}
+
+h1 small {
+ font-size: 24.5px;
+}
+
+h2 small {
+ font-size: 17.5px;
+}
+
+h3 small {
+ font-size: 14px;
+}
+
+h4 small {
+ font-size: 14px;
+}
+
+.page-header {
+ padding-bottom: 9px;
+ margin: 20px 0 30px;
+ border-bottom: 1px solid #eeeeee;
+}
+
+ul,
+ol {
+ padding: 0;
+ margin: 0 0 10px 25px;
+}
+
+ul ul,
+ul ol,
+ol ol,
+ol ul {
+ margin-bottom: 0;
+}
+
+li {
+ line-height: 20px;
+}
+
+ul.unstyled,
+ol.unstyled {
+ margin-left: 0;
+ list-style: none;
+}
+
+ul.inline,
+ol.inline {
+ margin-left: 0;
+ list-style: none;
+}
+
+ul.inline > li,
+ol.inline > li {
+ display: inline-block;
+ *display: inline;
+ padding-right: 5px;
+ padding-left: 5px;
+ *zoom: 1;
+}
+
+dl {
+ margin-bottom: 20px;
+}
+
+dt,
+dd {
+ line-height: 20px;
+}
+
+dt {
+ font-weight: bold;
+}
+
+dd {
+ margin-left: 10px;
+}
+
+.dl-horizontal {
+ *zoom: 1;
+}
+
+.dl-horizontal:before,
+.dl-horizontal:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.dl-horizontal:after {
+ clear: both;
+}
+
+.dl-horizontal dt {
+ float: left;
+ width: 160px;
+ overflow: hidden;
+ clear: left;
+ text-align: right;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.dl-horizontal dd {
+ margin-left: 180px;
+}
+
+hr {
+ margin: 20px 0;
+ border: 0;
+ border-top: 1px solid #eeeeee;
+ border-bottom: 1px solid #ffffff;
+}
+
+abbr[title],
+abbr[data-original-title] {
+ cursor: help;
+ border-bottom: 1px dotted #999999;
+}
+
+abbr.initialism {
+ font-size: 90%;
+ text-transform: uppercase;
+}
+
+blockquote {
+ padding: 0 0 0 15px;
+ margin: 0 0 20px;
+ border-left: 5px solid #eeeeee;
+}
+
+blockquote p {
+ margin-bottom: 0;
+ font-size: 17.5px;
+ font-weight: 300;
+ line-height: 1.25;
+}
+
+blockquote small {
+ display: block;
+ line-height: 20px;
+ color: #999999;
+}
+
+blockquote small:before {
+ content: '\2014 \00A0';
+}
+
+blockquote.pull-right {
+ float: right;
+ padding-right: 15px;
+ padding-left: 0;
+ border-right: 5px solid #eeeeee;
+ border-left: 0;
+}
+
+blockquote.pull-right p,
+blockquote.pull-right small {
+ text-align: right;
+}
+
+blockquote.pull-right small:before {
+ content: '';
+}
+
+blockquote.pull-right small:after {
+ content: '\00A0 \2014';
+}
+
+q:before,
+q:after,
+blockquote:before,
+blockquote:after {
+ content: "";
+}
+
+address {
+ display: block;
+ margin-bottom: 20px;
+ font-style: normal;
+ line-height: 20px;
+}
+
+code,
+pre {
+ padding: 0 3px 2px;
+ font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
+ font-size: 12px;
+ color: #333333;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+
+code {
+ padding: 2px 4px;
+ color: #d14;
+ white-space: nowrap;
+ background-color: #f7f7f9;
+ border: 1px solid #e1e1e8;
+}
+
+pre {
+ display: block;
+ padding: 9.5px;
+ margin: 0 0 10px;
+ font-size: 13px;
+ line-height: 20px;
+ word-break: break-all;
+ word-wrap: break-word;
+ white-space: pre;
+ white-space: pre-wrap;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, 0.15);
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+
+pre.prettyprint {
+ margin-bottom: 20px;
+}
+
+pre code {
+ padding: 0;
+ color: inherit;
+ white-space: pre;
+ white-space: pre-wrap;
+ background-color: transparent;
+ border: 0;
+}
+
+.pre-scrollable {
+ max-height: 340px;
+ overflow-y: scroll;
+}
+
+form {
+ margin: 0 0 20px;
+}
+
+fieldset {
+ padding: 0;
+ margin: 0;
+ border: 0;
+}
+
+legend {
+ display: block;
+ width: 100%;
+ padding: 0;
+ margin-bottom: 20px;
+ font-size: 21px;
+ line-height: 40px;
+ color: #333333;
+ border: 0;
+ border-bottom: 1px solid #e5e5e5;
+}
+
+legend small {
+ font-size: 15px;
+ color: #999999;
+}
+
+label,
+input,
+button,
+select,
+textarea {
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 20px;
+}
+
+input,
+button,
+select,
+textarea {
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+}
+
+label {
+ display: block;
+ margin-bottom: 5px;
+}
+
+select,
+textarea,
+input[type="text"],
+input[type="password"],
+input[type="datetime"],
+input[type="datetime-local"],
+input[type="date"],
+input[type="month"],
+input[type="time"],
+input[type="week"],
+input[type="number"],
+input[type="email"],
+input[type="url"],
+input[type="search"],
+input[type="tel"],
+input[type="color"],
+.uneditable-input {
+ display: inline-block;
+ height: 20px;
+ padding: 4px 6px;
+ margin-bottom: 10px;
+ font-size: 14px;
+ line-height: 20px;
+ color: #555555;
+ vertical-align: middle;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+
+input,
+textarea,
+.uneditable-input {
+ width: 206px;
+}
+
+textarea {
+ height: auto;
+}
+
+textarea,
+input[type="text"],
+input[type="password"],
+input[type="datetime"],
+input[type="datetime-local"],
+input[type="date"],
+input[type="month"],
+input[type="time"],
+input[type="week"],
+input[type="number"],
+input[type="email"],
+input[type="url"],
+input[type="search"],
+input[type="tel"],
+input[type="color"],
+.uneditable-input {
+ background-color: #ffffff;
+ border: 1px solid #cccccc;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
+ -moz-transition: border linear 0.2s, box-shadow linear 0.2s;
+ -o-transition: border linear 0.2s, box-shadow linear 0.2s;
+ transition: border linear 0.2s, box-shadow linear 0.2s;
+}
+
+textarea:focus,
+input[type="text"]:focus,
+input[type="password"]:focus,
+input[type="datetime"]:focus,
+input[type="datetime-local"]:focus,
+input[type="date"]:focus,
+input[type="month"]:focus,
+input[type="time"]:focus,
+input[type="week"]:focus,
+input[type="number"]:focus,
+input[type="email"]:focus,
+input[type="url"]:focus,
+input[type="search"]:focus,
+input[type="tel"]:focus,
+input[type="color"]:focus,
+.uneditable-input:focus {
+ border-color: rgba(82, 168, 236, 0.8);
+ outline: 0;
+ outline: thin dotted \9;
+ /* IE6-9 */
+
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
+}
+
+input[type="radio"],
+input[type="checkbox"] {
+ margin: 4px 0 0;
+ margin-top: 1px \9;
+ *margin-top: 0;
+ line-height: normal;
+}
+
+input[type="file"],
+input[type="image"],
+input[type="submit"],
+input[type="reset"],
+input[type="button"],
+input[type="radio"],
+input[type="checkbox"] {
+ width: auto;
+}
+
+select,
+input[type="file"] {
+ height: 30px;
+ /* In IE7, the height of the select element cannot be changed by height, only font-size */
+
+ *margin-top: 4px;
+ /* For IE7, add top margin to align select with labels */
+
+ line-height: 30px;
+}
+
+select {
+ width: 220px;
+ background-color: #ffffff;
+ border: 1px solid #cccccc;
+}
+
+select[multiple],
+select[size] {
+ height: auto;
+}
+
+select:focus,
+input[type="file"]:focus,
+input[type="radio"]:focus,
+input[type="checkbox"]:focus {
+ outline: thin dotted #333;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
+.uneditable-input,
+.uneditable-textarea {
+ color: #999999;
+ cursor: not-allowed;
+ background-color: #fcfcfc;
+ border-color: #cccccc;
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025);
+ -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025);
+}
+
+.uneditable-input {
+ overflow: hidden;
+ white-space: nowrap;
+}
+
+.uneditable-textarea {
+ width: auto;
+ height: auto;
+}
+
+input:-moz-placeholder,
+textarea:-moz-placeholder {
+ color: #999999;
+}
+
+input:-ms-input-placeholder,
+textarea:-ms-input-placeholder {
+ color: #999999;
+}
+
+input::-webkit-input-placeholder,
+textarea::-webkit-input-placeholder {
+ color: #999999;
+}
+
+.radio,
+.checkbox {
+ min-height: 20px;
+ padding-left: 20px;
+}
+
+.radio input[type="radio"],
+.checkbox input[type="checkbox"] {
+ float: left;
+ margin-left: -20px;
+}
+
+.controls > .radio:first-child,
+.controls > .checkbox:first-child {
+ padding-top: 5px;
+}
+
+.radio.inline,
+.checkbox.inline {
+ display: inline-block;
+ padding-top: 5px;
+ margin-bottom: 0;
+ vertical-align: middle;
+}
+
+.radio.inline + .radio.inline,
+.checkbox.inline + .checkbox.inline {
+ margin-left: 10px;
+}
+
+.input-mini {
+ width: 60px;
+}
+
+.input-small {
+ width: 90px;
+}
+
+.input-medium {
+ width: 150px;
+}
+
+.input-large {
+ width: 210px;
+}
+
+.input-xlarge {
+ width: 270px;
+}
+
+.input-xxlarge {
+ width: 530px;
+}
+
+input[class*="span"],
+select[class*="span"],
+textarea[class*="span"],
+.uneditable-input[class*="span"],
+.row-fluid input[class*="span"],
+.row-fluid select[class*="span"],
+.row-fluid textarea[class*="span"],
+.row-fluid .uneditable-input[class*="span"] {
+ float: none;
+ margin-left: 0;
+}
+
+.input-append input[class*="span"],
+.input-append .uneditable-input[class*="span"],
+.input-prepend input[class*="span"],
+.input-prepend .uneditable-input[class*="span"],
+.row-fluid input[class*="span"],
+.row-fluid select[class*="span"],
+.row-fluid textarea[class*="span"],
+.row-fluid .uneditable-input[class*="span"],
+.row-fluid .input-prepend [class*="span"],
+.row-fluid .input-append [class*="span"] {
+ display: inline-block;
+}
+
+input,
+textarea,
+.uneditable-input {
+ margin-left: 0;
+}
+
+.controls-row [class*="span"] + [class*="span"] {
+ margin-left: 20px;
+}
+
+input.span12,
+textarea.span12,
+.uneditable-input.span12 {
+ width: 926px;
+}
+
+input.span11,
+textarea.span11,
+.uneditable-input.span11 {
+ width: 846px;
+}
+
+input.span10,
+textarea.span10,
+.uneditable-input.span10 {
+ width: 766px;
+}
+
+input.span9,
+textarea.span9,
+.uneditable-input.span9 {
+ width: 686px;
+}
+
+input.span8,
+textarea.span8,
+.uneditable-input.span8 {
+ width: 606px;
+}
+
+input.span7,
+textarea.span7,
+.uneditable-input.span7 {
+ width: 526px;
+}
+
+input.span6,
+textarea.span6,
+.uneditable-input.span6 {
+ width: 446px;
+}
+
+input.span5,
+textarea.span5,
+.uneditable-input.span5 {
+ width: 366px;
+}
+
+input.span4,
+textarea.span4,
+.uneditable-input.span4 {
+ width: 286px;
+}
+
+input.span3,
+textarea.span3,
+.uneditable-input.span3 {
+ width: 206px;
+}
+
+input.span2,
+textarea.span2,
+.uneditable-input.span2 {
+ width: 126px;
+}
+
+input.span1,
+textarea.span1,
+.uneditable-input.span1 {
+ width: 46px;
+}
+
+.controls-row {
+ *zoom: 1;
+}
+
+.controls-row:before,
+.controls-row:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.controls-row:after {
+ clear: both;
+}
+
+.controls-row [class*="span"],
+.row-fluid .controls-row [class*="span"] {
+ float: left;
+}
+
+.controls-row .checkbox[class*="span"],
+.controls-row .radio[class*="span"] {
+ padding-top: 5px;
+}
+
+input[disabled],
+select[disabled],
+textarea[disabled],
+input[readonly],
+select[readonly],
+textarea[readonly] {
+ cursor: not-allowed;
+ background-color: #eeeeee;
+}
+
+input[type="radio"][disabled],
+input[type="checkbox"][disabled],
+input[type="radio"][readonly],
+input[type="checkbox"][readonly] {
+ background-color: transparent;
+}
+
+.control-group.warning .control-label,
+.control-group.warning .help-block,
+.control-group.warning .help-inline {
+ color: #c09853;
+}
+
+.control-group.warning .checkbox,
+.control-group.warning .radio,
+.control-group.warning input,
+.control-group.warning select,
+.control-group.warning textarea {
+ color: #c09853;
+}
+
+.control-group.warning input,
+.control-group.warning select,
+.control-group.warning textarea {
+ border-color: #c09853;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+
+.control-group.warning input:focus,
+.control-group.warning select:focus,
+.control-group.warning textarea:focus {
+ border-color: #a47e3c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;
+}
+
+.control-group.warning .input-prepend .add-on,
+.control-group.warning .input-append .add-on {
+ color: #c09853;
+ background-color: #fcf8e3;
+ border-color: #c09853;
+}
+
+.control-group.error .control-label,
+.control-group.error .help-block,
+.control-group.error .help-inline {
+ color: #b94a48;
+}
+
+.control-group.error .checkbox,
+.control-group.error .radio,
+.control-group.error input,
+.control-group.error select,
+.control-group.error textarea {
+ color: #b94a48;
+}
+
+.control-group.error input,
+.control-group.error select,
+.control-group.error textarea {
+ border-color: #b94a48;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+
+.control-group.error input:focus,
+.control-group.error select:focus,
+.control-group.error textarea:focus {
+ border-color: #953b39;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;
+}
+
+.control-group.error .input-prepend .add-on,
+.control-group.error .input-append .add-on {
+ color: #b94a48;
+ background-color: #f2dede;
+ border-color: #b94a48;
+}
+
+.control-group.success .control-label,
+.control-group.success .help-block,
+.control-group.success .help-inline {
+ color: #468847;
+}
+
+.control-group.success .checkbox,
+.control-group.success .radio,
+.control-group.success input,
+.control-group.success select,
+.control-group.success textarea {
+ color: #468847;
+}
+
+.control-group.success input,
+.control-group.success select,
+.control-group.success textarea {
+ border-color: #468847;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+
+.control-group.success input:focus,
+.control-group.success select:focus,
+.control-group.success textarea:focus {
+ border-color: #356635;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;
+}
+
+.control-group.success .input-prepend .add-on,
+.control-group.success .input-append .add-on {
+ color: #468847;
+ background-color: #dff0d8;
+ border-color: #468847;
+}
+
+.control-group.info .control-label,
+.control-group.info .help-block,
+.control-group.info .help-inline {
+ color: #3a87ad;
+}
+
+.control-group.info .checkbox,
+.control-group.info .radio,
+.control-group.info input,
+.control-group.info select,
+.control-group.info textarea {
+ color: #3a87ad;
+}
+
+.control-group.info input,
+.control-group.info select,
+.control-group.info textarea {
+ border-color: #3a87ad;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+
+.control-group.info input:focus,
+.control-group.info select:focus,
+.control-group.info textarea:focus {
+ border-color: #2d6987;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3;
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3;
+}
+
+.control-group.info .input-prepend .add-on,
+.control-group.info .input-append .add-on {
+ color: #3a87ad;
+ background-color: #d9edf7;
+ border-color: #3a87ad;
+}
+
+input:focus:invalid,
+textarea:focus:invalid,
+select:focus:invalid {
+ color: #b94a48;
+ border-color: #ee5f5b;
+}
+
+input:focus:invalid:focus,
+textarea:focus:invalid:focus,
+select:focus:invalid:focus {
+ border-color: #e9322d;
+ -webkit-box-shadow: 0 0 6px #f8b9b7;
+ -moz-box-shadow: 0 0 6px #f8b9b7;
+ box-shadow: 0 0 6px #f8b9b7;
+}
+
+.form-actions {
+ padding: 19px 20px 20px;
+ margin-top: 20px;
+ margin-bottom: 20px;
+ background-color: #f5f5f5;
+ border-top: 1px solid #e5e5e5;
+ *zoom: 1;
+}
+
+.form-actions:before,
+.form-actions:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.form-actions:after {
+ clear: both;
+}
+
+.help-block,
+.help-inline {
+ color: #595959;
+}
+
+.help-block {
+ display: block;
+ margin-bottom: 10px;
+}
+
+.help-inline {
+ display: inline-block;
+ *display: inline;
+ padding-left: 5px;
+ vertical-align: middle;
+ *zoom: 1;
+}
+
+.input-append,
+.input-prepend {
+ display: inline-block;
+ margin-bottom: 10px;
+ font-size: 0;
+ white-space: nowrap;
+ vertical-align: middle;
+}
+
+.input-append input,
+.input-prepend input,
+.input-append select,
+.input-prepend select,
+.input-append .uneditable-input,
+.input-prepend .uneditable-input,
+.input-append .dropdown-menu,
+.input-prepend .dropdown-menu,
+.input-append .popover,
+.input-prepend .popover {
+ font-size: 14px;
+}
+
+.input-append input,
+.input-prepend input,
+.input-append select,
+.input-prepend select,
+.input-append .uneditable-input,
+.input-prepend .uneditable-input {
+ position: relative;
+ margin-bottom: 0;
+ *margin-left: 0;
+ vertical-align: top;
+ -webkit-border-radius: 0 4px 4px 0;
+ -moz-border-radius: 0 4px 4px 0;
+ border-radius: 0 4px 4px 0;
+}
+
+.input-append input:focus,
+.input-prepend input:focus,
+.input-append select:focus,
+.input-prepend select:focus,
+.input-append .uneditable-input:focus,
+.input-prepend .uneditable-input:focus {
+ z-index: 2;
+}
+
+.input-append .add-on,
+.input-prepend .add-on {
+ display: inline-block;
+ width: auto;
+ height: 20px;
+ min-width: 16px;
+ padding: 4px 5px;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 20px;
+ text-align: center;
+ text-shadow: 0 1px 0 #ffffff;
+ background-color: #eeeeee;
+ border: 1px solid #ccc;
+}
+
+.input-append .add-on,
+.input-prepend .add-on,
+.input-append .btn,
+.input-prepend .btn,
+.input-append .btn-group > .dropdown-toggle,
+.input-prepend .btn-group > .dropdown-toggle {
+ vertical-align: top;
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+}
+
+.input-append .active,
+.input-prepend .active {
+ background-color: #a9dba9;
+ border-color: #46a546;
+}
+
+.input-prepend .add-on,
+.input-prepend .btn {
+ margin-right: -1px;
+}
+
+.input-prepend .add-on:first-child,
+.input-prepend .btn:first-child {
+ -webkit-border-radius: 4px 0 0 4px;
+ -moz-border-radius: 4px 0 0 4px;
+ border-radius: 4px 0 0 4px;
+}
+
+.input-append input,
+.input-append select,
+.input-append .uneditable-input {
+ -webkit-border-radius: 4px 0 0 4px;
+ -moz-border-radius: 4px 0 0 4px;
+ border-radius: 4px 0 0 4px;
+}
+
+.input-append input + .btn-group .btn:last-child,
+.input-append select + .btn-group .btn:last-child,
+.input-append .uneditable-input + .btn-group .btn:last-child {
+ -webkit-border-radius: 0 4px 4px 0;
+ -moz-border-radius: 0 4px 4px 0;
+ border-radius: 0 4px 4px 0;
+}
+
+.input-append .add-on,
+.input-append .btn,
+.input-append .btn-group {
+ margin-left: -1px;
+}
+
+.input-append .add-on:last-child,
+.input-append .btn:last-child,
+.input-append .btn-group:last-child > .dropdown-toggle {
+ -webkit-border-radius: 0 4px 4px 0;
+ -moz-border-radius: 0 4px 4px 0;
+ border-radius: 0 4px 4px 0;
+}
+
+.input-prepend.input-append input,
+.input-prepend.input-append select,
+.input-prepend.input-append .uneditable-input {
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+}
+
+.input-prepend.input-append input + .btn-group .btn,
+.input-prepend.input-append select + .btn-group .btn,
+.input-prepend.input-append .uneditable-input + .btn-group .btn {
+ -webkit-border-radius: 0 4px 4px 0;
+ -moz-border-radius: 0 4px 4px 0;
+ border-radius: 0 4px 4px 0;
+}
+
+.input-prepend.input-append .add-on:first-child,
+.input-prepend.input-append .btn:first-child {
+ margin-right: -1px;
+ -webkit-border-radius: 4px 0 0 4px;
+ -moz-border-radius: 4px 0 0 4px;
+ border-radius: 4px 0 0 4px;
+}
+
+.input-prepend.input-append .add-on:last-child,
+.input-prepend.input-append .btn:last-child {
+ margin-left: -1px;
+ -webkit-border-radius: 0 4px 4px 0;
+ -moz-border-radius: 0 4px 4px 0;
+ border-radius: 0 4px 4px 0;
+}
+
+.input-prepend.input-append .btn-group:first-child {
+ margin-left: 0;
+}
+
+input.search-query {
+ padding-right: 14px;
+ padding-right: 4px \9;
+ padding-left: 14px;
+ padding-left: 4px \9;
+ /* IE7-8 doesn't have border-radius, so don't indent the padding */
+
+ margin-bottom: 0;
+ -webkit-border-radius: 15px;
+ -moz-border-radius: 15px;
+ border-radius: 15px;
+}
+
+/* Allow for input prepend/append in search forms */
+
+.form-search .input-append .search-query,
+.form-search .input-prepend .search-query {
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+}
+
+.form-search .input-append .search-query {
+ -webkit-border-radius: 14px 0 0 14px;
+ -moz-border-radius: 14px 0 0 14px;
+ border-radius: 14px 0 0 14px;
+}
+
+.form-search .input-append .btn {
+ -webkit-border-radius: 0 14px 14px 0;
+ -moz-border-radius: 0 14px 14px 0;
+ border-radius: 0 14px 14px 0;
+}
+
+.form-search .input-prepend .search-query {
+ -webkit-border-radius: 0 14px 14px 0;
+ -moz-border-radius: 0 14px 14px 0;
+ border-radius: 0 14px 14px 0;
+}
+
+.form-search .input-prepend .btn {
+ -webkit-border-radius: 14px 0 0 14px;
+ -moz-border-radius: 14px 0 0 14px;
+ border-radius: 14px 0 0 14px;
+}
+
+.form-search input,
+.form-inline input,
+.form-horizontal input,
+.form-search textarea,
+.form-inline textarea,
+.form-horizontal textarea,
+.form-search select,
+.form-inline select,
+.form-horizontal select,
+.form-search .help-inline,
+.form-inline .help-inline,
+.form-horizontal .help-inline,
+.form-search .uneditable-input,
+.form-inline .uneditable-input,
+.form-horizontal .uneditable-input,
+.form-search .input-prepend,
+.form-inline .input-prepend,
+.form-horizontal .input-prepend,
+.form-search .input-append,
+.form-inline .input-append,
+.form-horizontal .input-append {
+ display: inline-block;
+ *display: inline;
+ margin-bottom: 0;
+ vertical-align: middle;
+ *zoom: 1;
+}
+
+.form-search .hide,
+.form-inline .hide,
+.form-horizontal .hide {
+ display: none;
+}
+
+.form-search label,
+.form-inline label,
+.form-search .btn-group,
+.form-inline .btn-group {
+ display: inline-block;
+}
+
+.form-search .input-append,
+.form-inline .input-append,
+.form-search .input-prepend,
+.form-inline .input-prepend {
+ margin-bottom: 0;
+}
+
+.form-search .radio,
+.form-search .checkbox,
+.form-inline .radio,
+.form-inline .checkbox {
+ padding-left: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+}
+
+.form-search .radio input[type="radio"],
+.form-search .checkbox input[type="checkbox"],
+.form-inline .radio input[type="radio"],
+.form-inline .checkbox input[type="checkbox"] {
+ float: left;
+ margin-right: 3px;
+ margin-left: 0;
+}
+
+.control-group {
+ margin-bottom: 10px;
+}
+
+legend + .control-group {
+ margin-top: 20px;
+ -webkit-margin-top-collapse: separate;
+}
+
+.form-horizontal .control-group {
+ margin-bottom: 20px;
+ *zoom: 1;
+}
+
+.form-horizontal .control-group:before,
+.form-horizontal .control-group:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.form-horizontal .control-group:after {
+ clear: both;
+}
+
+.form-horizontal .control-label {
+ float: left;
+ width: 160px;
+ padding-top: 5px;
+ text-align: right;
+}
+
+.form-horizontal .controls {
+ *display: inline-block;
+ *padding-left: 20px;
+ margin-left: 180px;
+ *margin-left: 0;
+}
+
+.form-horizontal .controls:first-child {
+ *padding-left: 180px;
+}
+
+.form-horizontal .help-block {
+ margin-bottom: 0;
+}
+
+.form-horizontal input + .help-block,
+.form-horizontal select + .help-block,
+.form-horizontal textarea + .help-block,
+.form-horizontal .uneditable-input + .help-block,
+.form-horizontal .input-prepend + .help-block,
+.form-horizontal .input-append + .help-block {
+ margin-top: 10px;
+}
+
+.form-horizontal .form-actions {
+ padding-left: 180px;
+}
+
+table {
+ max-width: 100%;
+ background-color: transparent;
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.table {
+ width: 100%;
+ margin-bottom: 20px;
+}
+
+.table th,
+.table td {
+ padding: 8px;
+ line-height: 20px;
+ text-align: left;
+ vertical-align: top;
+ border-top: 1px solid #dddddd;
+}
+
+.table th {
+ font-weight: bold;
+}
+
+.table thead th {
+ vertical-align: bottom;
+}
+
+.table caption + thead tr:first-child th,
+.table caption + thead tr:first-child td,
+.table colgroup + thead tr:first-child th,
+.table colgroup + thead tr:first-child td,
+.table thead:first-child tr:first-child th,
+.table thead:first-child tr:first-child td {
+ border-top: 0;
+}
+
+.table tbody + tbody {
+ border-top: 2px solid #dddddd;
+}
+
+.table .table {
+ background-color: #ffffff;
+}
+
+.table-condensed th,
+.table-condensed td {
+ padding: 4px 5px;
+}
+
+.table-bordered {
+ border: 1px solid #dddddd;
+ border-collapse: separate;
+ *border-collapse: collapse;
+ border-left: 0;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.table-bordered th,
+.table-bordered td {
+ border-left: 1px solid #dddddd;
+}
+
+.table-bordered caption + thead tr:first-child th,
+.table-bordered caption + tbody tr:first-child th,
+.table-bordered caption + tbody tr:first-child td,
+.table-bordered colgroup + thead tr:first-child th,
+.table-bordered colgroup + tbody tr:first-child th,
+.table-bordered colgroup + tbody tr:first-child td,
+.table-bordered thead:first-child tr:first-child th,
+.table-bordered tbody:first-child tr:first-child th,
+.table-bordered tbody:first-child tr:first-child td {
+ border-top: 0;
+}
+
+.table-bordered thead:first-child tr:first-child > th:first-child,
+.table-bordered tbody:first-child tr:first-child > td:first-child,
+.table-bordered tbody:first-child tr:first-child > th:first-child {
+ -webkit-border-top-left-radius: 4px;
+ border-top-left-radius: 4px;
+ -moz-border-radius-topleft: 4px;
+}
+
+.table-bordered thead:first-child tr:first-child > th:last-child,
+.table-bordered tbody:first-child tr:first-child > td:last-child,
+.table-bordered tbody:first-child tr:first-child > th:last-child {
+ -webkit-border-top-right-radius: 4px;
+ border-top-right-radius: 4px;
+ -moz-border-radius-topright: 4px;
+}
+
+.table-bordered thead:last-child tr:last-child > th:first-child,
+.table-bordered tbody:last-child tr:last-child > td:first-child,
+.table-bordered tbody:last-child tr:last-child > th:first-child,
+.table-bordered tfoot:last-child tr:last-child > td:first-child,
+.table-bordered tfoot:last-child tr:last-child > th:first-child {
+ -webkit-border-bottom-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+ -moz-border-radius-bottomleft: 4px;
+}
+
+.table-bordered thead:last-child tr:last-child > th:last-child,
+.table-bordered tbody:last-child tr:last-child > td:last-child,
+.table-bordered tbody:last-child tr:last-child > th:last-child,
+.table-bordered tfoot:last-child tr:last-child > td:last-child,
+.table-bordered tfoot:last-child tr:last-child > th:last-child {
+ -webkit-border-bottom-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+ -moz-border-radius-bottomright: 4px;
+}
+
+.table-bordered tfoot + tbody:last-child tr:last-child td:first-child {
+ -webkit-border-bottom-left-radius: 0;
+ border-bottom-left-radius: 0;
+ -moz-border-radius-bottomleft: 0;
+}
+
+.table-bordered tfoot + tbody:last-child tr:last-child td:last-child {
+ -webkit-border-bottom-right-radius: 0;
+ border-bottom-right-radius: 0;
+ -moz-border-radius-bottomright: 0;
+}
+
+.table-bordered caption + thead tr:first-child th:first-child,
+.table-bordered caption + tbody tr:first-child td:first-child,
+.table-bordered colgroup + thead tr:first-child th:first-child,
+.table-bordered colgroup + tbody tr:first-child td:first-child {
+ -webkit-border-top-left-radius: 4px;
+ border-top-left-radius: 4px;
+ -moz-border-radius-topleft: 4px;
+}
+
+.table-bordered caption + thead tr:first-child th:last-child,
+.table-bordered caption + tbody tr:first-child td:last-child,
+.table-bordered colgroup + thead tr:first-child th:last-child,
+.table-bordered colgroup + tbody tr:first-child td:last-child {
+ -webkit-border-top-right-radius: 4px;
+ border-top-right-radius: 4px;
+ -moz-border-radius-topright: 4px;
+}
+
+.table-striped tbody > tr:nth-child(odd) > td,
+.table-striped tbody > tr:nth-child(odd) > th {
+ background-color: #f9f9f9;
+}
+
+.table-hover tbody tr:hover > td,
+.table-hover tbody tr:hover > th {
+ background-color: #f5f5f5;
+}
+
+table td[class*="span"],
+table th[class*="span"],
+.row-fluid table td[class*="span"],
+.row-fluid table th[class*="span"] {
+ display: table-cell;
+ float: none;
+ margin-left: 0;
+}
+
+.table td.span1,
+.table th.span1 {
+ float: none;
+ width: 44px;
+ margin-left: 0;
+}
+
+.table td.span2,
+.table th.span2 {
+ float: none;
+ width: 124px;
+ margin-left: 0;
+}
+
+.table td.span3,
+.table th.span3 {
+ float: none;
+ width: 204px;
+ margin-left: 0;
+}
+
+.table td.span4,
+.table th.span4 {
+ float: none;
+ width: 284px;
+ margin-left: 0;
+}
+
+.table td.span5,
+.table th.span5 {
+ float: none;
+ width: 364px;
+ margin-left: 0;
+}
+
+.table td.span6,
+.table th.span6 {
+ float: none;
+ width: 444px;
+ margin-left: 0;
+}
+
+.table td.span7,
+.table th.span7 {
+ float: none;
+ width: 524px;
+ margin-left: 0;
+}
+
+.table td.span8,
+.table th.span8 {
+ float: none;
+ width: 604px;
+ margin-left: 0;
+}
+
+.table td.span9,
+.table th.span9 {
+ float: none;
+ width: 684px;
+ margin-left: 0;
+}
+
+.table td.span10,
+.table th.span10 {
+ float: none;
+ width: 764px;
+ margin-left: 0;
+}
+
+.table td.span11,
+.table th.span11 {
+ float: none;
+ width: 844px;
+ margin-left: 0;
+}
+
+.table td.span12,
+.table th.span12 {
+ float: none;
+ width: 924px;
+ margin-left: 0;
+}
+
+.table tbody tr.success > td {
+ background-color: #dff0d8;
+}
+
+.table tbody tr.error > td {
+ background-color: #f2dede;
+}
+
+.table tbody tr.warning > td {
+ background-color: #fcf8e3;
+}
+
+.table tbody tr.info > td {
+ background-color: #d9edf7;
+}
+
+.table-hover tbody tr.success:hover > td {
+ background-color: #d0e9c6;
+}
+
+.table-hover tbody tr.error:hover > td {
+ background-color: #ebcccc;
+}
+
+.table-hover tbody tr.warning:hover > td {
+ background-color: #faf2cc;
+}
+
+.table-hover tbody tr.info:hover > td {
+ background-color: #c4e3f3;
+}
+
+[class^="icon-"],
+[class*=" icon-"] {
+ display: inline-block;
+ width: 14px;
+ height: 14px;
+ margin-top: 1px;
+ *margin-right: .3em;
+ line-height: 14px;
+ vertical-align: text-top;
+ background-image: url("../img/glyphicons-halflings.png");
+ background-position: 14px 14px;
+ background-repeat: no-repeat;
+}
+
+/* White icons with optional class, or on hover/focus/active states of certain elements */
+
+.icon-white,
+.nav-pills > .active > a > [class^="icon-"],
+.nav-pills > .active > a > [class*=" icon-"],
+.nav-list > .active > a > [class^="icon-"],
+.nav-list > .active > a > [class*=" icon-"],
+.navbar-inverse .nav > .active > a > [class^="icon-"],
+.navbar-inverse .nav > .active > a > [class*=" icon-"],
+.dropdown-menu > li > a:hover > [class^="icon-"],
+.dropdown-menu > li > a:focus > [class^="icon-"],
+.dropdown-menu > li > a:hover > [class*=" icon-"],
+.dropdown-menu > li > a:focus > [class*=" icon-"],
+.dropdown-menu > .active > a > [class^="icon-"],
+.dropdown-menu > .active > a > [class*=" icon-"],
+.dropdown-submenu:hover > a > [class^="icon-"],
+.dropdown-submenu:focus > a > [class^="icon-"],
+.dropdown-submenu:hover > a > [class*=" icon-"],
+.dropdown-submenu:focus > a > [class*=" icon-"] {
+ background-image: url("../img/glyphicons-halflings-white.png");
+}
+
+.icon-glass {
+ background-position: 0 0;
+}
+
+.icon-music {
+ background-position: -24px 0;
+}
+
+.icon-search {
+ background-position: -48px 0;
+}
+
+.icon-envelope {
+ background-position: -72px 0;
+}
+
+.icon-heart {
+ background-position: -96px 0;
+}
+
+.icon-star {
+ background-position: -120px 0;
+}
+
+.icon-star-empty {
+ background-position: -144px 0;
+}
+
+.icon-user {
+ background-position: -168px 0;
+}
+
+.icon-film {
+ background-position: -192px 0;
+}
+
+.icon-th-large {
+ background-position: -216px 0;
+}
+
+.icon-th {
+ background-position: -240px 0;
+}
+
+.icon-th-list {
+ background-position: -264px 0;
+}
+
+.icon-ok {
+ background-position: -288px 0;
+}
+
+.icon-remove {
+ background-position: -312px 0;
+}
+
+.icon-zoom-in {
+ background-position: -336px 0;
+}
+
+.icon-zoom-out {
+ background-position: -360px 0;
+}
+
+.icon-off {
+ background-position: -384px 0;
+}
+
+.icon-signal {
+ background-position: -408px 0;
+}
+
+.icon-cog {
+ background-position: -432px 0;
+}
+
+.icon-trash {
+ background-position: -456px 0;
+}
+
+.icon-home {
+ background-position: 0 -24px;
+}
+
+.icon-file {
+ background-position: -24px -24px;
+}
+
+.icon-time {
+ background-position: -48px -24px;
+}
+
+.icon-road {
+ background-position: -72px -24px;
+}
+
+.icon-download-alt {
+ background-position: -96px -24px;
+}
+
+.icon-download {
+ background-position: -120px -24px;
+}
+
+.icon-upload {
+ background-position: -144px -24px;
+}
+
+.icon-inbox {
+ background-position: -168px -24px;
+}
+
+.icon-play-circle {
+ background-position: -192px -24px;
+}
+
+.icon-repeat {
+ background-position: -216px -24px;
+}
+
+.icon-refresh {
+ background-position: -240px -24px;
+}
+
+.icon-list-alt {
+ background-position: -264px -24px;
+}
+
+.icon-lock {
+ background-position: -287px -24px;
+}
+
+.icon-flag {
+ background-position: -312px -24px;
+}
+
+.icon-headphones {
+ background-position: -336px -24px;
+}
+
+.icon-volume-off {
+ background-position: -360px -24px;
+}
+
+.icon-volume-down {
+ background-position: -384px -24px;
+}
+
+.icon-volume-up {
+ background-position: -408px -24px;
+}
+
+.icon-qrcode {
+ background-position: -432px -24px;
+}
+
+.icon-barcode {
+ background-position: -456px -24px;
+}
+
+.icon-tag {
+ background-position: 0 -48px;
+}
+
+.icon-tags {
+ background-position: -25px -48px;
+}
+
+.icon-book {
+ background-position: -48px -48px;
+}
+
+.icon-bookmark {
+ background-position: -72px -48px;
+}
+
+.icon-print {
+ background-position: -96px -48px;
+}
+
+.icon-camera {
+ background-position: -120px -48px;
+}
+
+.icon-font {
+ background-position: -144px -48px;
+}
+
+.icon-bold {
+ background-position: -167px -48px;
+}
+
+.icon-italic {
+ background-position: -192px -48px;
+}
+
+.icon-text-height {
+ background-position: -216px -48px;
+}
+
+.icon-text-width {
+ background-position: -240px -48px;
+}
+
+.icon-align-left {
+ background-position: -264px -48px;
+}
+
+.icon-align-center {
+ background-position: -288px -48px;
+}
+
+.icon-align-right {
+ background-position: -312px -48px;
+}
+
+.icon-align-justify {
+ background-position: -336px -48px;
+}
+
+.icon-list {
+ background-position: -360px -48px;
+}
+
+.icon-indent-left {
+ background-position: -384px -48px;
+}
+
+.icon-indent-right {
+ background-position: -408px -48px;
+}
+
+.icon-facetime-video {
+ background-position: -432px -48px;
+}
+
+.icon-picture {
+ background-position: -456px -48px;
+}
+
+.icon-pencil {
+ background-position: 0 -72px;
+}
+
+.icon-map-marker {
+ background-position: -24px -72px;
+}
+
+.icon-adjust {
+ background-position: -48px -72px;
+}
+
+.icon-tint {
+ background-position: -72px -72px;
+}
+
+.icon-edit {
+ background-position: -96px -72px;
+}
+
+.icon-share {
+ background-position: -120px -72px;
+}
+
+.icon-check {
+ background-position: -144px -72px;
+}
+
+.icon-move {
+ background-position: -168px -72px;
+}
+
+.icon-step-backward {
+ background-position: -192px -72px;
+}
+
+.icon-fast-backward {
+ background-position: -216px -72px;
+}
+
+.icon-backward {
+ background-position: -240px -72px;
+}
+
+.icon-play {
+ background-position: -264px -72px;
+}
+
+.icon-pause {
+ background-position: -288px -72px;
+}
+
+.icon-stop {
+ background-position: -312px -72px;
+}
+
+.icon-forward {
+ background-position: -336px -72px;
+}
+
+.icon-fast-forward {
+ background-position: -360px -72px;
+}
+
+.icon-step-forward {
+ background-position: -384px -72px;
+}
+
+.icon-eject {
+ background-position: -408px -72px;
+}
+
+.icon-chevron-left {
+ background-position: -432px -72px;
+}
+
+.icon-chevron-right {
+ background-position: -456px -72px;
+}
+
+.icon-plus-sign {
+ background-position: 0 -96px;
+}
+
+.icon-minus-sign {
+ background-position: -24px -96px;
+}
+
+.icon-remove-sign {
+ background-position: -48px -96px;
+}
+
+.icon-ok-sign {
+ background-position: -72px -96px;
+}
+
+.icon-question-sign {
+ background-position: -96px -96px;
+}
+
+.icon-info-sign {
+ background-position: -120px -96px;
+}
+
+.icon-screenshot {
+ background-position: -144px -96px;
+}
+
+.icon-remove-circle {
+ background-position: -168px -96px;
+}
+
+.icon-ok-circle {
+ background-position: -192px -96px;
+}
+
+.icon-ban-circle {
+ background-position: -216px -96px;
+}
+
+.icon-arrow-left {
+ background-position: -240px -96px;
+}
+
+.icon-arrow-right {
+ background-position: -264px -96px;
+}
+
+.icon-arrow-up {
+ background-position: -289px -96px;
+}
+
+.icon-arrow-down {
+ background-position: -312px -96px;
+}
+
+.icon-share-alt {
+ background-position: -336px -96px;
+}
+
+.icon-resize-full {
+ background-position: -360px -96px;
+}
+
+.icon-resize-small {
+ background-position: -384px -96px;
+}
+
+.icon-plus {
+ background-position: -408px -96px;
+}
+
+.icon-minus {
+ background-position: -433px -96px;
+}
+
+.icon-asterisk {
+ background-position: -456px -96px;
+}
+
+.icon-exclamation-sign {
+ background-position: 0 -120px;
+}
+
+.icon-gift {
+ background-position: -24px -120px;
+}
+
+.icon-leaf {
+ background-position: -48px -120px;
+}
+
+.icon-fire {
+ background-position: -72px -120px;
+}
+
+.icon-eye-open {
+ background-position: -96px -120px;
+}
+
+.icon-eye-close {
+ background-position: -120px -120px;
+}
+
+.icon-warning-sign {
+ background-position: -144px -120px;
+}
+
+.icon-plane {
+ background-position: -168px -120px;
+}
+
+.icon-calendar {
+ background-position: -192px -120px;
+}
+
+.icon-random {
+ width: 16px;
+ background-position: -216px -120px;
+}
+
+.icon-comment {
+ background-position: -240px -120px;
+}
+
+.icon-magnet {
+ background-position: -264px -120px;
+}
+
+.icon-chevron-up {
+ background-position: -288px -120px;
+}
+
+.icon-chevron-down {
+ background-position: -313px -119px;
+}
+
+.icon-retweet {
+ background-position: -336px -120px;
+}
+
+.icon-shopping-cart {
+ background-position: -360px -120px;
+}
+
+.icon-folder-close {
+ width: 16px;
+ background-position: -384px -120px;
+}
+
+.icon-folder-open {
+ width: 16px;
+ background-position: -408px -120px;
+}
+
+.icon-resize-vertical {
+ background-position: -432px -119px;
+}
+
+.icon-resize-horizontal {
+ background-position: -456px -118px;
+}
+
+.icon-hdd {
+ background-position: 0 -144px;
+}
+
+.icon-bullhorn {
+ background-position: -24px -144px;
+}
+
+.icon-bell {
+ background-position: -48px -144px;
+}
+
+.icon-certificate {
+ background-position: -72px -144px;
+}
+
+.icon-thumbs-up {
+ background-position: -96px -144px;
+}
+
+.icon-thumbs-down {
+ background-position: -120px -144px;
+}
+
+.icon-hand-right {
+ background-position: -144px -144px;
+}
+
+.icon-hand-left {
+ background-position: -168px -144px;
+}
+
+.icon-hand-up {
+ background-position: -192px -144px;
+}
+
+.icon-hand-down {
+ background-position: -216px -144px;
+}
+
+.icon-circle-arrow-right {
+ background-position: -240px -144px;
+}
+
+.icon-circle-arrow-left {
+ background-position: -264px -144px;
+}
+
+.icon-circle-arrow-up {
+ background-position: -288px -144px;
+}
+
+.icon-circle-arrow-down {
+ background-position: -312px -144px;
+}
+
+.icon-globe {
+ background-position: -336px -144px;
+}
+
+.icon-wrench {
+ background-position: -360px -144px;
+}
+
+.icon-tasks {
+ background-position: -384px -144px;
+}
+
+.icon-filter {
+ background-position: -408px -144px;
+}
+
+.icon-briefcase {
+ background-position: -432px -144px;
+}
+
+.icon-fullscreen {
+ background-position: -456px -144px;
+}
+
+.dropup,
+.dropdown {
+ position: relative;
+}
+
+.dropdown-toggle {
+ *margin-bottom: -3px;
+}
+
+.dropdown-toggle:active,
+.open .dropdown-toggle {
+ outline: 0;
+}
+
+.caret {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ vertical-align: top;
+ border-top: 4px solid #000000;
+ border-right: 4px solid transparent;
+ border-left: 4px solid transparent;
+ content: "";
+}
+
+.dropdown .caret {
+ margin-top: 8px;
+ margin-left: 2px;
+}
+
+.dropdown-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: 1000;
+ display: none;
+ float: left;
+ min-width: 160px;
+ padding: 5px 0;
+ margin: 2px 0 0;
+ list-style: none;
+ background-color: #ffffff;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ *border-right-width: 2px;
+ *border-bottom-width: 2px;
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+ -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ -webkit-background-clip: padding-box;
+ -moz-background-clip: padding;
+ background-clip: padding-box;
+}
+
+.dropdown-menu.pull-right {
+ right: 0;
+ left: auto;
+}
+
+.dropdown-menu .divider {
+ *width: 100%;
+ height: 1px;
+ margin: 9px 1px;
+ *margin: -5px 0 5px;
+ overflow: hidden;
+ background-color: #e5e5e5;
+ border-bottom: 1px solid #ffffff;
+}
+
+.dropdown-menu > li > a {
+ display: block;
+ padding: 3px 20px;
+ clear: both;
+ font-weight: normal;
+ line-height: 20px;
+ color: #333333;
+ white-space: nowrap;
+}
+
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > a:focus,
+.dropdown-submenu:hover > a,
+.dropdown-submenu:focus > a {
+ color: #ffffff;
+ text-decoration: none;
+ background-color: #0081c2;
+ background-image: -moz-linear-gradient(top, #0088cc, #0077b3);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));
+ background-image: -webkit-linear-gradient(top, #0088cc, #0077b3);
+ background-image: -o-linear-gradient(top, #0088cc, #0077b3);
+ background-image: linear-gradient(to bottom, #0088cc, #0077b3);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);
+}
+
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus {
+ color: #ffffff;
+ text-decoration: none;
+ background-color: #0081c2;
+ background-image: -moz-linear-gradient(top, #0088cc, #0077b3);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));
+ background-image: -webkit-linear-gradient(top, #0088cc, #0077b3);
+ background-image: -o-linear-gradient(top, #0088cc, #0077b3);
+ background-image: linear-gradient(to bottom, #0088cc, #0077b3);
+ background-repeat: repeat-x;
+ outline: 0;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);
+}
+
+.dropdown-menu > .disabled > a,
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ color: #999999;
+}
+
+.dropdown-menu > .disabled > a:hover,
+.dropdown-menu > .disabled > a:focus {
+ text-decoration: none;
+ cursor: default;
+ background-color: transparent;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+
+.open {
+ *z-index: 1000;
+}
+
+.open > .dropdown-menu {
+ display: block;
+}
+
+.dropdown-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 990;
+}
+
+.pull-right > .dropdown-menu {
+ right: 0;
+ left: auto;
+}
+
+.dropup .caret,
+.navbar-fixed-bottom .dropdown .caret {
+ border-top: 0;
+ border-bottom: 4px solid #000000;
+ content: "";
+}
+
+.dropup .dropdown-menu,
+.navbar-fixed-bottom .dropdown .dropdown-menu {
+ top: auto;
+ bottom: 100%;
+ margin-bottom: 1px;
+}
+
+.dropdown-submenu {
+ position: relative;
+}
+
+.dropdown-submenu > .dropdown-menu {
+ top: 0;
+ left: 100%;
+ margin-top: -6px;
+ margin-left: -1px;
+ -webkit-border-radius: 0 6px 6px 6px;
+ -moz-border-radius: 0 6px 6px 6px;
+ border-radius: 0 6px 6px 6px;
+}
+
+.dropdown-submenu:hover > .dropdown-menu {
+ display: block;
+}
+
+.dropup .dropdown-submenu > .dropdown-menu {
+ top: auto;
+ bottom: 0;
+ margin-top: 0;
+ margin-bottom: -2px;
+ -webkit-border-radius: 5px 5px 5px 0;
+ -moz-border-radius: 5px 5px 5px 0;
+ border-radius: 5px 5px 5px 0;
+}
+
+.dropdown-submenu > a:after {
+ display: block;
+ float: right;
+ width: 0;
+ height: 0;
+ margin-top: 5px;
+ margin-right: -10px;
+ border-color: transparent;
+ border-left-color: #cccccc;
+ border-style: solid;
+ border-width: 5px 0 5px 5px;
+ content: " ";
+}
+
+.dropdown-submenu:hover > a:after {
+ border-left-color: #ffffff;
+}
+
+.dropdown-submenu.pull-left {
+ float: none;
+}
+
+.dropdown-submenu.pull-left > .dropdown-menu {
+ left: -100%;
+ margin-left: 10px;
+ -webkit-border-radius: 6px 0 6px 6px;
+ -moz-border-radius: 6px 0 6px 6px;
+ border-radius: 6px 0 6px 6px;
+}
+
+.dropdown .dropdown-menu .nav-header {
+ padding-right: 20px;
+ padding-left: 20px;
+}
+
+.typeahead {
+ z-index: 1051;
+ margin-top: 2px;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.well {
+ min-height: 20px;
+ padding: 19px;
+ margin-bottom: 20px;
+ background-color: #f5f5f5;
+ border: 1px solid #e3e3e3;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
+}
+
+.well blockquote {
+ border-color: #ddd;
+ border-color: rgba(0, 0, 0, 0.15);
+}
+
+.well-large {
+ padding: 24px;
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+}
+
+.well-small {
+ padding: 9px;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+
+.fade {
+ opacity: 0;
+ -webkit-transition: opacity 0.15s linear;
+ -moz-transition: opacity 0.15s linear;
+ -o-transition: opacity 0.15s linear;
+ transition: opacity 0.15s linear;
+}
+
+.fade.in {
+ opacity: 1;
+}
+
+.collapse {
+ position: relative;
+ height: 0;
+ overflow: hidden;
+ -webkit-transition: height 0.35s ease;
+ -moz-transition: height 0.35s ease;
+ -o-transition: height 0.35s ease;
+ transition: height 0.35s ease;
+}
+
+.collapse.in {
+ height: auto;
+}
+
+.close {
+ float: right;
+ font-size: 20px;
+ font-weight: bold;
+ line-height: 20px;
+ color: #000000;
+ text-shadow: 0 1px 0 #ffffff;
+ opacity: 0.2;
+ filter: alpha(opacity=20);
+}
+
+.close:hover,
+.close:focus {
+ color: #000000;
+ text-decoration: none;
+ cursor: pointer;
+ opacity: 0.4;
+ filter: alpha(opacity=40);
+}
+
+button.close {
+ padding: 0;
+ cursor: pointer;
+ background: transparent;
+ border: 0;
+ -webkit-appearance: none;
+}
+
+.btn {
+ display: inline-block;
+ *display: inline;
+ padding: 4px 12px;
+ margin-bottom: 0;
+ *margin-left: .3em;
+ font-size: 14px;
+ line-height: 20px;
+ color: #333333;
+ text-align: center;
+ text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
+ vertical-align: middle;
+ cursor: pointer;
+ background-color: #f5f5f5;
+ *background-color: #e6e6e6;
+ background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));
+ background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
+ background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
+ background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
+ background-repeat: repeat-x;
+ border: 1px solid #cccccc;
+ *border: 0;
+ border-color: #e6e6e6 #e6e6e6 #bfbfbf;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ border-bottom-color: #b3b3b3;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ *zoom: 1;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+}
+
+.btn:hover,
+.btn:focus,
+.btn:active,
+.btn.active,
+.btn.disabled,
+.btn[disabled] {
+ color: #333333;
+ background-color: #e6e6e6;
+ *background-color: #d9d9d9;
+}
+
+.btn:active,
+.btn.active {
+ background-color: #cccccc \9;
+}
+
+.btn:first-child {
+ *margin-left: 0;
+}
+
+.btn:hover,
+.btn:focus {
+ color: #333333;
+ text-decoration: none;
+ background-position: 0 -15px;
+ -webkit-transition: background-position 0.1s linear;
+ -moz-transition: background-position 0.1s linear;
+ -o-transition: background-position 0.1s linear;
+ transition: background-position 0.1s linear;
+}
+
+.btn:focus {
+ outline: thin dotted #333;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
+.btn.active,
+.btn:active {
+ background-image: none;
+ outline: 0;
+ -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+}
+
+.btn.disabled,
+.btn[disabled] {
+ cursor: default;
+ background-image: none;
+ opacity: 0.65;
+ filter: alpha(opacity=65);
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+}
+
+.btn-large {
+ padding: 11px 19px;
+ font-size: 17.5px;
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+}
+
+.btn-large [class^="icon-"],
+.btn-large [class*=" icon-"] {
+ margin-top: 4px;
+}
+
+.btn-small {
+ padding: 2px 10px;
+ font-size: 11.9px;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+
+.btn-small [class^="icon-"],
+.btn-small [class*=" icon-"] {
+ margin-top: 0;
+}
+
+.btn-mini [class^="icon-"],
+.btn-mini [class*=" icon-"] {
+ margin-top: -1px;
+}
+
+.btn-mini {
+ padding: 0 6px;
+ font-size: 10.5px;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+
+.btn-block {
+ display: block;
+ width: 100%;
+ padding-right: 0;
+ padding-left: 0;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+.btn-block + .btn-block {
+ margin-top: 5px;
+}
+
+input[type="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].btn-block {
+ width: 100%;
+}
+
+.btn-primary.active,
+.btn-warning.active,
+.btn-danger.active,
+.btn-success.active,
+.btn-info.active,
+.btn-inverse.active {
+ color: rgba(255, 255, 255, 0.75);
+}
+
+.btn-primary {
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ background-color: #006dcc;
+ *background-color: #0044cc;
+ background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
+ background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
+ background-image: -o-linear-gradient(top, #0088cc, #0044cc);
+ background-image: linear-gradient(to bottom, #0088cc, #0044cc);
+ background-repeat: repeat-x;
+ border-color: #0044cc #0044cc #002a80;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+
+.btn-primary:hover,
+.btn-primary:focus,
+.btn-primary:active,
+.btn-primary.active,
+.btn-primary.disabled,
+.btn-primary[disabled] {
+ color: #ffffff;
+ background-color: #0044cc;
+ *background-color: #003bb3;
+}
+
+.btn-primary:active,
+.btn-primary.active {
+ background-color: #003399 \9;
+}
+
+.btn-warning {
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ background-color: #faa732;
+ *background-color: #f89406;
+ background-image: -moz-linear-gradient(top, #fbb450, #f89406);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));
+ background-image: -webkit-linear-gradient(top, #fbb450, #f89406);
+ background-image: -o-linear-gradient(top, #fbb450, #f89406);
+ background-image: linear-gradient(to bottom, #fbb450, #f89406);
+ background-repeat: repeat-x;
+ border-color: #f89406 #f89406 #ad6704;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+
+.btn-warning:hover,
+.btn-warning:focus,
+.btn-warning:active,
+.btn-warning.active,
+.btn-warning.disabled,
+.btn-warning[disabled] {
+ color: #ffffff;
+ background-color: #f89406;
+ *background-color: #df8505;
+}
+
+.btn-warning:active,
+.btn-warning.active {
+ background-color: #c67605 \9;
+}
+
+.btn-danger {
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ background-color: #da4f49;
+ *background-color: #bd362f;
+ background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));
+ background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f);
+ background-image: -o-linear-gradient(top, #ee5f5b, #bd362f);
+ background-image: linear-gradient(to bottom, #ee5f5b, #bd362f);
+ background-repeat: repeat-x;
+ border-color: #bd362f #bd362f #802420;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+
+.btn-danger:hover,
+.btn-danger:focus,
+.btn-danger:active,
+.btn-danger.active,
+.btn-danger.disabled,
+.btn-danger[disabled] {
+ color: #ffffff;
+ background-color: #bd362f;
+ *background-color: #a9302a;
+}
+
+.btn-danger:active,
+.btn-danger.active {
+ background-color: #942a25 \9;
+}
+
+.btn-success {
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ background-color: #5bb75b;
+ *background-color: #51a351;
+ background-image: -moz-linear-gradient(top, #62c462, #51a351);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));
+ background-image: -webkit-linear-gradient(top, #62c462, #51a351);
+ background-image: -o-linear-gradient(top, #62c462, #51a351);
+ background-image: linear-gradient(to bottom, #62c462, #51a351);
+ background-repeat: repeat-x;
+ border-color: #51a351 #51a351 #387038;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+
+.btn-success:hover,
+.btn-success:focus,
+.btn-success:active,
+.btn-success.active,
+.btn-success.disabled,
+.btn-success[disabled] {
+ color: #ffffff;
+ background-color: #51a351;
+ *background-color: #499249;
+}
+
+.btn-success:active,
+.btn-success.active {
+ background-color: #408140 \9;
+}
+
+.btn-info {
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ background-color: #49afcd;
+ *background-color: #2f96b4;
+ background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));
+ background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4);
+ background-image: -o-linear-gradient(top, #5bc0de, #2f96b4);
+ background-image: linear-gradient(to bottom, #5bc0de, #2f96b4);
+ background-repeat: repeat-x;
+ border-color: #2f96b4 #2f96b4 #1f6377;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+
+.btn-info:hover,
+.btn-info:focus,
+.btn-info:active,
+.btn-info.active,
+.btn-info.disabled,
+.btn-info[disabled] {
+ color: #ffffff;
+ background-color: #2f96b4;
+ *background-color: #2a85a0;
+}
+
+.btn-info:active,
+.btn-info.active {
+ background-color: #24748c \9;
+}
+
+.btn-inverse {
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ background-color: #363636;
+ *background-color: #222222;
+ background-image: -moz-linear-gradient(top, #444444, #222222);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222));
+ background-image: -webkit-linear-gradient(top, #444444, #222222);
+ background-image: -o-linear-gradient(top, #444444, #222222);
+ background-image: linear-gradient(to bottom, #444444, #222222);
+ background-repeat: repeat-x;
+ border-color: #222222 #222222 #000000;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+
+.btn-inverse:hover,
+.btn-inverse:focus,
+.btn-inverse:active,
+.btn-inverse.active,
+.btn-inverse.disabled,
+.btn-inverse[disabled] {
+ color: #ffffff;
+ background-color: #222222;
+ *background-color: #151515;
+}
+
+.btn-inverse:active,
+.btn-inverse.active {
+ background-color: #080808 \9;
+}
+
+button.btn,
+input[type="submit"].btn {
+ *padding-top: 3px;
+ *padding-bottom: 3px;
+}
+
+button.btn::-moz-focus-inner,
+input[type="submit"].btn::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+}
+
+button.btn.btn-large,
+input[type="submit"].btn.btn-large {
+ *padding-top: 7px;
+ *padding-bottom: 7px;
+}
+
+button.btn.btn-small,
+input[type="submit"].btn.btn-small {
+ *padding-top: 3px;
+ *padding-bottom: 3px;
+}
+
+button.btn.btn-mini,
+input[type="submit"].btn.btn-mini {
+ *padding-top: 1px;
+ *padding-bottom: 1px;
+}
+
+.btn-link,
+.btn-link:active,
+.btn-link[disabled] {
+ background-color: transparent;
+ background-image: none;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+}
+
+.btn-link {
+ color: #0088cc;
+ cursor: pointer;
+ border-color: transparent;
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+}
+
+.btn-link:hover,
+.btn-link:focus {
+ color: #005580;
+ text-decoration: underline;
+ background-color: transparent;
+}
+
+.btn-link[disabled]:hover,
+.btn-link[disabled]:focus {
+ color: #333333;
+ text-decoration: none;
+}
+
+.btn-group {
+ position: relative;
+ display: inline-block;
+ *display: inline;
+ *margin-left: .3em;
+ font-size: 0;
+ white-space: nowrap;
+ vertical-align: middle;
+ *zoom: 1;
+}
+
+.btn-group:first-child {
+ *margin-left: 0;
+}
+
+.btn-group + .btn-group {
+ margin-left: 5px;
+}
+
+.btn-toolbar {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ font-size: 0;
+}
+
+.btn-toolbar > .btn + .btn,
+.btn-toolbar > .btn-group + .btn,
+.btn-toolbar > .btn + .btn-group {
+ margin-left: 5px;
+}
+
+.btn-group > .btn {
+ position: relative;
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+}
+
+.btn-group > .btn + .btn {
+ margin-left: -1px;
+}
+
+.btn-group > .btn,
+.btn-group > .dropdown-menu,
+.btn-group > .popover {
+ font-size: 14px;
+}
+
+.btn-group > .btn-mini {
+ font-size: 10.5px;
+}
+
+.btn-group > .btn-small {
+ font-size: 11.9px;
+}
+
+.btn-group > .btn-large {
+ font-size: 17.5px;
+}
+
+.btn-group > .btn:first-child {
+ margin-left: 0;
+ -webkit-border-bottom-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+ -webkit-border-top-left-radius: 4px;
+ border-top-left-radius: 4px;
+ -moz-border-radius-bottomleft: 4px;
+ -moz-border-radius-topleft: 4px;
+}
+
+.btn-group > .btn:last-child,
+.btn-group > .dropdown-toggle {
+ -webkit-border-top-right-radius: 4px;
+ border-top-right-radius: 4px;
+ -webkit-border-bottom-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+ -moz-border-radius-topright: 4px;
+ -moz-border-radius-bottomright: 4px;
+}
+
+.btn-group > .btn.large:first-child {
+ margin-left: 0;
+ -webkit-border-bottom-left-radius: 6px;
+ border-bottom-left-radius: 6px;
+ -webkit-border-top-left-radius: 6px;
+ border-top-left-radius: 6px;
+ -moz-border-radius-bottomleft: 6px;
+ -moz-border-radius-topleft: 6px;
+}
+
+.btn-group > .btn.large:last-child,
+.btn-group > .large.dropdown-toggle {
+ -webkit-border-top-right-radius: 6px;
+ border-top-right-radius: 6px;
+ -webkit-border-bottom-right-radius: 6px;
+ border-bottom-right-radius: 6px;
+ -moz-border-radius-topright: 6px;
+ -moz-border-radius-bottomright: 6px;
+}
+
+.btn-group > .btn:hover,
+.btn-group > .btn:focus,
+.btn-group > .btn:active,
+.btn-group > .btn.active {
+ z-index: 2;
+}
+
+.btn-group .dropdown-toggle:active,
+.btn-group.open .dropdown-toggle {
+ outline: 0;
+}
+
+.btn-group > .btn + .dropdown-toggle {
+ *padding-top: 5px;
+ padding-right: 8px;
+ *padding-bottom: 5px;
+ padding-left: 8px;
+ -webkit-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+}
+
+.btn-group > .btn-mini + .dropdown-toggle {
+ *padding-top: 2px;
+ padding-right: 5px;
+ *padding-bottom: 2px;
+ padding-left: 5px;
+}
+
+.btn-group > .btn-small + .dropdown-toggle {
+ *padding-top: 5px;
+ *padding-bottom: 4px;
+}
+
+.btn-group > .btn-large + .dropdown-toggle {
+ *padding-top: 7px;
+ padding-right: 12px;
+ *padding-bottom: 7px;
+ padding-left: 12px;
+}
+
+.btn-group.open .dropdown-toggle {
+ background-image: none;
+ -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+}
+
+.btn-group.open .btn.dropdown-toggle {
+ background-color: #e6e6e6;
+}
+
+.btn-group.open .btn-primary.dropdown-toggle {
+ background-color: #0044cc;
+}
+
+.btn-group.open .btn-warning.dropdown-toggle {
+ background-color: #f89406;
+}
+
+.btn-group.open .btn-danger.dropdown-toggle {
+ background-color: #bd362f;
+}
+
+.btn-group.open .btn-success.dropdown-toggle {
+ background-color: #51a351;
+}
+
+.btn-group.open .btn-info.dropdown-toggle {
+ background-color: #2f96b4;
+}
+
+.btn-group.open .btn-inverse.dropdown-toggle {
+ background-color: #222222;
+}
+
+.btn .caret {
+ margin-top: 8px;
+ margin-left: 0;
+}
+
+.btn-large .caret {
+ margin-top: 6px;
+}
+
+.btn-large .caret {
+ border-top-width: 5px;
+ border-right-width: 5px;
+ border-left-width: 5px;
+}
+
+.btn-mini .caret,
+.btn-small .caret {
+ margin-top: 8px;
+}
+
+.dropup .btn-large .caret {
+ border-bottom-width: 5px;
+}
+
+.btn-primary .caret,
+.btn-warning .caret,
+.btn-danger .caret,
+.btn-info .caret,
+.btn-success .caret,
+.btn-inverse .caret {
+ border-top-color: #ffffff;
+ border-bottom-color: #ffffff;
+}
+
+.btn-group-vertical {
+ display: inline-block;
+ *display: inline;
+ /* IE7 inline-block hack */
+
+ *zoom: 1;
+}
+
+.btn-group-vertical > .btn {
+ display: block;
+ float: none;
+ max-width: 100%;
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+}
+
+.btn-group-vertical > .btn + .btn {
+ margin-top: -1px;
+ margin-left: 0;
+}
+
+.btn-group-vertical > .btn:first-child {
+ -webkit-border-radius: 4px 4px 0 0;
+ -moz-border-radius: 4px 4px 0 0;
+ border-radius: 4px 4px 0 0;
+}
+
+.btn-group-vertical > .btn:last-child {
+ -webkit-border-radius: 0 0 4px 4px;
+ -moz-border-radius: 0 0 4px 4px;
+ border-radius: 0 0 4px 4px;
+}
+
+.btn-group-vertical > .btn-large:first-child {
+ -webkit-border-radius: 6px 6px 0 0;
+ -moz-border-radius: 6px 6px 0 0;
+ border-radius: 6px 6px 0 0;
+}
+
+.btn-group-vertical > .btn-large:last-child {
+ -webkit-border-radius: 0 0 6px 6px;
+ -moz-border-radius: 0 0 6px 6px;
+ border-radius: 0 0 6px 6px;
+}
+
+.alert {
+ padding: 8px 35px 8px 14px;
+ margin-bottom: 20px;
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
+ background-color: #fcf8e3;
+ border: 1px solid #fbeed5;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.alert,
+.alert h4 {
+ color: #c09853;
+}
+
+.alert h4 {
+ margin: 0;
+}
+
+.alert .close {
+ position: relative;
+ top: -2px;
+ right: -21px;
+ line-height: 20px;
+}
+
+.alert-success {
+ color: #468847;
+ background-color: #dff0d8;
+ border-color: #d6e9c6;
+}
+
+.alert-success h4 {
+ color: #468847;
+}
+
+.alert-danger,
+.alert-error {
+ color: #b94a48;
+ background-color: #f2dede;
+ border-color: #eed3d7;
+}
+
+.alert-danger h4,
+.alert-error h4 {
+ color: #b94a48;
+}
+
+.alert-info {
+ color: #3a87ad;
+ background-color: #d9edf7;
+ border-color: #bce8f1;
+}
+
+.alert-info h4 {
+ color: #3a87ad;
+}
+
+.alert-block {
+ padding-top: 14px;
+ padding-bottom: 14px;
+}
+
+.alert-block > p,
+.alert-block > ul {
+ margin-bottom: 0;
+}
+
+.alert-block p + p {
+ margin-top: 5px;
+}
+
+.nav {
+ margin-bottom: 20px;
+ margin-left: 0;
+ list-style: none;
+}
+
+.nav > li > a {
+ display: block;
+}
+
+.nav > li > a:hover,
+.nav > li > a:focus {
+ text-decoration: none;
+ background-color: #eeeeee;
+}
+
+.nav > li > a > img {
+ max-width: none;
+}
+
+.nav > .pull-right {
+ float: right;
+}
+
+.nav-header {
+ display: block;
+ padding: 3px 15px;
+ font-size: 11px;
+ font-weight: bold;
+ line-height: 20px;
+ color: #999999;
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
+ text-transform: uppercase;
+}
+
+.nav li + .nav-header {
+ margin-top: 9px;
+}
+
+.nav-list {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-bottom: 0;
+}
+
+.nav-list > li > a,
+.nav-list .nav-header {
+ margin-right: -15px;
+ margin-left: -15px;
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
+}
+
+.nav-list > li > a {
+ padding: 3px 15px;
+}
+
+.nav-list > .active > a,
+.nav-list > .active > a:hover,
+.nav-list > .active > a:focus {
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);
+ background-color: #0088cc;
+}
+
+.nav-list [class^="icon-"],
+.nav-list [class*=" icon-"] {
+ margin-right: 2px;
+}
+
+.nav-list .divider {
+ *width: 100%;
+ height: 1px;
+ margin: 9px 1px;
+ *margin: -5px 0 5px;
+ overflow: hidden;
+ background-color: #e5e5e5;
+ border-bottom: 1px solid #ffffff;
+}
+
+.nav-tabs,
+.nav-pills {
+ *zoom: 1;
+}
+
+.nav-tabs:before,
+.nav-pills:before,
+.nav-tabs:after,
+.nav-pills:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.nav-tabs:after,
+.nav-pills:after {
+ clear: both;
+}
+
+.nav-tabs > li,
+.nav-pills > li {
+ float: left;
+}
+
+.nav-tabs > li > a,
+.nav-pills > li > a {
+ padding-right: 12px;
+ padding-left: 12px;
+ margin-right: 2px;
+ line-height: 14px;
+}
+
+.nav-tabs {
+ border-bottom: 1px solid #ddd;
+}
+
+.nav-tabs > li {
+ margin-bottom: -1px;
+}
+
+.nav-tabs > li > a {
+ padding-top: 8px;
+ padding-bottom: 8px;
+ line-height: 20px;
+ border: 1px solid transparent;
+ -webkit-border-radius: 4px 4px 0 0;
+ -moz-border-radius: 4px 4px 0 0;
+ border-radius: 4px 4px 0 0;
+}
+
+.nav-tabs > li > a:hover,
+.nav-tabs > li > a:focus {
+ border-color: #eeeeee #eeeeee #dddddd;
+}
+
+.nav-tabs > .active > a,
+.nav-tabs > .active > a:hover,
+.nav-tabs > .active > a:focus {
+ color: #555555;
+ cursor: default;
+ background-color: #ffffff;
+ border: 1px solid #ddd;
+ border-bottom-color: transparent;
+}
+
+.nav-pills > li > a {
+ padding-top: 8px;
+ padding-bottom: 8px;
+ margin-top: 2px;
+ margin-bottom: 2px;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+}
+
+.nav-pills > .active > a,
+.nav-pills > .active > a:hover,
+.nav-pills > .active > a:focus {
+ color: #ffffff;
+ background-color: #0088cc;
+}
+
+.nav-stacked > li {
+ float: none;
+}
+
+.nav-stacked > li > a {
+ margin-right: 0;
+}
+
+.nav-tabs.nav-stacked {
+ border-bottom: 0;
+}
+
+.nav-tabs.nav-stacked > li > a {
+ border: 1px solid #ddd;
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+}
+
+.nav-tabs.nav-stacked > li:first-child > a {
+ -webkit-border-top-right-radius: 4px;
+ border-top-right-radius: 4px;
+ -webkit-border-top-left-radius: 4px;
+ border-top-left-radius: 4px;
+ -moz-border-radius-topright: 4px;
+ -moz-border-radius-topleft: 4px;
+}
+
+.nav-tabs.nav-stacked > li:last-child > a {
+ -webkit-border-bottom-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+ -webkit-border-bottom-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+ -moz-border-radius-bottomright: 4px;
+ -moz-border-radius-bottomleft: 4px;
+}
+
+.nav-tabs.nav-stacked > li > a:hover,
+.nav-tabs.nav-stacked > li > a:focus {
+ z-index: 2;
+ border-color: #ddd;
+}
+
+.nav-pills.nav-stacked > li > a {
+ margin-bottom: 3px;
+}
+
+.nav-pills.nav-stacked > li:last-child > a {
+ margin-bottom: 1px;
+}
+
+.nav-tabs .dropdown-menu {
+ -webkit-border-radius: 0 0 6px 6px;
+ -moz-border-radius: 0 0 6px 6px;
+ border-radius: 0 0 6px 6px;
+}
+
+.nav-pills .dropdown-menu {
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+}
+
+.nav .dropdown-toggle .caret {
+ margin-top: 6px;
+ border-top-color: #0088cc;
+ border-bottom-color: #0088cc;
+}
+
+.nav .dropdown-toggle:hover .caret,
+.nav .dropdown-toggle:focus .caret {
+ border-top-color: #005580;
+ border-bottom-color: #005580;
+}
+
+/* move down carets for tabs */
+
+.nav-tabs .dropdown-toggle .caret {
+ margin-top: 8px;
+}
+
+.nav .active .dropdown-toggle .caret {
+ border-top-color: #fff;
+ border-bottom-color: #fff;
+}
+
+.nav-tabs .active .dropdown-toggle .caret {
+ border-top-color: #555555;
+ border-bottom-color: #555555;
+}
+
+.nav > .dropdown.active > a:hover,
+.nav > .dropdown.active > a:focus {
+ cursor: pointer;
+}
+
+.nav-tabs .open .dropdown-toggle,
+.nav-pills .open .dropdown-toggle,
+.nav > li.dropdown.open.active > a:hover,
+.nav > li.dropdown.open.active > a:focus {
+ color: #ffffff;
+ background-color: #999999;
+ border-color: #999999;
+}
+
+.nav li.dropdown.open .caret,
+.nav li.dropdown.open.active .caret,
+.nav li.dropdown.open a:hover .caret,
+.nav li.dropdown.open a:focus .caret {
+ border-top-color: #ffffff;
+ border-bottom-color: #ffffff;
+ opacity: 1;
+ filter: alpha(opacity=100);
+}
+
+.tabs-stacked .open > a:hover,
+.tabs-stacked .open > a:focus {
+ border-color: #999999;
+}
+
+.tabbable {
+ *zoom: 1;
+}
+
+.tabbable:before,
+.tabbable:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.tabbable:after {
+ clear: both;
+}
+
+.tab-content {
+ overflow: auto;
+}
+
+.tabs-below > .nav-tabs,
+.tabs-right > .nav-tabs,
+.tabs-left > .nav-tabs {
+ border-bottom: 0;
+}
+
+.tab-content > .tab-pane,
+.pill-content > .pill-pane {
+ display: none;
+}
+
+.tab-content > .active,
+.pill-content > .active {
+ display: block;
+}
+
+.tabs-below > .nav-tabs {
+ border-top: 1px solid #ddd;
+}
+
+.tabs-below > .nav-tabs > li {
+ margin-top: -1px;
+ margin-bottom: 0;
+}
+
+.tabs-below > .nav-tabs > li > a {
+ -webkit-border-radius: 0 0 4px 4px;
+ -moz-border-radius: 0 0 4px 4px;
+ border-radius: 0 0 4px 4px;
+}
+
+.tabs-below > .nav-tabs > li > a:hover,
+.tabs-below > .nav-tabs > li > a:focus {
+ border-top-color: #ddd;
+ border-bottom-color: transparent;
+}
+
+.tabs-below > .nav-tabs > .active > a,
+.tabs-below > .nav-tabs > .active > a:hover,
+.tabs-below > .nav-tabs > .active > a:focus {
+ border-color: transparent #ddd #ddd #ddd;
+}
+
+.tabs-left > .nav-tabs > li,
+.tabs-right > .nav-tabs > li {
+ float: none;
+}
+
+.tabs-left > .nav-tabs > li > a,
+.tabs-right > .nav-tabs > li > a {
+ min-width: 74px;
+ margin-right: 0;
+ margin-bottom: 3px;
+}
+
+.tabs-left > .nav-tabs {
+ float: left;
+ margin-right: 19px;
+ border-right: 1px solid #ddd;
+}
+
+.tabs-left > .nav-tabs > li > a {
+ margin-right: -1px;
+ -webkit-border-radius: 4px 0 0 4px;
+ -moz-border-radius: 4px 0 0 4px;
+ border-radius: 4px 0 0 4px;
+}
+
+.tabs-left > .nav-tabs > li > a:hover,
+.tabs-left > .nav-tabs > li > a:focus {
+ border-color: #eeeeee #dddddd #eeeeee #eeeeee;
+}
+
+.tabs-left > .nav-tabs .active > a,
+.tabs-left > .nav-tabs .active > a:hover,
+.tabs-left > .nav-tabs .active > a:focus {
+ border-color: #ddd transparent #ddd #ddd;
+ *border-right-color: #ffffff;
+}
+
+.tabs-right > .nav-tabs {
+ float: right;
+ margin-left: 19px;
+ border-left: 1px solid #ddd;
+}
+
+.tabs-right > .nav-tabs > li > a {
+ margin-left: -1px;
+ -webkit-border-radius: 0 4px 4px 0;
+ -moz-border-radius: 0 4px 4px 0;
+ border-radius: 0 4px 4px 0;
+}
+
+.tabs-right > .nav-tabs > li > a:hover,
+.tabs-right > .nav-tabs > li > a:focus {
+ border-color: #eeeeee #eeeeee #eeeeee #dddddd;
+}
+
+.tabs-right > .nav-tabs .active > a,
+.tabs-right > .nav-tabs .active > a:hover,
+.tabs-right > .nav-tabs .active > a:focus {
+ border-color: #ddd #ddd #ddd transparent;
+ *border-left-color: #ffffff;
+}
+
+.nav > .disabled > a {
+ color: #999999;
+}
+
+.nav > .disabled > a:hover,
+.nav > .disabled > a:focus {
+ text-decoration: none;
+ cursor: default;
+ background-color: transparent;
+}
+
+.navbar {
+ *position: relative;
+ *z-index: 2;
+ margin-bottom: 20px;
+ overflow: visible;
+}
+
+.navbar-inner {
+ min-height: 40px;
+ padding-right: 20px;
+ padding-left: 20px;
+ background-color: #fafafa;
+ background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2));
+ background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2);
+ background-image: -o-linear-gradient(top, #ffffff, #f2f2f2);
+ background-image: linear-gradient(to bottom, #ffffff, #f2f2f2);
+ background-repeat: repeat-x;
+ border: 1px solid #d4d4d4;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0);
+ *zoom: 1;
+ -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);
+ -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);
+}
+
+.navbar-inner:before,
+.navbar-inner:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.navbar-inner:after {
+ clear: both;
+}
+
+.navbar .container {
+ width: auto;
+}
+
+.nav-collapse.collapse {
+ height: auto;
+ overflow: visible;
+}
+
+.navbar .brand {
+ display: block;
+ float: left;
+ padding: 10px 20px 10px;
+ margin-left: -20px;
+ font-size: 20px;
+ font-weight: 200;
+ color: #777777;
+ text-shadow: 0 1px 0 #ffffff;
+}
+
+.navbar .brand:hover,
+.navbar .brand:focus {
+ text-decoration: none;
+}
+
+.navbar-text {
+ margin-bottom: 0;
+ line-height: 40px;
+ color: #777777;
+}
+
+.navbar-link {
+ color: #777777;
+}
+
+.navbar-link:hover,
+.navbar-link:focus {
+ color: #333333;
+}
+
+.navbar .divider-vertical {
+ height: 40px;
+ margin: 0 9px;
+ border-right: 1px solid #ffffff;
+ border-left: 1px solid #f2f2f2;
+}
+
+.navbar .btn,
+.navbar .btn-group {
+ margin-top: 5px;
+}
+
+.navbar .btn-group .btn,
+.navbar .input-prepend .btn,
+.navbar .input-append .btn,
+.navbar .input-prepend .btn-group,
+.navbar .input-append .btn-group {
+ margin-top: 0;
+}
+
+.navbar-form {
+ margin-bottom: 0;
+ *zoom: 1;
+}
+
+.navbar-form:before,
+.navbar-form:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.navbar-form:after {
+ clear: both;
+}
+
+.navbar-form input,
+.navbar-form select,
+.navbar-form .radio,
+.navbar-form .checkbox {
+ margin-top: 5px;
+}
+
+.navbar-form input,
+.navbar-form select,
+.navbar-form .btn {
+ display: inline-block;
+ margin-bottom: 0;
+}
+
+.navbar-form input[type="image"],
+.navbar-form input[type="checkbox"],
+.navbar-form input[type="radio"] {
+ margin-top: 3px;
+}
+
+.navbar-form .input-append,
+.navbar-form .input-prepend {
+ margin-top: 5px;
+ white-space: nowrap;
+}
+
+.navbar-form .input-append input,
+.navbar-form .input-prepend input {
+ margin-top: 0;
+}
+
+.navbar-search {
+ position: relative;
+ float: left;
+ margin-top: 5px;
+ margin-bottom: 0;
+}
+
+.navbar-search .search-query {
+ padding: 4px 14px;
+ margin-bottom: 0;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 13px;
+ font-weight: normal;
+ line-height: 1;
+ -webkit-border-radius: 15px;
+ -moz-border-radius: 15px;
+ border-radius: 15px;
+}
+
+.navbar-static-top {
+ position: static;
+ margin-bottom: 0;
+}
+
+.navbar-static-top .navbar-inner {
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+}
+
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+ position: fixed;
+ right: 0;
+ left: 0;
+ z-index: 1030;
+ margin-bottom: 0;
+}
+
+.navbar-fixed-top .navbar-inner,
+.navbar-static-top .navbar-inner {
+ border-width: 0 0 1px;
+}
+
+.navbar-fixed-bottom .navbar-inner {
+ border-width: 1px 0 0;
+}
+
+.navbar-fixed-top .navbar-inner,
+.navbar-fixed-bottom .navbar-inner {
+ padding-right: 0;
+ padding-left: 0;
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+}
+
+.navbar-static-top .container,
+.navbar-fixed-top .container,
+.navbar-fixed-bottom .container {
+ width: 940px;
+}
+
+.navbar-fixed-top {
+ top: 0;
+}
+
+.navbar-fixed-top .navbar-inner,
+.navbar-static-top .navbar-inner {
+ -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1);
+ -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1);
+ box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1);
+}
+
+.navbar-fixed-bottom {
+ bottom: 0;
+}
+
+.navbar-fixed-bottom .navbar-inner {
+ -webkit-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1);
+ -moz-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1);
+ box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1);
+}
+
+.navbar .nav {
+ position: relative;
+ left: 0;
+ display: block;
+ float: left;
+ margin: 0 10px 0 0;
+}
+
+.navbar .nav.pull-right {
+ float: right;
+ margin-right: 0;
+}
+
+.navbar .nav > li {
+ float: left;
+}
+
+.navbar .nav > li > a {
+ float: none;
+ padding: 10px 15px 10px;
+ color: #777777;
+ text-decoration: none;
+ text-shadow: 0 1px 0 #ffffff;
+}
+
+.navbar .nav .dropdown-toggle .caret {
+ margin-top: 8px;
+}
+
+.navbar .nav > li > a:focus,
+.navbar .nav > li > a:hover {
+ color: #333333;
+ text-decoration: none;
+ background-color: transparent;
+}
+
+.navbar .nav > .active > a,
+.navbar .nav > .active > a:hover,
+.navbar .nav > .active > a:focus {
+ color: #555555;
+ text-decoration: none;
+ background-color: #e5e5e5;
+ -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);
+ -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);
+ box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);
+}
+
+.navbar .btn-navbar {
+ display: none;
+ float: right;
+ padding: 7px 10px;
+ margin-right: 5px;
+ margin-left: 5px;
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ background-color: #ededed;
+ *background-color: #e5e5e5;
+ background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5));
+ background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5);
+ background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5);
+ background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5);
+ background-repeat: repeat-x;
+ border-color: #e5e5e5 #e5e5e5 #bfbfbf;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075);
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075);
+}
+
+.navbar .btn-navbar:hover,
+.navbar .btn-navbar:focus,
+.navbar .btn-navbar:active,
+.navbar .btn-navbar.active,
+.navbar .btn-navbar.disabled,
+.navbar .btn-navbar[disabled] {
+ color: #ffffff;
+ background-color: #e5e5e5;
+ *background-color: #d9d9d9;
+}
+
+.navbar .btn-navbar:active,
+.navbar .btn-navbar.active {
+ background-color: #cccccc \9;
+}
+
+.navbar .btn-navbar .icon-bar {
+ display: block;
+ width: 18px;
+ height: 2px;
+ background-color: #f5f5f5;
+ -webkit-border-radius: 1px;
+ -moz-border-radius: 1px;
+ border-radius: 1px;
+ -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
+ -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
+ box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
+}
+
+.btn-navbar .icon-bar + .icon-bar {
+ margin-top: 3px;
+}
+
+.navbar .nav > li > .dropdown-menu:before {
+ position: absolute;
+ top: -7px;
+ left: 9px;
+ display: inline-block;
+ border-right: 7px solid transparent;
+ border-bottom: 7px solid #ccc;
+ border-left: 7px solid transparent;
+ border-bottom-color: rgba(0, 0, 0, 0.2);
+ content: '';
+}
+
+.navbar .nav > li > .dropdown-menu:after {
+ position: absolute;
+ top: -6px;
+ left: 10px;
+ display: inline-block;
+ border-right: 6px solid transparent;
+ border-bottom: 6px solid #ffffff;
+ border-left: 6px solid transparent;
+ content: '';
+}
+
+.navbar-fixed-bottom .nav > li > .dropdown-menu:before {
+ top: auto;
+ bottom: -7px;
+ border-top: 7px solid #ccc;
+ border-bottom: 0;
+ border-top-color: rgba(0, 0, 0, 0.2);
+}
+
+.navbar-fixed-bottom .nav > li > .dropdown-menu:after {
+ top: auto;
+ bottom: -6px;
+ border-top: 6px solid #ffffff;
+ border-bottom: 0;
+}
+
+.navbar .nav li.dropdown > a:hover .caret,
+.navbar .nav li.dropdown > a:focus .caret {
+ border-top-color: #333333;
+ border-bottom-color: #333333;
+}
+
+.navbar .nav li.dropdown.open > .dropdown-toggle,
+.navbar .nav li.dropdown.active > .dropdown-toggle,
+.navbar .nav li.dropdown.open.active > .dropdown-toggle {
+ color: #555555;
+ background-color: #e5e5e5;
+}
+
+.navbar .nav li.dropdown > .dropdown-toggle .caret {
+ border-top-color: #777777;
+ border-bottom-color: #777777;
+}
+
+.navbar .nav li.dropdown.open > .dropdown-toggle .caret,
+.navbar .nav li.dropdown.active > .dropdown-toggle .caret,
+.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret {
+ border-top-color: #555555;
+ border-bottom-color: #555555;
+}
+
+.navbar .pull-right > li > .dropdown-menu,
+.navbar .nav > li > .dropdown-menu.pull-right {
+ right: 0;
+ left: auto;
+}
+
+.navbar .pull-right > li > .dropdown-menu:before,
+.navbar .nav > li > .dropdown-menu.pull-right:before {
+ right: 12px;
+ left: auto;
+}
+
+.navbar .pull-right > li > .dropdown-menu:after,
+.navbar .nav > li > .dropdown-menu.pull-right:after {
+ right: 13px;
+ left: auto;
+}
+
+.navbar .pull-right > li > .dropdown-menu .dropdown-menu,
+.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu {
+ right: 100%;
+ left: auto;
+ margin-right: -1px;
+ margin-left: 0;
+ -webkit-border-radius: 6px 0 6px 6px;
+ -moz-border-radius: 6px 0 6px 6px;
+ border-radius: 6px 0 6px 6px;
+}
+
+.navbar-inverse .navbar-inner {
+ background-color: #1b1b1b;
+ background-image: -moz-linear-gradient(top, #222222, #111111);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111));
+ background-image: -webkit-linear-gradient(top, #222222, #111111);
+ background-image: -o-linear-gradient(top, #222222, #111111);
+ background-image: linear-gradient(to bottom, #222222, #111111);
+ background-repeat: repeat-x;
+ border-color: #252525;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0);
+}
+
+.navbar-inverse .brand,
+.navbar-inverse .nav > li > a {
+ color: #999999;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+}
+
+.navbar-inverse .brand:hover,
+.navbar-inverse .nav > li > a:hover,
+.navbar-inverse .brand:focus,
+.navbar-inverse .nav > li > a:focus {
+ color: #ffffff;
+}
+
+.navbar-inverse .brand {
+ color: #999999;
+}
+
+.navbar-inverse .navbar-text {
+ color: #999999;
+}
+
+.navbar-inverse .nav > li > a:focus,
+.navbar-inverse .nav > li > a:hover {
+ color: #ffffff;
+ background-color: transparent;
+}
+
+.navbar-inverse .nav .active > a,
+.navbar-inverse .nav .active > a:hover,
+.navbar-inverse .nav .active > a:focus {
+ color: #ffffff;
+ background-color: #111111;
+}
+
+.navbar-inverse .navbar-link {
+ color: #999999;
+}
+
+.navbar-inverse .navbar-link:hover,
+.navbar-inverse .navbar-link:focus {
+ color: #ffffff;
+}
+
+.navbar-inverse .divider-vertical {
+ border-right-color: #222222;
+ border-left-color: #111111;
+}
+
+.navbar-inverse .nav li.dropdown.open > .dropdown-toggle,
+.navbar-inverse .nav li.dropdown.active > .dropdown-toggle,
+.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle {
+ color: #ffffff;
+ background-color: #111111;
+}
+
+.navbar-inverse .nav li.dropdown > a:hover .caret,
+.navbar-inverse .nav li.dropdown > a:focus .caret {
+ border-top-color: #ffffff;
+ border-bottom-color: #ffffff;
+}
+
+.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret {
+ border-top-color: #999999;
+ border-bottom-color: #999999;
+}
+
+.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret,
+.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret,
+.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret {
+ border-top-color: #ffffff;
+ border-bottom-color: #ffffff;
+}
+
+.navbar-inverse .navbar-search .search-query {
+ color: #ffffff;
+ background-color: #515151;
+ border-color: #111111;
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15);
+ -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15);
+ -webkit-transition: none;
+ -moz-transition: none;
+ -o-transition: none;
+ transition: none;
+}
+
+.navbar-inverse .navbar-search .search-query:-moz-placeholder {
+ color: #cccccc;
+}
+
+.navbar-inverse .navbar-search .search-query:-ms-input-placeholder {
+ color: #cccccc;
+}
+
+.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder {
+ color: #cccccc;
+}
+
+.navbar-inverse .navbar-search .search-query:focus,
+.navbar-inverse .navbar-search .search-query.focused {
+ padding: 5px 15px;
+ color: #333333;
+ text-shadow: 0 1px 0 #ffffff;
+ background-color: #ffffff;
+ border: 0;
+ outline: 0;
+ -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15);
+ -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15);
+ box-shadow: 0 0 3px rgba(0, 0, 0, 0.15);
+}
+
+.navbar-inverse .btn-navbar {
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ background-color: #0e0e0e;
+ *background-color: #040404;
+ background-image: -moz-linear-gradient(top, #151515, #040404);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404));
+ background-image: -webkit-linear-gradient(top, #151515, #040404);
+ background-image: -o-linear-gradient(top, #151515, #040404);
+ background-image: linear-gradient(to bottom, #151515, #040404);
+ background-repeat: repeat-x;
+ border-color: #040404 #040404 #000000;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+
+.navbar-inverse .btn-navbar:hover,
+.navbar-inverse .btn-navbar:focus,
+.navbar-inverse .btn-navbar:active,
+.navbar-inverse .btn-navbar.active,
+.navbar-inverse .btn-navbar.disabled,
+.navbar-inverse .btn-navbar[disabled] {
+ color: #ffffff;
+ background-color: #040404;
+ *background-color: #000000;
+}
+
+.navbar-inverse .btn-navbar:active,
+.navbar-inverse .btn-navbar.active {
+ background-color: #000000 \9;
+}
+
+.breadcrumb {
+ padding: 8px 15px;
+ margin: 0 0 20px;
+ list-style: none;
+ background-color: #f5f5f5;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.breadcrumb > li {
+ display: inline-block;
+ *display: inline;
+ text-shadow: 0 1px 0 #ffffff;
+ *zoom: 1;
+}
+
+.breadcrumb > li > .divider {
+ padding: 0 5px;
+ color: #ccc;
+}
+
+.breadcrumb > .active {
+ color: #999999;
+}
+
+.pagination {
+ margin: 20px 0;
+}
+
+.pagination ul {
+ display: inline-block;
+ *display: inline;
+ margin-bottom: 0;
+ margin-left: 0;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ *zoom: 1;
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
+}
+
+.pagination ul > li {
+ display: inline;
+}
+
+.pagination ul > li > a,
+.pagination ul > li > span {
+ float: left;
+ padding: 4px 12px;
+ line-height: 20px;
+ text-decoration: none;
+ background-color: #ffffff;
+ border: 1px solid #dddddd;
+ border-left-width: 0;
+}
+
+.pagination ul > li > a:hover,
+.pagination ul > li > a:focus,
+.pagination ul > .active > a,
+.pagination ul > .active > span {
+ background-color: #f5f5f5;
+}
+
+.pagination ul > .active > a,
+.pagination ul > .active > span {
+ color: #999999;
+ cursor: default;
+}
+
+.pagination ul > .disabled > span,
+.pagination ul > .disabled > a,
+.pagination ul > .disabled > a:hover,
+.pagination ul > .disabled > a:focus {
+ color: #999999;
+ cursor: default;
+ background-color: transparent;
+}
+
+.pagination ul > li:first-child > a,
+.pagination ul > li:first-child > span {
+ border-left-width: 1px;
+ -webkit-border-bottom-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+ -webkit-border-top-left-radius: 4px;
+ border-top-left-radius: 4px;
+ -moz-border-radius-bottomleft: 4px;
+ -moz-border-radius-topleft: 4px;
+}
+
+.pagination ul > li:last-child > a,
+.pagination ul > li:last-child > span {
+ -webkit-border-top-right-radius: 4px;
+ border-top-right-radius: 4px;
+ -webkit-border-bottom-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+ -moz-border-radius-topright: 4px;
+ -moz-border-radius-bottomright: 4px;
+}
+
+.pagination-centered {
+ text-align: center;
+}
+
+.pagination-right {
+ text-align: right;
+}
+
+.pagination-large ul > li > a,
+.pagination-large ul > li > span {
+ padding: 11px 19px;
+ font-size: 17.5px;
+}
+
+.pagination-large ul > li:first-child > a,
+.pagination-large ul > li:first-child > span {
+ -webkit-border-bottom-left-radius: 6px;
+ border-bottom-left-radius: 6px;
+ -webkit-border-top-left-radius: 6px;
+ border-top-left-radius: 6px;
+ -moz-border-radius-bottomleft: 6px;
+ -moz-border-radius-topleft: 6px;
+}
+
+.pagination-large ul > li:last-child > a,
+.pagination-large ul > li:last-child > span {
+ -webkit-border-top-right-radius: 6px;
+ border-top-right-radius: 6px;
+ -webkit-border-bottom-right-radius: 6px;
+ border-bottom-right-radius: 6px;
+ -moz-border-radius-topright: 6px;
+ -moz-border-radius-bottomright: 6px;
+}
+
+.pagination-mini ul > li:first-child > a,
+.pagination-small ul > li:first-child > a,
+.pagination-mini ul > li:first-child > span,
+.pagination-small ul > li:first-child > span {
+ -webkit-border-bottom-left-radius: 3px;
+ border-bottom-left-radius: 3px;
+ -webkit-border-top-left-radius: 3px;
+ border-top-left-radius: 3px;
+ -moz-border-radius-bottomleft: 3px;
+ -moz-border-radius-topleft: 3px;
+}
+
+.pagination-mini ul > li:last-child > a,
+.pagination-small ul > li:last-child > a,
+.pagination-mini ul > li:last-child > span,
+.pagination-small ul > li:last-child > span {
+ -webkit-border-top-right-radius: 3px;
+ border-top-right-radius: 3px;
+ -webkit-border-bottom-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+ -moz-border-radius-topright: 3px;
+ -moz-border-radius-bottomright: 3px;
+}
+
+.pagination-small ul > li > a,
+.pagination-small ul > li > span {
+ padding: 2px 10px;
+ font-size: 11.9px;
+}
+
+.pagination-mini ul > li > a,
+.pagination-mini ul > li > span {
+ padding: 0 6px;
+ font-size: 10.5px;
+}
+
+.pager {
+ margin: 20px 0;
+ text-align: center;
+ list-style: none;
+ *zoom: 1;
+}
+
+.pager:before,
+.pager:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.pager:after {
+ clear: both;
+}
+
+.pager li {
+ display: inline;
+}
+
+.pager li > a,
+.pager li > span {
+ display: inline-block;
+ padding: 5px 14px;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ -webkit-border-radius: 15px;
+ -moz-border-radius: 15px;
+ border-radius: 15px;
+}
+
+.pager li > a:hover,
+.pager li > a:focus {
+ text-decoration: none;
+ background-color: #f5f5f5;
+}
+
+.pager .next > a,
+.pager .next > span {
+ float: right;
+}
+
+.pager .previous > a,
+.pager .previous > span {
+ float: left;
+}
+
+.pager .disabled > a,
+.pager .disabled > a:hover,
+.pager .disabled > a:focus,
+.pager .disabled > span {
+ color: #999999;
+ cursor: default;
+ background-color: #fff;
+}
+
+.modal-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1040;
+ background-color: #000000;
+}
+
+.modal-backdrop.fade {
+ opacity: 0;
+}
+
+.modal-backdrop,
+.modal-backdrop.fade.in {
+ opacity: 0.8;
+ filter: alpha(opacity=80);
+}
+
+.modal {
+ position: fixed;
+ top: 10%;
+ left: 50%;
+ z-index: 1050;
+ width: 560px;
+ margin-left: -280px;
+ background-color: #ffffff;
+ border: 1px solid #999;
+ border: 1px solid rgba(0, 0, 0, 0.3);
+ *border: 1px solid #999;
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+ outline: none;
+ -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
+ -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
+ box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
+ -webkit-background-clip: padding-box;
+ -moz-background-clip: padding-box;
+ background-clip: padding-box;
+}
+
+.modal.fade {
+ top: -25%;
+ -webkit-transition: opacity 0.3s linear, top 0.3s ease-out;
+ -moz-transition: opacity 0.3s linear, top 0.3s ease-out;
+ -o-transition: opacity 0.3s linear, top 0.3s ease-out;
+ transition: opacity 0.3s linear, top 0.3s ease-out;
+}
+
+.modal.fade.in {
+ top: 10%;
+}
+
+.modal-header {
+ padding: 9px 15px;
+ border-bottom: 1px solid #eee;
+}
+
+.modal-header .close {
+ margin-top: 2px;
+}
+
+.modal-header h3 {
+ margin: 0;
+ line-height: 30px;
+}
+
+.modal-body {
+ position: relative;
+ max-height: 400px;
+ padding: 15px;
+ overflow-y: auto;
+}
+
+.modal-form {
+ margin-bottom: 0;
+}
+
+.modal-footer {
+ padding: 14px 15px 15px;
+ margin-bottom: 0;
+ text-align: right;
+ background-color: #f5f5f5;
+ border-top: 1px solid #ddd;
+ -webkit-border-radius: 0 0 6px 6px;
+ -moz-border-radius: 0 0 6px 6px;
+ border-radius: 0 0 6px 6px;
+ *zoom: 1;
+ -webkit-box-shadow: inset 0 1px 0 #ffffff;
+ -moz-box-shadow: inset 0 1px 0 #ffffff;
+ box-shadow: inset 0 1px 0 #ffffff;
+}
+
+.modal-footer:before,
+.modal-footer:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.modal-footer:after {
+ clear: both;
+}
+
+.modal-footer .btn + .btn {
+ margin-bottom: 0;
+ margin-left: 5px;
+}
+
+.modal-footer .btn-group .btn + .btn {
+ margin-left: -1px;
+}
+
+.modal-footer .btn-block + .btn-block {
+ margin-left: 0;
+}
+
+.tooltip {
+ position: absolute;
+ z-index: 1030;
+ display: block;
+ font-size: 11px;
+ line-height: 1.4;
+ opacity: 0;
+ filter: alpha(opacity=0);
+ visibility: visible;
+}
+
+.tooltip.in {
+ opacity: 0.8;
+ filter: alpha(opacity=80);
+}
+
+.tooltip.top {
+ padding: 5px 0;
+ margin-top: -3px;
+}
+
+.tooltip.right {
+ padding: 0 5px;
+ margin-left: 3px;
+}
+
+.tooltip.bottom {
+ padding: 5px 0;
+ margin-top: 3px;
+}
+
+.tooltip.left {
+ padding: 0 5px;
+ margin-left: -3px;
+}
+
+.tooltip-inner {
+ max-width: 200px;
+ padding: 8px;
+ color: #ffffff;
+ text-align: center;
+ text-decoration: none;
+ background-color: #000000;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.tooltip-arrow {
+ position: absolute;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+
+.tooltip.top .tooltip-arrow {
+ bottom: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-top-color: #000000;
+ border-width: 5px 5px 0;
+}
+
+.tooltip.right .tooltip-arrow {
+ top: 50%;
+ left: 0;
+ margin-top: -5px;
+ border-right-color: #000000;
+ border-width: 5px 5px 5px 0;
+}
+
+.tooltip.left .tooltip-arrow {
+ top: 50%;
+ right: 0;
+ margin-top: -5px;
+ border-left-color: #000000;
+ border-width: 5px 0 5px 5px;
+}
+
+.tooltip.bottom .tooltip-arrow {
+ top: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-bottom-color: #000000;
+ border-width: 0 5px 5px;
+}
+
+.popover {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 1010;
+ display: none;
+ max-width: 276px;
+ padding: 1px;
+ text-align: left;
+ white-space: normal;
+ background-color: #ffffff;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+ -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ -webkit-background-clip: padding-box;
+ -moz-background-clip: padding;
+ background-clip: padding-box;
+}
+
+.popover.top {
+ margin-top: -10px;
+}
+
+.popover.right {
+ margin-left: 10px;
+}
+
+.popover.bottom {
+ margin-top: 10px;
+}
+
+.popover.left {
+ margin-left: -10px;
+}
+
+.popover-title {
+ padding: 8px 14px;
+ margin: 0;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 18px;
+ background-color: #f7f7f7;
+ border-bottom: 1px solid #ebebeb;
+ -webkit-border-radius: 5px 5px 0 0;
+ -moz-border-radius: 5px 5px 0 0;
+ border-radius: 5px 5px 0 0;
+}
+
+.popover-title:empty {
+ display: none;
+}
+
+.popover-content {
+ padding: 9px 14px;
+}
+
+.popover .arrow,
+.popover .arrow:after {
+ position: absolute;
+ display: block;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+
+.popover .arrow {
+ border-width: 11px;
+}
+
+.popover .arrow:after {
+ border-width: 10px;
+ content: "";
+}
+
+.popover.top .arrow {
+ bottom: -11px;
+ left: 50%;
+ margin-left: -11px;
+ border-top-color: #999;
+ border-top-color: rgba(0, 0, 0, 0.25);
+ border-bottom-width: 0;
+}
+
+.popover.top .arrow:after {
+ bottom: 1px;
+ margin-left: -10px;
+ border-top-color: #ffffff;
+ border-bottom-width: 0;
+}
+
+.popover.right .arrow {
+ top: 50%;
+ left: -11px;
+ margin-top: -11px;
+ border-right-color: #999;
+ border-right-color: rgba(0, 0, 0, 0.25);
+ border-left-width: 0;
+}
+
+.popover.right .arrow:after {
+ bottom: -10px;
+ left: 1px;
+ border-right-color: #ffffff;
+ border-left-width: 0;
+}
+
+.popover.bottom .arrow {
+ top: -11px;
+ left: 50%;
+ margin-left: -11px;
+ border-bottom-color: #999;
+ border-bottom-color: rgba(0, 0, 0, 0.25);
+ border-top-width: 0;
+}
+
+.popover.bottom .arrow:after {
+ top: 1px;
+ margin-left: -10px;
+ border-bottom-color: #ffffff;
+ border-top-width: 0;
+}
+
+.popover.left .arrow {
+ top: 50%;
+ right: -11px;
+ margin-top: -11px;
+ border-left-color: #999;
+ border-left-color: rgba(0, 0, 0, 0.25);
+ border-right-width: 0;
+}
+
+.popover.left .arrow:after {
+ right: 1px;
+ bottom: -10px;
+ border-left-color: #ffffff;
+ border-right-width: 0;
+}
+
+.thumbnails {
+ margin-left: -20px;
+ list-style: none;
+ *zoom: 1;
+}
+
+.thumbnails:before,
+.thumbnails:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.thumbnails:after {
+ clear: both;
+}
+
+.row-fluid .thumbnails {
+ margin-left: 0;
+}
+
+.thumbnails > li {
+ float: left;
+ margin-bottom: 20px;
+ margin-left: 20px;
+}
+
+.thumbnail {
+ display: block;
+ padding: 4px;
+ line-height: 20px;
+ border: 1px solid #ddd;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055);
+ -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055);
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055);
+ -webkit-transition: all 0.2s ease-in-out;
+ -moz-transition: all 0.2s ease-in-out;
+ -o-transition: all 0.2s ease-in-out;
+ transition: all 0.2s ease-in-out;
+}
+
+a.thumbnail:hover,
+a.thumbnail:focus {
+ border-color: #0088cc;
+ -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);
+ -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);
+ box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);
+}
+
+.thumbnail > img {
+ display: block;
+ max-width: 100%;
+ margin-right: auto;
+ margin-left: auto;
+}
+
+.thumbnail .caption {
+ padding: 9px;
+ color: #555555;
+}
+
+.media,
+.media-body {
+ overflow: hidden;
+ *overflow: visible;
+ zoom: 1;
+}
+
+.media,
+.media .media {
+ margin-top: 15px;
+}
+
+.media:first-child {
+ margin-top: 0;
+}
+
+.media-object {
+ display: block;
+}
+
+.media-heading {
+ margin: 0 0 5px;
+}
+
+.media > .pull-left {
+ margin-right: 10px;
+}
+
+.media > .pull-right {
+ margin-left: 10px;
+}
+
+.media-list {
+ margin-left: 0;
+ list-style: none;
+}
+
+.label,
+.badge {
+ display: inline-block;
+ padding: 2px 4px;
+ font-size: 11.844px;
+ font-weight: bold;
+ line-height: 14px;
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ white-space: nowrap;
+ vertical-align: baseline;
+ background-color: #999999;
+}
+
+.label {
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+
+.badge {
+ padding-right: 9px;
+ padding-left: 9px;
+ -webkit-border-radius: 9px;
+ -moz-border-radius: 9px;
+ border-radius: 9px;
+}
+
+.label:empty,
+.badge:empty {
+ display: none;
+}
+
+a.label:hover,
+a.label:focus,
+a.badge:hover,
+a.badge:focus {
+ color: #ffffff;
+ text-decoration: none;
+ cursor: pointer;
+}
+
+.label-important,
+.badge-important {
+ background-color: #b94a48;
+}
+
+.label-important[href],
+.badge-important[href] {
+ background-color: #953b39;
+}
+
+.label-warning,
+.badge-warning {
+ background-color: #f89406;
+}
+
+.label-warning[href],
+.badge-warning[href] {
+ background-color: #c67605;
+}
+
+.label-success,
+.badge-success {
+ background-color: #468847;
+}
+
+.label-success[href],
+.badge-success[href] {
+ background-color: #356635;
+}
+
+.label-info,
+.badge-info {
+ background-color: #3a87ad;
+}
+
+.label-info[href],
+.badge-info[href] {
+ background-color: #2d6987;
+}
+
+.label-inverse,
+.badge-inverse {
+ background-color: #333333;
+}
+
+.label-inverse[href],
+.badge-inverse[href] {
+ background-color: #1a1a1a;
+}
+
+.btn .label,
+.btn .badge {
+ position: relative;
+ top: -1px;
+}
+
+.btn-mini .label,
+.btn-mini .badge {
+ top: 0;
+}
+
+@-webkit-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+
+@-moz-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+
+@-ms-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+
+@-o-keyframes progress-bar-stripes {
+ from {
+ background-position: 0 0;
+ }
+ to {
+ background-position: 40px 0;
+ }
+}
+
+@keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+
+.progress {
+ height: 20px;
+ margin-bottom: 20px;
+ overflow: hidden;
+ background-color: #f7f7f7;
+ background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));
+ background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9);
+ background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9);
+ background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9);
+ background-repeat: repeat-x;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0);
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+ -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+}
+
+.progress .bar {
+ float: left;
+ width: 0;
+ height: 100%;
+ font-size: 12px;
+ color: #ffffff;
+ text-align: center;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ background-color: #0e90d2;
+ background-image: -moz-linear-gradient(top, #149bdf, #0480be);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));
+ background-image: -webkit-linear-gradient(top, #149bdf, #0480be);
+ background-image: -o-linear-gradient(top, #149bdf, #0480be);
+ background-image: linear-gradient(to bottom, #149bdf, #0480be);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0);
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+ -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ -webkit-transition: width 0.6s ease;
+ -moz-transition: width 0.6s ease;
+ -o-transition: width 0.6s ease;
+ transition: width 0.6s ease;
+}
+
+.progress .bar + .bar {
+ -webkit-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+ -moz-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+ box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+}
+
+.progress-striped .bar {
+ background-color: #149bdf;
+ background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ -webkit-background-size: 40px 40px;
+ -moz-background-size: 40px 40px;
+ -o-background-size: 40px 40px;
+ background-size: 40px 40px;
+}
+
+.progress.active .bar {
+ -webkit-animation: progress-bar-stripes 2s linear infinite;
+ -moz-animation: progress-bar-stripes 2s linear infinite;
+ -ms-animation: progress-bar-stripes 2s linear infinite;
+ -o-animation: progress-bar-stripes 2s linear infinite;
+ animation: progress-bar-stripes 2s linear infinite;
+}
+
+.progress-danger .bar,
+.progress .bar-danger {
+ background-color: #dd514c;
+ background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));
+ background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
+ background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
+ background-image: linear-gradient(to bottom, #ee5f5b, #c43c35);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0);
+}
+
+.progress-danger.progress-striped .bar,
+.progress-striped .bar-danger {
+ background-color: #ee5f5b;
+ background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+
+.progress-success .bar,
+.progress .bar-success {
+ background-color: #5eb95e;
+ background-image: -moz-linear-gradient(top, #62c462, #57a957);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));
+ background-image: -webkit-linear-gradient(top, #62c462, #57a957);
+ background-image: -o-linear-gradient(top, #62c462, #57a957);
+ background-image: linear-gradient(to bottom, #62c462, #57a957);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0);
+}
+
+.progress-success.progress-striped .bar,
+.progress-striped .bar-success {
+ background-color: #62c462;
+ background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+
+.progress-info .bar,
+.progress .bar-info {
+ background-color: #4bb1cf;
+ background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));
+ background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9);
+ background-image: -o-linear-gradient(top, #5bc0de, #339bb9);
+ background-image: linear-gradient(to bottom, #5bc0de, #339bb9);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0);
+}
+
+.progress-info.progress-striped .bar,
+.progress-striped .bar-info {
+ background-color: #5bc0de;
+ background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+
+.progress-warning .bar,
+.progress .bar-warning {
+ background-color: #faa732;
+ background-image: -moz-linear-gradient(top, #fbb450, #f89406);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));
+ background-image: -webkit-linear-gradient(top, #fbb450, #f89406);
+ background-image: -o-linear-gradient(top, #fbb450, #f89406);
+ background-image: linear-gradient(to bottom, #fbb450, #f89406);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);
+}
+
+.progress-warning.progress-striped .bar,
+.progress-striped .bar-warning {
+ background-color: #fbb450;
+ background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+
+.accordion {
+ margin-bottom: 20px;
+}
+
+.accordion-group {
+ margin-bottom: 2px;
+ border: 1px solid #e5e5e5;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.accordion-heading {
+ border-bottom: 0;
+}
+
+.accordion-heading .accordion-toggle {
+ display: block;
+ padding: 8px 15px;
+}
+
+.accordion-toggle {
+ cursor: pointer;
+}
+
+.accordion-inner {
+ padding: 9px 15px;
+ border-top: 1px solid #e5e5e5;
+}
+
+.carousel {
+ position: relative;
+ margin-bottom: 20px;
+ line-height: 1;
+}
+
+.carousel-inner {
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+}
+
+.carousel-inner > .item {
+ position: relative;
+ display: none;
+ -webkit-transition: 0.6s ease-in-out left;
+ -moz-transition: 0.6s ease-in-out left;
+ -o-transition: 0.6s ease-in-out left;
+ transition: 0.6s ease-in-out left;
+}
+
+.carousel-inner > .item > img,
+.carousel-inner > .item > a > img {
+ display: block;
+ line-height: 1;
+}
+
+.carousel-inner > .active,
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ display: block;
+}
+
+.carousel-inner > .active {
+ left: 0;
+}
+
+.carousel-inner > .next,
+.carousel-inner > .prev {
+ position: absolute;
+ top: 0;
+ width: 100%;
+}
+
+.carousel-inner > .next {
+ left: 100%;
+}
+
+.carousel-inner > .prev {
+ left: -100%;
+}
+
+.carousel-inner > .next.left,
+.carousel-inner > .prev.right {
+ left: 0;
+}
+
+.carousel-inner > .active.left {
+ left: -100%;
+}
+
+.carousel-inner > .active.right {
+ left: 100%;
+}
+
+.carousel-control {
+ position: absolute;
+ top: 40%;
+ left: 15px;
+ width: 40px;
+ height: 40px;
+ margin-top: -20px;
+ font-size: 60px;
+ font-weight: 100;
+ line-height: 30px;
+ color: #ffffff;
+ text-align: center;
+ background: #222222;
+ border: 3px solid #ffffff;
+ -webkit-border-radius: 23px;
+ -moz-border-radius: 23px;
+ border-radius: 23px;
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+}
+
+.carousel-control.right {
+ right: 15px;
+ left: auto;
+}
+
+.carousel-control:hover,
+.carousel-control:focus {
+ color: #ffffff;
+ text-decoration: none;
+ opacity: 0.9;
+ filter: alpha(opacity=90);
+}
+
+.carousel-indicators {
+ position: absolute;
+ top: 15px;
+ right: 15px;
+ z-index: 5;
+ margin: 0;
+ list-style: none;
+}
+
+.carousel-indicators li {
+ display: block;
+ float: left;
+ width: 10px;
+ height: 10px;
+ margin-left: 5px;
+ text-indent: -999px;
+ background-color: #ccc;
+ background-color: rgba(255, 255, 255, 0.25);
+ border-radius: 5px;
+}
+
+.carousel-indicators .active {
+ background-color: #fff;
+}
+
+.carousel-caption {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ padding: 15px;
+ background: #333333;
+ background: rgba(0, 0, 0, 0.75);
+}
+
+.carousel-caption h4,
+.carousel-caption p {
+ line-height: 20px;
+ color: #ffffff;
+}
+
+.carousel-caption h4 {
+ margin: 0 0 5px;
+}
+
+.carousel-caption p {
+ margin-bottom: 0;
+}
+
+.hero-unit {
+ padding: 60px;
+ margin-bottom: 30px;
+ font-size: 18px;
+ font-weight: 200;
+ line-height: 30px;
+ color: inherit;
+ background-color: #eeeeee;
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+}
+
+.hero-unit h1 {
+ margin-bottom: 0;
+ font-size: 60px;
+ line-height: 1;
+ letter-spacing: -1px;
+ color: inherit;
+}
+
+.hero-unit li {
+ line-height: 30px;
+}
+
+.pull-right {
+ float: right;
+}
+
+.pull-left {
+ float: left;
+}
+
+.hide {
+ display: none;
+}
+
+.show {
+ display: block;
+}
+
+.invisible {
+ visibility: hidden;
+}
+
+.affix {
+ position: fixed;
+}
Added: WebTimer/src/common/css/bootstrap.min.css
===================================================================
--- WebTimer/src/common/css/bootstrap.min.css (rev 0)
+++ WebTimer/src/common/css/bootstrap.min.css 2013-06-14 09:20:52 UTC (rev 670)
@@ -0,0 +1,9 @@
+/*!
+ * Bootstrap v2.3.2
+ *
+ * Copyright 2012 Twitter, Inc
+ * Licensed under the Apache License v2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Designed and built with all the love in the world @twitter by @mdo and @fat.
+ */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}audio:not([controls]){display:none}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}a:hover,a:active{outline:0}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{width:auto\9;height:auto;max-width:100%;vertical-align:middle;border:0;-ms-interpolation-mode:bicubic}#map_canvas img,.google-maps img{max-width:none}button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle}button,input{*overflow:visible;line-height:normal}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}button,html input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button}label,select,button,input[type="button"],input[type="reset"],input[type="submit"],input[type="radio"],input[type="checkbox"]{cursor:pointer}input[type="search"]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none}textarea{overflow:auto;vertical-align:top}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}}body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:20px;color:#333;background-color:#fff}a{color:#08c;text-decoration:none}a:hover,a:focus{color:#005580;text-decoration:underline}.img-rounded{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.img-polaroid{padding:4px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.1);box-shadow:0 1px 3px rgba(0,0,0,0.1)}.img-circle{-webkit-border-radius:500px;-moz-border-radius:500px;border-radius:500px}.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.span12{width:940px}.span11{width:860px}.span10{width:780px}.span9{width:700px}.span8{width:620px}.span7{width:540px}.span6{width:460px}.span5{width:380px}.span4{width:300px}.span3{width:220px}.span2{width:140px}.span1{width:60px}.offset12{margin-left:980px}.offset11{margin-left:900px}.offset10{margin-left:820px}.offset9{margin-left:740px}.offset8{margin-left:660px}.offset7{margin-left:580px}.offset6{margin-left:500px}.offset5{margin-left:420px}.offset4{margin-left:340px}.offset3{margin-left:260px}.offset2{margin-left:180px}.offset1{margin-left:100px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.127659574468085%;*margin-left:2.074468085106383%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.127659574468085%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.48936170212765%;*width:91.43617021276594%}.row-fluid .span10{width:82.97872340425532%;*width:82.92553191489361%}.row-fluid .span9{width:74.46808510638297%;*width:74.41489361702126%}.row-fluid .span8{width:65.95744680851064%;*width:65.90425531914893%}.row-fluid .span7{width:57.44680851063829%;*width:57.39361702127659%}.row-fluid .span6{width:48.93617021276595%;*width:48.88297872340425%}.row-fluid .span5{width:40.42553191489362%;*width:40.37234042553192%}.row-fluid .span4{width:31.914893617021278%;*width:31.861702127659576%}.row-fluid .span3{width:23.404255319148934%;*width:23.351063829787233%}.row-fluid .span2{width:14.893617021276595%;*width:14.840425531914894%}.row-fluid .span1{width:6.382978723404255%;*width:6.329787234042553%}.row-fluid .offset12{margin-left:104.25531914893617%;*margin-left:104.14893617021275%}.row-fluid .offset12:first-child{margin-left:102.12765957446808%;*margin-left:102.02127659574467%}.row-fluid .offset11{margin-left:95.74468085106382%;*margin-left:95.6382978723404%}.row-fluid .offset11:first-child{margin-left:93.61702127659574%;*margin-left:93.51063829787232%}.row-fluid .offset10{margin-left:87.23404255319149%;*margin-left:87.12765957446807%}.row-fluid .offset10:first-child{margin-left:85.1063829787234%;*margin-left:84.99999999999999%}.row-fluid .offset9{margin-left:78.72340425531914%;*margin-left:78.61702127659572%}.row-fluid .offset9:first-child{margin-left:76.59574468085106%;*margin-left:76.48936170212764%}.row-fluid .offset8{margin-left:70.2127659574468%;*margin-left:70.10638297872339%}.row-fluid .offset8:first-child{margin-left:68.08510638297872%;*margin-left:67.9787234042553%}.row-fluid .offset7{margin-left:61.70212765957446%;*margin-left:61.59574468085106%}.row-fluid .offset7:first-child{margin-left:59.574468085106375%;*margin-left:59.46808510638297%}.row-fluid .offset6{margin-left:53.191489361702125%;*margin-left:53.085106382978715%}.row-fluid .offset6:first-child{margin-left:51.063829787234035%;*margin-left:50.95744680851063%}.row-fluid .offset5{margin-left:44.68085106382979%;*margin-left:44.57446808510638%}.row-fluid .offset5:first-child{margin-left:42.5531914893617%;*margin-left:42.4468085106383%}.row-fluid .offset4{margin-left:36.170212765957444%;*margin-left:36.06382978723405%}.row-fluid .offset4:first-child{margin-left:34.04255319148936%;*margin-left:33.93617021276596%}.row-fluid .offset3{margin-left:27.659574468085104%;*margin-left:27.5531914893617%}.row-fluid .offset3:first-child{margin-left:25.53191489361702%;*margin-left:25.425531914893618%}.row-fluid .offset2{margin-left:19.148936170212764%;*margin-left:19.04255319148936%}.row-fluid .offset2:first-child{margin-left:17.02127659574468%;*margin-left:16.914893617021278%}.row-fluid .offset1{margin-left:10.638297872340425%;*margin-left:10.53191489361702%}.row-fluid .offset1:first-child{margin-left:8.51063829787234%;*margin-left:8.404255319148938%}[class*="span"].hide,.row-fluid [class*="span"].hide{display:none}[class*="span"].pull-right,.row-fluid [class*="span"].pull-right{float:right}.container{margin-right:auto;margin-left:auto;*zoom:1}.container:before,.container:after{display:table;line-height:0;content:""}.container:after{clear:both}.container-fluid{padding-right:20px;padding-left:20px;*zoom:1}.container-fluid:before,.container-fluid:after{display:table;line-height:0;content:""}.container-fluid:after{clear:both}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:21px;font-weight:200;line-height:30px}small{font-size:85%}strong{font-weight:bold}em{font-style:italic}cite{font-style:normal}.muted{color:#999}a.muted:hover,a.muted:focus{color:#808080}.text-warning{color:#c09853}a.text-warning:hover,a.text-warning:focus{color:#a47e3c}.text-error{color:#b94a48}a.text-error:hover,a.text-error:focus{color:#953b39}.text-info{color:#3a87ad}a.text-info:hover,a.text-info:focus{color:#2d6987}.text-success{color:#468847}a.text-success:hover,a.text-success:focus{color:#356635}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{margin:10px 0;font-family:inherit;font-weight:bold;line-height:20px;color:inherit;text-rendering:optimizelegibility}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;line-height:1;color:#999}h1,h2,h3{line-height:40px}h1{font-size:38.5px}h2{font-size:31.5px}h3{font-size:24.5px}h4{font-size:17.5px}h5{font-size:14px}h6{font-size:11.9px}h1 small{font-size:24.5px}h2 small{font-size:17.5px}h3 small{font-size:14px}h4 small{font-size:14px}.page-header{padding-bottom:9px;margin:20px 0 30px;border-bottom:1px solid #eee}ul,ol{padding:0;margin:0 0 10px 25px}ul ul,ul ol,ol ol,ol ul{margin-bottom:0}li{line-height:20px}ul.unstyled,ol.unstyled{margin-left:0;list-style:none}ul.inline,ol.inline{margin-left:0;list-style:none}ul.inline>li,ol.inline>li{display:inline-block;*display:inline;padding-right:5px;padding-left:5px;*zoom:1}dl{margin-bottom:20px}dt,dd{line-height:20px}dt{font-weight:bold}dd{margin-left:10px}.dl-horizontal{*zoom:1}.dl-horizontal:before,.dl-horizontal:after{display:table;line-height:0;content:""}.dl-horizontal:after{clear:both}.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}hr{margin:20px 0;border:0;border-top:1px solid #eee;border-bottom:1px solid #fff}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}abbr.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:0 0 0 15px;margin:0 0 20px;border-left:5px solid #eee}blockquote p{margin-bottom:0;font-size:17.5px;font-weight:300;line-height:1.25}blockquote small{display:block;line-height:20px;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote.pull-right{float:right;padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0}blockquote.pull-right p,blockquote.pull-right small{text-align:right}blockquote.pull-right small:before{content:''}blockquote.pull-right small:after{content:'\00A0 \2014'}q:before,q:after,blockquote:before,blockquote:after{content:""}address{display:block;margin-bottom:20px;font-style:normal;line-height:20px}code,pre{padding:0 3px 2px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:12px;color:#333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}code{padding:2px 4px;color:#d14;white-space:nowrap;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:20px;word-break:break-all;word-wrap:break-word;white-space:pre;white-space:pre-wrap;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}pre.prettyprint{margin-bottom:20px}pre code{padding:0;color:inherit;white-space:pre;white-space:pre-wrap;background-color:transparent;border:0}.pre-scrollable{max-height:340px;overflow-y:scroll}form{margin:0 0 20px}fieldset{padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:40px;color:#333;border:0;border-bottom:1px solid #e5e5e5}legend small{font-size:15px;color:#999}label,input,button,select,textarea{font-size:14px;font-weight:normal;line-height:20px}input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}label{display:block;margin-bottom:5px}select,textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{display:inline-block;height:20px;padding:4px 6px;margin-bottom:10px;font-size:14px;line-height:20px;color:#555;vertical-align:middle;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}input,textarea,.uneditable-input{width:206px}textarea{height:auto}textarea,input[type="text"],input[type="password"],input[type="datetime"],input[type="datetime-local"],input[type="date"],input[type="month"],input[type="time"],input[type="week"],input[type="number"],input[type="email"],input[type="url"],input[type="search"],input[type="tel"],input[type="color"],.uneditable-input{background-color:#fff;border:1px solid #ccc;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border linear .2s,box-shadow linear .2s;-moz-transition:border linear .2s,box-shadow linear .2s;-o-transition:border linear .2s,box-shadow linear .2s;transition:border linear .2s,box-shadow linear .2s}textarea:focus,input[type="text"]:focus,input[type="password"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="time"]:focus,input[type="week"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="search"]:focus,input[type="tel"]:focus,input[type="color"]:focus,.uneditable-input:focus{border-color:rgba(82,168,236,0.8);outline:0;outline:thin dotted \9;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(82,168,236,0.6)}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;*margin-top:0;line-height:normal}input[type="file"],input[type="image"],input[type="submit"],input[type="reset"],input[type="button"],input[type="radio"],input[type="checkbox"]{width:auto}select,input[type="file"]{height:30px;*margin-top:4px;line-height:30px}select{width:220px;background-color:#fff;border:1px solid #ccc}select[multiple],select[size]{height:auto}select:focus,input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.uneditable-input,.uneditable-textarea{color:#999;cursor:not-allowed;background-color:#fcfcfc;border-color:#ccc;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.025);box-shadow:inset 0 1px 2px rgba(0,0,0,0.025)}.uneditable-input{overflow:hidden;white-space:nowrap}.uneditable-textarea{width:auto;height:auto}input:-moz-placeholder,textarea:-moz-placeholder{color:#999}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:#999}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#999}.radio,.checkbox{min-height:20px;padding-left:20px}.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-20px}.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px}.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle}.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px}.input-mini{width:60px}.input-small{width:90px}.input-medium{width:150px}.input-large{width:210px}.input-xlarge{width:270px}.input-xxlarge{width:530px}input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0}.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:926px}input.span11,textarea.span11,.uneditable-input.span11{width:846px}input.span10,textarea.span10,.uneditable-input.span10{width:766px}input.span9,textarea.span9,.uneditable-input.span9{width:686px}input.span8,textarea.span8,.uneditable-input.span8{width:606px}input.span7,textarea.span7,.uneditable-input.span7{width:526px}input.span6,textarea.span6,.uneditable-input.span6{width:446px}input.span5,textarea.span5,.uneditable-input.span5{width:366px}input.span4,textarea.span4,.uneditable-input.span4{width:286px}input.span3,textarea.span3,.uneditable-input.span3{width:206px}input.span2,textarea.span2,.uneditable-input.span2{width:126px}input.span1,textarea.span1,.uneditable-input.span1{width:46px}.controls-row{*zoom:1}.controls-row:before,.controls-row:after{display:table;line-height:0;content:""}.controls-row:after{clear:both}.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left}.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px}input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eee}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent}.control-group.warning .control-label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853}.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853}.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853}.control-group.error .control-label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48}.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48}.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48}.control-group.success .control-label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847}.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847}.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847}.control-group.info .control-label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad}.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad}.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7ab5d3}.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad}input:focus:invalid,textarea:focus:invalid,select:focus:invalid{color:#b94a48;border-color:#ee5f5b}input:focus:invalid:focus,textarea:focus:invalid:focus,select:focus:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7}.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1}.form-actions:before,.form-actions:after{display:table;line-height:0;content:""}.form-actions:after{clear:both}.help-block,.help-inline{color:#595959}.help-block{display:block;margin-bottom:10px}.help-inline{display:inline-block;*display:inline;padding-left:5px;vertical-align:middle;*zoom:1}.input-append,.input-prepend{display:inline-block;margin-bottom:10px;font-size:0;white-space:nowrap;vertical-align:middle}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu,.input-append .popover,.input-prepend .popover{font-size:14px}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2}.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #fff;background-color:#eee;border:1px solid #ccc}.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn,.input-append .btn-group>.dropdown-toggle,.input-prepend .btn-group>.dropdown-toggle{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546}.input-prepend .add-on,.input-prepend .btn{margin-right:-1px}.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-append input+.btn-group .btn:last-child,.input-append select+.btn-group .btn:last-child,.input-append .uneditable-input+.btn-group .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px}.input-append .add-on:last-child,.input-append .btn:last-child,.input-append .btn-group:last-child>.dropdown-toggle{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.input-prepend.input-append .btn-group:first-child{margin-left:0}input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0}.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px}.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;margin-bottom:0;vertical-align:middle;*zoom:1}.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none}.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block}.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0}.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle}.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0}.control-group{margin-bottom:10px}legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate}.form-horizontal .control-group{margin-bottom:20px;*zoom:1}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;line-height:0;content:""}.form-horizontal .control-group:after{clear:both}.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right}.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0}.form-horizontal .controls:first-child{*padding-left:180px}.form-horizontal .help-block{margin-bottom:0}.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block,.form-horizontal .uneditable-input+.help-block,.form-horizontal .input-prepend+.help-block,.form-horizontal .input-append+.help-block{margin-top:10px}.form-horizontal .form-actions{padding-left:180px}table{max-width:100%;background-color:transparent;border-collapse:collapse;border-spacing:0}.table{width:100%;margin-bottom:20px}.table th,.table td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}.table th{font-weight:bold}.table thead th{vertical-align:bottom}.table caption+thead tr:first-child th,.table caption+thead tr:first-child td,.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0}.table tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed th,.table-condensed td{padding:4px 5px}.table-bordered{border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.table-bordered th,.table-bordered td{border-left:1px solid #ddd}.table-bordered caption+thead tr:first-child th,.table-bordered caption+tbody tr:first-child th,.table-bordered caption+tbody tr:first-child td,.table-bordered colgroup+thead tr:first-child th,.table-bordered colgroup+tbody tr:first-child th,.table-bordered colgroup+tbody tr:first-child td,.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0}.table-bordered thead:first-child tr:first-child>th:first-child,.table-bordered tbody:first-child tr:first-child>td:first-child,.table-bordered tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered thead:first-child tr:first-child>th:last-child,.table-bordered tbody:first-child tr:first-child>td:last-child,.table-bordered tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-bordered thead:last-child tr:last-child>th:first-child,.table-bordered tbody:last-child tr:last-child>td:first-child,.table-bordered tbody:last-child tr:last-child>th:first-child,.table-bordered tfoot:last-child tr:last-child>td:first-child,.table-bordered tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}.table-bordered thead:last-child tr:last-child>th:last-child,.table-bordered tbody:last-child tr:last-child>td:last-child,.table-bordered tbody:last-child tr:last-child>th:last-child,.table-bordered tfoot:last-child tr:last-child>td:last-child,.table-bordered tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}.table-bordered tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}.table-bordered tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}.table-bordered caption+thead tr:first-child th:first-child,.table-bordered caption+tbody tr:first-child td:first-child,.table-bordered colgroup+thead tr:first-child th:first-child,.table-bordered colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}.table-bordered caption+thead tr:first-child th:last-child,.table-bordered caption+tbody tr:first-child td:last-child,.table-bordered colgroup+thead tr:first-child th:last-child,.table-bordered colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}.table-striped tbody>tr:nth-child(odd)>td,.table-striped tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover tbody tr:hover>td,.table-hover tbody tr:hover>th{background-color:#f5f5f5}table td[class*="span"],table th[class*="span"],.row-fluid table td[class*="span"],.row-fluid table th[class*="span"]{display:table-cell;float:none;margin-left:0}.table td.span1,.table th.span1{float:none;width:44px;margin-left:0}.table td.span2,.table th.span2{float:none;width:124px;margin-left:0}.table td.span3,.table th.span3{float:none;width:204px;margin-left:0}.table td.span4,.table th.span4{float:none;width:284px;margin-left:0}.table td.span5,.table th.span5{float:none;width:364px;margin-left:0}.table td.span6,.table th.span6{float:none;width:444px;margin-left:0}.table td.span7,.table th.span7{float:none;width:524px;margin-left:0}.table td.span8,.table th.span8{float:none;width:604px;margin-left:0}.table td.span9,.table th.span9{float:none;width:684px;margin-left:0}.table td.span10,.table th.span10{float:none;width:764px;margin-left:0}.table td.span11,.table th.span11{float:none;width:844px;margin-left:0}.table td.span12,.table th.span12{float:none;width:924px;margin-left:0}.table tbody tr.success>td{background-color:#dff0d8}.table tbody tr.error>td{background-color:#f2dede}.table tbody tr.warning>td{background-color:#fcf8e3}.table tbody tr.info>td{background-color:#d9edf7}.table-hover tbody tr.success:hover>td{background-color:#d0e9c6}.table-hover tbody tr.error:hover>td{background-color:#ebcccc}.table-hover tbody tr.warning:hover>td{background-color:#faf2cc}.table-hover tbody tr.info:hover>td{background-color:#c4e3f3}[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;margin-top:1px;*margin-right:.3em;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat}.icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:focus>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>li>a:focus>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:focus>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"],.dropdown-submenu:focus>a>[class*=" icon-"]{background-image:url("../img/glyphicons-halflings-white.png")}.icon-glass{background-position:0 0}.icon-music{background-position:-24px 0}.icon-search{background-position:-48px 0}.icon-envelope{background-position:-72px 0}.icon-heart{background-position:-96px 0}.icon-star{background-position:-120px 0}.icon-star-empty{background-position:-144px 0}.icon-user{background-position:-168px 0}.icon-film{background-position:-192px 0}.icon-th-large{background-position:-216px 0}.icon-th{background-position:-240px 0}.icon-th-list{background-position:-264px 0}.icon-ok{background-position:-288px 0}.icon-remove{background-position:-312px 0}.icon-zoom-in{background-position:-336px 0}.icon-zoom-out{background-position:-360px 0}.icon-off{background-position:-384px 0}.icon-signal{background-position:-408px 0}.icon-cog{background-position:-432px 0}.icon-trash{background-position:-456px 0}.icon-home{background-position:0 -24px}.icon-file{background-position:-24px -24px}.icon-time{background-position:-48px -24px}.icon-road{background-position:-72px -24px}.icon-download-alt{background-position:-96px -24px}.icon-download{background-position:-120px -24px}.icon-upload{background-position:-144px -24px}.icon-inbox{background-position:-168px -24px}.icon-play-circle{background-position:-192px -24px}.icon-repeat{background-position:-216px -24px}.icon-refresh{background-position:-240px -24px}.icon-list-alt{background-position:-264px -24px}.icon-lock{background-position:-287px -24px}.icon-flag{background-position:-312px -24px}.icon-headphones{background-position:-336px -24px}.icon-volume-off{background-position:-360px -24px}.icon-volume-down{background-position:-384px -24px}.icon-volume-up{background-position:-408px -24px}.icon-qrcode{background-position:-432px -24px}.icon-barcode{background-position:-456px -24px}.icon-tag{background-position:0 -48px}.icon-tags{background-position:-25px -48px}.icon-book{background-position:-48px -48px}.icon-bookmark{background-position:-72px -48px}.icon-print{background-position:-96px -48px}.icon-camera{background-position:-120px -48px}.icon-font{background-position:-144px -48px}.icon-bold{background-position:-167px -48px}.icon-italic{background-position:-192px -48px}.icon-text-height{background-position:-216px -48px}.icon-text-width{background-position:-240px -48px}.icon-align-left{background-position:-264px -48px}.icon-align-center{background-position:-288px -48px}.icon-align-right{background-position:-312px -48px}.icon-align-justify{background-position:-336px -48px}.icon-list{background-position:-360px -48px}.icon-indent-left{background-position:-384px -48px}.icon-indent-right{background-position:-408px -48px}.icon-facetime-video{background-position:-432px -48px}.icon-picture{background-position:-456px -48px}.icon-pencil{background-position:0 -72px}.icon-map-marker{background-position:-24px -72px}.icon-adjust{background-position:-48px -72px}.icon-tint{background-position:-72px -72px}.icon-edit{background-position:-96px -72px}.icon-share{background-position:-120px -72px}.icon-check{background-position:-144px -72px}.icon-move{background-position:-168px -72px}.icon-step-backward{background-position:-192px -72px}.icon-fast-backward{background-position:-216px -72px}.icon-backward{background-position:-240px -72px}.icon-play{background-position:-264px -72px}.icon-pause{background-position:-288px -72px}.icon-stop{background-position:-312px -72px}.icon-forward{background-position:-336px -72px}.icon-fast-forward{background-position:-360px -72px}.icon-step-forward{background-position:-384px -72px}.icon-eject{background-position:-408px -72px}.icon-chevron-left{background-position:-432px -72px}.icon-chevron-right{background-position:-456px -72px}.icon-plus-sign{background-position:0 -96px}.icon-minus-sign{background-position:-24px -96px}.icon-remove-sign{background-position:-48px -96px}.icon-ok-sign{background-position:-72px -96px}.icon-question-sign{background-position:-96px -96px}.icon-info-sign{background-position:-120px -96px}.icon-screenshot{background-position:-144px -96px}.icon-remove-circle{background-position:-168px -96px}.icon-ok-circle{background-position:-192px -96px}.icon-ban-circle{background-position:-216px -96px}.icon-arrow-left{background-position:-240px -96px}.icon-arrow-right{background-position:-264px -96px}.icon-arrow-up{background-position:-289px -96px}.icon-arrow-down{background-position:-312px -96px}.icon-share-alt{background-position:-336px -96px}.icon-resize-full{background-position:-360px -96px}.icon-resize-small{background-position:-384px -96px}.icon-plus{background-position:-408px -96px}.icon-minus{background-position:-433px -96px}.icon-asterisk{background-position:-456px -96px}.icon-exclamation-sign{background-position:0 -120px}.icon-gift{background-position:-24px -120px}.icon-leaf{background-position:-48px -120px}.icon-fire{background-position:-72px -120px}.icon-eye-open{background-position:-96px -120px}.icon-eye-close{background-position:-120px -120px}.icon-warning-sign{background-position:-144px -120px}.icon-plane{background-position:-168px -120px}.icon-calendar{background-position:-192px -120px}.icon-random{width:16px;background-position:-216px -120px}.icon-comment{background-position:-240px -120px}.icon-magnet{background-position:-264px -120px}.icon-chevron-up{background-position:-288px -120px}.icon-chevron-down{background-position:-313px -119px}.icon-retweet{background-position:-336px -120px}.icon-shopping-cart{background-position:-360px -120px}.icon-folder-close{width:16px;background-position:-384px -120px}.icon-folder-open{width:16px;background-position:-408px -120px}.icon-resize-vertical{background-position:-432px -119px}.icon-resize-horizontal{background-position:-456px -118px}.icon-hdd{background-position:0 -144px}.icon-bullhorn{background-position:-24px -144px}.icon-bell{background-position:-48px -144px}.icon-certificate{background-position:-72px -144px}.icon-thumbs-up{background-position:-96px -144px}.icon-thumbs-down{background-position:-120px -144px}.icon-hand-right{background-position:-144px -144px}.icon-hand-left{background-position:-168px -144px}.icon-hand-up{background-position:-192px -144px}.icon-hand-down{background-position:-216px -144px}.icon-circle-arrow-right{background-position:-240px -144px}.icon-circle-arrow-left{background-position:-264px -144px}.icon-circle-arrow-up{background-position:-288px -144px}.icon-circle-arrow-down{background-position:-312px -144px}.icon-globe{background-position:-336px -144px}.icon-wrench{background-position:-360px -144px}.icon-tasks{background-position:-384px -144px}.icon-filter{background-position:-408px -144px}.icon-briefcase{background-position:-432px -144px}.icon-fullscreen{background-position:-456px -144px}.dropup,.dropdown{position:relative}.dropdown-toggle{*margin-bottom:-3px}.dropdown-toggle:active,.open .dropdown-toggle{outline:0}.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.dropdown .caret{margin-top:8px;margin-left:2px}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus,.dropdown-submenu:hover>a,.dropdown-submenu:focus>a{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;outline:0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0077b3',GradientType=0)}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open{*z-index:1000}.open>.dropdown-menu{display:block}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}.dropdown-submenu{position:relative}.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px}.dropdown-submenu:hover>.dropdown-menu{display:block}.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0}.dropdown-submenu>a:after{display:block;float:right;width:0;height:0;margin-top:5px;margin-right:-10px;border-color:transparent;border-left-color:#ccc;border-style:solid;border-width:5px 0 5px 5px;content:" "}.dropdown-submenu:hover>a:after{border-left-color:#fff}.dropdown-submenu.pull-left{float:none}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.dropdown .dropdown-menu .nav-header{padding-right:20px;padding-left:20px}.typeahead{z-index:1051;margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.fade{opacity:0;-webkit-transition:opacity .15s linear;-moz-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-moz-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.collapse.in{height:auto}.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.btn{display:inline-block;*display:inline;padding:4px 12px;margin-bottom:0;*margin-left:.3em;font-size:14px;line-height:20px;color:#333;text-align:center;text-shadow:0 1px 1px rgba(255,255,255,0.75);vertical-align:middle;cursor:pointer;background-color:#f5f5f5;*background-color:#e6e6e6;background-image:-moz-linear-gradient(top,#fff,#e6e6e6);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));background-image:-webkit-linear-gradient(top,#fff,#e6e6e6);background-image:-o-linear-gradient(top,#fff,#e6e6e6);background-image:linear-gradient(to bottom,#fff,#e6e6e6);background-repeat:repeat-x;border:1px solid #ccc;*border:0;border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);*zoom:1;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn:hover,.btn:focus,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333;background-color:#e6e6e6;*background-color:#d9d9d9}.btn:active,.btn.active{background-color:#ccc \9}.btn:first-child{*margin-left:0}.btn:hover,.btn:focus{color:#333;text-decoration:none;background-position:0 -15px;-webkit-transition:background-position .1s linear;-moz-transition:background-position .1s linear;-o-transition:background-position .1s linear;transition:background-position .1s linear}.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn.disabled,.btn[disabled]{cursor:default;background-image:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:4px}.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0}.btn-mini [class^="icon-"],.btn-mini [class*=" icon-"]{margin-top:-1px}.btn-mini{padding:0 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.btn-block{display:block;width:100%;padding-right:0;padding-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255,255,255,0.75)}.btn-primary{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#006dcc;*background-color:#04c;background-image:-moz-linear-gradient(top,#08c,#04c);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#04c));background-image:-webkit-linear-gradient(top,#08c,#04c);background-image:-o-linear-gradient(top,#08c,#04c);background-image:linear-gradient(to bottom,#08c,#04c);background-repeat:repeat-x;border-color:#04c #04c #002a80;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc',endColorstr='#ff0044cc',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#fff;background-color:#04c;*background-color:#003bb3}.btn-primary:active,.btn-primary.active{background-color:#039 \9}.btn-warning{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#faa732;*background-color:#f89406;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;border-color:#f89406 #f89406 #ad6704;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#fff;background-color:#f89406;*background-color:#df8505}.btn-warning:active,.btn-warning.active{background-color:#c67605 \9}.btn-danger{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#da4f49;*background-color:#bd362f;background-image:-moz-linear-gradient(top,#ee5f5b,#bd362f);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#bd362f));background-image:-webkit-linear-gradient(top,#ee5f5b,#bd362f);background-image:-o-linear-gradient(top,#ee5f5b,#bd362f);background-image:linear-gradient(to bottom,#ee5f5b,#bd362f);background-repeat:repeat-x;border-color:#bd362f #bd362f #802420;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffbd362f',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#fff;background-color:#bd362f;*background-color:#a9302a}.btn-danger:active,.btn-danger.active{background-color:#942a25 \9}.btn-success{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#5bb75b;*background-color:#51a351;background-image:-moz-linear-gradient(top,#62c462,#51a351);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#51a351));background-image:-webkit-linear-gradient(top,#62c462,#51a351);background-image:-o-linear-gradient(top,#62c462,#51a351);background-image:linear-gradient(to bottom,#62c462,#51a351);background-repeat:repeat-x;border-color:#51a351 #51a351 #387038;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff51a351',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#fff;background-color:#51a351;*background-color:#499249}.btn-success:active,.btn-success.active{background-color:#408140 \9}.btn-info{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#49afcd;*background-color:#2f96b4;background-image:-moz-linear-gradient(top,#5bc0de,#2f96b4);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#2f96b4));background-image:-webkit-linear-gradient(top,#5bc0de,#2f96b4);background-image:-o-linear-gradient(top,#5bc0de,#2f96b4);background-image:linear-gradient(to bottom,#5bc0de,#2f96b4);background-repeat:repeat-x;border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2f96b4',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#fff;background-color:#2f96b4;*background-color:#2a85a0}.btn-info:active,.btn-info.active{background-color:#24748c \9}.btn-inverse{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#363636;*background-color:#222;background-image:-moz-linear-gradient(top,#444,#222);background-image:-webkit-gradient(linear,0 0,0 100%,from(#444),to(#222));background-image:-webkit-linear-gradient(top,#444,#222);background-image:-o-linear-gradient(top,#444,#222);background-image:linear-gradient(to bottom,#444,#222);background-repeat:repeat-x;border-color:#222 #222 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-inverse:hover,.btn-inverse:focus,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#fff;background-color:#222;*background-color:#151515}.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9}button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0}button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px}button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px}button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px}.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.btn-link{color:#08c;cursor:pointer;border-color:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-link:hover,.btn-link:focus{color:#005580;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,.btn-link[disabled]:focus{color:#333;text-decoration:none}.btn-group{position:relative;display:inline-block;*display:inline;*margin-left:.3em;font-size:0;white-space:nowrap;vertical-align:middle;*zoom:1}.btn-group:first-child{*margin-left:0}.btn-group+.btn-group{margin-left:5px}.btn-toolbar{margin-top:10px;margin-bottom:10px;font-size:0}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group{margin-left:5px}.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group>.btn+.btn{margin-left:-1px}.btn-group>.btn,.btn-group>.dropdown-menu,.btn-group>.popover{font-size:14px}.btn-group>.btn-mini{font-size:10.5px}.btn-group>.btn-small{font-size:11.9px}.btn-group>.btn-large{font-size:17.5px}.btn-group>.btn:first-child{margin-left:0;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{*padding-top:5px;padding-right:8px;*padding-bottom:5px;padding-left:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 1px 0 0 rgba(255,255,255,0.125),inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05)}.btn-group>.btn-mini+.dropdown-toggle{*padding-top:2px;padding-right:5px;*padding-bottom:2px;padding-left:5px}.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px}.btn-group>.btn-large+.dropdown-toggle{*padding-top:7px;padding-right:12px;*padding-bottom:7px;padding-left:12px}.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05)}.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6}.btn-group.open .btn-primary.dropdown-toggle{background-color:#04c}.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406}.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f}.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351}.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4}.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222}.btn .caret{margin-top:8px;margin-left:0}.btn-large .caret{margin-top:6px}.btn-large .caret{border-top-width:5px;border-right-width:5px;border-left-width:5px}.btn-mini .caret,.btn-small .caret{margin-top:8px}.dropup .btn-large .caret{border-bottom-width:5px}.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#fff;border-bottom-color:#fff}.btn-group-vertical{display:inline-block;*display:inline;*zoom:1}.btn-group-vertical>.btn{display:block;float:none;max-width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.btn-group-vertical>.btn+.btn{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.btn-group-vertical>.btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0}.btn-group-vertical>.btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.alert,.alert h4{color:#c09853}.alert h4{margin:0}.alert .close{position:relative;top:-2px;right:-21px;line-height:20px}.alert-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.alert-success h4{color:#468847}.alert-danger,.alert-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.alert-danger h4,.alert-error h4{color:#b94a48}.alert-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.alert-info h4{color:#3a87ad}.alert-block{padding-top:14px;padding-bottom:14px}.alert-block>p,.alert-block>ul{margin-bottom:0}.alert-block p+p{margin-top:5px}.nav{margin-bottom:20px;margin-left:0;list-style:none}.nav>li>a{display:block}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li>a>img{max-width:none}.nav>.pull-right{float:right}.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999;text-shadow:0 1px 0 rgba(255,255,255,0.5);text-transform:uppercase}.nav li+.nav-header{margin-top:9px}.nav-list{padding-right:15px;padding-left:15px;margin-bottom:0}.nav-list>li>a,.nav-list .nav-header{margin-right:-15px;margin-left:-15px;text-shadow:0 1px 0 rgba(255,255,255,0.5)}.nav-list>li>a{padding:3px 15px}.nav-list>.active>a,.nav-list>.active>a:hover,.nav-list>.active>a:focus{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.2);background-color:#08c}.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px}.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #fff}.nav-tabs,.nav-pills{*zoom:1}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;line-height:0;content:""}.nav-tabs:after,.nav-pills:after{clear:both}.nav-tabs>li,.nav-pills>li{float:left}.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{margin-bottom:-1px}.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus{border-color:#eee #eee #ddd}.nav-tabs>.active>a,.nav-tabs>.active>a:hover,.nav-tabs>.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nav-pills>.active>a,.nav-pills>.active>a:hover,.nav-pills>.active>a:focus{color:#fff;background-color:#08c}.nav-stacked>li{float:none}.nav-stacked>li>a{margin-right:0}.nav-tabs.nav-stacked{border-bottom:0}.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.nav-tabs.nav-stacked>li>a:hover,.nav-tabs.nav-stacked>li>a:focus{z-index:2;border-color:#ddd}.nav-pills.nav-stacked>li>a{margin-bottom:3px}.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px}.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.nav .dropdown-toggle .caret{margin-top:6px;border-top-color:#08c;border-bottom-color:#08c}.nav .dropdown-toggle:hover .caret,.nav .dropdown-toggle:focus .caret{border-top-color:#005580;border-bottom-color:#005580}.nav-tabs .dropdown-toggle .caret{margin-top:8px}.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.nav>.dropdown.active>a:hover,.nav>.dropdown.active>a:focus{cursor:pointer}.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover,.nav>li.dropdown.open.active>a:focus{color:#fff;background-color:#999;border-color:#999}.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret,.nav li.dropdown.open a:focus .caret{border-top-color:#fff;border-bottom-color:#fff;opacity:1;filter:alpha(opacity=100)}.tabs-stacked .open>a:hover,.tabs-stacked .open>a:focus{border-color:#999}.tabbable{*zoom:1}.tabbable:before,.tabbable:after{display:table;line-height:0;content:""}.tabbable:after{clear:both}.tab-content{overflow:auto}.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0}.tab-content>.tab-pane,.pill-content>.pill-pane{display:none}.tab-content>.active,.pill-content>.active{display:block}.tabs-below>.nav-tabs{border-top:1px solid #ddd}.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0}.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}.tabs-below>.nav-tabs>li>a:hover,.tabs-below>.nav-tabs>li>a:focus{border-top-color:#ddd;border-bottom-color:transparent}.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover,.tabs-below>.nav-tabs>.active>a:focus{border-color:transparent #ddd #ddd #ddd}.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none}.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px}.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd}.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.tabs-left>.nav-tabs>li>a:hover,.tabs-left>.nav-tabs>li>a:focus{border-color:#eee #ddd #eee #eee}.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover,.tabs-left>.nav-tabs .active>a:focus{border-color:#ddd transparent #ddd #ddd;*border-right-color:#fff}.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd}.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.tabs-right>.nav-tabs>li>a:hover,.tabs-right>.nav-tabs>li>a:focus{border-color:#eee #eee #eee #ddd}.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover,.tabs-right>.nav-tabs .active>a:focus{border-color:#ddd #ddd #ddd transparent;*border-left-color:#fff}.nav>.disabled>a{color:#999}.nav>.disabled>a:hover,.nav>.disabled>a:focus{text-decoration:none;cursor:default;background-color:transparent}.navbar{*position:relative;*z-index:2;margin-bottom:20px;overflow:visible}.navbar-inner{min-height:40px;padding-right:20px;padding-left:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff2f2f2',GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,0.065);box-shadow:0 1px 4px rgba(0,0,0,0.065)}.navbar-inner:before,.navbar-inner:after{display:table;line-height:0;content:""}.navbar-inner:after{clear:both}.navbar .container{width:auto}.nav-collapse.collapse{height:auto;overflow:visible}.navbar .brand{display:block;float:left;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777;text-shadow:0 1px 0 #fff}.navbar .brand:hover,.navbar .brand:focus{text-decoration:none}.navbar-text{margin-bottom:0;line-height:40px;color:#777}.navbar-link{color:#777}.navbar-link:hover,.navbar-link:focus{color:#333}.navbar .divider-vertical{height:40px;margin:0 9px;border-right:1px solid #fff;border-left:1px solid #f2f2f2}.navbar .btn,.navbar .btn-group{margin-top:5px}.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn,.navbar .input-prepend .btn-group,.navbar .input-append .btn-group{margin-top:0}.navbar-form{margin-bottom:0;*zoom:1}.navbar-form:before,.navbar-form:after{display:table;line-height:0;content:""}.navbar-form:after{clear:both}.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px}.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0}.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px}.navbar-form .input-append,.navbar-form .input-prepend{margin-top:5px;white-space:nowrap}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0}.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0}.navbar-search .search-query{padding:4px 14px;margin-bottom:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.navbar-static-top{position:static;margin-bottom:0}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px}.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-right:0;padding-left:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px}.navbar-fixed-top{top:0}.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,0.1);box-shadow:0 1px 10px rgba(0,0,0,0.1)}.navbar-fixed-bottom{bottom:0}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,0.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,0.1);box-shadow:0 -1px 10px rgba(0,0,0,0.1)}.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0}.navbar .nav.pull-right{float:right;margin-right:0}.navbar .nav>li{float:left}.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777;text-decoration:none;text-shadow:0 1px 0 #fff}.navbar .nav .dropdown-toggle .caret{margin-top:8px}.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{color:#333;text-decoration:none;background-color:transparent}.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 8px rgba(0,0,0,0.125);box-shadow:inset 0 3px 8px rgba(0,0,0,0.125)}.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-right:5px;margin-left:5px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#ededed;*background-color:#e5e5e5;background-image:-moz-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f2f2f2),to(#e5e5e5));background-image:-webkit-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:-o-linear-gradient(top,#f2f2f2,#e5e5e5);background-image:linear-gradient(to bottom,#f2f2f2,#e5e5e5);background-repeat:repeat-x;border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2',endColorstr='#ffe5e5e5',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.075)}.navbar .btn-navbar:hover,.navbar .btn-navbar:focus,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#fff;background-color:#e5e5e5;*background-color:#d9d9d9}.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#ccc \9}.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.25);-moz-box-shadow:0 1px 0 rgba(0,0,0,0.25);box-shadow:0 1px 0 rgba(0,0,0,0.25)}.btn-navbar .icon-bar+.icon-bar{margin-top:3px}.navbar .nav>li>.dropdown-menu:before{position:absolute;top:-7px;left:9px;display:inline-block;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-left:7px solid transparent;border-bottom-color:rgba(0,0,0,0.2);content:''}.navbar .nav>li>.dropdown-menu:after{position:absolute;top:-6px;left:10px;display:inline-block;border-right:6px solid transparent;border-bottom:6px solid #fff;border-left:6px solid transparent;content:''}.navbar-fixed-bottom .nav>li>.dropdown-menu:before{top:auto;bottom:-7px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.navbar-fixed-bottom .nav>li>.dropdown-menu:after{top:auto;bottom:-6px;border-top:6px solid #fff;border-bottom:0}.navbar .nav li.dropdown>a:hover .caret,.navbar .nav li.dropdown>a:focus .caret{border-top-color:#333;border-bottom-color:#333}.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{color:#555;background-color:#e5e5e5}.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777;border-bottom-color:#777}.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555;border-bottom-color:#555}.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{right:0;left:auto}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{right:12px;left:auto}.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{right:13px;left:auto}.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{right:100%;left:auto;margin-right:-1px;margin-left:0;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top,#222,#111);background-image:-webkit-gradient(linear,0 0,0 100%,from(#222),to(#111));background-image:-webkit-linear-gradient(top,#222,#111);background-image:-o-linear-gradient(top,#222,#111);background-image:linear-gradient(to bottom,#222,#111);background-repeat:repeat-x;border-color:#252525;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff111111',GradientType=0)}.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999;text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover,.navbar-inverse .brand:focus,.navbar-inverse .nav>li>a:focus{color:#fff}.navbar-inverse .brand{color:#999}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#fff;background-color:#111}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover,.navbar-inverse .navbar-link:focus{color:#fff}.navbar-inverse .divider-vertical{border-right-color:#222;border-left-color:#111}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{color:#fff;background-color:#111}.navbar-inverse .nav li.dropdown>a:hover .caret,.navbar-inverse .nav li.dropdown>a:focus .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999;border-bottom-color:#999}.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff}.navbar-inverse .navbar-search .search-query{color:#fff;background-color:#515151;border-color:#111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 1px 0 rgba(255,255,255,0.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#ccc}.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333;text-shadow:0 1px 0 #fff;background-color:#fff;border:0;outline:0;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.15);-moz-box-shadow:0 0 3px rgba(0,0,0,0.15);box-shadow:0 0 3px rgba(0,0,0,0.15)}.navbar-inverse .btn-navbar{color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e0e0e;*background-color:#040404;background-image:-moz-linear-gradient(top,#151515,#040404);background-image:-webkit-gradient(linear,0 0,0 100%,from(#151515),to(#040404));background-image:-webkit-linear-gradient(top,#151515,#040404);background-image:-o-linear-gradient(top,#151515,#040404);background-image:linear-gradient(to bottom,#151515,#040404);background-repeat:repeat-x;border-color:#040404 #040404 #000;border-color:rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515',endColorstr='#ff040404',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:focus,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#fff;background-color:#040404;*background-color:#000}.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000 \9}.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.breadcrumb>li{display:inline-block;*display:inline;text-shadow:0 1px 0 #fff;*zoom:1}.breadcrumb>li>.divider{padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{margin:20px 0}.pagination ul{display:inline-block;*display:inline;margin-bottom:0;margin-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*zoom:1;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);-moz-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.pagination ul>li{display:inline}.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#fff;border:1px solid #ddd;border-left-width:0}.pagination ul>li>a:hover,.pagination ul>li>a:focus,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5}.pagination ul>.active>a,.pagination ul>.active>span{color:#999;cursor:default}.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover,.pagination ul>.disabled>a:focus{color:#999;cursor:default;background-color:transparent}.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-bottomleft:4px;-moz-border-radius-topleft:4px}.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-bottomright:4px}.pagination-centered{text-align:center}.pagination-right{text-align:right}.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px}.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-bottom-left-radius:6px;border-bottom-left-radius:6px;-webkit-border-top-left-radius:6px;border-top-left-radius:6px;-moz-border-radius-bottomleft:6px;-moz-border-radius-topleft:6px}.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;border-bottom-right-radius:6px;-moz-border-radius-topright:6px;-moz-border-radius-bottomright:6px}.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-bottom-left-radius:3px;border-bottom-left-radius:3px;-webkit-border-top-left-radius:3px;border-top-left-radius:3px;-moz-border-radius-bottomleft:3px;-moz-border-radius-topleft:3px}.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;border-bottom-right-radius:3px;-moz-border-radius-topright:3px;-moz-border-radius-bottomright:3px}.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px}.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:0 6px;font-size:10.5px}.pager{margin:20px 0;text-align:center;list-style:none;*zoom:1}.pager:before,.pager:after{display:table;line-height:0;content:""}.pager:after{clear:both}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#f5f5f5}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;cursor:default;background-color:#fff}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop,.modal-backdrop.fade.in{opacity:.8;filter:alpha(opacity=80)}.modal{position:fixed;top:10%;left:50%;z-index:1050;width:560px;margin-left:-280px;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;outline:0;-webkit-box-shadow:0 3px 7px rgba(0,0,0,0.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,0.3);box-shadow:0 3px 7px rgba(0,0,0,0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.modal.fade{top:-25%;-webkit-transition:opacity .3s linear,top .3s ease-out;-moz-transition:opacity .3s linear,top .3s ease-out;-o-transition:opacity .3s linear,top .3s ease-out;transition:opacity .3s linear,top .3s ease-out}.modal.fade.in{top:10%}.modal-header{padding:9px 15px;border-bottom:1px solid #eee}.modal-header .close{margin-top:2px}.modal-header h3{margin:0;line-height:30px}.modal-body{position:relative;max-height:400px;padding:15px;overflow-y:auto}.modal-form{margin-bottom:0}.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;*zoom:1;-webkit-box-shadow:inset 0 1px 0 #fff;-moz-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff}.modal-footer:before,.modal-footer:after{display:table;line-height:0;content:""}.modal-footer:after{clear:both}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.tooltip{position:absolute;z-index:1030;display:block;font-size:11px;line-height:1.4;opacity:0;filter:alpha(opacity=0);visibility:visible}.tooltip.in{opacity:.8;filter:alpha(opacity=80)}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-color:#000;border-width:5px 5px 0}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-right-color:#000;border-width:5px 5px 5px 0}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-left-color:#000;border-width:5px 0 5px 5px}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-color:#000;border-width:0 5px 5px}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.popover-title:empty{display:none}.popover-content{padding:9px 14px}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover .arrow{border-width:11px}.popover .arrow:after{border-width:10px;content:""}.popover.top .arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,0.25);border-bottom-width:0}.popover.top .arrow:after{bottom:1px;margin-left:-10px;border-top-color:#fff;border-bottom-width:0}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,0.25);border-left-width:0}.popover.right .arrow:after{bottom:-10px;left:1px;border-right-color:#fff;border-left-width:0}.popover.bottom .arrow{top:-11px;left:50%;margin-left:-11px;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,0.25);border-top-width:0}.popover.bottom .arrow:after{top:1px;margin-left:-10px;border-bottom-color:#fff;border-top-width:0}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-left-color:#999;border-left-color:rgba(0,0,0,0.25);border-right-width:0}.popover.left .arrow:after{right:1px;bottom:-10px;border-left-color:#fff;border-right-width:0}.thumbnails{margin-left:-20px;list-style:none;*zoom:1}.thumbnails:before,.thumbnails:after{display:table;line-height:0;content:""}.thumbnails:after{clear:both}.row-fluid .thumbnails{margin-left:0}.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px}.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.055);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.055);box-shadow:0 1px 3px rgba(0,0,0,0.055);-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}a.thumbnail:hover,a.thumbnail:focus{border-color:#08c;-webkit-box-shadow:0 1px 4px rgba(0,105,214,0.25);-moz-box-shadow:0 1px 4px rgba(0,105,214,0.25);box-shadow:0 1px 4px rgba(0,105,214,0.25)}.thumbnail>img{display:block;max-width:100%;margin-right:auto;margin-left:auto}.thumbnail .caption{padding:9px;color:#555}.media,.media-body{overflow:hidden;*overflow:visible;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{margin-left:0;list-style:none}.label,.badge{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999}.label{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.badge{padding-right:9px;padding-left:9px;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px}.label:empty,.badge:empty{display:none}a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.label-important,.badge-important{background-color:#b94a48}.label-important[href],.badge-important[href]{background-color:#953b39}.label-warning,.badge-warning{background-color:#f89406}.label-warning[href],.badge-warning[href]{background-color:#c67605}.label-success,.badge-success{background-color:#468847}.label-success[href],.badge-success[href]{background-color:#356635}.label-info,.badge-info{background-color:#3a87ad}.label-info[href],.badge-info[href]{background-color:#2d6987}.label-inverse,.badge-inverse{background-color:#333}.label-inverse[href],.badge-inverse[href]{background-color:#1a1a1a}.btn .label,.btn .badge{position:relative;top:-1px}.btn-mini .label,.btn-mini .badge{top:0}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:0 0}to{background-position:40px 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress .bar{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 1px 0 0 rgba(0,0,0,0.15),inset 0 -1px 0 rgba(0,0,0,0.15)}.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px}.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top,#ee5f5b,#c43c35);background-image:-webkit-gradient(linear,0 0,0 100%,from(#ee5f5b),to(#c43c35));background-image:-webkit-linear-gradient(top,#ee5f5b,#c43c35);background-image:-o-linear-gradient(top,#ee5f5b,#c43c35);background-image:linear-gradient(to bottom,#ee5f5b,#c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b',endColorstr='#ffc43c35',GradientType=0)}.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top,#62c462,#57a957);background-image:-webkit-gradient(linear,0 0,0 100%,from(#62c462),to(#57a957));background-image:-webkit-linear-gradient(top,#62c462,#57a957);background-image:-o-linear-gradient(top,#62c462,#57a957);background-image:linear-gradient(to bottom,#62c462,#57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462',endColorstr='#ff57a957',GradientType=0)}.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top,#5bc0de,#339bb9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#5bc0de),to(#339bb9));background-image:-webkit-linear-gradient(top,#5bc0de,#339bb9);background-image:-o-linear-gradient(top,#5bc0de,#339bb9);background-image:linear-gradient(to bottom,#5bc0de,#339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff339bb9',GradientType=0)}.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top,#fbb450,#f89406);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fbb450),to(#f89406));background-image:-webkit-linear-gradient(top,#fbb450,#f89406);background-image:-o-linear-gradient(top,#fbb450,#f89406);background-image:linear-gradient(to bottom,#fbb450,#f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450',endColorstr='#fff89406',GradientType=0)}.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear,0 100%,100% 0,color-stop(0.25,rgba(255,255,255,0.15)),color-stop(0.25,transparent),color-stop(0.5,transparent),color-stop(0.5,rgba(255,255,255,0.15)),color-stop(0.75,rgba(255,255,255,0.15)),color-stop(0.75,transparent),to(transparent));background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-moz-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,0.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,0.15) 50%,rgba(255,255,255,0.15) 75%,transparent 75%,transparent)}.accordion{margin-bottom:20px}.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.accordion-heading{border-bottom:0}.accordion-heading .accordion-toggle{display:block;padding:8px 15px}.accordion-toggle{cursor:pointer}.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5}.carousel{position:relative;margin-bottom:20px;line-height:1}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-moz-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#fff;text-align:center;background:#222;border:3px solid #fff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:.5;filter:alpha(opacity=50)}.carousel-control.right{right:15px;left:auto}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-indicators{position:absolute;top:15px;right:15px;z-index:5;margin:0;list-style:none}.carousel-indicators li{display:block;float:left;width:10px;height:10px;margin-left:5px;text-indent:-999px;background-color:#ccc;background-color:rgba(255,255,255,0.25);border-radius:5px}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:0;bottom:0;left:0;padding:15px;background:#333;background:rgba(0,0,0,0.75)}.carousel-caption h4,.carousel-caption p{line-height:20px;color:#fff}.carousel-caption h4{margin:0 0 5px}.carousel-caption p{margin-bottom:0}.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;letter-spacing:-1px;color:inherit}.hero-unit li{line-height:30px}.pull-right{float:right}.pull-left{float:left}.hide{display:none}.show{display:block}.invisible{visibility:hidden}.affix{position:fixed}
Added: WebTimer/src/common/img/glyphicons-halflings-white.png
===================================================================
(Binary files differ)
Property changes on: WebTimer/src/common/img/glyphicons-halflings-white.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: WebTimer/src/common/img/glyphicons-halflings.png
===================================================================
(Binary files differ)
Property changes on: WebTimer/src/common/img/glyphicons-halflings.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
1
0
Author: kmorin
Date: 2013-06-14 11:12:04 +0200 (Fri, 14 Jun 2013)
New Revision: 669
Url: http://nuiton.org/projects/sandbox/repository/revisions/669
Log:
add project in sandbox
Added:
WebTimer/
1
0
r668 - in nuiton-jpa: nuiton-jpa-api/src/main/java/org/nuiton/jpa/api nuiton-jpa-templates/src/it/magalie-with-generated-value/src/main/xmi nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates
by tchemit@users.nuiton.org June 12, 2013
by tchemit@users.nuiton.org June 12, 2013
June 12, 2013
Author: tchemit
Date: 2013-06-12 10:20:19 +0200 (Wed, 12 Jun 2013)
New Revision: 668
Url: http://nuiton.org/projects/sandbox/repository/revisions/668
Log:
add PCS Support + clean code
Modified:
nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaDao.java
nuiton-jpa/nuiton-jpa-templates/src/it/magalie-with-generated-value/src/main/xmi/magalie.properties
nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/AbstractJpaTransformer.java
nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java
nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaModelValidator.java
nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaPersistenceContextTransformer.java
nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java
nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesStereoTypes.java
nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesTagValues.java
Modified: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaDao.java
===================================================================
--- nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaDao.java 2013-06-11 14:55:44 UTC (rev 667)
+++ nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaDao.java 2013-06-12 08:20:19 UTC (rev 668)
@@ -35,14 +35,13 @@
/**
* This abstract class gather all code which is common to all daos for all entities.
- *
+ * <p/>
* Code included is common implementations of {@link JpaDao} interface and there is
* also commun helpers methods for implementation business-specific operations
* exposed as protected.
*
* @author bleny <leny(a)codelutin.com>
* @author tchemit <chemit(a)codelutin.com>
- *
* @since 0.1
*/
public abstract class AbstractJpaDao<E extends JpaEntity> implements JpaDao<E> {
@@ -89,8 +88,7 @@
return entityManager.contains(entity);
}
- public E findByProperty(String propertyName, Object value)
- {
+ public E findByProperty(String propertyName, Object value) {
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(propertyName, value);
E result = findByProperties(properties);
@@ -98,36 +96,34 @@
}
public List<E> findAllByProperty(String propertyName, Object value) {
- TypedQuery<E> query = createQuery(propertyName, value);
+ TypedQuery<E> query = createQuery(propertyName, value);
List<E> result = findAll(query);
return result;
}
- public List<E> findAllByProperties(Map<String, Object> properties)
- {
- TypedQuery<E> query = createQuery(properties);
+ public List<E> findAllByProperties(Map<String, Object> properties) {
+ TypedQuery<E> query = createQuery(properties);
List<E> results = findAll(query);
return results;
}
- public E findByProperties(Map<String, Object> properties)
- {
- TypedQuery<E> query = createQuery(properties);
+ public E findByProperties(Map<String, Object> properties) {
+ TypedQuery<E> query = createQuery(properties);
E result = findAnyOrNull(query);
return result;
}
public E findContains(String propertyName,
Object property) {
- TypedQuery<E> query= createQuery("From "+getEntityClass().getSimpleName()+" Where "+propertyName+" in elements(:K)");
+ TypedQuery<E> query = createQuery("From " + getEntityClass().getSimpleName() + " Where " + propertyName + " In elements(:K)");
query.setParameter("K", property);
return findAnyOrNull(query);
}
public List<E> findAllContains(String propertyName,
Object property) {
- TypedQuery<E> query = createQuery("From "+getEntityClass().getSimpleName()+" Where "+propertyName+" in elements(:K)");
- query.setParameter("K", property);
+ TypedQuery<E> query = createQuery("From " + getEntityClass().getSimpleName() + " Where " + propertyName + " In elements(:K)");
+ query.setParameter("K", property);
return findAll(query);
}
@@ -138,7 +134,7 @@
newInstance = getEntityClass().newInstance();
// TODO brendan 24/05/13 proper exception management
} catch (InstantiationException e) {
- throw new RuntimeException(e);
+ throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
@@ -160,13 +156,13 @@
} catch (ClassCastException eee) {
throw new IllegalArgumentException(
"Les noms des propriétés doivent être des chaines et " +
- "non pas " + propertyName.getClass().getName(),
+ "non pas " + propertyName.getClass().getName(),
eee);
} catch (ArrayIndexOutOfBoundsException eee) {
throw new IllegalArgumentException(
"Le nombre d'argument n'est pas un nombre pair: "
- + (others.length + 2)
- + " La dernière propriété était: " + name, eee);
+ + (others.length + 2)
+ + " La dernière propriété était: " + name, eee);
}
}
return createQuery(properties);
@@ -191,8 +187,8 @@
}
protected <E> TypedQuery<E> createQuery(Class<E> type, String propertyName,
- Object propertyValue,
- Object... others) {
+ Object propertyValue,
+ Object... others) {
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(propertyName, propertyValue);
@@ -217,7 +213,7 @@
return createQuery(type, properties);
}
- protected <E>TypedQuery<E> createQuery(Class<E> type, Map<String, Object> properties) {
+ protected <E> TypedQuery<E> createQuery(Class<E> type, Map<String, Object> properties) {
List<String> whereClauses = new LinkedList<String>();
for (String propertyName : properties.keySet()) {
whereClauses.add(propertyName + " = :" + propertyName);
@@ -235,7 +231,7 @@
return query;
}
- protected List<E> findAll(TypedQuery <E> query) {
+ protected List<E> findAll(TypedQuery<E> query) {
return query.getResultList();
}
@@ -246,7 +242,7 @@
protected E findAnyOrNull(TypedQuery<E> query) {
List<E> all = findAll(query);
E onlyElement = null;
- if ( ! all.isEmpty()) {
+ if (!all.isEmpty()) {
onlyElement = all.get(0);
}
return onlyElement;
@@ -255,7 +251,7 @@
protected E findUniqueOrNull(TypedQuery<E> query) {
List<E> all = findAll(query);
E onlyElement = null;
- if ( ! all.isEmpty()) {
+ if (!all.isEmpty()) {
if (all.size() > 1) {
throw new IllegalStateException(
"multiple results for query = " + query
Modified: nuiton-jpa/nuiton-jpa-templates/src/it/magalie-with-generated-value/src/main/xmi/magalie.properties
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/it/magalie-with-generated-value/src/main/xmi/magalie.properties 2013-06-11 14:55:44 UTC (rev 667)
+++ nuiton-jpa/nuiton-jpa-templates/src/it/magalie-with-generated-value/src/main/xmi/magalie.properties 2013-06-12 08:20:19 UTC (rev 668)
@@ -22,6 +22,7 @@
# #L%
###
model.tagValue.idFactory=true
+model.tagValue.generatePropertyChangeListeners=true
com.franciaflex.magalie.persistence.entity.Article.attribute.fixedLocations.stereotype=unique
Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/AbstractJpaTransformer.java
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/AbstractJpaTransformer.java 2013-06-11 14:55:44 UTC (rev 667)
+++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/AbstractJpaTransformer.java 2013-06-12 08:20:19 UTC (rev 668)
@@ -179,98 +179,4 @@
}
return foundSerializable;
}
-
- protected void createPropertyChangeSupport(ObjectModelClass output) {
-
- addAttribute(output,
- "pcs",
- PropertyChangeSupport.class,
- "new PropertyChangeSupport(this)",
- ObjectModelJavaModifier.PROTECTED,
- ObjectModelJavaModifier.FINAL,
- ObjectModelJavaModifier.TRANSIENT
- );
-
- // Add PropertyListener
-
- ObjectModelOperation operation;
-
- operation = addOperation(output,
- "addPropertyChangeListener",
- "void",
- ObjectModelJavaModifier.PUBLIC
- );
- addParameter(operation, PropertyChangeListener.class, "listener");
- setOperationBody(operation, ""
- /*{
- pcs.addPropertyChangeListener(listener);
- }*/
- );
-
- operation = addOperation(output,
- "addPropertyChangeListener",
- "void",
- ObjectModelJavaModifier.PUBLIC
- );
- addParameter(operation, String.class, "propertyName");
- addParameter(operation, PropertyChangeListener.class, "listener");
- setOperationBody(operation, ""
- /*{
- pcs.addPropertyChangeListener(propertyName, listener);
- }*/
- );
-
- operation = addOperation(output,
- "removePropertyChangeListener",
- "void",
- ObjectModelJavaModifier.PUBLIC
- );
- addParameter(operation, PropertyChangeListener.class, "listener");
- setOperationBody(operation, ""
- /*{
- pcs.removePropertyChangeListener(listener);
- }*/
- );
-
- operation = addOperation(output,
- "removePropertyChangeListener",
- "void",
- ObjectModelJavaModifier.PUBLIC
- );
- addParameter(operation, String.class, "propertyName");
- addParameter(operation, PropertyChangeListener.class, "listener");
- setOperationBody(operation, ""
- /*{
- pcs.removePropertyChangeListener(propertyName, listener);
- }*/
- );
-
- operation = addOperation(output,
- "firePropertyChange",
- "void",
- ObjectModelJavaModifier.PROTECTED
- );
- addParameter(operation, String.class, "propertyName");
- addParameter(operation, Object.class, "oldValue");
- addParameter(operation, Object.class, "newValue");
- setOperationBody(operation, ""
- /*{
- pcs.firePropertyChange(propertyName, oldValue, newValue);
- }*/
- );
-
- operation = addOperation(output,
- "firePropertyChange",
- "void",
- ObjectModelJavaModifier.PROTECTED
- );
- addParameter(operation, String.class, "propertyName");
- addParameter(operation, Object.class, "newValue");
- setOperationBody(operation, ""
- /*{
- firePropertyChange(propertyName, null, newValue);
- }*/
- );
- }
-
}
Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java 2013-06-11 14:55:44 UTC (rev 667)
+++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java 2013-06-12 08:20:19 UTC (rev 668)
@@ -55,6 +55,8 @@
import javax.persistence.OneToOne;
import javax.persistence.OrderColumn;
import javax.persistence.PrePersist;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
import java.util.Collection;
import java.util.List;
import java.util.Set;
@@ -80,8 +82,6 @@
private static final Log log =
LogFactory.getLog(JpaEntityTransformer.class);
-// public static final String PROPERTY_ID = "id";
-
@Override
public void transformFromClass(ObjectModelClass input) {
@@ -198,6 +198,8 @@
);
}
+ boolean usePCS = JpaTemplatesGeneratorUtil.useGeneratePropertyChangeListeners(getModel());
+
Set<String> constantNames = addConstantsFromDependency(input, output);
// Get available properties
@@ -226,9 +228,15 @@
// Add properties field + javabean methods
for (ObjectModelAttribute attr : properties) {
- createProperty(output, attr, annotationsForAttributes.get(attr));
+ createProperty(output, attr, usePCS, annotationsForAttributes.get(attr));
}
+ if (usePCS) {
+
+ // Add property change support
+ createPropertyChangeSupport(output);
+ }
+
boolean hasAMultipleProperty =
JpaTemplatesGeneratorUtil.containsMutiple(properties);
@@ -403,10 +411,9 @@
protected void createProperty(ObjectModelClass output,
ObjectModelAttribute attr,
+ boolean usePCS,
Collection<String> annotations) {
- boolean usePCS = false;
-
String attrName = JpaTemplatesGeneratorUtil.getAttributeName(attr);
String attrType = JpaTemplatesGeneratorUtil.getAttributeType(attr);
@@ -484,13 +491,20 @@
boolean booleanProperty = JpaTemplatesGeneratorUtil.isBooleanPrimitive(attr);
+ String getterPrefix;
if (booleanProperty && !multiple) {
+ getterPrefix = JpaTemplatesGeneratorUtil.OPERATION_GETTER_BOOLEAN_PREFIX;
+ } else {
+ getterPrefix = JpaTemplatesGeneratorUtil.OPERATION_GETTER_DEFAULT_PREFIX;
+ }
+ if (booleanProperty && !multiple) {
+
// creates a isXXX method
createGetMethod(output,
attrName,
attrType,
- JpaTemplatesGeneratorUtil.OPERATION_GETTER_BOOLEAN_PREFIX
+ getterPrefix
);
}
@@ -499,7 +513,7 @@
ObjectModelOperation getMethod = createGetMethod(output,
attrName,
attrType,
- JpaTemplatesGeneratorUtil.OPERATION_GETTER_DEFAULT_PREFIX
+ getterPrefix
);
if (JpaEntity.PROPERTY_ID.equals(attrName)) {
@@ -512,6 +526,7 @@
attrType,
simpleType,
constantName,
+ getterPrefix,
usePCS
);
@@ -820,6 +835,7 @@
String attrType,
String simpleType,
String constantName,
+ String getterPrefix,
boolean usePCS) {
ObjectModelOperation operation = addOperation(
output,
@@ -830,7 +846,7 @@
addParameter(operation, attrType, attrName);
if (usePCS) {
- String methodName = getJavaBeanMethodName("get", attrName);
+ String methodName = getJavaBeanMethodName(getterPrefix, attrName);
setOperationBody(operation, ""
/*{
<%=simpleType%> oldValue = <%=methodName%>();
@@ -880,4 +896,97 @@
}*/
);
}
+
+ protected void createPropertyChangeSupport(ObjectModelClass output) {
+
+ addAttribute(output,
+ "pcs",
+ PropertyChangeSupport.class,
+ "new PropertyChangeSupport(this)",
+ ObjectModelJavaModifier.PROTECTED,
+ ObjectModelJavaModifier.FINAL,
+ ObjectModelJavaModifier.TRANSIENT
+ );
+
+ // Add PropertyListener
+
+ ObjectModelOperation operation;
+
+ operation = addOperation(output,
+ "addPropertyChangeListener",
+ "void",
+ ObjectModelJavaModifier.PUBLIC
+ );
+ addParameter(operation, PropertyChangeListener.class, "listener");
+ setOperationBody(operation, ""
+ /*{
+ pcs.addPropertyChangeListener(listener);
+ }*/
+ );
+
+ operation = addOperation(output,
+ "addPropertyChangeListener",
+ "void",
+ ObjectModelJavaModifier.PUBLIC
+ );
+ addParameter(operation, String.class, "propertyName");
+ addParameter(operation, PropertyChangeListener.class, "listener");
+ setOperationBody(operation, ""
+ /*{
+ pcs.addPropertyChangeListener(propertyName, listener);
+ }*/
+ );
+
+ operation = addOperation(output,
+ "removePropertyChangeListener",
+ "void",
+ ObjectModelJavaModifier.PUBLIC
+ );
+ addParameter(operation, PropertyChangeListener.class, "listener");
+ setOperationBody(operation, ""
+ /*{
+ pcs.removePropertyChangeListener(listener);
+ }*/
+ );
+
+ operation = addOperation(output,
+ "removePropertyChangeListener",
+ "void",
+ ObjectModelJavaModifier.PUBLIC
+ );
+ addParameter(operation, String.class, "propertyName");
+ addParameter(operation, PropertyChangeListener.class, "listener");
+ setOperationBody(operation, ""
+ /*{
+ pcs.removePropertyChangeListener(propertyName, listener);
+ }*/
+ );
+
+ operation = addOperation(output,
+ "firePropertyChange",
+ "void",
+ ObjectModelJavaModifier.PROTECTED
+ );
+ addParameter(operation, String.class, "propertyName");
+ addParameter(operation, Object.class, "oldValue");
+ addParameter(operation, Object.class, "newValue");
+ setOperationBody(operation, ""
+ /*{
+ pcs.firePropertyChange(propertyName, oldValue, newValue);
+ }*/
+ );
+
+ operation = addOperation(output,
+ "firePropertyChange",
+ "void",
+ ObjectModelJavaModifier.PROTECTED
+ );
+ addParameter(operation, String.class, "propertyName");
+ addParameter(operation, Object.class, "newValue");
+ setOperationBody(operation, ""
+ /*{
+ firePropertyChange(propertyName, null, newValue);
+ }*/
+ );
+ }
}
\ No newline at end of file
Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaModelValidator.java
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaModelValidator.java 2013-06-11 14:55:44 UTC (rev 667)
+++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaModelValidator.java 2013-06-12 08:20:19 UTC (rev 668)
@@ -55,9 +55,9 @@
if (useIdGenerator) {
// can't have any stuff around GeneraturValue
- if(JpaTemplatesGeneratorUtil.hasNotGeneratedValueStereotype(clazz)) {
+ if (JpaTemplatesGeneratorUtil.hasNotGeneratedValueStereotype(clazz)) {
- addError(clazz,"Can't use a NotGenerated tag value when using an id factory");
+ addError(clazz, "Can't use a NotGenerated tag value when using an id factory");
}
}
}
Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaPersistenceContextTransformer.java
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaPersistenceContextTransformer.java 2013-06-11 14:55:44 UTC (rev 667)
+++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaPersistenceContextTransformer.java 2013-06-12 08:20:19 UTC (rev 668)
@@ -117,7 +117,7 @@
// using an idGenerator
- addImport(output,DefaultJpaEntityIdFactory.class);
+ addImport(output, DefaultJpaEntityIdFactory.class);
ObjectModelOperation constructor = addConstructor(
output,
ObjectModelJavaModifier.PUBLIC);
Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java 2013-06-11 14:55:44 UTC (rev 667)
+++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java 2013-06-12 08:20:19 UTC (rev 668)
@@ -236,15 +236,13 @@
/**
* Obtain the value of the {@link JpaTemplatesTagValues#TAG_ID_FACTORY}
- * tag value on the given model or classifier.
- * <p/>
- * It will first look on the model, and then in the given classifier.
+ * tag value on the given model.
*
* @param model model to seek
* @return the none empty value of the found tag value or {@code null}
* if not found nor empty.
* @see JpaTemplatesTagValues#TAG_ID_FACTORY
- * @since 2.3
+ * @since 0.1
*/
public static String getIdFactoryTagValue(ObjectModel model) {
String value = findTagValue(JpaTemplatesTagValues.TAG_ID_FACTORY, null, model);
@@ -257,6 +255,26 @@
}
/**
+ * Obtain the value of the {@link JpaTemplatesTagValues#TAG_GENERATE_PROPERTY_CHANGE_LISTENERS}
+ * tag value on the given model.
+ *
+ * @param model model to seek
+ * @return the none empty value of the found tag value or {@code null}
+ * if not found nor empty.
+ * @see JpaTemplatesTagValues#TAG_GENERATE_PROPERTY_CHANGE_LISTENERS
+ * @since 0.1
+ */
+ public static String getGeneratePropertyChangeListenersTagValue(ObjectModel model) {
+ String value = findTagValue(JpaTemplatesTagValues.TAG_GENERATE_PROPERTY_CHANGE_LISTENERS, null, model);
+ return value;
+ }
+
+ public static boolean useGeneratePropertyChangeListeners(ObjectModel model) {
+ String value = getGeneratePropertyChangeListenersTagValue(model);
+ return ObjectUtils.equals("true", value);
+ }
+
+ /**
* Obtain the value of the {@link JpaTemplatesTagValues#TAG_ENTITY_SUPER_CLASS}
* tag value on the given model or classifier.
* <p/>
@@ -266,7 +284,7 @@
* @param classifier classifier to seek
* @return the none empty value of the found tag value or {@code null} if not found nor empty.
* @see JpaTemplatesTagValues#TAG_ENTITY_SUPER_CLASS
- * @since 2.3
+ * @since 0.1
*/
public static String getEntitySuperClassTagValue(ObjectModel model, ObjectModelClassifier classifier) {
String value = findTagValue(JpaTemplatesTagValues.TAG_ENTITY_SUPER_CLASS, classifier, model);
@@ -283,7 +301,7 @@
* @param classifier classifier to seek
* @return the none empty value of the found tag value or {@code null} if not found nor empty.
* @see JpaTemplatesTagValues#TAG_DAO_SUPER_CLASS
- * @since 2.3
+ * @since 0.1
*/
public static String getDaoSuperClassTagValue(ObjectModel model, ObjectModelClassifier classifier) {
String value = findTagValue(JpaTemplatesTagValues.TAG_DAO_SUPER_CLASS, classifier, model);
@@ -297,7 +315,7 @@
* @param model model to seek
* @return the none empty value of the found tag value or {@code null} if not found nor empty.
* @see JpaTemplatesTagValues#TAG_PERSISTENCE_CONTEXT_SUPER_CLASS
- * @since 2.3
+ * @since 0.1
*/
public static String getPersistenceContextSuperClassTagValue(ObjectModel model) {
String value = findTagValue(JpaTemplatesTagValues.TAG_PERSISTENCE_CONTEXT_SUPER_CLASS, null, model);
Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesStereoTypes.java
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesStereoTypes.java 2013-06-11 14:55:44 UTC (rev 667)
+++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesStereoTypes.java 2013-06-12 08:20:19 UTC (rev 668)
@@ -27,7 +27,6 @@
import org.nuiton.eugene.EugeneStereoTypes;
import org.nuiton.eugene.ModelPropertiesUtil;
import org.nuiton.eugene.models.object.ObjectModelAttribute;
-import org.nuiton.eugene.models.object.ObjectModelClass;
import org.nuiton.eugene.models.object.ObjectModelClassifier;
import javax.persistence.GeneratedValue;
@@ -36,7 +35,7 @@
* Defines all stereotypes managed by JPA templates.
*
* @author tchemit <chemit(a)codelutin.com>
- * @since 2.7
+ * @since 0.1
*/
public interface JpaTemplatesStereoTypes extends EugeneStereoTypes {
@@ -44,6 +43,7 @@
* Stéréotype pour les collections avec unicité.
*
* @see JpaTemplatesGeneratorUtil#hasUniqueStereotype(ObjectModelAttribute)
+ * @since 0.1
*/
@ModelPropertiesUtil.StereotypeDefinition(target = ObjectModelAttribute.class,
documentation = "To specify that an attribute is unique (JPA mapping)")
@@ -53,6 +53,7 @@
* Stéréotype pour ne pas générer l'annotation {@link GeneratedValue} sur une entité.
*
* @see JpaTemplatesGeneratorUtil#hasNotGeneratedValueStereotype(ObjectModelClassifier)
+ * @since 0.1
*/
@ModelPropertiesUtil.StereotypeDefinition(target = ObjectModelClassifier.class,
documentation = "To specify that an entity deal by itself with his id, the GeneratedValue annotation will not be generated then(JPA mapping)")
Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesTagValues.java
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesTagValues.java 2013-06-11 14:55:44 UTC (rev 667)
+++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesTagValues.java 2013-06-12 08:20:19 UTC (rev 668)
@@ -34,7 +34,7 @@
* Defines all tag values managed by JPA templates.
*
* @author tchemit <chemit(a)codelutin.com>
- * @since 2.7
+ * @since 0.1
*/
public interface JpaTemplatesTagValues extends EugeneTagValues {
@@ -81,7 +81,7 @@
* l'ordre alphabétique.
*
* @see JpaTemplatesGeneratorUtil#getInverseTagValue(ObjectModelAttribute)
- * @since 2.5
+ * @since 0.1
*/
@ModelPropertiesUtil.TagValueDefinition(target = {ObjectModelAttribute.class},
documentation = "Sets which part of a N-N relation is master (inverse=true) and slave (inverse=false) (must be put on each side on a such relation) (Hibernate mapping)")
@@ -97,4 +97,17 @@
target = {ObjectModel.class},
documentation = "To specify a user defined id factory to use for all entities of the model")
String TAG_ID_FACTORY = "idFactory";
+
+ /**
+ * Tag value to generate property change listeners on entities
+ * if setted to {@code true}.
+ *
+ * @see JpaTemplatesGeneratorUtil#getGeneratePropertyChangeListenersTagValue(ObjectModel)
+ * @since 0.1
+ */
+ @ModelPropertiesUtil.TagValueDefinition(
+ target = {ObjectModel.class},
+ documentation = "Tag value to generate property change listeners on entities.")
+ String TAG_GENERATE_PROPERTY_CHANGE_LISTENERS = "generatePropertyChangeListeners";
+
}
1
0
Author: agiraudet
Date: 2013-06-11 16:55:44 +0200 (Tue, 11 Jun 2013)
New Revision: 667
Url: http://nuiton.org/projects/sandbox/repository/revisions/667
Log:
ajout d'une demonstration de la syntaxe yaml
Added:
testEugeneUML-YAML/demo/
testEugeneUML-YAML/demo/demo.tar.gz
testEugeneUML-YAML/demo/eugene-pollen.sh
Added: testEugeneUML-YAML/demo/demo.tar.gz
===================================================================
(Binary files differ)
Property changes on: testEugeneUML-YAML/demo/demo.tar.gz
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: testEugeneUML-YAML/demo/eugene-pollen.sh
===================================================================
--- testEugeneUML-YAML/demo/eugene-pollen.sh (rev 0)
+++ testEugeneUML-YAML/demo/eugene-pollen.sh 2013-06-11 14:55:44 UTC (rev 667)
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+#cd /tmp
+#installation de eugene
+svn checkout http://svn.nuiton.org/svn/eugene/trunk/ eugene
+cd eugene
+mvn clean && mvn install -e
+cd ..
+#installation de pollen
+svn checkout http://svn.chorem.org/svn/pollen/trunk/ pollen
+wget http://svn.nuiton.org/svn/sandbox/testEugeneUML-YAML/pollen/demo-pollen-use… -O pollen/pollen-persistence/src/main/models/pollen.yamlobjectmodel
+sed -i '152s/.*/\ \ \ \ \<eugenePluginVersion\>2.6.4-SNAPSHOT\<\/eugenePluginVersion\>/' pollen/pom.xml
+sed -i "107i\ org.nuiton.eugene.plantuml.PlantumlTemplatesGenerator," pollen/pollen-persistence/pom.xml
+cd pollen
+mvn clean && mvn install -e
+#lancement de pollen
+#&& cd pollen-ui-struts2 && mvn jetty:run
+#localhost:8080/pollen
+
Property changes on: testEugeneUML-YAML/demo/eugene-pollen.sh
___________________________________________________________________
Added: svn:executable
+ *
1
0
r666 - in nuiton-jpa: nuiton-jpa-api/src/main/java/org/nuiton/jpa/api nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates
by tchemit@users.nuiton.org June 11, 2013
by tchemit@users.nuiton.org June 11, 2013
June 11, 2013
Author: tchemit
Date: 2013-06-11 10:36:20 +0200 (Tue, 11 Jun 2013)
New Revision: 666
Url: http://nuiton.org/projects/sandbox/repository/revisions/666
Log:
generates nice dao methods
Modified:
nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaDao.java
nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaDaoTransformer.java
nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java
nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java
Modified: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaDao.java
===================================================================
--- nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaDao.java 2013-06-10 13:56:13 UTC (rev 665)
+++ nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/AbstractJpaDao.java 2013-06-11 08:36:20 UTC (rev 666)
@@ -89,6 +89,48 @@
return entityManager.contains(entity);
}
+ public E findByProperty(String propertyName, Object value)
+ {
+ Map<String, Object> properties = new HashMap<String, Object>();
+ properties.put(propertyName, value);
+ E result = findByProperties(properties);
+ return result;
+ }
+
+ public List<E> findAllByProperty(String propertyName, Object value) {
+ TypedQuery<E> query = createQuery(propertyName, value);
+ List<E> result = findAll(query);
+ return result;
+ }
+
+ public List<E> findAllByProperties(Map<String, Object> properties)
+ {
+ TypedQuery<E> query = createQuery(properties);
+ List<E> results = findAll(query);
+ return results;
+ }
+
+ public E findByProperties(Map<String, Object> properties)
+ {
+ TypedQuery<E> query = createQuery(properties);
+ E result = findAnyOrNull(query);
+ return result;
+ }
+
+ public E findContains(String propertyName,
+ Object property) {
+ TypedQuery<E> query= createQuery("From "+getEntityClass().getSimpleName()+" Where "+propertyName+" in elements(:K)");
+ query.setParameter("K", property);
+ return findAnyOrNull(query);
+ }
+
+ public List<E> findAllContains(String propertyName,
+ Object property) {
+ TypedQuery<E> query = createQuery("From "+getEntityClass().getSimpleName()+" Where "+propertyName+" in elements(:K)");
+ query.setParameter("K", property);
+ return findAll(query);
+ }
+
@Override
public E newInstance() {
E newInstance;
Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaDaoTransformer.java
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaDaoTransformer.java 2013-06-10 13:56:13 UTC (rev 665)
+++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaDaoTransformer.java 2013-06-11 08:36:20 UTC (rev 666)
@@ -28,13 +28,19 @@
/*{generator option: parentheses = false}*/
/*{generator option: writeString = +}*/
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.nuiton.eugene.GeneratorUtil;
+import org.nuiton.eugene.models.object.ObjectModelAttribute;
import org.nuiton.eugene.models.object.ObjectModelClass;
import org.nuiton.eugene.models.object.ObjectModelJavaModifier;
import org.nuiton.eugene.models.object.ObjectModelOperation;
import org.nuiton.jpa.api.AbstractJpaDao;
+import java.util.Collection;
+import java.util.List;
+
/**
* JpaDaoTransformer generates a dao for an entity.
* <p/>
@@ -84,6 +90,9 @@
String abstractDaoName,
String concreteEntityQualifiedName) {
+ String prefix = getConstantPrefix(input, DEFAULT_CONSTANT_PREFIX);
+ setConstantPrefix(prefix);
+
String entityName = input.getName();
ObjectModelClass output =
@@ -139,6 +148,23 @@
}*/
);
+ Collection<ObjectModelAttribute> attributes = input.getAttributes();
+ if (CollectionUtils.isNotEmpty(attributes)) {
+ addImport(output, List.class);
+ }
+
+ for (ObjectModelAttribute attr : attributes) {
+ if (!attr.isNavigable()) {
+ continue;
+ }
+
+ if (!GeneratorUtil.isNMultiplicity(attr)) {
+ generateNoNMultiplicity(entityName, output, attr, false);
+ } else {
+ generateNMultiplicity(entityName, output, attr);
+ }
+ }
+
if (isVerbose()) {
log.info("will generate " + output.getQualifiedName());
}
@@ -161,4 +187,117 @@
}
return output;
}
+
+ protected void generateNoNMultiplicity(String clazzName,
+ ObjectModelClass result,
+ ObjectModelAttribute attr,
+ boolean isAssoc) {
+ String attrName = attr.getName();
+ String attrType = attr.getType();
+ String propertyName = clazzName + "." + getConstantName(attrName);
+ if (!isAssoc && attr.hasAssociationClass()) {
+ String assocClassName = attr.getAssociationClass().getName();
+ String assocAttrName = JpaTemplatesGeneratorUtil.getAssocAttrName(attr);
+ // It is about transitivity : use the property to access the
+ // associationClass + '.' + the property to access the expected
+ // attribute
+ // <class>.<attrAssoc> + '.' + <assocClass>.<attr>
+ propertyName =
+ clazzName + '.' + getConstantName(assocAttrName) +
+ " + '.' + " +
+ assocClassName + '.' + getConstantName(attrName);
+ }
+
+ ObjectModelOperation op;
+ op = addOperation(result,
+ getJavaBeanMethodName("findBy", attrName),
+ clazzName,
+ ObjectModelJavaModifier.PUBLIC);
+ addParameter(op, attrType, "v");
+ setOperationBody(op, ""
+/*{
+ <%=clazzName%> result = findByProperty(<%=propertyName%>, v);
+ return result;
+ }*/
+ );
+
+ op = addOperation(result,
+ getJavaBeanMethodName("findAllBy", attrName),
+ "List<" + clazzName + ">",
+ ObjectModelJavaModifier.PUBLIC);
+ addParameter(op, attrType, "v");
+ setOperationBody(op, ""
+/*{
+ List<<%=clazzName%>> result = findAllByProperty(<%=propertyName%>, v);
+ return result;
+ }*/
+ );
+
+ if (!isAssoc && attr.hasAssociationClass()) {
+ String assocClassName = attr.getAssociationClass().getName();
+ String assocClassFQN = attr.getAssociationClass().getQualifiedName();
+ String assocAttrName = GeneratorUtil.getAssocAttrName(attr);
+ String assocPropertyConstantName = getConstantName(assocAttrName);
+ op = addOperation(result,
+ getJavaBeanMethodName("findBy", assocClassName),
+ clazzName,
+ ObjectModelJavaModifier.PUBLIC);
+ addParameter(op, assocClassFQN, "value");
+ setOperationBody(op, ""
+/*{
+ <%=clazzName%> result = findByProperty(<%=clazzName + "." + assocPropertyConstantName%>, value);
+ return result;
+ }*/
+ );
+
+ op = addOperation(result,
+ getJavaBeanMethodName("findAllBy", assocClassName),
+ "List<" + clazzName + ">",
+ ObjectModelJavaModifier.PUBLIC);
+ addParameter(op, assocClassFQN, "value");
+ setOperationBody(op, ""
+/*{
+ List<<%=clazzName%>> result = findAllByProperty(<%=clazzName + "." + assocPropertyConstantName%>, value);
+ return result;
+ }*/
+ );
+ }
+ }
+
+ protected void generateNMultiplicity(String clazzName,
+ ObjectModelClass result,
+ ObjectModelAttribute attr) {
+ String attrName = attr.getName();
+ String attrType = attr.getType();
+ if (attr.hasAssociationClass()) {
+ // do nothing for association class, too complex...
+ return;
+ }
+ ObjectModelOperation op;
+ // Since 2.4 do nothing, findContains and findAllContains are not generated anymore
+ op = addOperation(result,
+ getJavaBeanMethodName("findContains", attrName),
+ clazzName,
+ ObjectModelJavaModifier.PUBLIC);
+ addParameter(op, attrType, "v");
+ setOperationBody(op, ""
+/*{
+ <%=clazzName%> result = findContains(<%=clazzName + "." + getConstantName(attrName)%>, v);
+ return result;
+ }*/
+ );
+
+ op = addOperation(result,
+ getJavaBeanMethodName("findAllContains", attrName),
+ "List<" + clazzName + ">",
+ ObjectModelJavaModifier.PUBLIC);
+ addParameter(op, attrType, "v");
+ setOperationBody(op, ""
+/*{
+ List<<%=clazzName%>> result = findAllContains(<%=clazzName + "." + getConstantName(attrName)%>, v);
+ return result;
+ }*/
+ );
+ }
+
}
\ No newline at end of file
Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java 2013-06-10 13:56:13 UTC (rev 665)
+++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java 2013-06-11 08:36:20 UTC (rev 666)
@@ -39,6 +39,7 @@
import org.nuiton.eugene.models.object.xml.ObjectModelAttributeImpl;
import org.nuiton.jpa.api.AbstractJpaEntity;
import org.nuiton.jpa.api.JpaEntities;
+import org.nuiton.jpa.api.JpaEntity;
import org.nuiton.jpa.api.JpaEntityIdFactoryResolver;
import javax.persistence.CascadeType;
@@ -79,7 +80,7 @@
private static final Log log =
LogFactory.getLog(JpaEntityTransformer.class);
- public static final String PROPERTY_ID = "id";
+// public static final String PROPERTY_ID = "id";
@Override
public void transformFromClass(ObjectModelClass input) {
@@ -206,7 +207,7 @@
// Create an id property
ObjectModelAttributeImpl idAttr = new ObjectModelAttributeImpl();
idAttr.setDeclaringElement(input);
- idAttr.setName(PROPERTY_ID);
+ idAttr.setName(JpaEntity.PROPERTY_ID);
idAttr.setType(String.class.getName());
properties.add(0, idAttr);
@@ -281,7 +282,7 @@
for (ObjectModelAttribute property : properties) {
String propertyName = property.getName();
String propertyType = property.getType();
- if (PROPERTY_ID.equals(propertyName)) {
+ if (JpaEntity.PROPERTY_ID.equals(propertyName)) {
addAnnotation(result, property, output, Id.class);
if (JpaTemplatesGeneratorUtil.generateEntityGeneratedValueAnnotation(model, input)) {
@@ -333,7 +334,7 @@
if (bidirection && !isInverse) {
// add the mappedBy parameter
- annotationParams.add("mappedBy = \"" + reverseAttribute.getName()+"\"");
+ annotationParams.add("mappedBy = \"" + reverseAttribute.getName() + "\"");
}
if (nMultiplicity) {
@@ -419,7 +420,7 @@
createGetChildMethod(output,
attrName,
attrType,
- simpleType );
+ simpleType);
createGetChildByIdMethod(output,
attrName,
@@ -427,40 +428,40 @@
simpleType);
createIsEmptyMethod(output,
- attrName );
+ attrName);
createSizeMethod(output,
- attrName );
+ attrName);
createAddChildMethod(output,
attrName,
attrType,
constantName,
- usePCS );
+ usePCS);
createAddAllChildrenMethod(output,
attrName,
attrType,
constantName,
- usePCS );
+ usePCS);
createRemoveChildMethod(output,
attrName,
attrType,
constantName,
- usePCS );
+ usePCS);
createRemoveAllChildrenMethod(output,
attrName,
attrType,
constantName,
- usePCS );
+ usePCS);
createContainsChildMethod(output,
attrName,
attrType,
constantName,
- usePCS );
+ usePCS);
createContainsChildByIdMethod(output,
attrName,
@@ -472,7 +473,7 @@
attrName,
attrType,
constantName,
- usePCS );
+ usePCS);
// Change type for Multiple attribute
Class<?> collectionType = JpaTemplatesGeneratorUtil.getCollectionType(attr);
@@ -501,7 +502,7 @@
JpaTemplatesGeneratorUtil.OPERATION_GETTER_DEFAULT_PREFIX
);
- if (PROPERTY_ID.equals(attrName)) {
+ if (JpaEntity.PROPERTY_ID.equals(attrName)) {
addAnnotation(output, getMethod, Override.class);
}
@@ -567,9 +568,9 @@
}
protected void createGetChildByIdMethod(ObjectModelClass output,
- String attrName,
- String attrType,
- String simpleType) {
+ String attrName,
+ String attrType,
+ String simpleType) {
ObjectModelOperation operation = addOperation(
output,
getJavaBeanMethodName("get", attrName + "ById"),
@@ -767,14 +768,14 @@
}
protected void createContainsChildByIdMethod(ObjectModelClass output,
- String attrName,
- String attrType,
- String constantName,
- boolean usePCS) {
+ String attrName,
+ String attrType,
+ String constantName,
+ boolean usePCS) {
ObjectModelOperation operation = addOperation(
output,
- getJavaBeanMethodName("contains", attrName+"ById"),
+ getJavaBeanMethodName("contains", attrName + "ById"),
"boolean",
ObjectModelJavaModifier.PUBLIC
);
Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java 2013-06-10 13:56:13 UTC (rev 665)
+++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaTemplatesGeneratorUtil.java 2013-06-11 08:36:20 UTC (rev 666)
@@ -185,7 +185,7 @@
return result;
}
- public static boolean containsMutiple(List<ObjectModelAttribute> attributes) {
+ public static boolean containsMutiple(Collection<ObjectModelAttribute> attributes) {
boolean result = false;
1
0
June 10, 2013
Author: agiraudet
Date: 2013-06-10 15:56:13 +0200 (Mon, 10 Jun 2013)
New Revision: 665
Url: http://nuiton.org/projects/sandbox/repository/revisions/665
Log:
petite correction du modele pure yaml
Modified:
testEugeneUML-YAML/pollen/demo-pollen-pure_yaml/pollen.yamlobjectmodel
Modified: testEugeneUML-YAML/pollen/demo-pollen-pure_yaml/pollen.yamlobjectmodel
===================================================================
--- testEugeneUML-YAML/pollen/demo-pollen-pure_yaml/pollen.yamlobjectmodel 2013-06-10 13:44:15 UTC (rev 664)
+++ testEugeneUML-YAML/pollen/demo-pollen-pure_yaml/pollen.yamlobjectmodel 2013-06-10 13:56:13 UTC (rev 665)
@@ -460,7 +460,7 @@
- maxMultiplicity: 1
- operation:
- name: getVoteByPollAccount
- - visibility: public>
+ - visibility: public
- returnParameter:
- type: org.chorem.pollen.business.persistence.Vote
- parameter:
1
0
June 10, 2013
Author: agiraudet
Date: 2013-06-10 15:44:15 +0200 (Mon, 10 Jun 2013)
New Revision: 664
Url: http://nuiton.org/projects/sandbox/repository/revisions/664
Log:
mise a jour du modele pure yaml
Modified:
testEugeneUML-YAML/pollen/demo-pollen-pure_yaml/pollen.yamlobjectmodel
Modified: testEugeneUML-YAML/pollen/demo-pollen-pure_yaml/pollen.yamlobjectmodel
===================================================================
--- testEugeneUML-YAML/pollen/demo-pollen-pure_yaml/pollen.yamlobjectmodel 2013-06-10 13:27:30 UTC (rev 663)
+++ testEugeneUML-YAML/pollen/demo-pollen-pure_yaml/pollen.yamlobjectmodel 2013-06-10 13:44:15 UTC (rev 664)
@@ -1,5 +1,6 @@
%YAML 1.1
---
+- syntaxe: 1.0
- name: Pollen
- version: 1.0
@@ -7,8 +8,7 @@
- class:
- name: Choice
- - stereotypes:
- - entity
+ - stereotypes: entity
- attribute:
- name: name
- associationType: composite
@@ -53,8 +53,7 @@
- class:
- name: PollAccount
- - stereotypes:
- - entity
+ - stereotypes: entity
- attribute:
- name: accountId
- associationType: composite
@@ -129,8 +128,7 @@
- class:
- name: VotingList
- - stereotypes:
- - entity
+ - stereotypes: entity
- attribute:
- name: name
- associationType: composite
@@ -173,8 +171,7 @@
- class:
- name: Vote
- - stereotypes:
- - entity
+ - stereotypes: entity
- attribute:
- name: weight
- associationType: composite
@@ -232,8 +229,7 @@
- class:
- name: UserAccount
- - stereotypes:
- - entity
+ - stereotypes: entity
- attribute:
- name: login
- associationType: composite
@@ -309,8 +305,7 @@
- class:
- name: PreventRule
- - stereotypes:
- - entity
+ - stereotypes: entity
- attribute:
- name: scope
- associationType: composite
@@ -364,8 +359,7 @@
- class:
- name: Poll
- - stereotypes:
- - entity
+ - stereotypes: entity
- attribute:
- name: pollId
- associationType: composite
@@ -466,7 +460,7 @@
- maxMultiplicity: 1
- operation:
- name: getVoteByPollAccount
- - visibility: public
+ - visibility: public>
- returnParameter:
- type: org.chorem.pollen.business.persistence.Vote
- parameter:
@@ -662,8 +656,7 @@
- class:
- name: PersonList
- - stereotypes:
- - entity
+ - stereotypes: entity
- attribute:
- name: name
- associationType: composite
@@ -692,8 +685,7 @@
- class:
- name: Comment
- - stereotypes:
- - entity
+ - stereotypes: entity
- attribute:
- name: text
- associationType: composite
@@ -734,8 +726,7 @@
- associationClass:
- name: PersonToList
- - stereotypes:
- - entity
+ - stereotypes: entity
- participant:
- name: org.chorem.pollen.business.persistence.PollAccount
- participant:
@@ -757,8 +748,7 @@
- associationClass:
- name: VoteToChoice
- - stereotypes:
- - entity
+ - stereotypes: entity
- participant:
- name: org.chorem.pollen.business.persistence.Choice
- participant:
1
0
r663 - in testEugeneUML-YAML/pollen: . demo-pollen-pure_yaml demo-pollen-user_friendly
by agiraudet@users.nuiton.org June 10, 2013
by agiraudet@users.nuiton.org June 10, 2013
June 10, 2013
Author: agiraudet
Date: 2013-06-10 15:27:30 +0200 (Mon, 10 Jun 2013)
New Revision: 663
Url: http://nuiton.org/projects/sandbox/repository/revisions/663
Log:
ajout des demos pollen avec la syntaxe pure yaml et la syntaxe user friendly (avec les fichiers)
Added:
testEugeneUML-YAML/pollen/demo-pollen-pure_yaml/
testEugeneUML-YAML/pollen/demo-pollen-pure_yaml/pollen-yaml.sh
testEugeneUML-YAML/pollen/demo-pollen-pure_yaml/pollen.yamlobjectmodel
testEugeneUML-YAML/pollen/demo-pollen-user_friendly/
testEugeneUML-YAML/pollen/demo-pollen-user_friendly/pollen-yaml.sh
testEugeneUML-YAML/pollen/demo-pollen-user_friendly/pollen.yamlobjectmodel
Added: testEugeneUML-YAML/pollen/demo-pollen-pure_yaml/pollen-yaml.sh
===================================================================
--- testEugeneUML-YAML/pollen/demo-pollen-pure_yaml/pollen-yaml.sh (rev 0)
+++ testEugeneUML-YAML/pollen/demo-pollen-pure_yaml/pollen-yaml.sh 2013-06-10 13:27:30 UTC (rev 663)
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+#cd /tmp
+svn checkout http://svn.chorem.org/svn/pollen/trunk/ pollen
+wget http://svn.nuiton.org/svn/sandbox/testEugeneUML-YAML/pollen/demo-pollen-pur… -O pollen/pollen-persistence/src/main/models/pollen.yamlobjectmodel
+sed -i '152s/.*/\ \ \ \ \<eugenePluginVersion\>2.6.4-SNAPSHOT\<\/eugenePluginVersion\>/' pollen/pom.xml
+cd pollen
+mvn clean && mvn install -e
+#&& cd pollen-ui-struts2 && mvn jetty:run
+#localhost:8080/pollen
+
Property changes on: testEugeneUML-YAML/pollen/demo-pollen-pure_yaml/pollen-yaml.sh
___________________________________________________________________
Added: svn:executable
+ *
Added: testEugeneUML-YAML/pollen/demo-pollen-pure_yaml/pollen.yamlobjectmodel
===================================================================
--- testEugeneUML-YAML/pollen/demo-pollen-pure_yaml/pollen.yamlobjectmodel (rev 0)
+++ testEugeneUML-YAML/pollen/demo-pollen-pure_yaml/pollen.yamlobjectmodel 2013-06-10 13:27:30 UTC (rev 663)
@@ -0,0 +1,785 @@
+%YAML 1.1
+---
+
+- name: Pollen
+- version: 1.0
+- package: org.chorem.pollen.business.persistence
+
+- class:
+ - name: Choice
+ - stereotypes:
+ - entity
+ - attribute:
+ - name: name
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: description
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: validate
+ - associationType: composite
+ - visibility: public
+ - type: boolean
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - visibility: public
+ - associationClassName: org.chorem.pollen.business.persistence.VoteToChoice
+ - type: org.chorem.pollen.business.persistence.Vote
+ - reverseMaxMultiplicity: -1
+ - minMultiplicity: 0
+ - maxMultiplicity: -1
+ - navigable: true
+ - ordering: ordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.Poll
+ - reverseMaxMultiplicity: -1
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - navigable: false
+ - ordering: unordered
+
+- class:
+ - name: ChoicesGroup
+
+- class:
+ - name: PollAccount
+ - stereotypes:
+ - entity
+ - attribute:
+ - name: accountId
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: votingId
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: email
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - visibility: public
+ - associationClassName: org.chorem.pollen.business.persistence.PersonToList
+ - type: org.chorem.pollen.business.persistence.VotingList
+ - reverseMaxMultiplicity: -1
+ - minMultiplicity: 0
+ - maxMultiplicity: -1
+ - navigable: true
+ - ordering: ordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.Poll
+ - reverseAttributeName: creator
+ - reverseMaxMultiplicity: 1
+ - minMultiplicity: 0
+ - maxMultiplicity: -1
+ - navigable: false
+ - ordering: ordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.Comment
+ - reverseMaxMultiplicity: 1
+ - minMultiplicity: 0
+ - maxMultiplicity: -1
+ - navigable: false
+ - ordering: ordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.Vote
+ - reverseMaxMultiplicity: 1
+ - minMultiplicity: 0
+ - maxMultiplicity: -1
+ - navigable: true
+ - ordering: ordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.PersonList
+ - reverseMaxMultiplicity: -1
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - navigable: true
+ - ordering: unordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.UserAccount
+ - reverseMaxMultiplicity: -1
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - navigable: true
+ - ordering: unordered
+
+- class:
+ - name: VotingList
+ - stereotypes:
+ - entity
+ - attribute:
+ - name: name
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: weight
+ - associationType: composite
+ - visibility: public
+ - type: double
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - visibility: public
+ - associationClassName: org.chorem.pollen.business.persistence.PersonToList
+ - type: org.chorem.pollen.business.persistence.PollAccount
+ - reverseMaxMultiplicity: -1
+ - minMultiplicity: 1
+ - maxMultiplicity: -1
+ - navigable: true
+ - ordering: ordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.Poll
+ - reverseMaxMultiplicity: -1
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - navigable: false
+ - ordering: unordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.Vote
+ - reverseMaxMultiplicity: 1
+ - minMultiplicity: 0
+ - maxMultiplicity: 1
+ - navigable: true
+ - ordering: unordered
+
+- class:
+ - name: Vote
+ - stereotypes:
+ - entity
+ - attribute:
+ - name: weight
+ - associationType: composite
+ - visibility: public
+ - type: double
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: comment
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: anonymous
+ - associationType: composite
+ - visibility: public
+ - type: boolean
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - visibility: public
+ - associationClassName: org.chorem.pollen.business.persistence.VoteToChoice
+ - type: org.chorem.pollen.business.persistence.Choice
+ - reverseMaxMultiplicity: -1
+ - minMultiplicity: 1
+ - maxMultiplicity: -1
+ - navigable: true
+ - ordering: ordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.Poll
+ - reverseMaxMultiplicity: -1
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - navigable: false
+ - ordering: unordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.PollAccount
+ - reverseMaxMultiplicity: -1
+ - minMultiplicity: 0
+ - maxMultiplicity: 1
+ - navigable: true
+ - ordering: unordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.VotingList
+ - reverseMaxMultiplicity: 1
+ - minMultiplicity: 0
+ - maxMultiplicity: 1
+ - navigable: false
+ - ordering: unordered
+
+- class:
+ - name: UserAccount
+ - stereotypes:
+ - entity
+ - attribute:
+ - name: login
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: password
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: firstName
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: lastName
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: administrator
+ - associationType: composite
+ - visibility: public
+ - type: boolean
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: language
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: email
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - operation:
+ - name: getDisplayName
+ - visibility: public
+ - returnParameter:
+ - type: java.lang.String
+ - attribute:
+ - name: favoriteList
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.PersonList
+ - reverseAttributeName: owner
+ - reverseMaxMultiplicity: 1
+ - minMultiplicity: 0
+ - maxMultiplicity: -1
+ - navigable: true
+ - ordering: ordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.PollAccount
+ - reverseMaxMultiplicity: 1
+ - minMultiplicity: 0
+ - maxMultiplicity: -1
+ - navigable: true
+ - ordering: ordered
+
+- class:
+ - name: PreventRule
+ - stereotypes:
+ - entity
+ - attribute:
+ - name: scope
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: sensibility
+ - associationType: composite
+ - visibility: public
+ - type: int
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: repeated
+ - associationType: composite
+ - visibility: public
+ - type: boolean
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: active
+ - associationType: composite
+ - visibility: public
+ - type: boolean
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: oneTime
+ - associationType: composite
+ - visibility: public
+ - type: boolean
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: method
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.Poll
+ - reverseMaxMultiplicity: -1
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - navigable: false
+ - ordering: unordered
+
+- class:
+ - name: Poll
+ - stereotypes:
+ - entity
+ - attribute:
+ - name: pollId
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: title
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: description
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: beginChoiceDate
+ - associationType: composite
+ - visibility: public
+ - type: java.util.Date
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: beginDate
+ - associationType: composite
+ - visibility: public
+ - type: java.util.Date
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: endDate
+ - associationType: composite
+ - visibility: public
+ - type: java.util.Date
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: maxChoiceNb
+ - associationType: composite
+ - visibility: public
+ - type: int
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: closed
+ - associationType: composite
+ - visibility: public
+ - type: boolean
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: choiceAddAllowed
+ - associationType: composite
+ - visibility: public
+ - type: boolean
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: anonymousVoteAllowed
+ - associationType: composite
+ - visibility: public
+ - type: boolean
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: publicResults
+ - associationType: composite
+ - visibility: public
+ - type: boolean
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: continuousResults
+ - associationType: composite
+ - visibility: public
+ - type: boolean
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: endChoiceDate
+ - associationType: composite
+ - visibility: public
+ - type: java.util.Date
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: voteCountingType
+ - associationType: composite
+ - visibility: public
+ - type: int
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - operation:
+ - name: getVoteByPollAccount
+ - visibility: public
+ - returnParameter:
+ - type: org.chorem.pollen.business.persistence.Vote
+ - parameter:
+ - name: account
+ - type: org.chorem.pollen.business.persistence.PollAccount
+ - operation:
+ - name: getAdminId
+ - visibility: public
+ - returnParameter:
+ - type: java.lang.String
+ - operation:
+ - name: getVoteId
+ - visibility: public
+ - returnParameter:
+ - type: java.lang.String
+ - parameter:
+ - name: account
+ - type: org.chorem.pollen.business.persistence.PollAccount
+ - operation:
+ - name: isStarted
+ - visibility: public
+ - returnParameter:
+ - type: boolean
+ - parameter:
+ - name: currentDate
+ - type: java.util.Date
+ - operation:
+ - name: isRunning
+ - visibility: public
+ - returnParameter:
+ - type: boolean
+ - parameter:
+ - name: currentDate
+ - type: java.util.Date
+ - operation:
+ - name: isFinished
+ - visibility: public
+ - returnParameter:
+ - type: boolean
+ - parameter:
+ - name: currentDate
+ - type: java.util.Date
+ - operation:
+ - name: isAddChoiceStarted
+ - visibility: public
+ - returnParameter:
+ - type: boolean
+ - parameter:
+ - name: currentDate
+ - type: java.util.Date
+ - operation:
+ - name: isAddChoiceRunning
+ - visibility: public
+ - returnParameter:
+ - type: boolean
+ - parameter:
+ - name: currentDate
+ - type: java.util.Date
+ - operation:
+ - name: isAddChoiceFinished
+ - visibility: public
+ - returnParameter:
+ - type: boolean
+ - parameter:
+ - name: currentDate
+ - type: java.util.Date
+ - operation:
+ - name: getPollAccounts
+ - visibility: public
+ - returnParameter:
+ - type: java.util.List<org.chorem.pollen.business.persistence.PollAccount>
+ - parameter:
+ - name: withNoVote
+ - type: boolean
+ - operation:
+ - name: getPersonToListByVote
+ - visibility: public
+ - returnParameter:
+ - type: org.chorem.pollen.business.persistence.PersonToList
+ - parameter:
+ - name: vote
+ - type: org.chorem.pollen.business.persistence.Vote
+ - operation:
+ - name: getPreventRuleByScope
+ - visibility: public
+ - returnParameter:
+ - type: org.chorem.pollen.business.persistence.PreventRule
+ - parameter:
+ - name: scope
+ - type: java.lang.String
+ - operation:
+ - name: isAnonymous
+ - visibility: public
+ - returnParameter:
+ - type: boolean
+ - operation:
+ - name: isPollFree
+ - visibility: public
+ - returnParameter:
+ - type: boolean
+ - operation:
+ - name: isPollGroup
+ - visibility: public
+ - returnParameter:
+ - type: boolean
+ - operation:
+ - name: isPollRestricted
+ - visibility: public
+ - returnParameter:
+ - type: boolean
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.Vote
+ - associationType: composite
+ - reverseMaxMultiplicity: 1
+ - minMultiplicity: 0
+ - maxMultiplicity: -1
+ - navigable: true
+ - ordering: ordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.Choice
+ - associationType: composite
+ - reverseMaxMultiplicity: 1
+ - minMultiplicity: 0
+ - maxMultiplicity: -1
+ - navigable: true
+ - ordering: ordered
+ - attribute:
+ - name: creator
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.PollAccount
+ - reverseMaxMultiplicity: -1
+ - minMultiplicity: 0
+ - maxMultiplicity: 1
+ - navigable: true
+ - ordering: unordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.Comment
+ - associationType: composite
+ - reverseMaxMultiplicity: 1
+ - minMultiplicity: 0
+ - maxMultiplicity: -1
+ - navigable: true
+ - ordering: ordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.PreventRule
+ - associationType: composite
+ - reverseMaxMultiplicity: 1
+ - minMultiplicity: 0
+ - maxMultiplicity: -1
+ - navigable: true
+ - ordering: ordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.VotingList
+ - associationType: composite
+ - reverseMaxMultiplicity: 1
+ - minMultiplicity: 0
+ - maxMultiplicity: -1
+ - navigable: true
+ - ordering: ordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.PollType
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - navigable: true
+ - ordering: unordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.ChoiceType
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - navigable: true
+ - ordering: unordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.PollVoteVisibility
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - navigable: true
+ - ordering: unordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.PollCommentVisibility
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - navigable: true
+ - ordering: unordered
+
+- class:
+ - name: PersonList
+ - stereotypes:
+ - entity
+ - attribute:
+ - name: name
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: owner
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.UserAccount
+ - reverseAttributeName: favoriteList
+ - reverseMaxMultiplicity: -1
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - navigable: true
+ - ordering: unordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.PollAccount
+ - reverseMaxMultiplicity: 1
+ - minMultiplicity: 1
+ - maxMultiplicity: -1
+ - navigable: true
+ - ordering: ordered
+
+- class:
+ - name: Comment
+ - stereotypes:
+ - entity
+ - attribute:
+ - name: text
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: postDate
+ - associationType: composite
+ - visibility: public
+ - type: java.util.Date
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: author
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.String
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.Poll
+ - reverseMaxMultiplicity: -1
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - navigable: false
+ - ordering: unordered
+ - attribute:
+ - visibility: public
+ - type: org.chorem.pollen.business.persistence.PollAccount
+ - reverseMaxMultiplicity: -1
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - navigable: true
+ - ordering: unordered
+
+- associationClass:
+ - name: PersonToList
+ - stereotypes:
+ - entity
+ - participant:
+ - name: org.chorem.pollen.business.persistence.PollAccount
+ - participant:
+ - name: org.chorem.pollen.business.persistence.VotingList
+ - attribute:
+ - name: weight
+ - associationType: composite
+ - visibility: public
+ - type: double
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+ - attribute:
+ - name: hasVoted
+ - associationType: composite
+ - visibility: public
+ - type: boolean
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+
+- associationClass:
+ - name: VoteToChoice
+ - stereotypes:
+ - entity
+ - participant:
+ - name: org.chorem.pollen.business.persistence.Choice
+ - participant:
+ - name: org.chorem.pollen.business.persistence.Vote
+ - attribute:
+ - name: voteValue
+ - associationType: composite
+ - visibility: public
+ - type: java.lang.Integer
+ - minMultiplicity: 1
+ - maxMultiplicity: 1
+
+- enumeration:
+ - name: PollVoteVisibility
+
+- enumeration:
+ - name: PollCommentVisibility
+
+- enumeration:
+ - name: ChoiceType
+
+- enumeration:
+ - name: PollType
+
Added: testEugeneUML-YAML/pollen/demo-pollen-user_friendly/pollen-yaml.sh
===================================================================
--- testEugeneUML-YAML/pollen/demo-pollen-user_friendly/pollen-yaml.sh (rev 0)
+++ testEugeneUML-YAML/pollen/demo-pollen-user_friendly/pollen-yaml.sh 2013-06-10 13:27:30 UTC (rev 663)
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+#cd /tmp
+svn checkout http://svn.chorem.org/svn/pollen/trunk/ pollen
+wget http://svn.nuiton.org/svn/sandbox/testEugeneUML-YAML/pollen/demo-pollen-use… -O pollen/pollen-persistence/src/main/models/pollen.yamlobjectmodel
+sed -i '152s/.*/\ \ \ \ \<eugenePluginVersion\>2.6.4-SNAPSHOT\<\/eugenePluginVersion\>/' pollen/pom.xml
+cd pollen
+mvn clean && mvn install -e
+#&& cd pollen-ui-struts2 && mvn jetty:run
+#localhost:8080/pollen
+
Property changes on: testEugeneUML-YAML/pollen/demo-pollen-user_friendly/pollen-yaml.sh
___________________________________________________________________
Added: svn:executable
+ *
Added: testEugeneUML-YAML/pollen/demo-pollen-user_friendly/pollen.yamlobjectmodel
===================================================================
--- testEugeneUML-YAML/pollen/demo-pollen-user_friendly/pollen.yamlobjectmodel (rev 0)
+++ testEugeneUML-YAML/pollen/demo-pollen-user_friendly/pollen.yamlobjectmodel 2013-06-10 13:27:30 UTC (rev 663)
@@ -0,0 +1,135 @@
+%YAML 1.1
+---
+
+name: Pollen
+version: 1.0
+package: org.chorem.pollen.business.persistence
+imports:
+ - java.lang.String
+ - java.util.Date
+ - java.lang.Integer
+ - java.util.List
+
+class Choice <<entity>>:
+ String name:
+ String description:
+ boolean validate:
+ Vote ordered [*] "VoteToChoice":
+
+class ChoicesGroup:
+
+class PollAccount <<entity>>:
+ String accountId:
+ String votingId:
+ String email:
+ VotingList ordered [*] "PersonToList":
+ Vote ordered [*] "Vote--PollAccount":
+ PersonList unordered "PersonList--PollAccount":
+ UserAccount unordered "PollAccount--UserAccount":
+
+class VotingList <<entity>>:
+ String name:
+ double weight:
+ PollAccount ordered [1..*] "PersonToList":
+ Vote unordered [0..1]:
+
+class Vote <<entity>>:
+ double weight:
+ String comment:
+ boolean anonymous:
+ Choice ordered [1..*] "VoteToChoice":
+ PollAccount unordered [0..1] "Vote--PollAccount":
+
+class UserAccount <<entity>>:
+ String login:
+ String password:
+ String firstName:
+ String lastName:
+ boolean administrator:
+ String language:
+ String email:
+ getDisplayName(): String
+ PersonList favoriteList ordered [*] "UserAccount--PersonList":
+ PollAccount ordered [*] "PollAccount--UserAccount":
+
+class PreventRule <<entity>>:
+ String scope:
+ int sensibility:
+ boolean repeated:
+ boolean active:
+ boolean oneTime:
+ String method:
+
+class Poll <<entity>>:
+ String pollId:
+ String title:
+ String description:
+ Date beginChoiceDate:
+ Date beginDate:
+ Date endDate:
+ int maxChoiceNb:
+ boolean closed:
+ boolean choiceAddAllowed:
+ boolean anonymousVoteAllowed:
+ boolean publicResults:
+ boolean continuousResults:
+ Date endChoiceDate:
+ int voteCountingType:
+ getVoteByPollAccount(PollAccount account): Vote
+ getAdminId(): String
+ getVoteId(PollAccount account): String
+ isStarted(Date currentDate): boolean
+ isRunning(Date currentDate): boolean
+ isFinished(Date currentDate): boolean
+ isAddChoiceStarted(Date currentDate): boolean
+ isAddChoiceRunning(Date currentDate): boolean
+ isAddChoiceFinished(Date currentDate): boolean
+ getPollAccounts(boolean withNoVote): List<PollAccount>
+ getPersonToListByVote(Vote vote): PersonToList
+ getPreventRuleByScope(String scope): PreventRule
+ isAnonymous(): boolean
+ isPollFree(): boolean
+ isPollGroup(): boolean
+ isPollRestricted(): boolean
+ Vote ordered [*]:
+ Choice ordered [*]:
+ PollAccount creator unordered [0..1]:
+ Comment ordered [*]:
+ PreventRule ordered [*]:
+ VotingList ordered [*]:
+ PollType unordered:
+ ChoiceType unordered:
+ PollVoteVisibility unordered:
+ PollCommentVisibility unordered:
+
+class PersonList <<entity>>:
+ String name:
+ UserAccount owner unordered "UserAccount--PersonList":
+ PollAccount ordered [1..*] "PersonList--PollAccount":
+
+class Comment <<entity>>:
+ String text:
+ Date postDate:
+ String author:
+ PollAccount unordered:
+
+associationclass PersonToList <<entity>>:
+ participant:
+ PollAccount "PersonToList":
+ VotingList "PersonToList":
+ double weight:
+ boolean hasVoted:
+
+associationclass VoteToChoice <<entity>>:
+ participant:
+ Choice "VoteToChoice":
+ Vote "VoteToChoice":
+ Integer voteValue:
+
+enumeration PollVoteVisibility:
+
+enumeration PollCommentVisibility:
+
+enumeration ChoiceType:
+
+enumeration PollType:
1
0
Author: agiraudet
Date: 2013-06-10 15:26:34 +0200 (Mon, 10 Jun 2013)
New Revision: 662
Url: http://nuiton.org/projects/sandbox/repository/revisions/662
Log:
ajout des demos pollen avec la syntaxe pure yaml et la syntaxe user friendly
Removed:
testEugeneUML-YAML/pollen-yaml.sh
testEugeneUML-YAML/pollen/pollen.yamlobjectmodel
Deleted: testEugeneUML-YAML/pollen/pollen.yamlobjectmodel
===================================================================
--- testEugeneUML-YAML/pollen/pollen.yamlobjectmodel 2013-06-07 16:58:19 UTC (rev 661)
+++ testEugeneUML-YAML/pollen/pollen.yamlobjectmodel 2013-06-10 13:26:34 UTC (rev 662)
@@ -1,822 +0,0 @@
-%YAML 1.1
----
-
-- name: Pollen
-- version: 1.0
-- package: org.chorem.pollen.business.persistence
-- imports:
- - java.lang.String
- - java.util.Date
- - java.lang.Integer
-
-- class:
- - name: Choice
- - stereotypes:
- - entity
- - attribute:
- - name: name
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: description
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: validate
- - associationType: composite
- - visibility: public
- - type: boolean
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - visibility: public
- - associationClassName: org.chorem.pollen.business.persistence.VoteToChoice
- - type: org.chorem.pollen.business.persistence.Vote
-# - reverseAttributeName:
- - reverseMaxMultiplicity: -1
- - minMultiplicity: 0
- - maxMultiplicity: -1
- - navigable: true
- - ordering: ordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.Poll
-# - reverseAttributeName:
- - reverseMaxMultiplicity: -1
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - navigable: false
- - ordering: unordered
-
-- class:
- - name: ChoicesGroup
-
-- class:
- - name: PollAccount
- - stereotypes:
- - entity
- - attribute:
- - name: accountId
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: votingId
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: email
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - visibility: public
- - associationClassName: org.chorem.pollen.business.persistence.PersonToList
- - type: org.chorem.pollen.business.persistence.VotingList
-# - reverseAttributeName:
- - reverseMaxMultiplicity: -1
- - minMultiplicity: 0
- - maxMultiplicity: -1
- - navigable: true
- - ordering: ordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.Poll
- - reverseAttributeName: creator
- - reverseMaxMultiplicity: 1
- - minMultiplicity: 0
- - maxMultiplicity: -1
- - navigable: false
- - ordering: ordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.Comment
-# - reverseAttributeName:
- - reverseMaxMultiplicity: 1
- - minMultiplicity: 0
- - maxMultiplicity: -1
- - navigable: false
- - ordering: ordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.Vote
-# - reverseAttributeName:
- - reverseMaxMultiplicity: 1
- - minMultiplicity: 0
- - maxMultiplicity: -1
- - navigable: true
- - ordering: ordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.PersonList
-# - reverseAttributeName:
- - reverseMaxMultiplicity: -1
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - navigable: true
- - ordering: unordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.UserAccount
-# - reverseAttributeName:
- - reverseMaxMultiplicity: -1
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - navigable: true
- - ordering: unordered
-
-- class:
- - name: VotingList
- - stereotypes:
- - entity
- - attribute:
- - name: name
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: weight
- - associationType: composite
- - visibility: public
- - type: double
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - visibility: public
- - associationClassName: org.chorem.pollen.business.persistence.PersonToList
- - type: org.chorem.pollen.business.persistence.PollAccount
-# - reverseAttributeName:
- - reverseMaxMultiplicity: -1
- - minMultiplicity: 1
- - maxMultiplicity: -1
- - navigable: true
- - ordering: ordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.Poll
-# - reverseAttributeName:
- - reverseMaxMultiplicity: -1
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - navigable: false
- - ordering: unordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.Vote
-# - reverseAttributeName:
- - reverseMaxMultiplicity: 1
- - minMultiplicity: 0
- - maxMultiplicity: 1
- - navigable: true
- - ordering: unordered
-
-- class:
- - name: Vote
- - stereotypes:
- - entity
- - attribute:
- - name: weight
- - associationType: composite
- - visibility: public
- - type: double
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: comment
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: anonymous
- - associationType: composite
- - visibility: public
- - type: boolean
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - visibility: public
- - associationClassName: org.chorem.pollen.business.persistence.VoteToChoice
- - type: org.chorem.pollen.business.persistence.Choice
-# - reverseAttributeName:
- - reverseMaxMultiplicity: -1
- - minMultiplicity: 1
- - maxMultiplicity: -1
- - navigable: true
- - ordering: ordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.Poll
-# - reverseAttributeName:
- - reverseMaxMultiplicity: -1
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - navigable: false
- - ordering: unordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.PollAccount
-# - reverseAttributeName:
- - reverseMaxMultiplicity: -1
- - minMultiplicity: 0
- - maxMultiplicity: 1
- - navigable: true
- - ordering: unordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.VotingList
-# - reverseAttributeName:
- - reverseMaxMultiplicity: 1
- - minMultiplicity: 0
- - maxMultiplicity: 1
- - navigable: false
- - ordering: unordered
-
-- class:
- - name: UserAccount
- - stereotypes:
- - entity
- - attribute:
- - name: login
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: password
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: firstName
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: lastName
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: administrator
- - associationType: composite
- - visibility: public
- - type: boolean
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: language
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: email
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - operation:
- - name: getDisplayName
- - visibility: public
- - returnParameter:
- - type: java.lang.String
- - attribute:
- - name: favoriteList
- - visibility: public
- - type: org.chorem.pollen.business.persistence.PersonList
- - reverseAttributeName: owner
- - reverseMaxMultiplicity: 1
- - minMultiplicity: 0
- - maxMultiplicity: -1
- - navigable: true
- - ordering: ordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.PollAccount
-# - reverseAttributeName:
- - reverseMaxMultiplicity: 1
- - minMultiplicity: 0
- - maxMultiplicity: -1
- - navigable: true
- - ordering: ordered
-
-- class:
- - name: PreventRule
- - stereotypes:
- - entity
- - attribute:
- - name: scope
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: sensibility
- - associationType: composite
- - visibility: public
- - type: int
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: repeated
- - associationType: composite
- - visibility: public
- - type: boolean
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: active
- - associationType: composite
- - visibility: public
- - type: boolean
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: oneTime
- - associationType: composite
- - visibility: public
- - type: boolean
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: method
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.Poll
-# - reverseAttributeName:
- - reverseMaxMultiplicity: -1
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - navigable: false
- - ordering: unordered
-
-- class:
- - name: Poll
- - stereotypes:
- - entity
- - attribute:
- - name: pollId
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: title
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: description
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: beginChoiceDate
- - associationType: composite
- - visibility: public
- - type: java.util.Date
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: beginDate
- - associationType: composite
- - visibility: public
- - type: java.util.Date
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: endDate
- - associationType: composite
- - visibility: public
- - type: java.util.Date
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: maxChoiceNb
- - associationType: composite
- - visibility: public
- - type: int
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: closed
- - associationType: composite
- - visibility: public
- - type: boolean
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: choiceAddAllowed
- - associationType: composite
- - visibility: public
- - type: boolean
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: anonymousVoteAllowed
- - associationType: composite
- - visibility: public
- - type: boolean
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: publicResults
- - associationType: composite
- - visibility: public
- - type: boolean
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: continuousResults
- - associationType: composite
- - visibility: public
- - type: boolean
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: endChoiceDate
- - associationType: composite
- - visibility: public
- - type: java.util.Date
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: voteCountingType
- - associationType: composite
- - visibility: public
- - type: int
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - operation:
- - name: getVoteByPollAccount
- - visibility: public>
- - returnParameter:
- - type: org.chorem.pollen.business.persistence.Vote
- - parameter:
- - name: account
- - type: org.chorem.pollen.business.persistence.PollAccount
- - operation:
- - name: getAdminId
- - visibility: public
- - returnParameter:
- - type: java.lang.String
- - operation:
- - name: getVoteId
- - visibility: public
- - returnParameter:
- - type: java.lang.String
- - parameter:
- - name: account
- - type: org.chorem.pollen.business.persistence.PollAccount
- - operation:
- - name: isStarted
- - visibility: public
- - returnParameter:
- - type: boolean
- - parameter:
- - name: currentDate
- - type: java.util.Date
- - operation:
- - name: isRunning
- - visibility: public
- - returnParameter:
- - type: boolean
- - parameter:
- - name: currentDate
- - type: java.util.Date
- - operation:
- - name: isFinished
- - visibility: public
- - returnParameter:
- - type: boolean
- - parameter:
- - name: currentDate
- - type: java.util.Date
- - operation:
- - name: isAddChoiceStarted
- - visibility: public
- - returnParameter:
- - type: boolean
- - parameter:
- - name: currentDate
- - type: java.util.Date
- - operation:
- - name: isAddChoiceRunning
- - visibility: public
- - returnParameter:
- - type: boolean
- - parameter:
- - name: currentDate
- - type: java.util.Date
- - operation:
- - name: isAddChoiceFinished
- - visibility: public
- - returnParameter:
- - type: boolean
- - parameter:
- - name: currentDate
- - type: java.util.Date
- - operation:
- - name: getPollAccounts
- - visibility: public
- - returnParameter:
- - type: java.util.List<org.chorem.pollen.business.persistence.PollAccount>
- - parameter:
- - name: withNoVote
- - type: boolean
- - operation:
- - name: getPersonToListByVote
- - visibility: public
- - returnParameter:
- - type: org.chorem.pollen.business.persistence.PersonToList
- - parameter:
- - name: vote
- - type: org.chorem.pollen.business.persistence.Vote
- - operation:
- - name: getPreventRuleByScope
- - visibility: public
- - returnParameter:
- - type: org.chorem.pollen.business.persistence.PreventRule
- - parameter:
- - name: scope
- - type: java.lang.String
- - operation:
- - name: isAnonymous
- - visibility: public
- - returnParameter:
- - type: boolean
- - operation:
- - name: isPollFree
- - visibility: public
- - returnParameter:
- - type: boolean
- - operation:
- - name: isPollGroup
- - visibility: public
- - returnParameter:
- - type: boolean
- - operation:
- - name: isPollRestricted
- - visibility: public
- - returnParameter:
- - type: boolean
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.Vote
-# - reverseAttributeName:
- - associationType: composite
- - reverseMaxMultiplicity: 1
- - minMultiplicity: 0
- - maxMultiplicity: -1
- - navigable: true
- - ordering: ordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.Choice
-# - reverseAttributeName:
- - associationType: composite
- - reverseMaxMultiplicity: 1
- - minMultiplicity: 0
- - maxMultiplicity: -1
- - navigable: true
- - ordering: ordered
- - attribute:
- - name: creator
- - visibility: public
- - type: org.chorem.pollen.business.persistence.PollAccount
-# - reverseAttributeName:
- - reverseMaxMultiplicity: -1
- - minMultiplicity: 0
- - maxMultiplicity: 1
- - navigable: true
- - ordering: unordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.Comment
-# - reverseAttributeName:
- - associationType: composite
- - reverseMaxMultiplicity: 1
- - minMultiplicity: 0
- - maxMultiplicity: -1
- - navigable: true
- - ordering: ordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.PreventRule
-# - reverseAttributeName:
- - associationType: composite
- - reverseMaxMultiplicity: 1
- - minMultiplicity: 0
- - maxMultiplicity: -1
- - navigable: true
- - ordering: ordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.VotingList
-# - reverseAttributeName:
- - associationType: composite
- - reverseMaxMultiplicity: 1
- - minMultiplicity: 0
- - maxMultiplicity: -1
- - navigable: true
- - ordering: ordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.PollType
-# - reverseAttributeName:
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - navigable: true
- - ordering: unordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.ChoiceType
-# - reverseAttributeName:
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - navigable: true
- - ordering: unordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.PollVoteVisibility
-# - reverseAttributeName:
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - navigable: true
- - ordering: unordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.PollCommentVisibility
-# - reverseAttributeName:
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - navigable: true
- - ordering: unordered
-
-- class:
- - name: PersonList
- - stereotypes:
- - entity
- - attribute:
- - name: name
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: owner
- - visibility: public
- - type: org.chorem.pollen.business.persistence.UserAccount
- - reverseAttributeName: favoriteList
- - reverseMaxMultiplicity: -1
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - navigable: true
- - ordering: unordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.PollAccount
-# - reverseAttributeName:
- - reverseMaxMultiplicity: 1
- - minMultiplicity: 1
- - maxMultiplicity: -1
- - navigable: true
- - ordering: ordered
-
-- class:
- - name: Comment
- - stereotypes:
- - entity
- - attribute:
- - name: text
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: postDate
- - associationType: composite
- - visibility: public
- - type: java.util.Date
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: author
- - associationType: composite
- - visibility: public
- - type: java.lang.String
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.Poll
-# - reverseAttributeName:
- - reverseMaxMultiplicity: -1
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - navigable: false
- - ordering: unordered
- - attribute:
- - visibility: public
- - type: org.chorem.pollen.business.persistence.PollAccount
-# - reverseAttributeName:
- - reverseMaxMultiplicity: -1
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - navigable: true
- - ordering: unordered
-
-- associationClass:
- - name: PersonToList
- - stereotypes:
- - entity
- - participant:
- - name: org.chorem.pollen.business.persistence.PollAccount
-# - attribute:
- - participant:
- - name: org.chorem.pollen.business.persistence.VotingList
-# - attribute:
- - attribute:
- - name: weight
- - associationType: composite
- - visibility: public
- - type: double
- - minMultiplicity: 1
- - maxMultiplicity: 1
- - attribute:
- - name: hasVoted
- - associationType: composite
- - visibility: public
- - type: boolean
- - minMultiplicity: 1
- - maxMultiplicity: 1
-
-- associationClass:
- - name: VoteToChoice
- - stereotypes:
- - entity
- - participant:
- - name: org.chorem.pollen.business.persistence.Choice
-# - attribute:
- - participant:
- - name: org.chorem.pollen.business.persistence.Vote
-# - attribute:
- - attribute:
- - name: voteValue
- - associationType: composite
- - visibility: public
- - type: java.lang.Integer
- - minMultiplicity: 1
- - maxMultiplicity: 1
-
-- enumeration:
- - name: PollVoteVisibility
-
-- enumeration:
- - name: PollCommentVisibility
-
-- enumeration:
- - name: ChoiceType
-
-- enumeration:
- - name: PollType
-
Deleted: testEugeneUML-YAML/pollen-yaml.sh
===================================================================
--- testEugeneUML-YAML/pollen-yaml.sh 2013-06-07 16:58:19 UTC (rev 661)
+++ testEugeneUML-YAML/pollen-yaml.sh 2013-06-10 13:26:34 UTC (rev 662)
@@ -1,12 +0,0 @@
-#!/bin/bash
-
-#cd /tmp/
-svn checkout http://svn.chorem.org/svn/pollen/trunk/ pollen
-mkdir pollen/pollen-persistence/src/main/models
-wget http://svn.nuiton.org/svn/sandbox/testEugeneUML-YAML/pollen/pollen.yamlobje… -O pollen/pollen-persistence/src/main/models/pollen.yamlobjectmodel
-cp pollen/pollen-persistence/src/main/xmi/pollen.properties pollen/pollen-persistence/src/main/models/pollen.properties
-sed -i '497s/.*/\ \ \ \ \ \ \ \ \ \ \ \ \<inputs\>yamlmodel\<\/inputs\>/' pollen/pom.xml
-sed -i '152s/.*/\ \ \ \ \<eugenePluginVersion\>2.6.3-SNAPSHOT\<\/eugenePluginVersion\>/' pollen/pom.xml
-cd pollen
-mvn install
-
1
0
r661 - nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api
by tchemit@users.nuiton.org June 7, 2013
by tchemit@users.nuiton.org June 7, 2013
June 7, 2013
Author: tchemit
Date: 2013-06-07 18:58:19 +0200 (Fri, 07 Jun 2013)
New Revision: 661
Url: http://nuiton.org/projects/sandbox/repository/revisions/661
Log:
add id property constant
Modified:
nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntity.java
Modified: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntity.java
===================================================================
--- nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntity.java 2013-06-07 16:16:19 UTC (rev 660)
+++ nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/JpaEntity.java 2013-06-07 16:58:19 UTC (rev 661)
@@ -37,6 +37,8 @@
*/
public interface JpaEntity {
+ String PROPERTY_ID = "id";
+
String getId();
}
1
0
r660 - in html5videoplayer: js js/controls js/libs js/models views
by kmorin@users.nuiton.org June 7, 2013
by kmorin@users.nuiton.org June 7, 2013
June 7, 2013
Author: kmorin
Date: 2013-06-07 18:16:19 +0200 (Fri, 07 Jun 2013)
New Revision: 660
Url: http://nuiton.org/projects/sandbox/repository/revisions/660
Log:
first shot of the pollen UI with canJS
Added:
html5videoplayer/js/controls/menu.js
html5videoplayer/js/controls/poll_form.js
html5videoplayer/js/controls/poll_summary.js
html5videoplayer/js/controls/vote.js
html5videoplayer/js/libs/bootstrap.min.js
html5videoplayer/js/libs/can.fixture.js
html5videoplayer/js/libs/can.jquery.js
html5videoplayer/js/libs/can.jquery.min.js
html5videoplayer/js/libs/can.object.js
html5videoplayer/js/libs/can.observe.attributes.js
html5videoplayer/js/libs/can.observe.delegate.js
html5videoplayer/js/models/comments.js
html5videoplayer/js/models/polls.js
html5videoplayer/js/models/votes.js
html5videoplayer/js/route.js
html5videoplayer/views/menu.ejs
html5videoplayer/views/poll_form.ejs
html5videoplayer/views/summary.ejs
html5videoplayer/views/vote.ejs
Removed:
html5videoplayer/js/controls/video.js
html5videoplayer/js/models/video.js
html5videoplayer/views/video.ejs
Added: html5videoplayer/js/controls/menu.js
===================================================================
--- html5videoplayer/js/controls/menu.js (rev 0)
+++ html5videoplayer/js/controls/menu.js 2013-06-07 16:16:19 UTC (rev 660)
@@ -0,0 +1,5 @@
+var Menu = can.Control({
+ init: function() {
+ this.element.html(can.view('views/menu.ejs'));
+ },
+});
\ No newline at end of file
Added: html5videoplayer/js/controls/poll_form.js
===================================================================
--- html5videoplayer/js/controls/poll_form.js (rev 0)
+++ html5videoplayer/js/controls/poll_form.js 2013-06-07 16:16:19 UTC (rev 660)
@@ -0,0 +1,87 @@
+var PollForm = can.Control({
+
+ defaults: {
+ poll: new Poll()
+ }
+
+}, {
+ init: function() {
+
+ this.element.html(can.view('views/poll_form.ejs', {
+ poll: this.options.poll
+ }));
+
+ },
+
+ '{can.route} change': function(data, ev, prop, how, newVal, oldVal ) {
+ if (prop === "type" && (how === "set" || how === "add")) {
+ if (newVal != "poll") {
+ this.element.hide();
+ }
+ } else if (prop === "action" && (how === "set" || how === "add")) {
+ if (newVal != "edit") {
+ this.element.hide();
+ }
+ }
+ },
+
+ ':type/:action route': function(data) {
+ if (data.type === "poll" && data.action === "edit") {
+ this.editPoll(new Poll());
+ }
+ },
+
+ ':type/:id/:action route': function(data) {
+ if (data.type === "poll" && data.action === "edit") {
+ var self = this;
+ $.when(Poll.findOne({id: data.id})).then(
+ function(poll) {
+ self.editPoll(poll);
+ });
+ }
+ },
+
+ '.save click': function() {
+ this.updatePoll();
+ },
+
+ '.create click': function() {
+ can.route.attr({ type: "poll", action: "edit" }, true);
+ },
+
+ '[data-id] click': function(el, ev) {
+ can.route.attr({ type: "poll", action: "edit", id: el.data('id') });
+ },
+
+ '{poll} created': function(data) {
+ can.route.attr({ type: "poll", action: "summary", id: data.id });
+ },
+
+ '{poll} updated': function(data) {
+ can.route.attr({ type: "poll", action: "summary", id: data.id });
+ },
+
+ updatePoll: function() {
+ var form = this.element.find('form'),
+ values = can.deparam(form.serialize());
+
+ this.options.poll.attr(values).save();
+ },
+
+ editPoll: function(poll) {
+ console.log("edit poll " + poll.id + " : " + poll.description);
+ this.options.poll = poll;
+ this.on();
+ this.refreshForm();
+ this.element.show();
+ },
+
+ refreshForm: function() {
+ var form = this.element.find('form');
+ form[0].reset();
+ for (var k in this.options.poll._data) {
+ form.find("[name=" + k + "]").val(this.options.poll[k]);
+ }
+ }
+
+});
\ No newline at end of file
Added: html5videoplayer/js/controls/poll_summary.js
===================================================================
--- html5videoplayer/js/controls/poll_summary.js (rev 0)
+++ html5videoplayer/js/controls/poll_summary.js 2013-06-07 16:16:19 UTC (rev 660)
@@ -0,0 +1,32 @@
+var PollSummary = can.Control({
+
+ '{can.route} change': function(data, ev, prop, how, newVal, oldVal ) {
+ if (prop === "type" && (how === "set" || how === "add")) {
+ if (newVal != "poll") {
+ this.element.hide();
+ }
+ } else if (prop === "action" && (how === "set" || how === "add")) {
+ if (newVal != "summary") {
+ this.element.hide();
+ }
+ }
+ },
+
+ ':type/:id/:action route': function(data) {
+ if (data.type === "poll" && data.action === "summary") {
+ var self = this;
+ $.when(Poll.findOne({id: data.id})).then(
+ function(poll) {
+ self.showSummary(poll);
+ });
+ }
+ },
+
+ showSummary: function(poll) {
+ this.element.html(can.view('views/summary.ejs', {
+ poll: poll
+ }));
+ this.element.show();
+ }
+
+});
\ No newline at end of file
Deleted: html5videoplayer/js/controls/video.js
===================================================================
--- html5videoplayer/js/controls/video.js 2013-06-07 15:15:29 UTC (rev 659)
+++ html5videoplayer/js/controls/video.js 2013-06-07 16:16:19 UTC (rev 660)
@@ -1,17 +0,0 @@
-var VideoControl = can.Control({
-
- index: new can.Observe({index: 0}),
-
- play: function() {
- this.element.html(can.view('views/video.ejs', { videos: videos, index: this.index }));
- $("#layer").attr('src', "layer" + this.index.attr('index') + ".html");
- },
-
- next: function() {
- var index = this.index.attr('index');
- this.index.attr('index', (index + 1) % videos.length);
- $("#video").load();
- $("#layer").attr('src', "layer" + this.index.attr('index') + ".html");
- }
-
-});
\ No newline at end of file
Added: html5videoplayer/js/controls/vote.js
===================================================================
--- html5videoplayer/js/controls/vote.js (rev 0)
+++ html5videoplayer/js/controls/vote.js 2013-06-07 16:16:19 UTC (rev 660)
@@ -0,0 +1,36 @@
+var PollVote = can.Control({
+
+ '{can.route} change': function(data, ev, prop, how, newVal, oldVal ) {
+ if (prop === "type" && (how === "set" || how === "add")) {
+ if (newVal != "poll") {
+ this.element.hide();
+ }
+ } else if (prop === "action" && (how === "set" || how === "add")) {
+ if (newVal != "vote") {
+ this.element.hide();
+ }
+ }
+ },
+
+ ':type/:id/:action route': function(data) {
+ if (data.type === "poll" && data.action === "vote") {
+ var self = this;
+ $.when(Poll.findOne({id: data.id}),
+ Comment.findAll({pollId: data.id}),
+ Vote.findAll({pollId: data.id})).then(
+ function(poll, comments, votes) {
+ self.showPoll(poll, comments, votes);
+ });
+ }
+ },
+
+ showPoll: function(poll, comments, votes) {
+ this.element.html(can.view('views/vote.ejs', {
+ poll: poll,
+ comments: comments,
+ votes: votes
+ }));
+ this.element.show();
+ }
+
+});
\ No newline at end of file
Added: html5videoplayer/js/libs/bootstrap.min.js
===================================================================
--- html5videoplayer/js/libs/bootstrap.min.js (rev 0)
+++ html5videoplayer/js/libs/bootstrap.min.js 2013-06-07 16:16:19 UTC (rev 660)
@@ -0,0 +1,6 @@
+/*!
+* Bootstrap.js by @fat & @mdo
+* Copyright 2012 Twitter, Inc.
+* http://www.apache.org/licenses/LICENSE-2.0.txt
+*/
+!function(e){"use strict";e(function(){e.support.transition=function(){var e=function(){var e=document.createElement("bootstrap"),t={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},n;for(n in t)if(e.style[n]!==undefined)return t[n]}();return e&&{end:e}}()})}(window.jQuery),!function(e){"use strict";var t='[data-dismiss="alert"]',n=function(n){e(n).on("click",t,this.close)};n.prototype.close=function(t){function s(){i.trigger("closed").remove()}var n=e(this),r=n.attr("data-target"),i;r||(r=n.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,"")),i=e(r),t&&t.preventDefault(),i.length||(i=n.hasClass("alert")?n:n.parent()),i.trigger(t=e.Event("close"));if(t.isDefaultPrevented())return;i.removeClass("in"),e.support.transition&&i.hasClass("fade")?i.on(e.support.transition.end,s):s()};var r=e.fn.alert;e.fn.alert=function(t){return this.each(function(){var r=e(this),i=r.data("alert");i||r.data("alert",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.alert.Constructor=n,e.fn.alert.noConflict=function(){return e.fn.alert=r,this},e(document).on("click.alert.data-api",t,n.prototype.close)}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.button.defaults,n)};t.prototype.setState=function(e){var t="disabled",n=this.$element,r=n.data(),i=n.is("input")?"val":"html";e+="Text",r.resetText||n.data("resetText",n[i]()),n[i](r[e]||this.options[e]),setTimeout(function(){e=="loadingText"?n.addClass(t).attr(t,t):n.removeClass(t).removeAttr(t)},0)},t.prototype.toggle=function(){var e=this.$element.closest('[data-toggle="buttons-radio"]');e&&e.find(".active").removeClass("active"),this.$element.toggleClass("active")};var n=e.fn.button;e.fn.button=function(n){return this.each(function(){var r=e(this),i=r.data("button"),s=typeof n=="object"&&n;i||r.data("button",i=new t(this,s)),n=="toggle"?i.toggle():n&&i.setState(n)})},e.fn.button.defaults={loadingText:"loading..."},e.fn.button.Constructor=t,e.fn.button.noConflict=function(){return e.fn.button=n,this},e(document).on("click.button.data-api","[data-toggle^=button]",function(t){var n=e(t.target);n.hasClass("btn")||(n=n.closest(".btn")),n.button("toggle")})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.$indicators=this.$element.find(".carousel-indicators"),this.options=n,this.options.pause=="hover"&&this.$element.on("mouseenter",e.proxy(this.pause,this)).on("mouseleave",e.proxy(this.cycle,this))};t.prototype={cycle:function(t){return t||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(e.proxy(this.next,this),this.options.interval)),this},getActiveIndex:function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},to:function(t){var n=this.getActiveIndex(),r=this;if(t>this.$items.length-1||t<0)return;return this.sliding?this.$element.one("slid",function(){r.to(t)}):n==t?this.pause().cycle():this.slide(t>n?"next":"prev",e(this.$items[t]))},pause:function(t){return t||(this.paused=!0),this.$element.find(".next, .prev").length&&e.support.transition.end&&(this.$element.trigger(e.support.transition.end),this.cycle(!0)),clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(t,n){var r=this.$element.find(".item.active"),i=n||r[t](),s=this.interval,o=t=="next"?"left":"right",u=t=="next"?"first":"last",a=this,f;this.sliding=!0,s&&this.pause(),i=i.length?i:this.$element.find(".item")[u](),f=e.Event("slide",{relatedTarget:i[0],direction:o});if(i.hasClass("active"))return;this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid",function(){var t=e(a.$indicators.children()[a.getActiveIndex()]);t&&t.addClass("active")}));if(e.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(f);if(f.isDefaultPrevented())return;i.addClass(t),i[0].offsetWidth,r.addClass(o),i.addClass(o),this.$element.one(e.support.transition.end,function(){i.removeClass([t,o].join(" ")).addClass("active"),r.removeClass(["active",o].join(" ")),a.sliding=!1,setTimeout(function(){a.$element.trigger("slid")},0)})}else{this.$element.trigger(f);if(f.isDefaultPrevented())return;r.removeClass("active"),i.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return s&&this.cycle(),this}};var n=e.fn.carousel;e.fn.carousel=function(n){return this.each(function(){var r=e(this),i=r.data("carousel"),s=e.extend({},e.fn.carousel.defaults,typeof n=="object"&&n),o=typeof n=="string"?n:s.slide;i||r.data("carousel",i=new t(this,s)),typeof n=="number"?i.to(n):o?i[o]():s.interval&&i.pause().cycle()})},e.fn.carousel.defaults={interval:5e3,pause:"hover"},e.fn.carousel.Constructor=t,e.fn.carousel.noConflict=function(){return e.fn.carousel=n,this},e(document).on("click.carousel.data-api","[data-slide], [data-slide-to]",function(t){var n=e(this),r,i=e(n.attr("data-target")||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,"")),s=e.extend({},i.data(),n.data()),o;i.carousel(s),(o=n.attr("data-slide-to"))&&i.data("carousel").pause().to(o).cycle(),t.preventDefault()})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.collapse.defaults,n),this.options.parent&&(this.$parent=e(this.options.parent)),this.options.toggle&&this.toggle()};t.prototype={constructor:t,dimension:function(){var e=this.$element.hasClass("width");return e?"width":"height"},show:function(){var t,n,r,i;if(this.transitioning||this.$element.hasClass("in"))return;t=this.dimension(),n=e.camelCase(["scroll",t].join("-")),r=this.$parent&&this.$parent.find("> .accordion-group > .in");if(r&&r.length){i=r.data("collapse");if(i&&i.transitioning)return;r.collapse("hide"),i||r.data("collapse",null)}this.$element[t](0),this.transition("addClass",e.Event("show"),"shown"),e.support.transition&&this.$element[t](this.$element[0][n])},hide:function(){var t;if(this.transitioning||!this.$element.hasClass("in"))return;t=this.dimension(),this.reset(this.$element[t]()),this.transition("removeClass",e.Event("hide"),"hidden"),this.$element[t](0)},reset:function(e){var t=this.dimension();return this.$element.removeClass("collapse")[t](e||"auto")[0].offsetWidth,this.$element[e!==null?"addClass":"removeClass"]("collapse"),this},transition:function(t,n,r){var i=this,s=function(){n.type=="show"&&i.reset(),i.transitioning=0,i.$element.trigger(r)};this.$element.trigger(n);if(n.isDefaultPrevented())return;this.transitioning=1,this.$element[t]("in"),e.support.transition&&this.$element.hasClass("collapse")?this.$element.one(e.support.transition.end,s):s()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}};var n=e.fn.collapse;e.fn.collapse=function(n){return this.each(function(){var r=e(this),i=r.data("collapse"),s=e.extend({},e.fn.collapse.defaults,r.data(),typeof n=="object"&&n);i||r.data("collapse",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.collapse.defaults={toggle:!0},e.fn.collapse.Constructor=t,e.fn.collapse.noConflict=function(){return e.fn.collapse=n,this},e(document).on("click.collapse.data-api","[data-toggle=collapse]",function(t){var n=e(this),r,i=n.attr("data-target")||t.preventDefault()||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,""),s=e(i).data("collapse")?"toggle":n.data();n[e(i).hasClass("in")?"addClass":"removeClass"]("collapsed"),e(i).collapse(s)})}(window.jQuery),!function(e){"use strict";function r(){e(".dropdown-backdrop").remove(),e(t).each(function(){i(e(this)).removeClass("open")})}function i(t){var n=t.attr("data-target"),r;n||(n=t.attr("href"),n=n&&/#/.test(n)&&n.replace(/.*(?=#[^\s]*$)/,"")),r=n&&e(n);if(!r||!r.length)r=t.parent();return r}var t="[data-toggle=dropdown]",n=function(t){var n=e(t).on("click.dropdown.data-api",this.toggle);e("html").on("click.dropdown.data-api",function(){n.parent().removeClass("open")})};n.prototype={constructor:n,toggle:function(t){var n=e(this),s,o;if(n.is(".disabled, :disabled"))return;return s=i(n),o=s.hasClass("open"),r(),o||("ontouchstart"in document.documentElement&&e('<div class="dropdown-backdrop"/>').insertBefore(e(this)).on("click",r),s.toggleClass("open")),n.focus(),!1},keydown:function(n){var r,s,o,u,a,f;if(!/(38|40|27)/.test(n.keyCode))return;r=e(this),n.preventDefault(),n.stopPropagation();if(r.is(".disabled, :disabled"))return;u=i(r),a=u.hasClass("open");if(!a||a&&n.keyCode==27)return n.which==27&&u.find(t).focus(),r.click();s=e("[role=menu] li:not(.divider):visible a",u);if(!s.length)return;f=s.index(s.filter(":focus")),n.keyCode==38&&f>0&&f--,n.keyCode==40&&f<s.length-1&&f++,~f||(f=0),s.eq(f).focus()}};var s=e.fn.dropdown;e.fn.dropdown=function(t){return this.each(function(){var r=e(this),i=r.data("dropdown");i||r.data("dropdown",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.dropdown.Constructor=n,e.fn.dropdown.noConflict=function(){return e.fn.dropdown=s,this},e(document).on("click.dropdown.data-api",r).on("click.dropdown.data-api",".dropdown form",function(e){e.stopPropagation()}).on("click.dropdown.data-api",t,n.prototype.toggle).on("keydown.dropdown.data-api",t+", [role=menu]",n.prototype.keydown)}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.options=n,this.$element=e(t).delegate('[data-dismiss="modal"]',"click.dismiss.modal",e.proxy(this.hide,this)),this.options.remote&&this.$element.find(".modal-body").load(this.options.remote)};t.prototype={constructor:t,toggle:function(){return this[this.isShown?"hide":"show"]()},show:function(){var t=this,n=e.Event("show");this.$element.trigger(n);if(this.isShown||n.isDefaultPrevented())return;this.isShown=!0,this.escape(),this.backdrop(function(){var n=e.support.transition&&t.$element.hasClass("fade");t.$element.parent().length||t.$element.appendTo(document.body),t.$element.show(),n&&t.$element[0].offsetWidth,t.$element.addClass("in").attr("aria-hidden",!1),t.enforceFocus(),n?t.$element.one(e.support.transition.end,function(){t.$element.focus().trigger("shown")}):t.$element.focus().trigger("shown")})},hide:function(t){t&&t.preventDefault();var n=this;t=e.Event("hide"),this.$element.trigger(t);if(!this.isShown||t.isDefaultPrevented())return;this.isShown=!1,this.escape(),e(document).off("focusin.modal"),this.$element.removeClass("in").attr("aria-hidden",!0),e.support.transition&&this.$element.hasClass("fade")?this.hideWithTransition():this.hideModal()},enforceFocus:function(){var t=this;e(document).on("focusin.modal",function(e){t.$element[0]!==e.target&&!t.$element.has(e.target).length&&t.$element.focus()})},escape:function(){var e=this;this.isShown&&this.options.keyboard?this.$element.on("keyup.dismiss.modal",function(t){t.which==27&&e.hide()}):this.isShown||this.$element.off("keyup.dismiss.modal")},hideWithTransition:function(){var t=this,n=setTimeout(function(){t.$element.off(e.support.transition.end),t.hideModal()},500);this.$element.one(e.support.transition.end,function(){clearTimeout(n),t.hideModal()})},hideModal:function(){var e=this;this.$element.hide(),this.backdrop(function(){e.removeBackdrop(),e.$element.trigger("hidden")})},removeBackdrop:function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},backdrop:function(t){var n=this,r=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var i=e.support.transition&&r;this.$backdrop=e('<div class="modal-backdrop '+r+'" />').appendTo(document.body),this.$backdrop.click(this.options.backdrop=="static"?e.proxy(this.$element[0].focus,this.$element[0]):e.proxy(this.hide,this)),i&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in");if(!t)return;i?this.$backdrop.one(e.support.transition.end,t):t()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),e.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(e.support.transition.end,t):t()):t&&t()}};var n=e.fn.modal;e.fn.modal=function(n){return this.each(function(){var r=e(this),i=r.data("modal"),s=e.extend({},e.fn.modal.defaults,r.data(),typeof n=="object"&&n);i||r.data("modal",i=new t(this,s)),typeof n=="string"?i[n]():s.show&&i.show()})},e.fn.modal.defaults={backdrop:!0,keyboard:!0,show:!0},e.fn.modal.Constructor=t,e.fn.modal.noConflict=function(){return e.fn.modal=n,this},e(document).on("click.modal.data-api",'[data-toggle="modal"]',function(t){var n=e(this),r=n.attr("href"),i=e(n.attr("data-target")||r&&r.replace(/.*(?=#[^\s]+$)/,"")),s=i.data("modal")?"toggle":e.extend({remote:!/#/.test(r)&&r},i.data(),n.data());t.preventDefault(),i.modal(s).one("hide",function(){n.focus()})})}(window.jQuery),!function(e){"use strict";var t=function(e,t){this.init("tooltip",e,t)};t.prototype={constructor:t,init:function(t,n,r){var i,s,o,u,a;this.type=t,this.$element=e(n),this.options=this.getOptions(r),this.enabled=!0,o=this.options.trigger.split(" ");for(a=o.length;a--;)u=o[a],u=="click"?this.$element.on("click."+this.type,this.options.selector,e.proxy(this.toggle,this)):u!="manual"&&(i=u=="hover"?"mouseenter":"focus",s=u=="hover"?"mouseleave":"blur",this.$element.on(i+"."+this.type,this.options.selector,e.proxy(this.enter,this)),this.$element.on(s+"."+this.type,this.options.selector,e.proxy(this.leave,this)));this.options.selector?this._options=e.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},getOptions:function(t){return t=e.extend({},e.fn[this.type].defaults,this.$element.data(),t),t.delay&&typeof t.delay=="number"&&(t.delay={show:t.delay,hide:t.delay}),t},enter:function(t){var n=e.fn[this.type].defaults,r={},i;this._options&&e.each(this._options,function(e,t){n[e]!=t&&(r[e]=t)},this),i=e(t.currentTarget)[this.type](r).data(this.type);if(!i.options.delay||!i.options.delay.show)return i.show();clearTimeout(this.timeout),i.hoverState="in",this.timeout=setTimeout(function(){i.hoverState=="in"&&i.show()},i.options.delay.show)},leave:function(t){var n=e(t.currentTarget)[this.type](this._options).data(this.type);this.timeout&&clearTimeout(this.timeout);if(!n.options.delay||!n.options.delay.hide)return n.hide();n.hoverState="out",this.timeout=setTimeout(function(){n.hoverState=="out"&&n.hide()},n.options.delay.hide)},show:function(){var t,n,r,i,s,o,u=e.Event("show");if(this.hasContent()&&this.enabled){this.$element.trigger(u);if(u.isDefaultPrevented())return;t=this.tip(),this.setContent(),this.options.animation&&t.addClass("fade"),s=typeof this.options.placement=="function"?this.options.placement.call(this,t[0],this.$element[0]):this.options.placement,t.detach().css({top:0,left:0,display:"block"}),this.options.container?t.appendTo(this.options.container):t.insertAfter(this.$element),n=this.getPosition(),r=t[0].offsetWidth,i=t[0].offsetHeight;switch(s){case"bottom":o={top:n.top+n.height,left:n.left+n.width/2-r/2};break;case"top":o={top:n.top-i,left:n.left+n.width/2-r/2};break;case"left":o={top:n.top+n.height/2-i/2,left:n.left-r};break;case"right":o={top:n.top+n.height/2-i/2,left:n.left+n.width}}this.applyPlacement(o,s),this.$element.trigger("shown")}},applyPlacement:function(e,t){var n=this.tip(),r=n[0].offsetWidth,i=n[0].offsetHeight,s,o,u,a;n.offset(e).addClass(t).addClass("in"),s=n[0].offsetWidth,o=n[0].offsetHeight,t=="top"&&o!=i&&(e.top=e.top+i-o,a=!0),t=="bottom"||t=="top"?(u=0,e.left<0&&(u=e.left*-2,e.left=0,n.offset(e),s=n[0].offsetWidth,o=n[0].offsetHeight),this.replaceArrow(u-r+s,s,"left")):this.replaceArrow(o-i,o,"top"),a&&n.offset(e)},replaceArrow:function(e,t,n){this.arrow().css(n,e?50*(1-e/t)+"%":"")},setContent:function(){var e=this.tip(),t=this.getTitle();e.find(".tooltip-inner")[this.options.html?"html":"text"](t),e.removeClass("fade in top bottom left right")},hide:function(){function i(){var t=setTimeout(function(){n.off(e.support.transition.end).detach()},500);n.one(e.support.transition.end,function(){clearTimeout(t),n.detach()})}var t=this,n=this.tip(),r=e.Event("hide");this.$element.trigger(r);if(r.isDefaultPrevented())return;return n.removeClass("in"),e.support.transition&&this.$tip.hasClass("fade")?i():n.detach(),this.$element.trigger("hidden"),this},fixTitle:function(){var e=this.$element;(e.attr("title")||typeof e.attr("data-original-title")!="string")&&e.attr("data-original-title",e.attr("title")||"").attr("title","")},hasContent:function(){return this.getTitle()},getPosition:function(){var t=this.$element[0];return e.extend({},typeof t.getBoundingClientRect=="function"?t.getBoundingClientRect():{width:t.offsetWidth,height:t.offsetHeight},this.$element.offset())},getTitle:function(){var e,t=this.$element,n=this.options;return e=t.attr("data-original-title")||(typeof n.title=="function"?n.title.call(t[0]):n.title),e},tip:function(){return this.$tip=this.$tip||e(this.options.template)},arrow:function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled},toggle:function(t){var n=t?e(t.currentTarget)[this.type](this._options).data(this.type):this;n.tip().hasClass("in")?n.hide():n.show()},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}};var n=e.fn.tooltip;e.fn.tooltip=function(n){return this.each(function(){var r=e(this),i=r.data("tooltip"),s=typeof n=="object"&&n;i||r.data("tooltip",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.tooltip.Constructor=t,e.fn.tooltip.defaults={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1},e.fn.tooltip.noConflict=function(){return e.fn.tooltip=n,this}}(window.jQuery),!function(e){"use strict";var t=function(e,t){this.init("popover",e,t)};t.prototype=e.extend({},e.fn.tooltip.Constructor.prototype,{constructor:t,setContent:function(){var e=this.tip(),t=this.getTitle(),n=this.getContent();e.find(".popover-title")[this.options.html?"html":"text"](t),e.find(".popover-content")[this.options.html?"html":"text"](n),e.removeClass("fade top bottom left right in")},hasContent:function(){return this.getTitle()||this.getContent()},getContent:function(){var e,t=this.$element,n=this.options;return e=(typeof n.content=="function"?n.content.call(t[0]):n.content)||t.attr("data-content"),e},tip:function(){return this.$tip||(this.$tip=e(this.options.template)),this.$tip},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}});var n=e.fn.popover;e.fn.popover=function(n){return this.each(function(){var r=e(this),i=r.data("popover"),s=typeof n=="object"&&n;i||r.data("popover",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.popover.Constructor=t,e.fn.popover.defaults=e.extend({},e.fn.tooltip.defaults,{placement:"right",trigger:"click",content:"",template:'<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),e.fn.popover.noConflict=function(){return e.fn.popover=n,this}}(window.jQuery),!function(e){"use strict";function t(t,n){var r=e.proxy(this.process,this),i=e(t).is("body")?e(window):e(t),s;this.options=e.extend({},e.fn.scrollspy.defaults,n),this.$scrollElement=i.on("scroll.scroll-spy.data-api",r),this.selector=(this.options.target||(s=e(t).attr("href"))&&s.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.$body=e("body"),this.refresh(),this.process()}t.prototype={constructor:t,refresh:function(){var t=this,n;this.offsets=e([]),this.targets=e([]),n=this.$body.find(this.selector).map(function(){var n=e(this),r=n.data("target")||n.attr("href"),i=/^#\w/.test(r)&&e(r);return i&&i.length&&[[i.position().top+(!e.isWindow(t.$scrollElement.get(0))&&t.$scrollElement.scrollTop()),r]]||null}).sort(function(e,t){return e[0]-t[0]}).each(function(){t.offsets.push(this[0]),t.targets.push(this[1])})},process:function(){var e=this.$scrollElement.scrollTop()+this.options.offset,t=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,n=t-this.$scrollElement.height(),r=this.offsets,i=this.targets,s=this.activeTarget,o;if(e>=n)return s!=(o=i.last()[0])&&this.activate(o);for(o=r.length;o--;)s!=i[o]&&e>=r[o]&&(!r[o+1]||e<=r[o+1])&&this.activate(i[o])},activate:function(t){var n,r;this.activeTarget=t,e(this.selector).parent(".active").removeClass("active"),r=this.selector+'[data-target="'+t+'"],'+this.selector+'[href="'+t+'"]',n=e(r).parent("li").addClass("active"),n.parent(".dropdown-menu").length&&(n=n.closest("li.dropdown").addClass("active")),n.trigger("activate")}};var n=e.fn.scrollspy;e.fn.scrollspy=function(n){return this.each(function(){var r=e(this),i=r.data("scrollspy"),s=typeof n=="object"&&n;i||r.data("scrollspy",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.scrollspy.Constructor=t,e.fn.scrollspy.defaults={offset:10},e.fn.scrollspy.noConflict=function(){return e.fn.scrollspy=n,this},e(window).on("load",function(){e('[data-spy="scroll"]').each(function(){var t=e(this);t.scrollspy(t.data())})})}(window.jQuery),!function(e){"use strict";var t=function(t){this.element=e(t)};t.prototype={constructor:t,show:function(){var t=this.element,n=t.closest("ul:not(.dropdown-menu)"),r=t.attr("data-target"),i,s,o;r||(r=t.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,""));if(t.parent("li").hasClass("active"))return;i=n.find(".active:last a")[0],o=e.Event("show",{relatedTarget:i}),t.trigger(o);if(o.isDefaultPrevented())return;s=e(r),this.activate(t.parent("li"),n),this.activate(s,s.parent(),function(){t.trigger({type:"shown",relatedTarget:i})})},activate:function(t,n,r){function o(){i.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),t.addClass("active"),s?(t[0].offsetWidth,t.addClass("in")):t.removeClass("fade"),t.parent(".dropdown-menu")&&t.closest("li.dropdown").addClass("active"),r&&r()}var i=n.find("> .active"),s=r&&e.support.transition&&i.hasClass("fade");s?i.one(e.support.transition.end,o):o(),i.removeClass("in")}};var n=e.fn.tab;e.fn.tab=function(n){return this.each(function(){var r=e(this),i=r.data("tab");i||r.data("tab",i=new t(this)),typeof n=="string"&&i[n]()})},e.fn.tab.Constructor=t,e.fn.tab.noConflict=function(){return e.fn.tab=n,this},e(document).on("click.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(t){t.preventDefault(),e(this).tab("show")})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.typeahead.defaults,n),this.matcher=this.options.matcher||this.matcher,this.sorter=this.options.sorter||this.sorter,this.highlighter=this.options.highlighter||this.highlighter,this.updater=this.options.updater||this.updater,this.source=this.options.source,this.$menu=e(this.options.menu),this.shown=!1,this.listen()};t.prototype={constructor:t,select:function(){var e=this.$menu.find(".active").attr("data-value");return this.$element.val(this.updater(e)).change(),this.hide()},updater:function(e){return e},show:function(){var t=e.extend({},this.$element.position(),{height:this.$element[0].offsetHeight});return this.$menu.insertAfter(this.$element).css({top:t.top+t.height,left:t.left}).show(),this.shown=!0,this},hide:function(){return this.$menu.hide(),this.shown=!1,this},lookup:function(t){var n;return this.query=this.$element.val(),!this.query||this.query.length<this.options.minLength?this.shown?this.hide():this:(n=e.isFunction(this.source)?this.source(this.query,e.proxy(this.process,this)):this.source,n?this.process(n):this)},process:function(t){var n=this;return t=e.grep(t,function(e){return n.matcher(e)}),t=this.sorter(t),t.length?this.render(t.slice(0,this.options.items)).show():this.shown?this.hide():this},matcher:function(e){return~e.toLowerCase().indexOf(this.query.toLowerCase())},sorter:function(e){var t=[],n=[],r=[],i;while(i=e.shift())i.toLowerCase().indexOf(this.query.toLowerCase())?~i.indexOf(this.query)?n.push(i):r.push(i):t.push(i);return t.concat(n,r)},highlighter:function(e){var t=this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&");return e.replace(new RegExp("("+t+")","ig"),function(e,t){return"<strong>"+t+"</strong>"})},render:function(t){var n=this;return t=e(t).map(function(t,r){return t=e(n.options.item).attr("data-value",r),t.find("a").html(n.highlighter(r)),t[0]}),t.first().addClass("active"),this.$menu.html(t),this},next:function(t){var n=this.$menu.find(".active").removeClass("active"),r=n.next();r.length||(r=e(this.$menu.find("li")[0])),r.addClass("active")},prev:function(e){var t=this.$menu.find(".active").removeClass("active"),n=t.prev();n.length||(n=this.$menu.find("li").last()),n.addClass("active")},listen:function(){this.$element.on("focus",e.proxy(this.focus,this)).on("blur",e.proxy(this.blur,this)).on("keypress",e.proxy(this.keypress,this)).on("keyup",e.proxy(this.keyup,this)),this.eventSupported("keydown")&&this.$element.on("keydown",e.proxy(this.keydown,this)),this.$menu.on("click",e.proxy(this.click,this)).on("mouseenter","li",e.proxy(this.mouseenter,this)).on("mouseleave","li",e.proxy(this.mouseleave,this))},eventSupported:function(e){var t=e in this.$element;return t||(this.$element.setAttribute(e,"return;"),t=typeof this.$element[e]=="function"),t},move:function(e){if(!this.shown)return;switch(e.keyCode){case 9:case 13:case 27:e.preventDefault();break;case 38:e.preventDefault(),this.prev();break;case 40:e.preventDefault(),this.next()}e.stopPropagation()},keydown:function(t){this.suppressKeyPressRepeat=~e.inArray(t.keyCode,[40,38,9,13,27]),this.move(t)},keypress:function(e){if(this.suppressKeyPressRepeat)return;this.move(e)},keyup:function(e){switch(e.keyCode){case 40:case 38:case 16:case 17:case 18:break;case 9:case 13:if(!this.shown)return;this.select();break;case 27:if(!this.shown)return;this.hide();break;default:this.lookup()}e.stopPropagation(),e.preventDefault()},focus:function(e){this.focused=!0},blur:function(e){this.focused=!1,!this.mousedover&&this.shown&&this.hide()},click:function(e){e.stopPropagation(),e.preventDefault(),this.select(),this.$element.focus()},mouseenter:function(t){this.mousedover=!0,this.$menu.find(".active").removeClass("active"),e(t.currentTarget).addClass("active")},mouseleave:function(e){this.mousedover=!1,!this.focused&&this.shown&&this.hide()}};var n=e.fn.typeahead;e.fn.typeahead=function(n){return this.each(function(){var r=e(this),i=r.data("typeahead"),s=typeof n=="object"&&n;i||r.data("typeahead",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.typeahead.defaults={source:[],items:8,menu:'<ul class="typeahead dropdown-menu"></ul>',item:'<li><a href="#"></a></li>',minLength:1},e.fn.typeahead.Constructor=t,e.fn.typeahead.noConflict=function(){return e.fn.typeahead=n,this},e(document).on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(t){var n=e(this);if(n.data("typeahead"))return;n.typeahead(n.data())})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.options=e.extend({},e.fn.affix.defaults,n),this.$window=e(window).on("scroll.affix.data-api",e.proxy(this.checkPosition,this)).on("click.affix.data-api",e.proxy(function(){setTimeout(e.proxy(this.checkPosition,this),1)},this)),this.$element=e(t),this.checkPosition()};t.prototype.checkPosition=function(){if(!this.$element.is(":visible"))return;var t=e(document).height(),n=this.$window.scrollTop(),r=this.$element.offset(),i=this.options.offset,s=i.bottom,o=i.top,u="affix affix-top affix-bottom",a;typeof i!="object"&&(s=o=i),typeof o=="function"&&(o=i.top()),typeof s=="function"&&(s=i.bottom()),a=this.unpin!=null&&n+this.unpin<=r.top?!1:s!=null&&r.top+this.$element.height()>=t-s?"bottom":o!=null&&n<=o?"top":!1;if(this.affixed===a)return;this.affixed=a,this.unpin=a=="bottom"?r.top-n:null,this.$element.removeClass(u).addClass("affix"+(a?"-"+a:""))};var n=e.fn.affix;e.fn.affix=function(n){return this.each(function(){var r=e(this),i=r.data("affix"),s=typeof n=="object"&&n;i||r.data("affix",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.affix.Constructor=t,e.fn.affix.defaults={offset:0},e.fn.affix.noConflict=function(){return e.fn.affix=n,this},e(window).on("load",function(){e('[data-spy="affix"]').each(function(){var t=e(this),n=t.data();n.offset=n.offset||{},n.offsetBottom&&(n.offset.bottom=n.offsetBottom),n.offsetTop&&(n.offset.top=n.offsetTop),t.affix(n)})})}(window.jQuery);
\ No newline at end of file
Added: html5videoplayer/js/libs/can.fixture.js
===================================================================
--- html5videoplayer/js/libs/can.fixture.js (rev 0)
+++ html5videoplayer/js/libs/can.fixture.js 2013-06-07 16:16:19 UTC (rev 660)
@@ -0,0 +1,614 @@
+/*!
+ * CanJS - 1.1.6
+ * http://canjs.us/
+ * Copyright (c) 2013 Bitovi
+ * Wed, 29 May 2013 18:59:29 GMT
+ * Licensed MIT
+ * Includes: can/util/fixture
+ * Download from: http://canjs.com
+ */
+(function(can) {
+
+ // Get the URL from old Steal root, new Steal config or can.fixture.rootUrl
+ var getUrl = function(url) {
+ if (typeof steal !== 'undefined') {
+ if (can.isFunction(steal.config)) {
+ return steal.config().root.mapJoin(url).toString();
+ }
+ return steal.root.join(url).toString();
+ }
+ return (can.fixture.rootUrl || '') + url;
+ }
+
+ var updateSettings = function(settings, originalOptions) {
+ if (!can.fixture.on) {
+ return;
+ }
+
+ //simple wrapper for logging
+ var _logger = function(type, arr) {
+ if (console.log.apply) {
+ Function.prototype.call.apply(console[type], [console].concat(arr));
+ // console[type].apply(console, arr)
+ } else {
+ console[type](arr)
+ }
+ },
+ log = function() {
+ if (typeof steal !== 'undefined' && steal.dev) {
+ steal.dev.log('fixture INFO: ' + Array.prototype.slice.call(arguments).join(' '));
+ }
+ }
+
+ // We always need the type which can also be called method, default to GET
+ settings.type = settings.type || settings.method || 'GET';
+
+ // add the fixture option if programmed in
+ var data = overwrite(settings);
+
+ // if we don't have a fixture, do nothing
+ if (!settings.fixture) {
+ if (window.location.protocol === "file:") {
+ log("ajax request to " + settings.url + ", no fixture found");
+ }
+ return;
+ }
+
+ //if referencing something else, update the fixture option
+ if (typeof settings.fixture === "string" && can.fixture[settings.fixture]) {
+ settings.fixture = can.fixture[settings.fixture];
+ }
+
+ // if a string, we just point to the right url
+ if (typeof settings.fixture == "string") {
+ var url = settings.fixture;
+
+ if (/^\/\//.test(url)) {
+ // this lets us use rootUrl w/o having steal...
+ url = getUrl(settings.fixture.substr(2));
+ }
+
+ if (data) {
+ // Template static fixture URLs
+ url = can.sub(url, data);
+ }
+
+ delete settings.fixture;
+
+
+
+ settings.url = url;
+ settings.data = null;
+ settings.type = "GET";
+ if (!settings.error) {
+ settings.error = function(xhr, error, message) {
+ throw "fixtures.js Error " + error + " " + message;
+ };
+ }
+ } else {
+
+
+ //it's a function ... add the fixture datatype so our fixture transport handles it
+ // TODO: make everything go here for timing and other fun stuff
+ // add to settings data from fixture ...
+ settings.dataTypes && settings.dataTypes.splice(0, 0, "fixture");
+
+ if (data && originalOptions) {
+ can.extend(originalOptions.data, data)
+ }
+ }
+ },
+ // A helper function that takes what's called with response
+ // and moves some common args around to make it easier to call
+ extractResponse = function(status, statusText, responses, headers) {
+ // if we get response(RESPONSES, HEADERS)
+ if (typeof status != "number") {
+ headers = statusText;
+ responses = status;
+ statusText = "success"
+ status = 200;
+ }
+ // if we get response(200, RESPONSES, HEADERS)
+ if (typeof statusText != "string") {
+ headers = responses;
+ responses = statusText;
+ statusText = "success";
+ }
+ if (status >= 400 && status <= 599) {
+ this.dataType = "text"
+ }
+ return [status, statusText, extractResponses(this, responses), headers];
+ },
+ // If we get data instead of responses,
+ // make sure we provide a response type that matches the first datatype (typically json)
+ extractResponses = function(settings, responses) {
+ var next = settings.dataTypes ? settings.dataTypes[0] : (settings.dataType || 'json');
+ if (!responses || !responses[next]) {
+ var tmp = {}
+ tmp[next] = responses;
+ responses = tmp;
+ }
+ return responses;
+ };
+
+ //used to check urls
+ // check if jQuery
+ if (can.ajaxPrefilter && can.ajaxTransport) {
+
+ // the pre-filter needs to re-route the url
+ can.ajaxPrefilter(updateSettings);
+
+ can.ajaxTransport("fixture", function(s, original) {
+ // remove the fixture from the datatype
+ s.dataTypes.shift();
+
+ //we'll return the result of the next data type
+ var timeout, stopped = false;
+
+ return {
+ send: function(headers, callback) {
+ // we'll immediately wait the delay time for all fixtures
+ timeout = setTimeout(function() {
+ // if the user wants to call success on their own, we allow it ...
+ var success = function() {
+ if (stopped === false) {
+ callback.apply(null, extractResponse.apply(s, arguments));
+ }
+ },
+ // get the result form the fixture
+ result = s.fixture(original, success, headers, s);
+ if (result !== undefined) {
+ // make sure the result has the right dataType
+ callback(200, "success", extractResponses(s, result), {});
+ }
+ }, can.fixture.delay);
+ },
+ abort: function() {
+ stopped = true;
+ clearTimeout(timeout)
+ }
+ };
+ });
+ } else {
+ var AJAX = can.ajax;
+ can.ajax = function(settings) {
+ updateSettings(settings, settings);
+ if (settings.fixture) {
+ var timeout, d = new can.Deferred(),
+ stopped = false;
+
+ //TODO this should work with response
+ d.getResponseHeader = function() {}
+
+ // call success and fail
+ d.then(settings.success, settings.fail);
+
+ // abort should stop the timeout and calling success
+ d.abort = function() {
+ clearTimeout(timeout);
+ stopped = true;
+ d.reject(d)
+ }
+ // set a timeout that simulates making a request ....
+ timeout = setTimeout(function() {
+ // if the user wants to call success on their own, we allow it ...
+ var success = function() {
+ var response = extractResponse.apply(settings, arguments),
+ status = response[0];
+
+ if ((status >= 200 && status < 300 || status === 304) && stopped === false) {
+ d.resolve(response[2][settings.dataType])
+ } else {
+ // TODO probably resolve better
+ d.reject(d, 'error', response[1]);
+ }
+ },
+ // get the result form the fixture
+ result = settings.fixture(settings, success, settings.headers, settings);
+ if (result !== undefined) {
+ d.resolve(result)
+ }
+ }, can.fixture.delay);
+
+ return d;
+ } else {
+ return AJAX(settings);
+ }
+ }
+ }
+
+ var typeTest = /^(script|json|text|jsonp)$/,
+ // a list of 'overwrite' settings object
+ overwrites = [],
+ // returns the index of an overwrite function
+ find = function(settings, exact) {
+ for (var i = 0; i < overwrites.length; i++) {
+ if ($fixture._similar(settings, overwrites[i], exact)) {
+ return i;
+ }
+ }
+ return -1;
+ },
+ // overwrites the settings fixture if an overwrite matches
+ overwrite = function(settings) {
+ var index = find(settings);
+ if (index > -1) {
+ settings.fixture = overwrites[index].fixture;
+ return $fixture._getData(overwrites[index].url, settings.url)
+ }
+
+ },
+ // Makes an attempt to guess where the id is at in the url and returns it.
+ getId = function(settings) {
+ var id = settings.data.id;
+
+ if (id === undefined && typeof settings.data === "number") {
+ id = settings.data;
+ }
+
+
+
+ if (id === undefined) {
+ settings.url.replace(/\/(\d+)(\/|$|\.)/g, function(all, num) {
+ id = num;
+ });
+ }
+
+ if (id === undefined) {
+ id = settings.url.replace(/\/(\w+)(\/|$|\.)/g, function(all, num) {
+ if (num != 'update') {
+ id = num;
+ }
+ })
+ }
+
+ if (id === undefined) { // if still not set, guess a random number
+ id = Math.round(Math.random() * 1000)
+ }
+
+ return id;
+ };
+
+ var $fixture = can.fixture = function(settings, fixture) {
+ // if we provide a fixture ...
+ if (fixture !== undefined) {
+ if (typeof settings == 'string') {
+ // handle url strings
+ var matches = settings.match(/(GET|POST|PUT|DELETE) (.+)/i);
+ if (!matches) {
+ settings = {
+ url: settings
+ };
+ } else {
+ settings = {
+ url: matches[2],
+ type: matches[1]
+ };
+ }
+
+ }
+
+ //handle removing. An exact match if fixture was provided, otherwise, anything similar
+ var index = find(settings, !! fixture);
+ if (index > -1) {
+ overwrites.splice(index, 1)
+ }
+ if (fixture == null) {
+ return
+ }
+ settings.fixture = fixture;
+ overwrites.push(settings)
+ } else {
+ can.each(settings, function(fixture, url) {
+ $fixture(url, fixture);
+ })
+ }
+ };
+ var replacer = can.replacer;
+
+ can.extend(can.fixture, {
+ // given ajax settings, find an overwrite
+ _similar: function(settings, overwrite, exact) {
+ if (exact) {
+ return can.Object.same(settings, overwrite, {
+ fixture: null
+ })
+ } else {
+ return can.Object.subset(settings, overwrite, can.fixture._compare)
+ }
+ },
+ _compare: {
+ url: function(a, b) {
+ return !!$fixture._getData(b, a)
+ },
+ fixture: null,
+ type: "i"
+ },
+ // gets data from a url like "/todo/{id}" given "todo/5"
+ _getData: function(fixtureUrl, url) {
+ var order = [],
+ fixtureUrlAdjusted = fixtureUrl.replace('.', '\\.').replace('?', '\\?'),
+ res = new RegExp(fixtureUrlAdjusted.replace(replacer, function(whole, part) {
+ order.push(part)
+ return "([^\/]+)"
+ }) + "$").exec(url),
+ data = {};
+
+ if (!res) {
+ return null;
+ }
+ res.shift();
+ can.each(order, function(name) {
+ data[name] = res.shift()
+ })
+ return data;
+ },
+
+ store: function(types, count, make, filter) {
+
+ var items = [], // TODO: change this to a hash
+ currentId = 0,
+ findOne = function(id) {
+ for (var i = 0; i < items.length; i++) {
+ if (id == items[i].id) {
+ return items[i];
+ }
+ }
+ },
+ methods = {};
+
+ if (typeof types === "string") {
+ types = [types + "s", types]
+ } else if (!can.isArray(types)) {
+ filter = make;
+ make = count;
+ count = types;
+ }
+
+ // make all items
+ can.extend(methods, {
+
+ findAll: function(request) {
+ request = request || {}
+ //copy array of items
+ var retArr = items.slice(0);
+ request.data = request.data || {};
+ //sort using order
+ //order looks like ["age ASC","gender DESC"]
+ can.each((request.data.order || []).slice(0).reverse(), function(name) {
+ var split = name.split(" ");
+ retArr = retArr.sort(function(a, b) {
+ if (split[1].toUpperCase() !== "ASC") {
+ if (a[split[0]] < b[split[0]]) {
+ return 1;
+ } else if (a[split[0]] == b[split[0]]) {
+ return 0
+ } else {
+ return -1;
+ }
+ } else {
+ if (a[split[0]] < b[split[0]]) {
+ return -1;
+ } else if (a[split[0]] == b[split[0]]) {
+ return 0
+ } else {
+ return 1;
+ }
+ }
+ });
+ });
+
+ //group is just like a sort
+ can.each((request.data.group || []).slice(0).reverse(), function(name) {
+ var split = name.split(" ");
+ retArr = retArr.sort(function(a, b) {
+ return a[split[0]] > b[split[0]];
+ });
+ });
+
+ var offset = parseInt(request.data.offset, 10) || 0,
+ limit = parseInt(request.data.limit, 10) || (items.length - offset),
+ i = 0;
+
+ //filter results if someone added an attr like parentId
+ for (var param in request.data) {
+ i = 0;
+ if (request.data[param] !== undefined && // don't do this if the value of the param is null (ignore it)
+ (param.indexOf("Id") != -1 || param.indexOf("_id") != -1)) {
+ while (i < retArr.length) {
+ if (request.data[param] != retArr[i][param]) {
+ retArr.splice(i, 1);
+ } else {
+ i++;
+ }
+ }
+ }
+ }
+
+ if (filter) {
+ i = 0;
+ while (i < retArr.length) {
+ if (!filter(retArr[i], request)) {
+ retArr.splice(i, 1);
+ } else {
+ i++;
+ }
+ }
+ }
+
+ //return data spliced with limit and offset
+ return {
+ "count": retArr.length,
+ "limit": request.data.limit,
+ "offset": request.data.offset,
+ "data": retArr.slice(offset, offset + limit)
+ };
+ },
+
+ findOne: function(request, response) {
+ var item = findOne(getId(request));
+ response(item ? item : undefined);
+ },
+
+ update: function(request, response) {
+ var id = getId(request);
+
+ // TODO: make it work with non-linear ids ..
+ can.extend(findOne(id), request.data);
+ response({
+ id: getId(request)
+ }, {
+ location: request.url || "/" + getId(request)
+ });
+ },
+
+ destroy: function(request) {
+ var id = getId(request);
+ for (var i = 0; i < items.length; i++) {
+ if (items[i].id == id) {
+ items.splice(i, 1);
+ break;
+ }
+ }
+
+ // TODO: make it work with non-linear ids ..
+ can.extend(findOne(id) || {}, request.data);
+ return {};
+ },
+
+ create: function(settings, response) {
+ var item = make(items.length, items);
+
+ can.extend(item, settings.data);
+
+ if (!item.id) {
+ item.id = currentId++;
+ }
+
+ items.push(item);
+ response({
+ id: item.id
+ }, {
+ location: settings.url + "/" + item.id
+ })
+ }
+ });
+
+ var reset = function() {
+ items = [];
+ for (var i = 0; i < (count); i++) {
+ //call back provided make
+ var item = make(i, items);
+
+ if (!item.id) {
+ item.id = i;
+ }
+ currentId = Math.max(item.id + 1, currentId + 1) || items.length;
+ items.push(item);
+ }
+ if (can.isArray(types)) {
+ can.fixture["~" + types[0]] = items;
+ can.fixture["-" + types[0]] = methods.findAll;
+ can.fixture["-" + types[1]] = methods.findOne;
+ can.fixture["-" + types[1] + "Update"] = methods.update;
+ can.fixture["-" + types[1] + "Destroy"] = methods.destroy;
+ can.fixture["-" + types[1] + "Create"] = methods.create;
+ }
+
+ }
+ reset()
+ // if we have types given add them to can.fixture
+
+
+ return can.extend({
+ getId: getId,
+
+ find: function(settings) {
+ return findOne(getId(settings));
+ },
+
+ reset: reset
+ }, methods);
+ },
+
+ rand: function(arr, min, max) {
+ if (typeof arr == 'number') {
+ if (typeof min == 'number') {
+ return arr + Math.floor(Math.random() * (min - arr));
+ } else {
+ return Math.floor(Math.random() * arr);
+ }
+
+ }
+ var rand = arguments.callee;
+ // get a random set
+ if (min === undefined) {
+ return rand(arr, rand(arr.length + 1))
+ }
+ // get a random selection of arr
+ var res = [];
+ arr = arr.slice(0);
+ // set max
+ if (!max) {
+ max = min;
+ }
+ //random max
+ max = min + Math.round(rand(max - min))
+ for (var i = 0; i < max; i++) {
+ res.push(arr.splice(rand(arr.length), 1)[0])
+ }
+ return res;
+ },
+
+ xhr: function(xhr) {
+ return can.extend({}, {
+ abort: can.noop,
+ getAllResponseHeaders: function() {
+ return "";
+ },
+ getResponseHeader: function() {
+ return "";
+ },
+ open: can.noop,
+ overrideMimeType: can.noop,
+ readyState: 4,
+ responseText: "",
+ responseXML: null,
+ send: can.noop,
+ setRequestHeader: can.noop,
+ status: 200,
+ statusText: "OK"
+ }, xhr);
+ },
+
+ on: true
+ });
+
+ can.fixture.delay = 200;
+
+
+ can.fixture.rootUrl = getUrl('');
+
+ can.fixture["-handleFunction"] = function(settings) {
+ if (typeof settings.fixture === "string" && can.fixture[settings.fixture]) {
+ settings.fixture = can.fixture[settings.fixture];
+ }
+ if (typeof settings.fixture == "function") {
+ setTimeout(function() {
+ if (settings.success) {
+ settings.success.apply(null, settings.fixture(settings, "success"));
+ }
+ if (settings.complete) {
+ settings.complete.apply(null, settings.fixture(settings, "complete"));
+ }
+ }, can.fixture.delay);
+ return true;
+ }
+ return false;
+ };
+
+ //Expose this for fixture debugging
+ can.fixture.overwrites = overwrites;
+ can.fixture.make = can.fixture.store;
+ return can.fixture;
+ })(can);
\ No newline at end of file
Added: html5videoplayer/js/libs/can.jquery.js
===================================================================
--- html5videoplayer/js/libs/can.jquery.js (rev 0)
+++ html5videoplayer/js/libs/can.jquery.js 2013-06-07 16:16:19 UTC (rev 660)
@@ -0,0 +1,4367 @@
+/*!
+ * CanJS - 1.1.6
+ * http://canjs.us/
+ * Copyright (c) 2013 Bitovi
+ * Wed, 29 May 2013 18:59:27 GMT
+ * Licensed MIT
+ * Includes: can/construct,can/observe,can/observe/compute,can/model,can/view,can/view/ejs,can/control,can/route,can/control/route
+ * Download from: http://canjs.com
+ */
+(function(undefined) {
+
+ // ## util/can.js
+ var __m5 = (function() {
+ var can = window.can || {};
+ if (typeof GLOBALCAN === 'undefined' || GLOBALCAN !== false) {
+ window.can = can;
+ }
+
+ can.isDeferred = function(obj) {
+ var isFunction = this.isFunction;
+ // Returns `true` if something looks like a deferred.
+ return obj && isFunction(obj.then) && isFunction(obj.pipe);
+ };
+
+ var cid = 0;
+ can.cid = function(object, name) {
+ if (object._cid) {
+ return object._cid
+ } else {
+ return object._cid = (name || "") + (++cid)
+ }
+ }
+ can.VERSION = '@EDGE';
+ return can;
+ })();
+
+ // ## util/array/each.js
+ var __m6 = (function(can) {
+ can.each = function(elements, callback, context) {
+ var i = 0,
+ key;
+ if (elements) {
+ if (typeof elements.length === 'number' && elements.pop) {
+ if (elements.attr) {
+ elements.attr('length');
+ }
+ for (key = elements.length; i < key; i++) {
+ if (callback.call(context || elements[i], elements[i], i, elements) === false) {
+ break;
+ }
+ }
+ } else if (elements.hasOwnProperty) {
+ for (key in elements) {
+ if (elements.hasOwnProperty(key)) {
+ if (callback.call(context || elements[key], elements[key], key, elements) === false) {
+ break;
+ }
+ }
+ }
+ }
+ }
+ return elements;
+ };
+
+ return can;
+ })(__m5);
+
+ // ## util/jquery/jquery.js
+ var __m3 = (function($, can) {
+ // _jQuery node list._
+ $.extend(can, $, {
+ trigger: function(obj, event, args) {
+ if (obj.trigger) {
+ obj.trigger(event, args);
+ } else {
+ $.event.trigger(event, args, obj, true);
+ }
+ },
+ addEvent: function(ev, cb) {
+ $([this]).bind(ev, cb);
+ return this;
+ },
+ removeEvent: function(ev, cb) {
+ $([this]).unbind(ev, cb);
+ return this;
+ },
+ // jquery caches fragments, we always needs a new one
+ buildFragment: function(elems, context) {
+ var oldFragment = $.buildFragment,
+ ret;
+
+ elems = [elems];
+ // Set context per 1.8 logic
+ context = context || document;
+ context = !context.nodeType && context[0] || context;
+ context = context.ownerDocument || context;
+
+ ret = oldFragment.call(jQuery, elems, context);
+
+ return ret.cacheable ? $.clone(ret.fragment) : ret.fragment || ret;
+ },
+ $: $,
+ each: can.each
+ });
+
+ // Wrap binding functions.
+ $.each(['bind', 'unbind', 'undelegate', 'delegate'], function(i, func) {
+ can[func] = function() {
+ var t = this[func] ? this : $([this]);
+ t[func].apply(t, arguments);
+ return this;
+ };
+ });
+
+ // Wrap modifier functions.
+ $.each(["append", "filter", "addClass", "remove", "data", "get"], function(i, name) {
+ can[name] = function(wrapped) {
+ return wrapped[name].apply(wrapped, can.makeArray(arguments).slice(1));
+ };
+ });
+
+ // Memory safe destruction.
+ var oldClean = $.cleanData;
+
+ $.cleanData = function(elems) {
+ $.each(elems, function(i, elem) {
+ if (elem) {
+ can.trigger(elem, "destroyed", [], false);
+ }
+ });
+ oldClean(elems);
+ };
+
+ return can;
+ })(jQuery, __m5, __m6);
+
+ // ## util/string/string.js
+ var __m2 = (function(can) {
+ // ##string.js
+ // _Miscellaneous string utility functions._
+
+ // Several of the methods in this plugin use code adapated from Prototype
+ // Prototype JavaScript framework, version 1.6.0.1.
+ // © 2005-2007 Sam Stephenson
+ var strUndHash = /_|-/,
+ strColons = /\=\=/,
+ strWords = /([A-Z]+)([A-Z][a-z])/g,
+ strLowUp = /([a-z\d])([A-Z])/g,
+ strDash = /([a-z\d])([A-Z])/g,
+ strReplacer = /\{([^\}]+)\}/g,
+ strQuote = /"/g,
+ strSingleQuote = /'/g,
+
+ // Returns the `prop` property from `obj`.
+ // If `add` is true and `prop` doesn't exist in `obj`, create it as an
+ // empty object.
+ getNext = function(obj, prop, add) {
+ var result = obj[prop];
+
+ if (result === undefined && add === true) {
+ result = obj[prop] = {}
+ }
+ return result
+ },
+
+ // Returns `true` if the object can have properties (no `null`s).
+ isContainer = function(current) {
+ return (/^f|^o/).test(typeof current);
+ };
+
+ can.extend(can, {
+ // Escapes strings for HTML.
+
+ esc: function(content) {
+ // Convert bad values into empty strings
+ var isInvalid = content === null || content === undefined || (isNaN(content) && ("" + content === 'NaN'));
+ return ("" + (isInvalid ? '' : content))
+ .replace(/&/g, '&')
+ .replace(/</g, '<')
+ .replace(/>/g, '>')
+ .replace(strQuote, '"')
+ .replace(strSingleQuote, "'");
+ },
+
+
+ getObject: function(name, roots, add) {
+
+ // The parts of the name we are looking up
+ // `['App','Models','Recipe']`
+ var parts = name ? name.split('.') : [],
+ length = parts.length,
+ current,
+ r = 0,
+ i, container, rootsLength;
+
+ // Make sure roots is an `array`.
+ roots = can.isArray(roots) ? roots : [roots || window];
+
+ rootsLength = roots.length
+
+ if (!length) {
+ return roots[0];
+ }
+
+ // For each root, mark it as current.
+ for (r; r < rootsLength; r++) {
+ current = roots[r];
+ container = undefined;
+
+ // Walk current to the 2nd to last object or until there
+ // is not a container.
+ for (i = 0; i < length && isContainer(current); i++) {
+ container = current;
+ current = getNext(container, parts[i]);
+ }
+
+ // If we found property break cycle
+ if (container !== undefined && current !== undefined) {
+ break
+ }
+ }
+
+ // Remove property from found container
+ if (add === false && current !== undefined) {
+ delete container[parts[i - 1]]
+ }
+
+ // When adding property add it to the first root
+ if (add === true && current === undefined) {
+ current = roots[0]
+
+ for (i = 0; i < length && isContainer(current); i++) {
+ current = getNext(current, parts[i], true);
+ }
+ }
+
+ return current;
+ },
+ // Capitalizes a string.
+
+ capitalize: function(s, cache) {
+ // Used to make newId.
+ return s.charAt(0).toUpperCase() + s.slice(1);
+ },
+
+ // Underscores a string.
+
+ underscore: function(s) {
+ return s
+ .replace(strColons, '/')
+ .replace(strWords, '$1_$2')
+ .replace(strLowUp, '$1_$2')
+ .replace(strDash, '_')
+ .toLowerCase();
+ },
+ // Micro-templating.
+
+ sub: function(str, data, remove) {
+ var obs = [];
+
+ str = str || '';
+
+ obs.push(str.replace(strReplacer, function(whole, inside) {
+
+ // Convert inside to type.
+ var ob = can.getObject(inside, data, remove === true ? false : undefined);
+
+ if (ob === undefined) {
+ obs = null;
+ return "";
+ }
+
+ // If a container, push into objs (which will return objects found).
+ if (isContainer(ob) && obs) {
+ obs.push(ob);
+ return "";
+ }
+
+ return "" + ob;
+ }));
+
+ return obs === null ? obs : (obs.length <= 1 ? obs[0] : obs);
+ },
+
+ // These regex's are used throughout the rest of can, so let's make
+ // them available.
+ replacer: strReplacer,
+ undHash: strUndHash
+ });
+ return can;
+ })(__m3);
+
+ // ## construct/construct.js
+ var __m1 = (function(can) {
+
+ // ## construct.js
+ // `can.Construct`
+ // _This is a modified version of
+ // [John Resig's class](http://ejohn.org/blog/simple-javascript-inheritance/).
+ // It provides class level inheritance and callbacks._
+
+ // A private flag used to initialize a new class instance without
+ // initializing it's bindings.
+ var initializing = 0;
+
+
+ can.Construct = function() {
+ if (arguments.length) {
+ return can.Construct.extend.apply(can.Construct, arguments);
+ }
+ };
+
+
+ can.extend(can.Construct, {
+
+ newInstance: function() {
+ // Get a raw instance object (`init` is not called).
+ var inst = this.instance(),
+ arg = arguments,
+ args;
+
+ // Call `setup` if there is a `setup`
+ if (inst.setup) {
+ args = inst.setup.apply(inst, arguments);
+ }
+
+ // Call `init` if there is an `init`
+ // If `setup` returned `args`, use those as the arguments
+ if (inst.init) {
+ inst.init.apply(inst, args || arguments);
+ }
+
+ return inst;
+ },
+ // Overwrites an object with methods. Used in the `super` plugin.
+ // `newProps` - New properties to add.
+ // `oldProps` - Where the old properties might be (used with `super`).
+ // `addTo` - What we are adding to.
+ _inherit: function(newProps, oldProps, addTo) {
+ can.extend(addTo || newProps, newProps || {})
+ },
+ // used for overwriting a single property.
+ // this should be used for patching other objects
+ // the super plugin overwrites this
+ _overwrite: function(what, oldProps, propName, val) {
+ what[propName] = val;
+ },
+ // Set `defaults` as the merger of the parent `defaults` and this
+ // object's `defaults`. If you overwrite this method, make sure to
+ // include option merging logic.
+
+ setup: function(base, fullName) {
+ this.defaults = can.extend(true, {}, base.defaults, this.defaults);
+ },
+ // Create's a new `class` instance without initializing by setting the
+ // `initializing` flag.
+ instance: function() {
+
+ // Prevents running `init`.
+ initializing = 1;
+
+ var inst = new this();
+
+ // Allow running `init`.
+ initializing = 0;
+
+ return inst;
+ },
+ // Extends classes.
+
+ extend: function(fullName, klass, proto) {
+ // Figure out what was passed and normalize it.
+ if (typeof fullName != 'string') {
+ proto = klass;
+ klass = fullName;
+ fullName = null;
+ }
+
+ if (!proto) {
+ proto = klass;
+ klass = null;
+ }
+ proto = proto || {};
+
+ var _super_class = this,
+ _super = this.prototype,
+ name, shortName, namespace, prototype;
+
+ // Instantiate a base class (but only create the instance,
+ // don't run the init constructor).
+ prototype = this.instance();
+
+ // Copy the properties over onto the new prototype.
+ can.Construct._inherit(proto, _super, prototype);
+
+ // The dummy class constructor.
+
+ function Constructor() {
+ // All construction is actually done in the init method.
+ if (!initializing) {
+ return this.constructor !== Constructor && arguments.length ?
+ // We are being called without `new` or we are extending.
+ arguments.callee.extend.apply(arguments.callee, arguments) :
+ // We are being called with `new`.
+ this.constructor.newInstance.apply(this.constructor, arguments);
+ }
+ }
+
+ // Copy old stuff onto class (can probably be merged w/ inherit)
+ for (name in _super_class) {
+ if (_super_class.hasOwnProperty(name)) {
+ Constructor[name] = _super_class[name];
+ }
+ }
+
+ // Copy new static properties on class.
+ can.Construct._inherit(klass, _super_class, Constructor);
+
+ // Setup namespaces.
+ if (fullName) {
+
+ var parts = fullName.split('.'),
+ shortName = parts.pop(),
+ current = can.getObject(parts.join('.'), window, true),
+ namespace = current,
+ _fullName = can.underscore(fullName.replace(/\./g, "_")),
+ _shortName = can.underscore(shortName);
+
+
+
+ current[shortName] = Constructor;
+ }
+
+ // Set things that shouldn't be overwritten.
+ can.extend(Constructor, {
+ constructor: Constructor,
+ prototype: prototype,
+
+ namespace: namespace,
+
+ _shortName: _shortName,
+
+ fullName: fullName,
+ _fullName: _fullName
+ });
+
+ // Dojo and YUI extend undefined
+ if (shortName !== undefined) {
+ Constructor.shortName = shortName;
+ }
+
+ // Make sure our prototype looks nice.
+ Constructor.prototype.constructor = Constructor;
+
+
+ // Call the class `setup` and `init`
+ var t = [_super_class].concat(can.makeArray(arguments)),
+ args = Constructor.setup.apply(Constructor, t);
+
+ if (Constructor.init) {
+ Constructor.init.apply(Constructor, args || t);
+ }
+
+
+ return Constructor;
+
+ }
+
+ });
+ return can.Construct;
+ })(__m2);
+
+ // ## util/bind/bind.js
+ var __m8 = (function(can) {
+
+
+ // ## Bind helpers
+ can.bindAndSetup = function() {
+ // Add the event to this object
+ can.addEvent.apply(this, arguments);
+ // If not initializing, and the first binding
+ // call bindsetup if the function exists.
+ if (!this._init) {
+ if (!this._bindings) {
+ this._bindings = 1;
+ // setup live-binding
+ this._bindsetup && this._bindsetup();
+
+ } else {
+ this._bindings++;
+ }
+
+ }
+
+ return this;
+ };
+
+ can.unbindAndTeardown = function(ev, handler) {
+ // Remove the event handler
+ can.removeEvent.apply(this, arguments);
+
+ this._bindings--;
+ // If there are no longer any bindings and
+ // there is a bindteardown method, call it.
+ if (!this._bindings) {
+ this._bindteardown && this._bindteardown();
+ }
+ return this;
+ }
+
+ return can;
+
+ })(__m3);
+
+ // ## observe/observe.js
+ var __m7 = (function(can, bind) {
+ // ## observe.js
+ // `can.Observe`
+ // _Provides the observable pattern for JavaScript Objects._
+ // Returns `true` if something is an object with properties of its own.
+ var canMakeObserve = function(obj) {
+ return obj && !can.isDeferred(obj) && (can.isArray(obj) || can.isPlainObject(obj) || (obj instanceof can.Observe));
+ },
+
+ // Removes all listeners.
+ unhookup = function(items, namespace) {
+ return can.each(items, function(item) {
+ if (item && item.unbind) {
+ item.unbind("change" + namespace);
+ }
+ });
+ },
+ // Listens to changes on `child` and "bubbles" the event up.
+ // `child` - The object to listen for changes on.
+ // `prop` - The property name is at on.
+ // `parent` - The parent object of prop.
+ // `ob` - (optional) The Observe object constructor
+ // `list` - (optional) The observable list constructor
+ hookupBubble = function(child, prop, parent, Ob, List) {
+ Ob = Ob || Observe;
+ List = List || Observe.List;
+
+ // If it's an `array` make a list, otherwise a child.
+ if (child instanceof Observe) {
+ // We have an `observe` already...
+ // Make sure it is not listening to this already
+ // It's only listening if it has bindings already.
+ parent._bindings && unhookup([child], parent._cid);
+ } else if (can.isArray(child)) {
+ child = new List(child);
+ } else {
+ child = new Ob(child);
+ }
+ // only listen if something is listening to you
+ if (parent._bindings) {
+ // Listen to all changes and `batchTrigger` upwards.
+ bindToChildAndBubbleToParent(child, prop, parent)
+ }
+
+
+ return child;
+ },
+ bindToChildAndBubbleToParent = function(child, prop, parent) {
+ child.bind("change" + parent._cid, function() {
+ // `batchTrigger` the type on this...
+ var args = can.makeArray(arguments),
+ ev = args.shift();
+ args[0] = (prop === "*" ? [parent.indexOf(child), args[0]] : [prop, args[0]]).join(".");
+
+ // track objects dispatched on this observe
+ ev.triggeredNS = ev.triggeredNS || {};
+
+ // if it has already been dispatched exit
+ if (ev.triggeredNS[parent._cid]) {
+ return;
+ }
+
+ ev.triggeredNS[parent._cid] = true;
+ // send change event with modified attr to parent
+ can.trigger(parent, ev, args);
+ // send modified attr event to parent
+ //can.trigger(parent, args[0], args);
+ });
+ }
+ // An `id` to track events for a given observe.
+ observeId = 0,
+ // A helper used to serialize an `Observe` or `Observe.List`.
+ // `observe` - The observable.
+ // `how` - To serialize with `attr` or `serialize`.
+ // `where` - To put properties, in an `{}` or `[]`.
+ serialize = function(observe, how, where) {
+ // Go through each property.
+ observe.each(function(val, name) {
+ // If the value is an `object`, and has an `attrs` or `serialize` function.
+ where[name] = canMakeObserve(val) && can.isFunction(val[how]) ?
+ // Call `attrs` or `serialize` to get the original data back.
+ val[how]() :
+ // Otherwise return the value.
+ val;
+ });
+ return where;
+ },
+ attrParts = function(attr, keepKey) {
+ if (keepKey) {
+ return [attr];
+ }
+ return can.isArray(attr) ? attr : ("" + attr).split(".");
+ },
+ // Which batch of events this is for -- might not want to send multiple
+ // messages on the same batch. This is mostly for event delegation.
+ batchNum = 1,
+ // how many times has start been called without a stop
+ transactions = 0,
+ // an array of events within a transaction
+ batchEvents = [],
+ stopCallbacks = [],
+ makeBindSetup = function(wildcard) {
+ return function() {
+ var parent = this;
+ this._each(function(child, prop) {
+ if (child && child.bind) {
+ bindToChildAndBubbleToParent(child, wildcard || prop, parent)
+ }
+ })
+ };
+ };
+
+
+ var Observe = can.Map = can.Observe = can.Construct({
+
+ // keep so it can be overwritten
+ bind: can.bindAndSetup,
+ unbind: can.unbindAndTeardown,
+ id: "id",
+ canMakeObserve: canMakeObserve,
+ // starts collecting events
+ // takes a callback for after they are updated
+ // how could you hook into after ejs
+
+ startBatch: function(batchStopHandler) {
+ transactions++;
+ batchStopHandler && stopCallbacks.push(batchStopHandler);
+ },
+
+ stopBatch: function(force, callStart) {
+ if (force) {
+ transactions = 0;
+ } else {
+ transactions--;
+ }
+
+ if (transactions == 0) {
+ var items = batchEvents.slice(0),
+ callbacks = stopCallbacks.slice(0);
+ batchEvents = [];
+ stopCallbacks = [];
+ batchNum++;
+ callStart && this.startBatch();
+ can.each(items, function(args) {
+ can.trigger.apply(can, args);
+ });
+ can.each(callbacks, function(cb) {
+ cb();
+ });
+ }
+ },
+
+ triggerBatch: function(item, event, args) {
+ // Don't send events if initalizing.
+ if (!item._init) {
+ if (transactions == 0) {
+ return can.trigger(item, event, args);
+ } else {
+ event = typeof event === "string" ? {
+ type: event
+ } :
+ event;
+ event.batchNum = batchNum;
+ batchEvents.push([
+ item,
+ event,
+ args
+ ]);
+ }
+ }
+ },
+
+ keys: function(observe) {
+ var keys = [];
+ Observe.__reading && Observe.__reading(observe, '__keys');
+ for (var keyName in observe._data) {
+ keys.push(keyName);
+ }
+ return keys;
+ }
+ },
+
+ {
+ setup: function(obj) {
+ // `_data` is where we keep the properties.
+ this._data = {};
+
+ // The namespace this `object` uses to listen to events.
+ can.cid(this, ".observe");
+ // Sets all `attrs`.
+ this._init = 1;
+ this.attr(obj);
+ this.bind('change' + this._cid, can.proxy(this._changes, this));
+ delete this._init;
+ },
+ _bindsetup: makeBindSetup(),
+ _bindteardown: function() {
+ var cid = this._cid;
+ this._each(function(child) {
+ unhookup([child], cid)
+ })
+ },
+ _changes: function(ev, attr, how, newVal, oldVal) {
+ Observe.triggerBatch(this, {
+ type: attr,
+ batchNum: ev.batchNum
+ }, [newVal, oldVal]);
+ },
+ _triggerChange: function(attr, how, newVal, oldVal) {
+ Observe.triggerBatch(this, "change", can.makeArray(arguments))
+ },
+ // no live binding iterator
+ _each: function(callback) {
+ var data = this.__get();
+ for (var prop in data) {
+ if (data.hasOwnProperty(prop)) {
+ callback(data[prop], prop)
+ }
+ }
+ },
+
+ attr: function(attr, val) {
+ // This is super obfuscated for space -- basically, we're checking
+ // if the type of the attribute is not a `number` or a `string`.
+ var type = typeof attr;
+ if (type !== "string" && type !== "number") {
+ return this._attrs(attr, val)
+ } else if (val === undefined) { // If we are getting a value.
+ // Let people know we are reading.
+ Observe.__reading && Observe.__reading(this, attr)
+ return this._get(attr)
+ } else {
+ // Otherwise we are setting.
+ this._set(attr, val);
+ return this;
+ }
+ },
+
+ each: function() {
+ Observe.__reading && Observe.__reading(this, '__keys');
+ return can.each.apply(undefined, [this.__get()].concat(can.makeArray(arguments)))
+ },
+
+ removeAttr: function(attr) {
+ // Info if this is List or not
+ var isList = this instanceof can.Observe.List,
+ // Convert the `attr` into parts (if nested).
+ parts = attrParts(attr),
+ // The actual property to remove.
+ prop = parts.shift(),
+ // The current value.
+ current = isList ? this[prop] : this._data[prop];
+
+ // If we have more parts, call `removeAttr` on that part.
+ if (parts.length) {
+ return current.removeAttr(parts)
+ } else {
+ if (isList) {
+ this.splice(prop, 1)
+ } else if (prop in this._data) {
+ // Otherwise, `delete`.
+ delete this._data[prop];
+ // Create the event.
+ if (!(prop in this.constructor.prototype)) {
+ delete this[prop]
+ }
+ // Let others know the number of keys have changed
+ Observe.triggerBatch(this, "__keys");
+ this._triggerChange(prop, "remove", undefined, current);
+
+ }
+ return current;
+ }
+ },
+ // Reads a property from the `object`.
+ _get: function(attr) {
+ var value = typeof attr === 'string' && !! ~attr.indexOf('.') && this.__get(attr);
+ if (value) {
+ return value;
+ }
+
+ // break up the attr (`"foo.bar"`) into `["foo","bar"]`
+ var parts = attrParts(attr),
+ // get the value of the first attr name (`"foo"`)
+ current = this.__get(parts.shift());
+ // if there are other attributes to read
+ return parts.length ?
+ // and current has a value
+ current ?
+ // lookup the remaining attrs on current
+ current._get(parts) :
+ // or if there's no current, return undefined
+ undefined :
+ // if there are no more parts, return current
+ current;
+ },
+ // Reads a property directly if an `attr` is provided, otherwise
+ // returns the "real" data object itself.
+ __get: function(attr) {
+ return attr ? this._data[attr] : this._data;
+ },
+ // Sets `attr` prop as value on this object where.
+ // `attr` - Is a string of properties or an array of property values.
+ // `value` - The raw value to set.
+ _set: function(attr, value, keepKey) {
+ // Convert `attr` to attr parts (if it isn't already).
+ var parts = attrParts(attr, keepKey),
+ // The immediate prop we are setting.
+ prop = parts.shift(),
+ // The current value.
+ current = this.__get(prop);
+
+ // If we have an `object` and remaining parts.
+ if (canMakeObserve(current) && parts.length) {
+ // That `object` should set it (this might need to call attr).
+ current._set(parts, value)
+ } else if (!parts.length) {
+ // We're in "real" set territory.
+ if (this.__convert) {
+ value = this.__convert(prop, value)
+ }
+ this.__set(prop, value, current)
+ } else {
+ throw "can.Observe: Object does not exist"
+ }
+ },
+ __set: function(prop, value, current) {
+
+ // Otherwise, we are setting it on this `object`.
+ // TODO: Check if value is object and transform
+ // are we changing the value.
+ if (value !== current) {
+ // Check if we are adding this for the first time --
+ // if we are, we need to create an `add` event.
+ var changeType = this.__get().hasOwnProperty(prop) ? "set" : "add";
+
+ // Set the value on data.
+ this.___set(prop,
+
+ // If we are getting an object.
+ canMakeObserve(value) ?
+
+ // Hook it up to send event.
+ hookupBubble(value, prop, this) :
+ // Value is normal.
+ value);
+
+ if (changeType == "add") {
+ // If there is no current value, let others know that
+ // the the number of keys have changed
+
+ Observe.triggerBatch(this, "__keys", undefined);
+
+ }
+ // `batchTrigger` the change event.
+ this._triggerChange(prop, changeType, value, current);
+
+ //Observe.triggerBatch(this, prop, [value, current]);
+ // If we can stop listening to our old value, do it.
+ current && unhookup([current], this._cid);
+ }
+
+ },
+ // Directly sets a property on this `object`.
+ ___set: function(prop, val) {
+ this._data[prop] = val;
+ // Add property directly for easy writing.
+ // Check if its on the `prototype` so we don't overwrite methods like `attrs`.
+ if (!(prop in this.constructor.prototype)) {
+ this[prop] = val
+ }
+ },
+
+
+ bind: can.bindAndSetup,
+
+ unbind: can.unbindAndTeardown,
+
+ serialize: function() {
+ return serialize(this, 'serialize', {});
+ },
+
+ _attrs: function(props, remove) {
+
+ if (props === undefined) {
+ return serialize(this, 'attr', {})
+ }
+
+ props = can.extend({}, props);
+ var prop,
+ self = this,
+ newVal;
+ Observe.startBatch();
+ this.each(function(curVal, prop) {
+ newVal = props[prop];
+
+ // If we are merging...
+ if (newVal === undefined) {
+ remove && self.removeAttr(prop);
+ return;
+ }
+
+ if (self.__convert) {
+ newVal = self.__convert(prop, newVal)
+ }
+
+ // if we're dealing with models, want to call _set to let converter run
+ if (newVal instanceof can.Observe) {
+ self.__set(prop, newVal, curVal)
+ // if its an object, let attr merge
+ } else if (canMakeObserve(curVal) && canMakeObserve(newVal) && curVal.attr) {
+ curVal.attr(newVal, remove)
+ // otherwise just set
+ } else if (curVal != newVal) {
+ self.__set(prop, newVal, curVal)
+ }
+
+ delete props[prop];
+ })
+ // Add remaining props.
+ for (var prop in props) {
+ newVal = props[prop];
+ this._set(prop, newVal, true)
+ }
+ Observe.stopBatch()
+ return this;
+ },
+
+
+ compute: function(prop) {
+ return can.compute(this, prop);
+ }
+ });
+ // Helpers for `observable` lists.
+ var splice = [].splice,
+
+ list = Observe(
+
+ {
+ setup: function(instances, options) {
+ this.length = 0;
+ can.cid(this, ".observe")
+ this._init = 1;
+ if (can.isDeferred(instances)) {
+ this.replace(instances)
+ } else {
+ this.push.apply(this, can.makeArray(instances || []));
+ }
+ // this change needs to be ignored
+ this.bind('change' + this._cid, can.proxy(this._changes, this));
+ can.extend(this, options);
+ delete this._init;
+ },
+ _triggerChange: function(attr, how, newVal, oldVal) {
+
+ Observe.prototype._triggerChange.apply(this, arguments)
+ // `batchTrigger` direct add and remove events...
+ if (!~attr.indexOf('.')) {
+
+ if (how === 'add') {
+ Observe.triggerBatch(this, how, [newVal, +attr]);
+ Observe.triggerBatch(this, 'length', [this.length]);
+ } else if (how === 'remove') {
+ Observe.triggerBatch(this, how, [oldVal, +attr]);
+ Observe.triggerBatch(this, 'length', [this.length]);
+ } else {
+ Observe.triggerBatch(this, how, [newVal, +attr])
+ }
+
+ }
+
+ },
+ __get: function(attr) {
+ return attr ? this[attr] : this;
+ },
+ ___set: function(attr, val) {
+ this[attr] = val;
+ if (+attr >= this.length) {
+ this.length = (+attr + 1)
+ }
+ },
+ _each: function(callback) {
+ var data = this.__get();
+ for (var i = 0; i < data.length; i++) {
+ callback(data[i], i)
+ }
+ },
+ _bindsetup: makeBindSetup("*"),
+ // Returns the serialized form of this list.
+
+ serialize: function() {
+ return serialize(this, 'serialize', []);
+ },
+
+ splice: function(index, howMany) {
+ var args = can.makeArray(arguments),
+ i;
+
+ for (i = 2; i < args.length; i++) {
+ var val = args[i];
+ if (canMakeObserve(val)) {
+ args[i] = hookupBubble(val, "*", this, this.constructor.Observe, this.constructor)
+ }
+ }
+ if (howMany === undefined) {
+ howMany = args[1] = this.length - index;
+ }
+ var removed = splice.apply(this, args);
+ can.Observe.startBatch();
+ if (howMany > 0) {
+ this._triggerChange("" + index, "remove", undefined, removed);
+ unhookup(removed, this._cid);
+ }
+ if (args.length > 2) {
+ this._triggerChange("" + index, "add", args.slice(2), removed);
+ }
+ can.Observe.stopBatch();
+ return removed;
+ },
+
+ _attrs: function(items, remove) {
+ if (items === undefined) {
+ return serialize(this, 'attr', []);
+ }
+
+ // Create a copy.
+ items = can.makeArray(items);
+
+ Observe.startBatch();
+ this._updateAttrs(items, remove);
+ Observe.stopBatch()
+ },
+
+ _updateAttrs: function(items, remove) {
+ var len = Math.min(items.length, this.length);
+
+ for (var prop = 0; prop < len; prop++) {
+ var curVal = this[prop],
+ newVal = items[prop];
+
+ if (canMakeObserve(curVal) && canMakeObserve(newVal)) {
+ curVal.attr(newVal, remove)
+ } else if (curVal != newVal) {
+ this._set(prop, newVal)
+ } else {
+
+ }
+ }
+ if (items.length > this.length) {
+ // Add in the remaining props.
+ this.push.apply(this, items.slice(this.length));
+ } else if (items.length < this.length && remove) {
+ this.splice(items.length)
+ }
+ }
+ }),
+
+ // Converts to an `array` of arguments.
+ getArgs = function(args) {
+ return args[0] && can.isArray(args[0]) ?
+ args[0] :
+ can.makeArray(args);
+ };
+ // Create `push`, `pop`, `shift`, and `unshift`
+ can.each({
+
+ push: "length",
+
+ unshift: 0
+ },
+ // Adds a method
+ // `name` - The method name.
+ // `where` - Where items in the `array` should be added.
+
+ function(where, name) {
+ var orig = [][name]
+ list.prototype[name] = function() {
+ // Get the items being added.
+ var args = [],
+ // Where we are going to add items.
+ len = where ? this.length : 0,
+ i = arguments.length,
+ res,
+ val,
+ constructor = this.constructor;
+
+ // Go through and convert anything to an `observe` that needs to be converted.
+ while (i--) {
+ val = arguments[i];
+ args[i] = canMakeObserve(val) ?
+ hookupBubble(val, "*", this, this.constructor.Observe, this.constructor) :
+ val;
+ }
+
+ // Call the original method.
+ res = orig.apply(this, args);
+
+ if (!this.comparator || args.length) {
+
+ this._triggerChange("" + len, "add", args, undefined);
+ }
+
+ return res;
+ }
+ });
+
+ can.each({
+
+ pop: "length",
+
+ shift: 0
+ },
+ // Creates a `remove` type method
+
+ function(where, name) {
+ list.prototype[name] = function() {
+
+ var args = getArgs(arguments),
+ len = where && this.length ? this.length - 1 : 0;
+
+ var res = [][name].apply(this, args)
+
+ // Create a change where the args are
+ // `len` - Where these items were removed.
+ // `remove` - Items removed.
+ // `undefined` - The new values (there are none).
+ // `res` - The old, removed values (should these be unbound).
+ this._triggerChange("" + len, "remove", undefined, [res])
+
+ if (res && res.unbind) {
+ res.unbind("change" + this._cid)
+ }
+ return res;
+ }
+ });
+
+ can.extend(list.prototype, {
+
+ indexOf: function(item) {
+ this.attr('length')
+ return can.inArray(item, this)
+ },
+
+
+ join: [].join,
+
+
+ reverse: [].reverse,
+
+
+ slice: function() {
+ var temp = Array.prototype.slice.apply(this, arguments);
+ return new this.constructor(temp);
+ },
+
+
+ concat: function() {
+ var args = [];
+ can.each(can.makeArray(arguments), function(arg, i) {
+ args[i] = arg instanceof can.Observe.List ? arg.serialize() : arg;
+ });
+ return new this.constructor(Array.prototype.concat.apply(this.serialize(), args));
+ },
+
+
+ forEach: function(cb, thisarg) {
+ can.each(this, cb, thisarg || this);
+ },
+
+
+ replace: function(newList) {
+ if (can.isDeferred(newList)) {
+ newList.then(can.proxy(this.replace, this));
+ } else {
+ this.splice.apply(this, [0, this.length].concat(can.makeArray(newList || [])));
+ }
+
+ return this;
+ }
+ });
+
+ can.List = Observe.List = list;
+ Observe.setup = function() {
+ can.Construct.setup.apply(this, arguments);
+ // I would prefer not to do it this way. It should
+ // be using the attributes plugin to do this type of conversion.
+ this.List = Observe.List({
+ Observe: this
+ }, {});
+ }
+ return Observe;
+ })(__m3, __m8, __m1);
+
+ // ## observe/compute/compute.js
+ var __m9 = (function(can, bind) {
+
+ // returns the
+ // - observes and attr methods are called by func
+ // - the value returned by func
+ // ex: `{value: 100, observed: [{obs: o, attr: "completed"}]}`
+ var getValueAndObserved = function(func, self) {
+
+ var oldReading;
+ if (can.Observe) {
+ // Set a callback on can.Observe to know
+ // when an attr is read.
+ // Keep a reference to the old reader
+ // if there is one. This is used
+ // for nested live binding.
+ oldReading = can.Observe.__reading;
+ can.Observe.__reading = function(obj, attr) {
+ // Add the observe and attr that was read
+ // to `observed`
+ observed.push({
+ obj: obj,
+ attr: attr + ""
+ });
+ };
+ }
+
+ var observed = [],
+ // Call the "wrapping" function to get the value. `observed`
+ // will have the observe/attribute pairs that were read.
+ value = func.call(self);
+
+ // Set back so we are no longer reading.
+ if (can.Observe) {
+ can.Observe.__reading = oldReading;
+ }
+ return {
+ value: value,
+ observed: observed
+ };
+ },
+ // Calls `callback(newVal, oldVal)` everytime an observed property
+ // called within `getterSetter` is changed and creates a new result of `getterSetter`.
+ // Also returns an object that can teardown all event handlers.
+ computeBinder = function(getterSetter, context, callback, computeState) {
+ // track what we are observing
+ var observing = {},
+ // a flag indicating if this observe/attr pair is already bound
+ matched = true,
+ // the data to return
+ data = {
+ // we will maintain the value while live-binding is taking place
+ value: undefined,
+ // a teardown method that stops listening
+ teardown: function() {
+ for (var name in observing) {
+ var ob = observing[name];
+ ob.observe.obj.unbind(ob.observe.attr, onchanged);
+ delete observing[name];
+ }
+ }
+ },
+ batchNum;
+
+ // when a property value is changed
+ var onchanged = function(ev) {
+ // If the compute is no longer bound (because the same change event led to an unbind)
+ // then do not call getValueAndBind, or we will leak bindings.
+ if (computeState && !computeState.bound) {
+ return;
+ }
+ if (ev.batchNum === undefined || ev.batchNum !== batchNum) {
+ // store the old value
+ var oldValue = data.value,
+ // get the new value
+ newvalue = getValueAndBind();
+
+ // update the value reference (in case someone reads)
+ data.value = newvalue;
+ // if a change happened
+ if (newvalue !== oldValue) {
+ callback(newvalue, oldValue);
+ }
+ batchNum = batchNum = ev.batchNum;
+ }
+
+
+ };
+
+ // gets the value returned by `getterSetter` and also binds to any attributes
+ // read by the call
+ var getValueAndBind = function() {
+ var info = getValueAndObserved(getterSetter, context),
+ newObserveSet = info.observed;
+
+ var value = info.value;
+ matched = !matched;
+
+ // go through every attribute read by this observe
+ can.each(newObserveSet, function(ob) {
+ // if the observe/attribute pair is being observed
+ if (observing[ob.obj._cid + "|" + ob.attr]) {
+ // mark at as observed
+ observing[ob.obj._cid + "|" + ob.attr].matched = matched;
+ } else {
+ // otherwise, set the observe/attribute on oldObserved, marking it as being observed
+ observing[ob.obj._cid + "|" + ob.attr] = {
+ matched: matched,
+ observe: ob
+ };
+ ob.obj.bind(ob.attr, onchanged);
+ }
+ });
+
+ // Iterate through oldObserved, looking for observe/attributes
+ // that are no longer being bound and unbind them
+ for (var name in observing) {
+ var ob = observing[name];
+ if (ob.matched !== matched) {
+ ob.observe.obj.unbind(ob.observe.attr, onchanged);
+ delete observing[name];
+ }
+ }
+ return value;
+ };
+ // set the initial value
+ data.value = getValueAndBind();
+
+ data.isListening = !can.isEmptyObject(observing);
+ return data;
+ }
+
+ // if no one is listening ... we can not calculate every time
+
+ can.compute = function(getterSetter, context, eventName) {
+ if (getterSetter && getterSetter.isComputed) {
+ return getterSetter;
+ }
+ // stores the result of computeBinder
+ var computedData,
+ // how many listeners to this this compute
+ bindings = 0,
+ // the computed object
+ computed,
+ // an object that keeps track if the computed is bound
+ // onchanged needs to know this. It's possible a change happens and results in
+ // something that unbinds the compute, it needs to not to try to recalculate who it
+ // is listening to
+ computeState = {
+ bound: false,
+ // true if this compute is calculated from other computes and observes
+ hasDependencies: false
+ },
+ // The following functions are overwritten depending on how compute() is called
+ // a method to setup listening
+ on = function() {},
+ // a method to teardown listening
+ off = function() {},
+ // the current cached value (only valid if bound = true)
+ value,
+ // how to read the value
+ get = function() {
+ return value
+ },
+ // sets the value
+ set = function(newVal) {
+ value = newVal;
+ },
+ // this compute can be a dependency of other computes
+ canReadForChangeEvent = true;
+
+ computed = function(newVal) {
+ // setting ...
+ if (arguments.length) {
+ // save a reference to the old value
+ var old = value;
+
+ // setter may return a value if
+ // setter is for a value maintained exclusively by this compute
+ var setVal = set.call(context, newVal, old);
+
+ // if this has dependencies return the current value
+ if (computed.hasDependencies) {
+ return get.call(context);
+ }
+
+ if (setVal === undefined) {
+ // it's possible, like with the DOM, setting does not
+ // fire a change event, so we must read
+ value = get.call(context);
+ } else {
+ value = setVal;
+ }
+ // fire the change
+ if (old !== value) {
+ can.Observe.triggerBatch(computed, "change", [value, old]);
+ }
+ return value;
+ } else {
+ // Let others know to listen to changes in this compute
+ if (can.Observe.__reading && canReadForChangeEvent) {
+ can.Observe.__reading(computed, 'change');
+ }
+ // if we are bound, use the cached value
+ if (computeState.bound) {
+ return value;
+ } else {
+ return get.call(context);
+ }
+ }
+ }
+ if (typeof getterSetter === "function") {
+ set = getterSetter;
+ get = getterSetter;
+ canReadForChangeEvent = eventName === false ? false : true;
+ computed.hasDependencies = false;
+ on = function(update) {
+ computedData = computeBinder(getterSetter, context || this, update, computeState);
+ computed.hasDependencies = computedData.isListening
+ value = computedData.value;
+ }
+ off = function() {
+ computedData.teardown();
+ }
+ } else if (context) {
+
+ if (typeof context == "string") {
+ // `can.compute(obj, "propertyName", [eventName])`
+
+ var propertyName = context,
+ isObserve = getterSetter instanceof can.Observe;
+ if (isObserve) {
+ computed.hasDependencies = true;
+ }
+ get = function() {
+ if (isObserve) {
+ return getterSetter.attr(propertyName);
+ } else {
+ return getterSetter[propertyName];
+ }
+ }
+ set = function(newValue) {
+ if (isObserve) {
+ getterSetter.attr(propertyName, newValue)
+ } else {
+ getterSetter[propertyName] = newValue;
+ }
+ }
+ var handler;
+ on = function(update) {
+ handler = function() {
+ update(get(), value)
+ };
+ can.bind.call(getterSetter, eventName || propertyName, handler)
+
+ // use getValueAndObserved because
+ // we should not be indicating that some parent
+ // reads this property if it happens to be binding on it
+ value = getValueAndObserved(get).value
+ }
+ off = function() {
+ can.unbind.call(getterSetter, eventName || propertyName, handler)
+ }
+
+ } else {
+ // `can.compute(initialValue, setter)`
+ if (typeof context === "function") {
+ value = getterSetter;
+ set = context;
+ } else {
+ // `can.compute(initialValue,{get:, set:, on:, off:})`
+ value = getterSetter;
+ var options = context;
+ get = options.get || get;
+ set = options.set || set;
+ on = options.on || on;
+ off = options.off || off;
+ }
+
+ }
+
+
+
+ } else {
+ // `can.compute(5)`
+ value = getterSetter;
+ }
+
+ computed.isComputed = true;
+
+ can.cid(computed, "compute")
+
+ var updater = function(newValue, oldValue) {
+ value = newValue;
+ // might need a way to look up new and oldVal
+ can.Observe.triggerBatch(computed, "change", [newValue, oldValue])
+ }
+
+ return can.extend(computed, {
+ _bindsetup: function() {
+ computeState.bound = true;
+ // setup live-binding
+ on.call(this, updater)
+ },
+ _bindteardown: function() {
+ off.call(this, updater)
+ computeState.bound = false;
+ },
+
+ bind: can.bindAndSetup,
+
+ unbind: can.unbindAndTeardown
+ });
+ };
+ can.compute.binder = computeBinder;
+ return can.compute;
+ })(__m3, __m8);
+
+ // ## model/model.js
+ var __m10 = (function(can) {
+
+ // ## model.js
+ // `can.Model`
+ // _A `can.Observe` that connects to a RESTful interface._
+ // Generic deferred piping function
+
+ var pipe = function(def, model, func) {
+ var d = new can.Deferred();
+ def.then(function() {
+ var args = can.makeArray(arguments);
+ args[0] = model[func](args[0]);
+ d.resolveWith(d, args);
+ }, function() {
+ d.rejectWith(this, arguments);
+ });
+
+ if (typeof def.abort === 'function') {
+ d.abort = function() {
+ return def.abort();
+ }
+ }
+
+ return d;
+ },
+ modelNum = 0,
+ ignoreHookup = /change.observe\d+/,
+ getId = function(inst) {
+ // Instead of using attr, use __get for performance.
+ // Need to set reading
+ can.Observe.__reading && can.Observe.__reading(inst, inst.constructor.id)
+ return inst.__get(inst.constructor.id);
+ },
+ // Ajax `options` generator function
+ ajax = function(ajaxOb, data, type, dataType, success, error) {
+
+ var params = {};
+
+ // If we get a string, handle it.
+ if (typeof ajaxOb == "string") {
+ // If there's a space, it's probably the type.
+ var parts = ajaxOb.split(/\s+/);
+ params.url = parts.pop();
+ if (parts.length) {
+ params.type = parts.pop();
+ }
+ } else {
+ can.extend(params, ajaxOb);
+ }
+
+ // If we are a non-array object, copy to a new attrs.
+ params.data = typeof data == "object" && !can.isArray(data) ?
+ can.extend(params.data || {}, data) : data;
+
+ // Get the url with any templated values filled out.
+ params.url = can.sub(params.url, params.data, true);
+
+ return can.ajax(can.extend({
+ type: type || "post",
+ dataType: dataType || "json",
+ success: success,
+ error: error
+ }, params));
+ },
+ makeRequest = function(self, type, success, error, method) {
+ var args;
+ // if we pass an array as `self` it it means we are coming from
+ // the queued request, and we're passing already serialized data
+ // self's signature will be: [self, serializedData]
+ if (can.isArray(self)) {
+ args = self[1];
+ self = self[0];
+ } else {
+ args = self.serialize();
+ }
+ args = [args];
+ var deferred,
+ // The model.
+ model = self.constructor,
+ jqXHR;
+
+ // `destroy` does not need data.
+ if (type == 'destroy') {
+ args.shift();
+ }
+ // `update` and `destroy` need the `id`.
+ if (type !== 'create') {
+ args.unshift(getId(self));
+ }
+
+
+ jqXHR = model[type].apply(model, args);
+
+ deferred = jqXHR.pipe(function(data) {
+ self[method || type + "d"](data, jqXHR);
+ return self;
+ });
+
+ // Hook up `abort`
+ if (jqXHR.abort) {
+ deferred.abort = function() {
+ jqXHR.abort();
+ };
+ }
+
+ deferred.then(success, error);
+ return deferred;
+ },
+
+ // This object describes how to make an ajax request for each ajax method.
+ // The available properties are:
+ // `url` - The default url to use as indicated as a property on the model.
+ // `type` - The default http request type
+ // `data` - A method that takes the `arguments` and returns `data` used for ajax.
+
+ ajaxMethods = {
+
+ create: {
+ url: "_shortName",
+ type: "post"
+ },
+
+ update: {
+ data: function(id, attrs) {
+ attrs = attrs || {};
+ var identity = this.id;
+ if (attrs[identity] && attrs[identity] !== id) {
+ attrs["new" + can.capitalize(id)] = attrs[identity];
+ delete attrs[identity];
+ }
+ attrs[identity] = id;
+ return attrs;
+ },
+ type: "put"
+ },
+
+ destroy: {
+ type: "delete",
+ data: function(id) {
+ var args = {};
+ args.id = args[this.id] = id;
+ return args;
+ }
+ },
+
+ findAll: {
+ url: "_shortName"
+ },
+
+ findOne: {}
+ },
+ // Makes an ajax request `function` from a string.
+ // `ajaxMethod` - The `ajaxMethod` object defined above.
+ // `str` - The string the user provided. Ex: `findAll: "/recipes.json"`.
+ ajaxMaker = function(ajaxMethod, str) {
+ // Return a `function` that serves as the ajax method.
+ return function(data) {
+ // If the ajax method has it's own way of getting `data`, use that.
+ data = ajaxMethod.data ?
+ ajaxMethod.data.apply(this, arguments) :
+ // Otherwise use the data passed in.
+ data;
+ // Return the ajax method with `data` and the `type` provided.
+ return ajax(str || this[ajaxMethod.url || "_url"], data, ajaxMethod.type || "get")
+ }
+ }
+
+
+
+ can.Model = can.Observe({
+ fullName: "can.Model",
+ _reqs: 0,
+ setup: function(base) {
+ // create store here if someone wants to use model without inheriting from it
+ this.store = {};
+ can.Observe.setup.apply(this, arguments);
+ // Set default list as model list
+ if (!can.Model) {
+ return;
+ }
+ this.List = ML({
+ Observe: this
+ }, {});
+ var self = this,
+ clean = can.proxy(this._clean, self);
+
+
+ // go through ajax methods and set them up
+ can.each(ajaxMethods, function(method, name) {
+ // if an ajax method is not a function, it's either
+ // a string url like findAll: "/recipes" or an
+ // ajax options object like {url: "/recipes"}
+ if (!can.isFunction(self[name])) {
+ // use ajaxMaker to convert that into a function
+ // that returns a deferred with the data
+ self[name] = ajaxMaker(method, self[name]);
+ }
+ // check if there's a make function like makeFindAll
+ // these take deferred function and can do special
+ // behavior with it (like look up data in a store)
+ if (self["make" + can.capitalize(name)]) {
+ // pass the deferred method to the make method to get back
+ // the "findAll" method.
+ var newMethod = self["make" + can.capitalize(name)](self[name]);
+ can.Construct._overwrite(self, base, name, function() {
+ // increment the numer of requests
+ can.Model._reqs++;
+ var def = newMethod.apply(this, arguments);
+ var then = def.then(clean, clean);
+ then.abort = def.abort;
+
+ // attach abort to our then and return it
+ return then;
+ })
+ }
+ });
+
+ if (self.fullName == "can.Model" || !self.fullName) {
+ self.fullName = "Model" + (++modelNum);
+ }
+ // Add ajax converters.
+ can.Model._reqs = 0;
+ this._url = this._shortName + "/{" + this.id + "}"
+ },
+ _ajax: ajaxMaker,
+ _makeRequest: makeRequest,
+ _clean: function() {
+ can.Model._reqs--;
+ if (!can.Model._reqs) {
+ for (var id in this.store) {
+ if (!this.store[id]._bindings) {
+ delete this.store[id];
+ }
+ }
+ }
+ return arguments[0];
+ },
+
+ models: function(instancesRawData, oldList) {
+ // until "end of turn", increment reqs counter so instances will be added to the store
+ can.Model._reqs++;
+ if (!instancesRawData) {
+ return;
+ }
+
+ if (instancesRawData instanceof this.List) {
+ return instancesRawData;
+ }
+
+ // Get the list type.
+ var self = this,
+ tmp = [],
+ res = oldList instanceof can.Observe.List ? oldList : new(self.List || ML),
+ // Did we get an `array`?
+ arr = can.isArray(instancesRawData),
+
+ // Did we get a model list?
+ ml = (instancesRawData instanceof ML),
+
+ // Get the raw `array` of objects.
+ raw = arr ?
+
+ // If an `array`, return the `array`.
+ instancesRawData :
+
+ // Otherwise if a model list.
+ (ml ?
+
+ // Get the raw objects from the list.
+ instancesRawData.serialize() :
+
+ // Get the object's data.
+ instancesRawData.data),
+ i = 0;
+
+
+
+ if (res.length) {
+ res.splice(0);
+ }
+
+ can.each(raw, function(rawPart) {
+ tmp.push(self.model(rawPart));
+ });
+
+ // We only want one change event so push everything at once
+ res.push.apply(res, tmp);
+
+ if (!arr) { // Push other stuff onto `array`.
+ can.each(instancesRawData, function(val, prop) {
+ if (prop !== 'data') {
+ res.attr(prop, val);
+ }
+ })
+ }
+ // at "end of turn", clean up the store
+ setTimeout(can.proxy(this._clean, this), 1);
+ return res;
+ },
+
+ model: function(attributes) {
+ if (!attributes) {
+ return;
+ }
+ if (attributes instanceof this) {
+ attributes = attributes.serialize();
+ }
+ var id = attributes[this.id],
+ model = (id || id === 0) && this.store[id] ?
+ this.store[id].attr(attributes, this.removeAttr || false) : new this(attributes);
+ if (can.Model._reqs) {
+ this.store[attributes[this.id]] = model;
+ }
+ return model;
+ }
+ },
+
+
+ {
+
+ isNew: function() {
+ var id = getId(this);
+ return !(id || id === 0); // If `null` or `undefined`
+ },
+
+ save: function(success, error) {
+ return makeRequest(this, this.isNew() ? 'create' : 'update', success, error);
+ },
+
+ destroy: function(success, error) {
+ if (this.isNew()) {
+ var self = this;
+ var def = can.Deferred();
+ def.then(success, error);
+ return def.done(function(data) {
+ self.destroyed(data)
+ }).resolve(self);
+ }
+ return makeRequest(this, 'destroy', success, error, 'destroyed');
+ },
+
+ _bindsetup: function() {
+ this.constructor.store[this.__get(this.constructor.id)] = this;
+ return can.Observe.prototype._bindsetup.apply(this, arguments);
+ },
+
+ _bindteardown: function() {
+ delete this.constructor.store[getId(this)];
+ return can.Observe.prototype._bindteardown.apply(this, arguments)
+ },
+ // Change `id`.
+ ___set: function(prop, val) {
+ can.Observe.prototype.___set.call(this, prop, val)
+ // If we add an `id`, move it to the store.
+ if (prop === this.constructor.id && this._bindings) {
+ this.constructor.store[getId(this)] = this;
+ }
+ }
+ });
+
+ can.each({
+ makeFindAll: "models",
+ makeFindOne: "model",
+ makeCreate: "model",
+ makeUpdate: "model"
+ }, function(method, name) {
+ can.Model[name] = function(oldMethod) {
+ return function() {
+ var args = can.makeArray(arguments),
+ oldArgs = can.isFunction(args[1]) ? args.splice(0, 1) : args.splice(0, 2),
+ def = pipe(oldMethod.apply(this, oldArgs), this, method);
+ def.then(args[0], args[1]);
+ // return the original promise
+ return def;
+ };
+ };
+ });
+
+ can.each([
+
+ "created",
+
+ "updated",
+
+ "destroyed"
+ ], function(funcName) {
+ can.Model.prototype[funcName] = function(attrs) {
+ var stub,
+ constructor = this.constructor;
+
+ // Update attributes if attributes have been passed
+ stub = attrs && typeof attrs == 'object' && this.attr(attrs.attr ? attrs.attr() : attrs);
+
+ // triggers change event that bubble's like
+ // handler( 'change','1.destroyed' ). This is used
+ // to remove items on destroyed from Model Lists.
+ // but there should be a better way.
+ can.trigger(this, "change", funcName)
+
+
+ // Call event on the instance's Class
+ can.trigger(constructor, funcName, this);
+ };
+ });
+
+ // Model lists are just like `Observe.List` except that when their items are
+ // destroyed, it automatically gets removed from the list.
+
+ var ML = can.Model.List = can.Observe.List({
+ setup: function(params) {
+ if (can.isPlainObject(params) && !can.isArray(params)) {
+ can.Observe.List.prototype.setup.apply(this);
+ this.replace(this.constructor.Observe.findAll(params))
+ } else {
+ can.Observe.List.prototype.setup.apply(this, arguments);
+ }
+ },
+ _changes: function(ev, attr) {
+ can.Observe.List.prototype._changes.apply(this, arguments);
+ if (/\w+\.destroyed/.test(attr)) {
+ var index = this.indexOf(ev.target);
+ if (index != -1) {
+ this.splice(index, 1);
+ }
+ }
+ }
+ })
+
+ return can.Model;
+ })(__m3, __m7);
+
+ // ## view/view.js
+ var __m11 = (function(can) {
+ // ## view.js
+ // `can.view`
+ // _Templating abstraction._
+
+ var isFunction = can.isFunction,
+ makeArray = can.makeArray,
+ // Used for hookup `id`s.
+ hookupId = 1,
+
+ $view = can.view = can.template = function(view, data, helpers, callback) {
+ // If helpers is a `function`, it is actually a callback.
+ if (isFunction(helpers)) {
+ callback = helpers;
+ helpers = undefined;
+ }
+
+ var pipe = function(result) {
+ return $view.frag(result);
+ },
+ // In case we got a callback, we need to convert the can.view.render
+ // result to a document fragment
+ wrapCallback = isFunction(callback) ? function(frag) {
+ callback(pipe(frag));
+ } : null,
+ // Get the result.
+ result = $view.render(view, data, helpers, wrapCallback),
+ deferred = can.Deferred();
+
+ if (isFunction(result)) {
+ return result;
+ }
+
+ if (can.isDeferred(result)) {
+ result.then(function(result, data) {
+ deferred.resolve.call(deferred, pipe(result), data);
+ }, function() {
+ deferred.fail.apply(deferred, arguments);
+ });
+ return deferred;
+ }
+
+ // Convert it into a dom frag.
+ return pipe(result);
+ };
+
+ can.extend($view, {
+ // creates a frag and hooks it up all at once
+ frag: function(result, parentNode) {
+ return $view.hookup($view.fragment(result), parentNode);
+ },
+
+ // simply creates a frag
+ // this is used internally to create a frag
+ // insert it
+ // then hook it up
+ fragment: function(result) {
+ var frag = can.buildFragment(result, document.body);
+ // If we have an empty frag...
+ if (!frag.childNodes.length) {
+ frag.appendChild(document.createTextNode(''));
+ }
+ return frag;
+ },
+
+ // Convert a path like string into something that's ok for an `element` ID.
+ toId: function(src) {
+ return can.map(src.toString().split(/\/|\./g), function(part) {
+ // Dont include empty strings in toId functions
+ if (part) {
+ return part;
+ }
+ }).join("_");
+ },
+
+ hookup: function(fragment, parentNode) {
+ var hookupEls = [],
+ id,
+ func;
+
+ // Get all `childNodes`.
+ can.each(fragment.childNodes ? can.makeArray(fragment.childNodes) : fragment, function(node) {
+ if (node.nodeType === 1) {
+ hookupEls.push(node);
+ hookupEls.push.apply(hookupEls, can.makeArray(node.getElementsByTagName('*')));
+ }
+ });
+
+ // Filter by `data-view-id` attribute.
+ can.each(hookupEls, function(el) {
+ if (el.getAttribute && (id = el.getAttribute('data-view-id')) && (func = $view.hookups[id])) {
+ func(el, parentNode, id);
+ delete $view.hookups[id];
+ el.removeAttribute('data-view-id');
+ }
+ });
+
+ return fragment;
+ },
+
+
+ hookups: {},
+
+
+ hook: function(cb) {
+ $view.hookups[++hookupId] = cb;
+ return " data-view-id='" + hookupId + "'";
+ },
+
+
+ cached: {},
+
+ cachedRenderers: {},
+
+
+ cache: true,
+
+
+ register: function(info) {
+ this.types["." + info.suffix] = info;
+ },
+
+ types: {},
+
+
+ ext: ".ejs",
+
+
+ registerScript: function() {},
+
+
+ preload: function() {},
+
+
+ render: function(view, data, helpers, callback) {
+ // If helpers is a `function`, it is actually a callback.
+ if (isFunction(helpers)) {
+ callback = helpers;
+ helpers = undefined;
+ }
+
+ // See if we got passed any deferreds.
+ var deferreds = getDeferreds(data);
+
+ if (deferreds.length) { // Does data contain any deferreds?
+ // The deferred that resolves into the rendered content...
+ var deferred = new can.Deferred(),
+ dataCopy = can.extend({}, data);
+
+ // Add the view request to the list of deferreds.
+ deferreds.push(get(view, true))
+
+ // Wait for the view and all deferreds to finish...
+ can.when.apply(can, deferreds).then(function(resolved) {
+ // Get all the resolved deferreds.
+ var objs = makeArray(arguments),
+ // Renderer is the last index of the data.
+ renderer = objs.pop(),
+ // The result of the template rendering with data.
+ result;
+
+ // Make data look like the resolved deferreds.
+ if (can.isDeferred(data)) {
+ dataCopy = usefulPart(resolved);
+ } else {
+ // Go through each prop in data again and
+ // replace the defferreds with what they resolved to.
+ for (var prop in data) {
+ if (can.isDeferred(data[prop])) {
+ dataCopy[prop] = usefulPart(objs.shift());
+ }
+ }
+ }
+
+ // Get the rendered result.
+ result = renderer(dataCopy, helpers);
+
+ // Resolve with the rendered view.
+ deferred.resolve(result, dataCopy);
+
+ // If there's a `callback`, call it back with the result.
+ callback && callback(result, dataCopy);
+ }, function() {
+ deferred.reject.apply(deferred, arguments)
+ });
+ // Return the deferred...
+ return deferred;
+ } else {
+ // No deferreds! Render this bad boy.
+ var response,
+ // If there's a `callback` function
+ async = isFunction(callback),
+ // Get the `view` type
+ deferred = get(view, async);
+
+ // If we are `async`...
+ if (async) {
+ // Return the deferred
+ response = deferred;
+ // And fire callback with the rendered result.
+ deferred.then(function(renderer) {
+ callback(data ? renderer(data, helpers) : renderer);
+ })
+ } else {
+ // if the deferred is resolved, call the cached renderer instead
+ // this is because it's possible, with recursive deferreds to
+ // need to render a view while its deferred is _resolving_. A _resolving_ deferred
+ // is a deferred that was just resolved and is calling back it's success callbacks.
+ // If a new success handler is called while resoliving, it does not get fired by
+ // jQuery's deferred system. So instead of adding a new callback
+ // we use the cached renderer.
+ // We also add __view_id on the deferred so we can look up it's cached renderer.
+ // In the future, we might simply store either a deferred or the cached result.
+ if (deferred.state() === "resolved" && deferred.__view_id) {
+ var currentRenderer = $view.cachedRenderers[deferred.__view_id];
+ return data ? currentRenderer(data, helpers) : currentRenderer;
+ } else {
+ // Otherwise, the deferred is complete, so
+ // set response to the result of the rendering.
+ deferred.then(function(renderer) {
+ response = data ? renderer(data, helpers) : renderer;
+ });
+ }
+ }
+
+ return response;
+ }
+ },
+
+
+ registerView: function(id, text, type, def) {
+ // Get the renderer function.
+ var func = (type || $view.types[$view.ext]).renderer(id, text);
+ def = def || new can.Deferred();
+
+ // Cache if we are caching.
+ if ($view.cache) {
+ $view.cached[id] = def;
+ def.__view_id = id;
+ $view.cachedRenderers[id] = func;
+ }
+
+ // Return the objects for the response's `dataTypes`
+ // (in this case view).
+ return def.resolve(func);
+ }
+ });
+
+ // Makes sure there's a template, if not, have `steal` provide a warning.
+ var checkText = function(text, url) {
+ if (!text.length) {
+
+ throw "can.view: No template or empty template:" + url;
+ }
+ },
+ // `Returns a `view` renderer deferred.
+ // `url` - The url to the template.
+ // `async` - If the ajax request should be asynchronous.
+ // Returns a deferred.
+ get = function(url, async) {
+ var suffix = url.match(/\.[\w\d]+$/),
+ type,
+ // If we are reading a script element for the content of the template,
+ // `el` will be set to that script element.
+ el,
+ // A unique identifier for the view (used for caching).
+ // This is typically derived from the element id or
+ // the url for the template.
+ id,
+ // The ajax request used to retrieve the template content.
+ jqXHR;
+
+ //If the url has a #, we assume we want to use an inline template
+ //from a script element and not current page's HTML
+ if (url.match(/^#/)) {
+ url = url.substr(1);
+ }
+ // If we have an inline template, derive the suffix from the `text/???` part.
+ // This only supports `<script>` tags.
+ if (el = document.getElementById(url)) {
+ suffix = "." + el.type.match(/\/(x\-)?(.+)/)[2];
+ }
+
+ // If there is no suffix, add one.
+ if (!suffix && !$view.cached[url]) {
+ url += (suffix = $view.ext);
+ }
+
+ if (can.isArray(suffix)) {
+ suffix = suffix[0]
+ }
+
+ // Convert to a unique and valid id.
+ id = $view.toId(url);
+
+ // If an absolute path, use `steal` to get it.
+ // You should only be using `//` if you are using `steal`.
+ if (url.match(/^\/\//)) {
+ var sub = url.substr(2);
+ url = !window.steal ?
+ sub :
+ steal.config().root.mapJoin("" + steal.id(sub));
+ }
+
+ // Set the template engine type.
+ type = $view.types[suffix];
+
+ // If it is cached,
+ if ($view.cached[id]) {
+ // Return the cached deferred renderer.
+ return $view.cached[id];
+
+ // Otherwise if we are getting this from a `<script>` element.
+ } else if (el) {
+ // Resolve immediately with the element's `innerHTML`.
+ return $view.registerView(id, el.innerHTML, type);
+ } else {
+ // Make an ajax request for text.
+ var d = new can.Deferred();
+ can.ajax({
+ async: async,
+ url: url,
+ dataType: "text",
+ error: function(jqXHR) {
+ checkText("", url);
+ d.reject(jqXHR);
+ },
+ success: function(text) {
+ // Make sure we got some text back.
+ checkText(text, url);
+ $view.registerView(id, text, type, d)
+ }
+ });
+ return d;
+ }
+ },
+ // Gets an `array` of deferreds from an `object`.
+ // This only goes one level deep.
+ getDeferreds = function(data) {
+ var deferreds = [];
+
+ // pull out deferreds
+ if (can.isDeferred(data)) {
+ return [data]
+ } else {
+ for (var prop in data) {
+ if (can.isDeferred(data[prop])) {
+ deferreds.push(data[prop]);
+ }
+ }
+ }
+ return deferreds;
+ },
+ // Gets the useful part of a resolved deferred.
+ // This is for `model`s and `can.ajax` that resolve to an `array`.
+ usefulPart = function(resolved) {
+ return can.isArray(resolved) && resolved[1] === 'success' ? resolved[0] : resolved
+ };
+
+ //!steal-pluginify-remove-start
+ if (window.steal) {
+ steal.type("view js", function(options, success, error) {
+ var type = $view.types["." + options.type],
+ id = $view.toId(options.id);
+
+ options.text = "steal('" + (type.plugin || "can/view/" + options.type) + "',function(can){return " + "can.view.preload('" + id + "'," + options.text + ");\n})";
+ success();
+ })
+ }
+ //!steal-pluginify-remove-end
+
+ can.extend($view, {
+ register: function(info) {
+ this.types["." + info.suffix] = info;
+
+ //!steal-pluginify-remove-start
+ if (window.steal) {
+ steal.type(info.suffix + " view js", function(options, success, error) {
+ var type = $view.types["." + options.type],
+ id = $view.toId(options.id + '');
+
+ options.text = type.script(id, options.text)
+ success();
+ })
+ };
+ //!steal-pluginify-remove-end
+
+ $view[info.suffix] = function(id, text) {
+ if (!text) {
+ // Return a nameless renderer
+ var renderer = function() {
+ return $view.frag(renderer.render.apply(this, arguments));
+ }
+ renderer.render = function() {
+ var renderer = info.renderer(null, id);
+ return renderer.apply(renderer, arguments);
+ }
+ return renderer;
+ }
+
+ $view.preload(id, info.renderer(id, text));
+ return can.view(id);
+ }
+ },
+ registerScript: function(type, id, src) {
+ return "can.view.preload('" + id + "'," + $view.types["." + type].script(id, src) + ");";
+ },
+ preload: function(id, renderer) {
+ $view.cached[id] = new can.Deferred().resolve(function(data, helpers) {
+ return renderer.call(data, data, helpers);
+ });
+
+ function frag() {
+ return $view.frag(renderer.apply(this, arguments));
+ }
+ // expose the renderer for mustache
+ frag.render = renderer;
+ return frag;
+ }
+
+ });
+
+ return can;
+ })(__m3);
+
+ // ## view/elements.js
+ var __m14 = (function() {
+
+ var elements = {
+ tagToContentPropMap: {
+ option: "textContent" in document.createElement("option") ? "textContent" : "innerText",
+ textarea: "value"
+ },
+
+ attrMap: {
+ "class": "className",
+ "value": "value",
+ "innerText": "innerText",
+ "textContent": "textContent",
+ "checked": true,
+ "disabled": true,
+ "readonly": true,
+ "required": true
+ },
+ // elements whos default value we should set
+ defaultValue: ["input", "textarea"],
+ // a map of parent element to child elements
+ tagMap: {
+ "": "span",
+ table: "tbody",
+ tr: "td",
+ ol: "li",
+ ul: "li",
+ tbody: "tr",
+ thead: "tr",
+ tfoot: "tr",
+ select: "option",
+ optgroup: "option"
+ },
+ // a tag's parent element
+ reverseTagMap: {
+ tr: "tbody",
+ option: "select",
+ td: "tr",
+ th: "tr",
+ li: "ul"
+ },
+
+ getParentNode: function(el, defaultParentNode) {
+ return defaultParentNode && el.parentNode.nodeType === 11 ? defaultParentNode : el.parentNode;
+ },
+ // set an attribute on an element
+ setAttr: function(el, attrName, val) {
+ var tagName = el.nodeName.toString().toLowerCase(),
+ prop = elements.attrMap[attrName];
+ // if this is a special property
+ if (prop === true) {
+ el[attrName] = true;
+ } else if (prop) {
+ // set the value as true / false
+ el[prop] = val;
+ if (prop === "value" && can.inArray(tagName, elements.defaultValue) >= 0) {
+ el.defaultValue = val;
+ }
+ } else {
+ el.setAttribute(attrName, val);
+ }
+ },
+ // gets the value of an attribute
+ getAttr: function(el, attrName) {
+ // Default to a blank string for IE7/8
+ return (elements.attrMap[attrName] && el[elements.attrMap[attrName]] ?
+ el[elements.attrMap[attrName]] :
+ el.getAttribute(attrName)) || '';
+ },
+ // removes the attribute
+ removeAttr: function(el, attrName) {
+ if (elements.attrMap[attrName] === true) {
+ el[attrName] = false;
+ } else {
+ el.removeAttribute(attrName);
+ }
+ },
+ contentText: function(text) {
+ if (typeof text == 'string') {
+ return text;
+ }
+ // If has no value, return an empty string.
+ if (!text && text !== 0) {
+ return '';
+ }
+ return "" + text;
+ }
+ };
+
+ return elements;
+ })();
+
+ // ## view/scanner.js
+ var __m13 = (function(can, elements) {
+
+ var newLine = /(\r|\n)+/g,
+ // Escapes characters starting with `\`.
+ clean = function(content) {
+ return content
+ .split('\\').join("\\\\")
+ .split("\n").join("\\n")
+ .split('"').join('\\"')
+ .split("\t").join("\\t");
+ },
+ // Returns a tagName to use as a temporary placeholder for live content
+ // looks forward ... could be slow, but we only do it when necessary
+ getTag = function(tagName, tokens, i) {
+ // if a tagName is provided, use that
+ if (tagName) {
+ return tagName;
+ } else {
+ // otherwise go searching for the next two tokens like "<",TAG
+ while (i < tokens.length) {
+ if (tokens[i] == "<" && elements.reverseTagMap[tokens[i + 1]]) {
+ return elements.reverseTagMap[tokens[i + 1]];
+ }
+ i++;
+ }
+ }
+ return '';
+ },
+ bracketNum = function(content) {
+ return (--content.split("{").length) - (--content.split("}").length);
+ },
+ myEval = function(script) {
+ try {
+ eval(script);
+ } catch(e) {
+ console.log(script)
+ }
+ },
+ attrReg = /([^\s]+)[\s]*=[\s]*$/,
+ // Commands for caching.
+ startTxt = 'var ___v1ew = [];',
+ finishTxt = "return ___v1ew.join('')",
+ put_cmd = "___v1ew.push(",
+ insert_cmd = put_cmd,
+ // Global controls (used by other functions to know where we are).
+ // Are we inside a tag?
+ htmlTag = null,
+ // Are we within a quote within a tag?
+ quote = null,
+ // What was the text before the current quote? (used to get the `attr` name)
+ beforeQuote = null,
+ // Whether a rescan is in progress
+ rescan = null,
+ // Used to mark where the element is.
+ status = function() {
+ // `t` - `1`.
+ // `h` - `0`.
+ // `q` - String `beforeQuote`.
+ return quote ? "'" + beforeQuote.match(attrReg)[1] + "'" : (htmlTag ? 1 : 0);
+ };
+
+ can.view.Scanner = Scanner = function(options) {
+ // Set options on self
+ can.extend(this, {
+ text: {},
+ tokens: []
+ }, options);
+
+ // Cache a token lookup
+ this.tokenReg = [];
+ this.tokenSimple = {
+ "<": "<",
+ ">": ">",
+ '"': '"',
+ "'": "'"
+ };
+ this.tokenComplex = [];
+ this.tokenMap = {};
+ for (var i = 0, token; token = this.tokens[i]; i++) {
+
+
+ // Save complex mappings (custom regexp)
+ if (token[2]) {
+ this.tokenReg.push(token[2]);
+ this.tokenComplex.push({
+ abbr: token[1],
+ re: new RegExp(token[2]),
+ rescan: token[3]
+ });
+ }
+ // Save simple mappings (string only, no regexp)
+ else {
+ this.tokenReg.push(token[1]);
+ this.tokenSimple[token[1]] = token[0];
+ }
+ this.tokenMap[token[0]] = token[1];
+ }
+
+ // Cache the token registry.
+ this.tokenReg = new RegExp("(" + this.tokenReg.slice(0).concat(["<", ">", '"', "'"]).join("|") + ")", "g");
+ };
+
+ Scanner.prototype = {
+
+ helpers: [
+
+ {
+ name: /\s*\(([\$\w]+)\)\s*->([^\n]*)/,
+ fn: function(content) {
+ var quickFunc = /\s*\(([\$\w]+)\)\s*->([^\n]*)/,
+ parts = content.match(quickFunc);
+
+ return "can.proxy(function(__){var " + parts[1] + "=can.$(__);" + parts[2] + "}, this);";
+ }
+ }
+ ],
+
+ scan: function(source, name) {
+ var tokens = [],
+ last = 0,
+ simple = this.tokenSimple,
+ complex = this.tokenComplex;
+
+ source = source.replace(newLine, "\n");
+ if (this.transform) {
+ source = this.transform(source);
+ }
+ source.replace(this.tokenReg, function(whole, part) {
+ // offset is the second to last argument
+ var offset = arguments[arguments.length - 2];
+
+ // if the next token starts after the last token ends
+ // push what's in between
+ if (offset > last) {
+ tokens.push(source.substring(last, offset));
+ }
+
+ // push the simple token (if there is one)
+ if (simple[whole]) {
+ tokens.push(whole);
+ }
+ // otherwise lookup complex tokens
+ else {
+ for (var i = 0, token; token = complex[i]; i++) {
+ if (token.re.test(whole)) {
+ tokens.push(token.abbr);
+ // Push a rescan function if one exists
+ if (token.rescan) {
+ tokens.push(token.rescan(part));
+ }
+ break;
+ }
+ }
+ }
+
+ // update the position of the last part of the last token
+ last = offset + part.length;
+ });
+
+ // if there's something at the end, add it
+ if (last < source.length) {
+ tokens.push(source.substr(last));
+ }
+
+ var content = '',
+ buff = [startTxt + (this.text.start || '')],
+ // Helper `function` for putting stuff in the view concat.
+ put = function(content, bonus) {
+ buff.push(put_cmd, '"', clean(content), '"' + (bonus || '') + ');');
+ },
+ // A stack used to keep track of how we should end a bracket
+ // `}`.
+ // Once we have a `<%= %>` with a `leftBracket`,
+ // we store how the file should end here (either `))` or `;`).
+ endStack = [],
+ // The last token, used to remember which tag we are in.
+ lastToken,
+ // The corresponding magic tag.
+ startTag = null,
+ // Was there a magic tag inside an html tag?
+ magicInTag = false,
+ // The current tag name.
+ tagName = '',
+ // stack of tagNames
+ tagNames = [],
+ // Pop from tagNames?
+ popTagName = false,
+ // Declared here.
+ bracketCount,
+ i = 0,
+ token,
+ tmap = this.tokenMap;
+
+ // Reinitialize the tag state goodness.
+ htmlTag = quote = beforeQuote = null;
+
+ for (;
+ (token = tokens[i++]) !== undefined;) {
+ if (startTag === null) {
+ switch (token) {
+ case tmap.left:
+ case tmap.escapeLeft:
+ case tmap.returnLeft:
+ magicInTag = htmlTag && 1;
+ case tmap.commentLeft:
+ // A new line -- just add whatever content within a clean.
+ // Reset everything.
+ startTag = token;
+ if (content.length) {
+ put(content);
+ }
+ content = '';
+ break;
+ case tmap.escapeFull:
+ // This is a full line escape (a line that contains only whitespace and escaped logic)
+ // Break it up into escape left and right
+ magicInTag = htmlTag && 1;
+ rescan = 1;
+ startTag = tmap.escapeLeft;
+ if (content.length) {
+ put(content);
+ }
+ rescan = tokens[i++];
+ content = rescan.content || rescan;
+ if (rescan.before) {
+ put(rescan.before);
+ }
+ tokens.splice(i, 0, tmap.right);
+ break;
+ case tmap.commentFull:
+ // Ignore full line comments.
+ break;
+ case tmap.templateLeft:
+ content += tmap.left;
+ break;
+ case '<':
+ // Make sure we are not in a comment.
+ if (tokens[i].indexOf("!--") !== 0) {
+ htmlTag = 1;
+ magicInTag = 0;
+ }
+ content += token;
+ break;
+ case '>':
+ htmlTag = 0;
+ // content.substr(-1) doesn't work in IE7/8
+ var emptyElement = content.substr(content.length - 1) == "/" || content.substr(content.length - 2) == "--";
+ // if there was a magic tag
+ // or it's an element that has text content between its tags,
+ // but content is not other tags add a hookup
+ // TODO: we should only add `can.EJS.pending()` if there's a magic tag
+ // within the html tags.
+ if (magicInTag || !popTagName && elements.tagToContentPropMap[tagNames[tagNames.length - 1]]) {
+ // make sure / of /> is on the left of pending
+ if (emptyElement) {
+ put(content.substr(0, content.length - 1), ",can.view.pending(),\"/>\"");
+ } else {
+ put(content, ",can.view.pending(),\">\"");
+ }
+ content = '';
+ magicInTag = 0;
+ } else {
+ content += token;
+ }
+ // if it's a tag like <input/>
+ if (emptyElement || popTagName) {
+ // remove the current tag in the stack
+ tagNames.pop();
+ // set the current tag to the previous parent
+ tagName = tagNames[tagNames.length - 1];
+ // Don't pop next time
+ popTagName = false;
+ }
+ break;
+ case "'":
+ case '"':
+ // If we are in an html tag, finding matching quotes.
+ if (htmlTag) {
+ // We have a quote and it matches.
+ if (quote && quote === token) {
+ // We are exiting the quote.
+ quote = null;
+ // Otherwise we are creating a quote.
+ // TODO: does this handle `\`?
+ } else if (quote === null) {
+ quote = token;
+ beforeQuote = lastToken;
+ }
+ }
+ default:
+ // Track the current tag
+ if (lastToken === '<') {
+ tagName = token.split(/\s/)[0];
+ if (tagName.indexOf("/") === 0 && tagNames[tagNames.length - 1] === tagName.substr(1)) {
+ // set tagName to the last tagName
+ // if there are no more tagNames, we'll rely on getTag.
+ tagName = tagNames[tagNames.length - 1];
+ popTagName = true;
+ } else {
+ tagNames.push(tagName);
+ }
+ }
+ content += token;
+ break;
+ }
+ } else {
+ // We have a start tag.
+ switch (token) {
+ case tmap.right:
+ case tmap.returnRight:
+ switch (startTag) {
+ case tmap.left:
+ // Get the number of `{ minus }`
+ bracketCount = bracketNum(content);
+
+ // We are ending a block.
+ if (bracketCount == 1) {
+
+ // We are starting on.
+ buff.push(insert_cmd, "can.view.txt(0,'" + getTag(tagName, tokens, i) + "'," + status() + ",this,function(){", startTxt, content);
+
+ endStack.push({
+ before: "",
+ after: finishTxt + "}));\n"
+ });
+ } else {
+
+ // How are we ending this statement?
+ last = // If the stack has value and we are ending a block...
+ endStack.length && bracketCount == -1 ? // Use the last item in the block stack.
+ endStack.pop() : // Or use the default ending.
+ {
+ after: ";"
+ };
+
+ // If we are ending a returning block,
+ // add the finish text which returns the result of the
+ // block.
+ if (last.before) {
+ buff.push(last.before);
+ }
+ // Add the remaining content.
+ buff.push(content, ";", last.after);
+ }
+ break;
+ case tmap.escapeLeft:
+ case tmap.returnLeft:
+ // We have an extra `{` -> `block`.
+ // Get the number of `{ minus }`.
+ bracketCount = bracketNum(content);
+ // If we have more `{`, it means there is a block.
+ if (bracketCount) {
+ // When we return to the same # of `{` vs `}` end with a `doubleParent`.
+ endStack.push({
+ before: finishTxt,
+ after: "}));"
+ });
+ }
+
+ var escaped = startTag === tmap.escapeLeft ? 1 : 0,
+ commands = {
+ insert: insert_cmd,
+ tagName: getTag(tagName, tokens, i),
+ status: status()
+ };
+
+ for (var ii = 0; ii < this.helpers.length; ii++) {
+ // Match the helper based on helper
+ // regex name value
+ var helper = this.helpers[ii];
+ if (helper.name.test(content)) {
+ content = helper.fn(content, commands);
+
+ // dont escape partials
+ if (helper.name.source == /^>[\s]*\w*/.source) {
+ escaped = 0;
+ }
+ break;
+ }
+ }
+
+ // Handle special cases
+ if (typeof content == 'object') {
+ if (content.raw) {
+ buff.push(content.raw);
+ }
+ } else {
+ // If we have `<%== a(function(){ %>` then we want
+ // `can.EJS.text(0,this, function(){ return a(function(){ var _v1ew = [];`.
+ buff.push(insert_cmd, "can.view.txt(" + escaped + ",'" + tagName + "'," + status() + ",this,function(){ " + (this.text.escape || '') + "return ", content,
+ // If we have a block.
+ bracketCount ?
+ // Start with startTxt `"var _v1ew = [];"`.
+ startTxt :
+ // If not, add `doubleParent` to close push and text.
+ "}));");
+ }
+
+ if (rescan && rescan.after && rescan.after.length) {
+ put(rescan.after.length);
+ rescan = null;
+ }
+ break;
+ }
+ startTag = null;
+ content = '';
+ break;
+ case tmap.templateLeft:
+ content += tmap.left;
+ break;
+ default:
+ content += token;
+ break;
+ }
+ }
+ lastToken = token;
+ }
+
+ // Put it together...
+ if (content.length) {
+ // Should be `content.dump` in Ruby.
+ put(content);
+ }
+ buff.push(";");
+
+ var template = buff.join(''),
+ out = {
+ out: 'with(_VIEW) { with (_CONTEXT) {' + template + " " + finishTxt + "}}"
+ };
+ // Use `eval` instead of creating a function, because it is easier to debug.
+ myEval.call(out, 'this.fn = (function(_CONTEXT,_VIEW){' + out.out + '});\r\n//@ sourceURL=' + name + ".js");
+
+ return out;
+ }
+ };
+
+ return Scanner;
+ })(__m11, __m14);
+
+ // ## view/node_lists.js
+ var __m17 = (function(can) {
+
+ // text node expando test
+ var canExpando = true;
+ try {
+ document.createTextNode('')._ = 0;
+ } catch (ex) {
+ canExpando = false;
+ }
+
+ // a mapping of element ids to nodeList ids
+ var nodeMap = {},
+ // a mapping of ids to text nodes
+ textNodeMap = {},
+ // a mapping of nodeList ids to nodeList
+ nodeListMap = {},
+ expando = "ejs_" + Math.random(),
+ _id = 0,
+ id = function(node) {
+ if (canExpando || node.nodeType !== 3) {
+ if (node[expando]) {
+ return node[expando];
+ } else {
+ return node[expando] = (node.nodeName ? "element_" : "obj_") + (++_id);
+ }
+ } else {
+ for (var textNodeID in textNodeMap) {
+ if (textNodeMap[textNodeID] === node) {
+ return textNodeID;
+ }
+ }
+
+ textNodeMap["text_" + (++_id)] = node;
+ return "text_" + _id;
+ }
+ },
+ // removes a nodeListId from a node's nodeListIds
+ removeNodeListId = function(node, nodeListId) {
+ var nodeListIds = nodeMap[id(node)];
+ if (nodeListIds) {
+ var index = can.inArray(nodeListId, nodeListIds);
+
+ if (index >= 0) {
+ nodeListIds.splice(index, 1);
+ }
+ if (!nodeListIds.length) {
+ delete nodeMap[id(node)];
+ }
+ }
+ },
+ addNodeListId = function(node, nodeListId) {
+ var nodeListIds = nodeMap[id(node)];
+ if (!nodeListIds) {
+ nodeListIds = nodeMap[id(node)] = [];
+ }
+ nodeListIds.push(nodeListId);
+ };
+
+ var nodeLists = {
+ id: id,
+ // replaces the contents of one node list with the nodes in another list
+ replace: function(oldNodeList, newNodes) {
+ // for each node in the node list
+ oldNodeList = can.makeArray(oldNodeList);
+
+ // try every set
+ //can.each( oldNodeList, function(node){
+ var node = oldNodeList[0]
+ // for each nodeList the node is in
+ can.each(can.makeArray(nodeMap[id(node)]), function(nodeListId) {
+
+ // if startNode to endNode is
+ // within list, replace that list
+ // I think the problem is not the WHOLE part is being
+ // matched
+ var nodeList = nodeListMap[nodeListId],
+ startIndex = can.inArray(node, nodeList),
+ endIndex = can.inArray(oldNodeList[oldNodeList.length - 1], nodeList);
+
+
+ // remove this nodeListId from each node
+ if (startIndex >= 0 && endIndex >= 0) {
+ for (var i = startIndex; i <= endIndex; i++) {
+ var n = nodeList[i];
+ removeNodeListId(n, nodeListId);
+ }
+ // swap in new nodes into the nodeLIst
+ nodeList.splice.apply(nodeList, [startIndex, endIndex - startIndex + 1].concat(newNodes));
+
+ // tell these new nodes they belong to the nodeList
+ can.each(newNodes, function(node) {
+ addNodeListId(node, nodeListId);
+ });
+ } else {
+ nodeLists.unregister(nodeList);
+ }
+ });
+ //});
+ },
+ // registers a list of nodes
+ register: function(nodeList) {
+ var nLId = id(nodeList);
+ nodeListMap[nLId] = nodeList;
+
+ can.each(nodeList, function(node) {
+ addNodeListId(node, nLId);
+ });
+
+ },
+ // removes mappings
+ unregister: function(nodeList) {
+ var nLId = id(nodeList);
+ can.each(nodeList, function(node) {
+ removeNodeListId(node, nLId);
+ });
+ delete nodeListMap[nLId];
+ },
+ nodeMap: nodeMap,
+ nodeListMap: nodeListMap
+ }
+ var ids = function(nodeList) {
+ return nodeList.map(function(n) {
+ return id(n) + ":" + (n.innerHTML || n.nodeValue)
+ })
+ }
+ return nodeLists;
+
+ })(__m3);
+
+ // ## view/live.js
+ var __m16 = (function(can, elements, view, nodeLists) {
+ // ## live.js
+ // The live module provides live binding for computes
+ // and can.Observe.List.
+ // Currently, it's API is designed for `can/view/render`, but
+ // it could easily be used for other purposes.
+
+ // ### Helper methods
+ // #### setup
+ // `setup(HTMLElement, bind(data), unbind(data)) -> data`
+ // Calls bind right away, but will call unbind
+ // if the element is "destroyed" (removed from the DOM).
+ var setup = function(el, bind, unbind) {
+ var teardown = function() {
+ unbind(data)
+ can.unbind.call(el, 'destroyed', teardown);
+ },
+ data = {
+ teardownCheck: function(parent) {
+ if (!parent) {
+ teardown();
+ }
+ }
+ }
+
+ can.bind.call(el, 'destroyed', teardown);
+ bind(data)
+ return data;
+ },
+ // #### listen
+ // Calls setup, but presets bind and unbind to
+ // operate on a compute
+ listen = function(el, compute, change) {
+ return setup(el, function() {
+ compute.bind("change", change);
+ }, function(data) {
+ compute.unbind("change", change);
+ if (data.nodeList) {
+ nodeLists.unregister(data.nodeList);
+ }
+ });
+ },
+ // #### getAttributeParts
+ // Breaks up a string like foo='bar' into ["foo","'bar'""]
+ getAttributeParts = function(newVal) {
+ return (newVal || "").replace(/['"]/g, '').split('=')
+ }
+ // #### insertElementsAfter
+ // Appends elements after the last item in oldElements.
+ insertElementsAfter = function(oldElements, newFrag) {
+ var last = oldElements[oldElements.length - 1];
+
+ // Insert it in the `document` or `documentFragment`
+ if (last.nextSibling) {
+ last.parentNode.insertBefore(newFrag, last.nextSibling);
+ } else {
+ last.parentNode.appendChild(newFrag);
+ }
+ };
+
+ var live = {
+ nodeLists: nodeLists,
+ list: function(el, list, func, context, parentNode) {
+ // A mapping of the index to an array
+ // of elements that represent the item.
+ // Each array is registered so child or parent
+ // live structures can update the elements
+ var nodesMap = [],
+
+ add = function(ev, items, index) {
+
+ // Collect new html and mappings
+ var frag = document.createDocumentFragment(),
+ newMappings = [];
+ can.each(items, function(item) {
+ var itemHTML = func.call(context, item),
+ itemFrag = can.view.frag(itemHTML, parentNode);
+
+ newMappings.push(can.makeArray(itemFrag.childNodes));
+ frag.appendChild(itemFrag);
+ })
+
+ // Inserting at the end of the list
+ if (!nodesMap[index]) {
+ insertElementsAfter(
+ index == 0 ? [text] :
+ nodesMap[index - 1], frag)
+ } else {
+ var el = nodesMap[index][0];
+ el.parentNode.insertBefore(frag, el)
+ }
+ // register each item
+ can.each(newMappings, function(nodeList) {
+ nodeLists.register(nodeList)
+ });
+ [].splice.apply(nodesMap, [index, 0].concat(newMappings));
+ },
+ remove = function(ev, items, index) {
+ var removedMappings = nodesMap.splice(index, items.length),
+ itemsToRemove = [];
+
+ can.each(removedMappings, function(nodeList) {
+ // add items that we will remove all at once
+ [].push.apply(itemsToRemove, nodeList)
+ // Update any parent lists to remove these items
+ nodeLists.replace(nodeList, []);
+ // unregister the list
+ nodeLists.unregister(nodeList);
+
+ });
+ can.remove(can.$(itemsToRemove));
+ },
+ parentNode = elements.getParentNode(el, parentNode),
+ text = document.createTextNode("");
+
+ // Setup binding and teardown to add and remove events
+ setup(parentNode, function() {
+ list.bind("add", add).bind("remove", remove)
+ }, function() {
+ list.unbind("add", add).unbind("remove", remove);
+ can.each(nodesMap, function(nodeList) {
+ nodeLists.unregister(nodeList);
+ })
+ })
+
+ insertElementsAfter([el], text);
+ can.remove(can.$(el));
+ add({}, list, 0);
+
+ },
+ html: function(el, compute, parentNode) {
+ var parentNode = elements.getParentNode(el, parentNode),
+
+ data = listen(parentNode, compute, function(ev, newVal, oldVal) {
+ var attached = nodes[0].parentNode;
+ // update the nodes in the DOM with the new rendered value
+ if (attached) {
+ makeAndPut(newVal);
+ }
+ data.teardownCheck(nodes[0].parentNode);
+ });
+
+ var nodes,
+ makeAndPut = function(val) {
+ // create the fragment, but don't hook it up
+ // we need to insert it into the document first
+ var frag = can.view.frag(val, parentNode),
+ // keep a reference to each node
+ newNodes = can.makeArray(frag.childNodes);
+ // Insert it in the `document` or `documentFragment`
+ insertElementsAfter(nodes || [el], frag)
+ // nodes hasn't been set yet
+ if (!nodes) {
+ can.remove(can.$(el));
+ nodes = newNodes;
+ // set the teardown nodeList
+ data.nodeList = nodes;
+ nodeLists.register(nodes);
+ } else {
+ // Update node Array's to point to new nodes
+ // and then remove the old nodes.
+ // It has to be in this order for Mootools
+ // and IE because somehow, after an element
+ // is removed from the DOM, it loses its
+ // expando values.
+ var nodesToRemove = can.makeArray(nodes);
+ nodeLists.replace(nodes, newNodes);
+ can.remove(can.$(nodesToRemove));
+ }
+ };
+ makeAndPut(compute(), [el]);
+
+ },
+ text: function(el, compute, parentNode) {
+ var parent = elements.getParentNode(el, parentNode);
+
+ // setup listening right away so we don't have to re-calculate value
+ var data = listen(el.parentNode !== parent ? el.parentNode : parent, compute, function(ev, newVal, oldVal) {
+ // Sometimes this is 'unknown' in IE and will throw an exception if it is
+ if (typeof node.nodeValue != 'unknown') {
+ node.nodeValue = "" + newVal;
+ }
+ data.teardownCheck(node.parentNode);
+ });
+
+ var node = document.createTextNode(compute());
+
+ if (el.parentNode !== parent) {
+ parent = el.parentNode;
+ parent.insertBefore(node, el);
+ parent.removeChild(el);
+ } else {
+ parent.insertBefore(node, el);
+ parent.removeChild(el);
+ }
+ },
+ attributes: function(el, compute, currentValue) {
+ var setAttrs = function(newVal) {
+ var parts = getAttributeParts(newVal),
+ newAttrName = parts.shift();
+
+ // Remove if we have a change and used to have an `attrName`.
+ if ((newAttrName != attrName) && attrName) {
+ elements.removeAttr(el, attrName);
+ }
+ // Set if we have a new `attrName`.
+ if (newAttrName) {
+ elements.setAttr(el, newAttrName, parts.join('='));
+ attrName = newAttrName;
+ }
+ }
+
+ listen(el, compute, function(ev, newVal) {
+ setAttrs(newVal)
+ })
+ // current value has been set
+ if (arguments.length >= 3) {
+ var attrName = getAttributeParts(currentValue)[0]
+ } else {
+ setAttrs(compute())
+ }
+ },
+ attributePlaceholder: '__!!__',
+ attributeReplace: /__!!__/g,
+ attribute: function(el, attributeName, compute) {
+ listen(el, compute, function(ev, newVal) {
+ elements.setAttr(el, attributeName, hook.render());
+ })
+
+ var wrapped = can.$(el),
+ hooks;
+
+ // Get the list of hookups or create one for this element.
+ // Hooks is a map of attribute names to hookup `data`s.
+ // Each hookup data has:
+ // `render` - A `function` to render the value of the attribute.
+ // `funcs` - A list of hookup `function`s on that attribute.
+ // `batchNum` - The last event `batchNum`, used for performance.
+ hooks = can.data(wrapped, 'hooks');
+ if (!hooks) {
+ can.data(wrapped, 'hooks', hooks = {});
+ }
+
+ // Get the attribute value.
+ var attr = elements.getAttr(el, attributeName),
+ // Split the attribute value by the template.
+ // Only split out the first __!!__ so if we have multiple hookups in the same attribute,
+ // they will be put in the right spot on first render
+ parts = attr.split(live.attributePlaceholder),
+ goodParts = [],
+ hook;
+ goodParts.push(parts.shift(),
+ parts.join(live.attributePlaceholder));
+
+ // If we already had a hookup for this attribute...
+ if (hooks[attributeName]) {
+ // Just add to that attribute's list of `function`s.
+ hooks[attributeName].computes.push(compute);
+ } else {
+ // Create the hookup data.
+ hooks[attributeName] = {
+ render: function() {
+ var i = 0,
+ // attr doesn't have a value in IE
+ newAttr = attr ? attr.replace(live.attributeReplace, function() {
+ return elements.contentText(hook.computes[i++]());
+ }) : elements.contentText(hook.computes[i++]());
+ return newAttr;
+ },
+ computes: [compute],
+ batchNum: undefined
+ };
+ }
+
+ // Save the hook for slightly faster performance.
+ hook = hooks[attributeName];
+
+ // Insert the value in parts.
+ goodParts.splice(1, 0, compute());
+
+ // Set the attribute.
+ elements.setAttr(el, attributeName, goodParts.join(""));
+
+ }
+ }
+ return live;
+
+ })(__m3, __m14, __m11, __m17);
+
+ // ## view/render.js
+ var __m15 = (function(can, elements, live) {
+
+ var pendingHookups = [],
+ tagChildren = function(tagName) {
+ var newTag = elements.tagMap[tagName] || "span";
+ if (newTag === "span") {
+ //innerHTML in IE doesn't honor leading whitespace after empty elements
+ return "@@!!@@";
+ }
+ return "<" + newTag + ">" + tagChildren(newTag) + "</" + newTag + ">";
+ },
+ contentText = function(input, tag) {
+
+ // If it's a string, return.
+ if (typeof input == 'string') {
+ return input;
+ }
+ // If has no value, return an empty string.
+ if (!input && input !== 0) {
+ return '';
+ }
+
+ // If it's an object, and it has a hookup method.
+ var hook = (input.hookup &&
+
+ // Make a function call the hookup method.
+
+ function(el, id) {
+ input.hookup.call(input, el, id);
+ }) ||
+
+ // Or if it's a `function`, just use the input.
+ (typeof input == 'function' && input);
+
+ // Finally, if there is a `function` to hookup on some dom,
+ // add it to pending hookups.
+ if (hook) {
+ if (tag) {
+ return "<" + tag + " " + can.view.hook(hook) + "></" + tag + ">"
+ } else {
+ pendingHookups.push(hook);
+ }
+
+ return '';
+ }
+
+ // Finally, if all else is `false`, `toString()` it.
+ return "" + input;
+ },
+ // Returns escaped/sanatized content for anything other than a live-binding
+ contentEscape = function(txt) {
+ return (typeof txt == 'string' || typeof txt == 'number') ?
+ can.esc(txt) :
+ contentText(txt);
+ };
+
+ var current;
+
+ can.extend(can.view, {
+ live: live,
+ setupLists: function() {
+
+ var old = can.view.lists,
+ data;
+
+ can.view.lists = function(list, renderer) {
+ data = {
+ list: list,
+ renderer: renderer
+ }
+ }
+ return function() {
+ can.view.lists = old;
+ return data;
+ }
+ },
+ pending: function() {
+ // TODO, make this only run for the right tagName
+ var hooks = pendingHookups.slice(0);
+ lastHookups = hooks;
+ pendingHookups = [];
+ return can.view.hook(function(el) {
+ can.each(hooks, function(fn) {
+ fn(el);
+ });
+ });
+ },
+
+
+ txt: function(escape, tagName, status, self, func) {
+ var listTeardown = can.view.setupLists(),
+ emptyHandler = function() {},
+ unbind = function() {
+ compute.unbind("change", emptyHandler)
+ };
+
+ var compute = can.compute(func, self, false);
+ // bind to get and temporarily cache the value
+ compute.bind("change", emptyHandler);
+ // call the "wrapping" function and get the binding information
+ var tag = (elements.tagMap[tagName] || "span"),
+ listData = listTeardown(),
+ value = compute();
+
+
+ if (listData) {
+ return "<" + tag + can.view.hook(function(el, parentNode) {
+ live.list(el, listData.list, listData.renderer, self, parentNode);
+ }) + "></" + tag + ">";
+ }
+
+ // If we had no observes just return the value returned by func.
+ if (!compute.hasDependencies) {
+ unbind();
+ return (escape || status !== 0 ? contentEscape : contentText)(value, status === 0 && tag);
+ }
+
+ // the property (instead of innerHTML elements) to adjust. For
+ // example options should use textContent
+ var contentProp = elements.tagToContentPropMap[tagName];
+
+
+ // The magic tag is outside or between tags.
+ if (status === 0 && !contentProp) {
+ // Return an element tag with a hookup in place of the content
+ return "<" + tag + can.view.hook(
+ escape ?
+ // If we are escaping, replace the parentNode with
+ // a text node who's value is `func`'s return value.
+
+ function(el, parentNode) {
+ live.text(el, compute, parentNode);
+ unbind();
+ } :
+ // If we are not escaping, replace the parentNode with a
+ // documentFragment created as with `func`'s return value.
+
+ function(el, parentNode) {
+ live.html(el, compute, parentNode);
+ unbind();
+ //children have to be properly nested HTML for buildFragment to work properly
+ }) + ">" + tagChildren(tag) + "</" + tag + ">";
+ // In a tag, but not in an attribute
+ } else if (status === 1) {
+ // remember the old attr name
+ pendingHookups.push(function(el) {
+ live.attributes(el, compute, compute());
+ unbind();
+ });
+ return compute();
+ } else { // In an attribute...
+ var attributeName = status === 0 ? contentProp : status;
+ // if the magic tag is inside the element, like `<option><% TAG %></option>`,
+ // we add this hookup to the last element (ex: `option`'s) hookups.
+ // Otherwise, the magic tag is in an attribute, just add to the current element's
+ // hookups.
+ (status === 0 ? lastHookups : pendingHookups).push(function(el) {
+ live.attribute(el, attributeName, compute);
+ unbind();
+ });
+ return live.attributePlaceholder;
+ }
+ }
+ });
+
+ return can;
+ })(__m11, __m14, __m16, __m2);
+
+ // ## view/ejs/ejs.js
+ var __m12 = (function(can) {
+ // ## ejs.js
+ // `can.EJS`
+ // _Embedded JavaScript Templates._
+
+ // Helper methods.
+ var extend = can.extend,
+ EJS = function(options) {
+ // Supports calling EJS without the constructor
+ // This returns a function that renders the template.
+ if (this.constructor != EJS) {
+ var ejs = new EJS(options);
+ return function(data, helpers) {
+ return ejs.render(data, helpers);
+ };
+ }
+ // If we get a `function` directly, it probably is coming from
+ // a `steal`-packaged view.
+ if (typeof options == "function") {
+ this.template = {
+ fn: options
+ };
+ return;
+ }
+ // Set options on self.
+ extend(this, options);
+ this.template = this.scanner.scan(this.text, this.name);
+ };
+
+ can.EJS = EJS;
+
+
+ EJS.prototype.
+
+ render = function(object, extraHelpers) {
+ object = object || {};
+ return this.template.fn.call(object, object, new EJS.Helpers(object, extraHelpers || {}));
+ };
+
+ extend(EJS.prototype, {
+
+ scanner: new can.view.Scanner({
+
+ tokens: [
+ ["templateLeft", "<%%"], // Template
+ ["templateRight", "%>"], // Right Template
+ ["returnLeft", "<%=="], // Return Unescaped
+ ["escapeLeft", "<%="], // Return Escaped
+ ["commentLeft", "<%#"], // Comment
+ ["left", "<%"], // Run --- this is hack for now
+ ["right", "%>"], // Right -> All have same FOR Mustache ...
+ ["returnRight", "%>"]
+ ],
+
+
+ transform: function(source) {
+ return source.replace(/<%([\s\S]+?)%>/gm, function(whole, part) {
+ var brackets = [],
+ foundBracketPair,
+ i;
+
+ // Look for brackets (for removing self-contained blocks)
+ part.replace(/[{}]/gm, function(bracket, offset) {
+ brackets.push([bracket, offset]);
+ });
+
+ // Remove bracket pairs from the list of replacements
+ do {
+ foundBracketPair = false;
+ for (i = brackets.length - 2; i >= 0; i--) {
+ if (brackets[i][0] == '{' && brackets[i + 1][0] == '}') {
+ brackets.splice(i, 2);
+ foundBracketPair = true;
+ break;
+ }
+ }
+ } while (foundBracketPair);
+
+ // Unmatched brackets found, inject EJS tags
+ if (brackets.length >= 2) {
+ var result = ['<%'],
+ bracket,
+ last = 0;
+ for (i = 0; bracket = brackets[i]; i++) {
+ result.push(part.substring(last, last = bracket[1]));
+ if ((bracket[0] == '{' && i < brackets.length - 1) || (bracket[0] == '}' && i > 0)) {
+ result.push(bracket[0] == '{' ? '{ %><% ' : ' %><% }');
+ } else {
+ result.push(bracket[0]);
+ }
+ ++last;
+ }
+ result.push(part.substring(last), '%>');
+ return result.join('');
+ }
+ // Otherwise return the original
+ else {
+ return '<%' + part + '%>';
+ }
+ });
+ }
+ })
+ });
+
+ EJS.Helpers = function(data, extras) {
+ this._data = data;
+ this._extras = extras;
+ extend(this, extras);
+ };
+
+
+ EJS.Helpers.prototype = {
+ // TODO Deprecated!!
+ list: function(list, cb) {
+
+ can.each(list, function(item, i) {
+ cb(item, i, list)
+ })
+ },
+ each: function(list, cb) {
+ // Normal arrays don't get live updated
+ if (can.isArray(list)) {
+ this.list(list, cb);
+ } else {
+ can.view.lists(list, cb);
+ }
+ }
+ };
+
+ // Options for `steal`'s build.
+ can.view.register({
+ suffix: "ejs",
+ // returns a `function` that renders the view.
+ script: function(id, src) {
+ return "can.EJS(function(_CONTEXT,_VIEW) { " + new EJS({
+ text: src,
+ name: id
+ }).template.out + " })";
+ },
+ renderer: function(id, text) {
+ return EJS({
+ text: text,
+ name: id
+ });
+ }
+ });
+
+ return can;
+ })(__m3, __m11, __m2, __m9, __m13, __m15);
+
+ // ## control/control.js
+ var __m18 = (function(can) {
+ // ## control.js
+ // `can.Control`
+ // _Controller_
+
+ // Binds an element, returns a function that unbinds.
+ var bind = function(el, ev, callback) {
+
+ can.bind.call(el, ev, callback);
+
+ return function() {
+ can.unbind.call(el, ev, callback);
+ };
+ },
+ isFunction = can.isFunction,
+ extend = can.extend,
+ each = can.each,
+ slice = [].slice,
+ paramReplacer = /\{([^\}]+)\}/g,
+ special = can.getObject("$.event.special", [can]) || {},
+
+ // Binds an element, returns a function that unbinds.
+ delegate = function(el, selector, ev, callback) {
+ can.delegate.call(el, selector, ev, callback);
+ return function() {
+ can.undelegate.call(el, selector, ev, callback);
+ };
+ },
+
+ // Calls bind or unbind depending if there is a selector.
+ binder = function(el, ev, callback, selector) {
+ return selector ?
+ delegate(el, can.trim(selector), ev, callback) :
+ bind(el, ev, callback);
+ },
+
+ basicProcessor;
+
+ var Control = can.Control = can.Construct(
+
+ {
+ // Setup pre-processes which methods are event listeners.
+
+ setup: function() {
+
+ // Allow contollers to inherit "defaults" from super-classes as it
+ // done in `can.Construct`
+ can.Construct.setup.apply(this, arguments);
+
+ // If you didn't provide a name, or are `control`, don't do anything.
+ if (can.Control) {
+
+ // Cache the underscored names.
+ var control = this,
+ funcName;
+
+ // Calculate and cache actions.
+ control.actions = {};
+ for (funcName in control.prototype) {
+ if (control._isAction(funcName)) {
+ control.actions[funcName] = control._action(funcName);
+ }
+ }
+ }
+ },
+
+ // Moves `this` to the first argument, wraps it with `jQuery` if it's an element
+ _shifter: function(context, name) {
+
+ var method = typeof name == "string" ? context[name] : name;
+
+ if (!isFunction(method)) {
+ method = context[method];
+ }
+
+ return function() {
+ context.called = name;
+ return method.apply(context, [this.nodeName ? can.$(this) : this].concat(slice.call(arguments, 0)));
+ };
+ },
+
+ // Return `true` if is an action.
+
+ _isAction: function(methodName) {
+
+ var val = this.prototype[methodName],
+ type = typeof val;
+ // if not the constructor
+ return (methodName !== 'constructor') &&
+ // and is a function or links to a function
+ (type == "function" || (type == "string" && isFunction(this.prototype[val]))) &&
+ // and is in special, a processor, or has a funny character
+ !! (special[methodName] || processors[methodName] || /[^\w]/.test(methodName));
+ },
+ // Takes a method name and the options passed to a control
+ // and tries to return the data necessary to pass to a processor
+ // (something that binds things).
+
+ _action: function(methodName, options) {
+
+ // If we don't have options (a `control` instance), we'll run this
+ // later.
+ paramReplacer.lastIndex = 0;
+ if (options || !paramReplacer.test(methodName)) {
+ // If we have options, run sub to replace templates `{}` with a
+ // value from the options or the window
+ var convertedName = options ? can.sub(methodName, [options, window]) : methodName;
+ if (!convertedName) {
+ return null;
+ }
+ // If a `{}` template resolves to an object, `convertedName` will be
+ // an array
+ var arr = can.isArray(convertedName),
+
+ // Get the name
+ name = arr ? convertedName[1] : convertedName,
+
+ // Grab the event off the end
+ parts = name.split(/\s+/g),
+ event = parts.pop();
+
+ return {
+ processor: processors[event] || basicProcessor,
+ parts: [name, parts.join(" "), event],
+ delegate: arr ? convertedName[0] : undefined
+ };
+ }
+ },
+ // An object of `{eventName : function}` pairs that Control uses to
+ // hook up events auto-magically.
+
+ processors: {},
+ // A object of name-value pairs that act as default values for a
+ // control instance
+ defaults: {}
+
+ }, {
+
+ // Sets `this.element`, saves the control in `data, binds event
+ // handlers.
+
+ setup: function(element, options) {
+
+ var cls = this.constructor,
+ pluginname = cls.pluginName || cls._fullName,
+ arr;
+
+ // Want the raw element here.
+ this.element = can.$(element)
+
+ if (pluginname && pluginname !== 'can_control') {
+ // Set element and `className` on element.
+ this.element.addClass(pluginname);
+ }
+
+ (arr = can.data(this.element, "controls")) || can.data(this.element, "controls", arr = []);
+ arr.push(this);
+
+ // Option merging.
+
+ this.options = extend({}, cls.defaults, options);
+
+ // Bind all event handlers.
+ this.on();
+
+ // Gets passed into `init`.
+
+ return [this.element, this.options];
+ },
+
+ on: function(el, selector, eventName, func) {
+ if (!el) {
+
+ // Adds bindings.
+ this.off();
+
+ // Go through the cached list of actions and use the processor
+ // to bind
+ var cls = this.constructor,
+ bindings = this._bindings,
+ actions = cls.actions,
+ element = this.element,
+ destroyCB = can.Control._shifter(this, "destroy"),
+ funcName, ready;
+
+ for (funcName in actions) {
+ // Only push if we have the action and no option is `undefined`
+ if (actions.hasOwnProperty(funcName) &&
+ (ready = actions[funcName] || cls._action(funcName, this.options))) {
+ bindings.push(ready.processor(ready.delegate || element,
+ ready.parts[2], ready.parts[1], funcName, this));
+ }
+ }
+
+
+ // Setup to be destroyed...
+ // don't bind because we don't want to remove it.
+ can.bind.call(element, "destroyed", destroyCB);
+ bindings.push(function(el) {
+ can.unbind.call(el, "destroyed", destroyCB);
+ });
+ return bindings.length;
+ }
+
+ if (typeof el == 'string') {
+ func = eventName;
+ eventName = selector;
+ selector = el;
+ el = this.element;
+ }
+
+ if (func === undefined) {
+ func = eventName;
+ eventName = selector;
+ selector = null;
+ }
+
+ if (typeof func == 'string') {
+ func = can.Control._shifter(this, func);
+ }
+
+ this._bindings.push(binder(el, eventName, func, selector));
+
+ return this._bindings.length;
+ },
+ // Unbinds all event handlers on the controller.
+
+ off: function() {
+ var el = this.element[0]
+ each(this._bindings || [], function(value) {
+ value(el);
+ });
+ // Adds bindings.
+ this._bindings = [];
+ },
+ // Prepares a `control` for garbage collection
+
+ destroy: function() {
+ //Control already destroyed
+ if (this.element === null) {
+
+ return;
+ }
+ var Class = this.constructor,
+ pluginName = Class.pluginName || Class._fullName,
+ controls;
+
+ // Unbind bindings.
+ this.off();
+
+ if (pluginName && pluginName !== 'can_control') {
+ // Remove the `className`.
+ this.element.removeClass(pluginName);
+ }
+
+ // Remove from `data`.
+ controls = can.data(this.element, "controls");
+ controls.splice(can.inArray(this, controls), 1);
+
+ can.trigger(this, "destroyed"); // In case we want to know if the `control` is removed.
+
+ this.element = null;
+ }
+ });
+
+ var processors = can.Control.processors,
+ // Processors do the binding.
+ // They return a function that unbinds when called.
+ // The basic processor that binds events.
+ basicProcessor = function(el, event, selector, methodName, control) {
+ return binder(el, event, can.Control._shifter(control, methodName), selector);
+ };
+
+ // Set common events to be processed as a `basicProcessor`
+ each(["change", "click", "contextmenu", "dblclick", "keydown", "keyup",
+ "keypress", "mousedown", "mousemove", "mouseout", "mouseover",
+ "mouseup", "reset", "resize", "scroll", "select", "submit", "focusin",
+ "focusout", "mouseenter", "mouseleave",
+ // #104 - Add touch events as default processors
+ // TOOD feature detect?
+ "touchstart", "touchmove", "touchcancel", "touchend", "touchleave"
+ ], function(v) {
+ processors[v] = basicProcessor;
+ });
+
+ return Control;
+ })(__m3, __m1);
+
+ // ## util/string/deparam/deparam.js
+ var __m20 = (function(can) {
+
+ // ## deparam.js
+ // `can.deparam`
+ // _Takes a string of name value pairs and returns a Object literal that represents those params._
+ var digitTest = /^\d+$/,
+ keyBreaker = /([^\[\]]+)|(\[\])/g,
+ paramTest = /([^?#]*)(#.*)?$/,
+ prep = function(str) {
+ return decodeURIComponent(str.replace(/\+/g, " "));
+ };
+
+
+ can.extend(can, {
+
+ deparam: function(params) {
+
+ var data = {},
+ pairs, lastPart;
+
+ if (params && paramTest.test(params)) {
+
+ pairs = params.split('&'),
+
+ can.each(pairs, function(pair) {
+
+ var parts = pair.split('='),
+ key = prep(parts.shift()),
+ value = prep(parts.join("=")),
+ current = data;
+
+ if (key) {
+ parts = key.match(keyBreaker);
+
+ for (var j = 0, l = parts.length - 1; j < l; j++) {
+ if (!current[parts[j]]) {
+ // If what we are pointing to looks like an `array`
+ current[parts[j]] = digitTest.test(parts[j + 1]) || parts[j + 1] == "[]" ? [] : {};
+ }
+ current = current[parts[j]];
+ }
+ lastPart = parts.pop();
+ if (lastPart == "[]") {
+ current.push(value);
+ } else {
+ current[lastPart] = value;
+ }
+ }
+ });
+ }
+ return data;
+ }
+ });
+ return can;
+ })(__m3, __m2);
+
+ // ## route/route.js
+ var __m19 = (function(can) {
+
+ // ## route.js
+ // `can.route`
+ // _Helps manage browser history (and client state) by synchronizing the
+ // `window.location.hash` with a `can.Observe`._
+ // Helper methods used for matching routes.
+ var
+ // `RegExp` used to match route variables of the type ':name'.
+ // Any word character or a period is matched.
+ matcher = /\:([\w\.]+)/g,
+ // Regular expression for identifying &key=value lists.
+ paramsMatcher = /^(?:&[^=]+=[^&]*)+/,
+ // Converts a JS Object into a list of parameters that can be
+ // inserted into an html element tag.
+ makeProps = function(props) {
+ var tags = [];
+ can.each(props, function(val, name) {
+ tags.push((name === 'className' ? 'class' : name) + '="' +
+ (name === "href" ? val : can.esc(val)) + '"');
+ });
+ return tags.join(" ");
+ },
+ // Checks if a route matches the data provided. If any route variable
+ // is not present in the data, the route does not match. If all route
+ // variables are present in the data, the number of matches is returned
+ // to allow discerning between general and more specific routes.
+ matchesData = function(route, data) {
+ var count = 0,
+ i = 0,
+ defaults = {};
+ // look at default values, if they match ...
+ for (var name in route.defaults) {
+ if (route.defaults[name] === data[name]) {
+ // mark as matched
+ defaults[name] = 1;
+ count++;
+ }
+ }
+ for (; i < route.names.length; i++) {
+ if (!data.hasOwnProperty(route.names[i])) {
+ return -1;
+ }
+ if (!defaults[route.names[i]]) {
+ count++;
+ }
+
+ }
+
+ return count;
+ },
+ onready = !0,
+ location = window.location,
+ wrapQuote = function(str) {
+ return (str + '').replace(/([.?*+\^$\[\]\\(){}|\-])/g, "\\$1");
+ },
+ each = can.each,
+ extend = can.extend;
+
+ can.route = function(url, defaults) {
+ defaults = defaults || {};
+ // Extract the variable names and replace with `RegExp` that will match
+ // an atual URL with values.
+ var names = [],
+ test = url.replace(matcher, function(whole, name, i) {
+ names.push(name);
+ var next = "\\" + (url.substr(i + whole.length, 1) || can.route._querySeparator);
+ // a name without a default value HAS to have a value
+ // a name that has a default value can be empty
+ // The `\\` is for string-escaping giving single `\` for `RegExp` escaping.
+ return "([^" + next + "]" + (defaults[name] ? "*" : "+") + ")";
+ });
+
+ // Add route in a form that can be easily figured out.
+ can.route.routes[url] = {
+ // A regular expression that will match the route when variable values
+ // are present; i.e. for `:page/:type` the `RegExp` is `/([\w\.]*)/([\w\.]*)/` which
+ // will match for any value of `:page` and `:type` (word chars or period).
+ test: new RegExp("^" + test + "($|" + wrapQuote(can.route._querySeparator) + ")"),
+ // The original URL, same as the index for this entry in routes.
+ route: url,
+ // An `array` of all the variable names in this route.
+ names: names,
+ // Default values provided for the variables.
+ defaults: defaults,
+ // The number of parts in the URL separated by `/`.
+ length: url.split('/').length
+ };
+ return can.route;
+ };
+
+
+ extend(can.route, {
+
+ _querySeparator: '&',
+ _paramsMatcher: paramsMatcher,
+
+
+ param: function(data, _setRoute) {
+ // Check if the provided data keys match the names in any routes;
+ // Get the one with the most matches.
+ var route,
+ // Need to have at least 1 match.
+ matches = 0,
+ matchCount,
+ routeName = data.route,
+ propCount = 0;
+
+ delete data.route;
+
+ each(data, function() {
+ propCount++;
+ });
+ // Otherwise find route.
+ each(can.route.routes, function(temp, name) {
+ // best route is the first with all defaults matching
+
+
+ matchCount = matchesData(temp, data);
+ if (matchCount > matches) {
+ route = temp;
+ matches = matchCount;
+ }
+ if (matchCount >= propCount) {
+ return false;
+ }
+ });
+ // If we have a route name in our `can.route` data, and it's
+ // just as good as what currently matches, use that
+ if (can.route.routes[routeName] && matchesData(can.route.routes[routeName], data) === matches) {
+ route = can.route.routes[routeName];
+ }
+ // If this is match...
+ if (route) {
+ var cpy = extend({}, data),
+ // Create the url by replacing the var names with the provided data.
+ // If the default value is found an empty string is inserted.
+ res = route.route.replace(matcher, function(whole, name) {
+ delete cpy[name];
+ return data[name] === route.defaults[name] ? "" : encodeURIComponent(data[name]);
+ }),
+ after;
+ // Remove matching default values
+ each(route.defaults, function(val, name) {
+ if (cpy[name] === val) {
+ delete cpy[name];
+ }
+ });
+
+ // The remaining elements of data are added as
+ // `&` separated parameters to the url.
+ after = can.param(cpy);
+ // if we are paraming for setting the hash
+ // we also want to make sure the route value is updated
+ if (_setRoute) {
+ can.route.attr('route', route.route);
+ }
+ return res + (after ? can.route._querySeparator + after : "");
+ }
+ // If no route was found, there is no hash URL, only paramters.
+ return can.isEmptyObject(data) ? "" : can.route._querySeparator + can.param(data);
+ },
+
+ deparam: function(url) {
+ // See if the url matches any routes by testing it against the `route.test` `RegExp`.
+ // By comparing the URL length the most specialized route that matches is used.
+ var route = {
+ length: -1
+ };
+ each(can.route.routes, function(temp, name) {
+ if (temp.test.test(url) && temp.length > route.length) {
+ route = temp;
+ }
+ });
+ // If a route was matched.
+ if (route.length > -1) {
+
+ var // Since `RegExp` backreferences are used in `route.test` (parens)
+ // the parts will contain the full matched string and each variable (back-referenced) value.
+ parts = url.match(route.test),
+ // Start will contain the full matched string; parts contain the variable values.
+ start = parts.shift(),
+ // The remainder will be the `&key=value` list at the end of the URL.
+ remainder = url.substr(start.length - (parts[parts.length - 1] === can.route._querySeparator ? 1 : 0)),
+ // If there is a remainder and it contains a `&key=value` list deparam it.
+ obj = (remainder && can.route._paramsMatcher.test(remainder)) ? can.deparam(remainder.slice(1)) : {};
+
+ // Add the default values for this route.
+ obj = extend(true, {}, route.defaults, obj);
+ // Overwrite each of the default values in `obj` with those in
+ // parts if that part is not empty.
+ each(parts, function(part, i) {
+ if (part && part !== can.route._querySeparator) {
+ obj[route.names[i]] = decodeURIComponent(part);
+ }
+ });
+ obj.route = route.route;
+ return obj;
+ }
+ // If no route was matched, it is parsed as a `&key=value` list.
+ if (url.charAt(0) !== can.route._querySeparator) {
+ url = can.route._querySeparator + url;
+ }
+ return can.route._paramsMatcher.test(url) ? can.deparam(url.slice(1)) : {};
+ },
+
+ data: new can.Observe({}),
+
+ routes: {},
+
+ ready: function(val) {
+ if (val === false) {
+ onready = val;
+ }
+ if (val === true || onready === true) {
+ can.route._setup();
+ setState();
+ }
+ return can.route;
+ },
+
+ url: function(options, merge) {
+ if (merge) {
+ options = extend({}, curParams, options)
+ }
+ return "#!" + can.route.param(options);
+ },
+
+ link: function(name, options, props, merge) {
+ return "<a " + makeProps(
+ extend({
+ href: can.route.url(options, merge)
+ }, props)) + ">" + name + "</a>";
+ },
+
+ current: function(options) {
+ return location.hash == "#!" + can.route.param(options)
+ },
+ _setup: function() {
+ // If the hash changes, update the `can.route.data`.
+ can.bind.call(window, 'hashchange', setState);
+ },
+ _getHash: function() {
+ return location.href.split(/#!?/)[1] || "";
+ },
+ _setHash: function(serialized) {
+ var path = (can.route.param(serialized, true));
+ location.hash = "#!" + path;
+ return path;
+ }
+ });
+
+
+ // The functions in the following list applied to `can.route` (e.g. `can.route.attr('...')`) will
+ // instead act on the `can.route.data` observe.
+ each(['bind', 'unbind', 'delegate', 'undelegate', 'attr', 'removeAttr'], function(name) {
+ can.route[name] = function() {
+ // `delegate` and `undelegate` require
+ // the `can/observe/delegate` plugin
+ if (!can.route.data[name]) {
+ return;
+ }
+
+ return can.route.data[name].apply(can.route.data, arguments);
+ }
+ })
+
+ var // A ~~throttled~~ debounced function called multiple times will only fire once the
+ // timer runs down. Each call resets the timer.
+ timer,
+ // Intermediate storage for `can.route.data`.
+ curParams,
+ // Deparameterizes the portion of the hash of interest and assign the
+ // values to the `can.route.data` removing existing values no longer in the hash.
+ // setState is called typically by hashchange which fires asynchronously
+ // So it's possible that someone started changing the data before the
+ // hashchange event fired. For this reason, it will not set the route data
+ // if the data is changing or the hash already matches the hash that was set.
+ setState = can.route.setState = function() {
+ var hash = can.route._getHash();
+ curParams = can.route.deparam(hash);
+
+ // if the hash data is currently changing, or
+ // the hash is what we set it to anyway, do NOT change the hash
+ if (!changingData || hash !== lastHash) {
+ can.route.attr(curParams, true);
+ }
+ },
+ // The last hash caused by a data change
+ lastHash,
+ // Are data changes pending that haven't yet updated the hash
+ changingData;
+
+ // If the `can.route.data` changes, update the hash.
+ // Using `.serialize()` retrieves the raw data contained in the `observable`.
+ // This function is ~~throttled~~ debounced so it only updates once even if multiple values changed.
+ // This might be able to use batchNum and avoid this.
+ can.route.bind("change", function(ev, attr) {
+ // indicate that data is changing
+ changingData = 1;
+ clearTimeout(timer);
+ timer = setTimeout(function() {
+ // indicate that the hash is set to look like the data
+ changingData = 0;
+ var serialized = can.route.data.serialize();
+
+ lastHash = can.route._setHash(serialized);
+ }, 1);
+ });
+ // `onready` event...
+ can.bind.call(document, "ready", can.route.ready);
+
+ // Libraries other than jQuery don't execute the document `ready` listener
+ // if we are already DOM ready
+ if ((document.readyState === 'complete' || document.readyState === "interactive") && onready) {
+ can.route.ready();
+ }
+
+ // extend route to have a similar property
+ // that is often checked in mustache to determine
+ // an object's observability
+ can.route.constructor.canMakeObserve = can.Observe.canMakeObserve;
+
+ return can.route;
+ })(__m3, __m7, __m20);
+
+ // ## control/route/route.js
+ var __m21 = (function(can) {
+
+ // ## control/route.js
+ // _Controller route integration._
+
+ can.Control.processors.route = function(el, event, selector, funcName, controller) {
+ selector = selector || "";
+ can.route(selector);
+ var batchNum,
+ check = function(ev, attr, how) {
+ if (can.route.attr('route') === (selector) &&
+ (ev.batchNum === undefined || ev.batchNum !== batchNum)) {
+
+ batchNum = ev.batchNum;
+
+ var d = can.route.attr();
+ delete d.route;
+ if (can.isFunction(controller[funcName])) {
+ controller[funcName](d);
+ } else {
+ controller[controller[funcName]](d);
+ }
+
+ }
+ };
+ can.route.bind('change', check);
+ return function() {
+ can.route.unbind('change', check);
+ };
+ };
+
+ return can;
+ })(__m3, __m19, __m18);
+
+ window['can'] = __m5;
+ })();
\ No newline at end of file
Added: html5videoplayer/js/libs/can.jquery.min.js
===================================================================
--- html5videoplayer/js/libs/can.jquery.min.js (rev 0)
+++ html5videoplayer/js/libs/can.jquery.min.js 2013-06-07 16:16:19 UTC (rev 660)
@@ -0,0 +1,11 @@
+/*!
+ * CanJS - 1.1.6
+ * http://canjs.us/
+ * Copyright (c) 2013 Bitovi
+ * Wed, 29 May 2013 18:59:22 GMT
+ * Licensed MIT
+ * Includes: CanJS default build
+ * Download from: http://canjs.us/
+ */
+!function(undefined){var __m5=function(){var a=window.can||{};("undefined"==typeof GLOBALCAN||GLOBALCAN!==!1)&&(window.can=a),a.isDeferred=function(a){var b=this.isFunction;return a&&b(a.then)&&b(a.pipe)};var b=0;return a.cid=function(a,c){return a._cid?a._cid:a._cid=(c||"")+ ++b},a.VERSION="@EDGE",a}(),__m6=function(a){return a.each=function(a,b,c){var d,e=0;if(a)if("number"==typeof a.length&&a.pop)for(a.attr&&a.attr("length"),d=a.length;d>e&&b.call(c||a[e],a[e],e,a)!==!1;e++);else if(a.hasOwnProperty)for(d in a)if(a.hasOwnProperty(d)&&b.call(c||a[d],a[d],d,a)===!1)break;return a},a}(__m5),__m3=function(a,b){a.extend(b,a,{trigger:function(b,c,d){b.trigger?b.trigger(c,d):a.event.trigger(c,d,b,!0)},addEvent:function(b,c){return a([this]).bind(b,c),this},removeEvent:function(b,c){return a([this]).unbind(b,c),this},buildFragment:function(b,c){var d,e=a.buildFragment;return b=[b],c=c||document,c=!c.nodeType&&c[0]||c,c=c.ownerDocument||c,d=e.call(jQuery,b,c),d.cacheable?a.clone(d.fragment):d.fragment||d},$:a,each:b.each}),a.each(["bind","unbind","undelegate","delegate"],function(c,d){b[d]=function(){var b=this[d]?this:a([this]);return b[d].apply(b,arguments),this}}),a.each(["append","filter","addClass","remove","data","get"],function(a,c){b[c]=function(a){return a[c].apply(a,b.makeArray(arguments).slice(1))}});var c=a.cleanData;return a.cleanData=function(d){a.each(d,function(a,c){c&&b.trigger(c,"destroyed",[],!1)}),c(d)},b}(jQuery,__m5,__m6),__m2=function(a){var b=/_|-/,c=/\=\=/,d=/([A-Z]+)([A-Z][a-z])/g,e=/([a-z\d])([A-Z])/g,f=/([a-z\d])([A-Z])/g,g=/\{([^\}]+)\}/g,h=/"/g,i=/'/g,j=function(a,b,c){var d=a[b];return d===undefined&&c===!0&&(d=a[b]={}),d},k=function(a){return/^f|^o/.test(typeof a)};return a.extend(a,{esc:function(a){var b=null===a||a===undefined||isNaN(a)&&"NaN"==""+a;return(""+(b?"":a)).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(h,""").replace(i,"'")},getObject:function(b,c,d){var e,f,g,h,i=b?b.split("."):[],l=i.length,m=0;if(c=a.isArray(c)?c:[c||window],h=c.length,!l)return c[0];for(m;h>m;m++){for(e=c[m],g=undefined,f=0;l>f&&k(e);f++)g=e,e=j(g,i[f]);if(g!==undefined&&e!==undefined)break}if(d===!1&&e!==undefined&&delete g[i[f-1]],d===!0&&e===undefined)for(e=c[0],f=0;l>f&&k(e);f++)e=j(e,i[f],!0);return e},capitalize:function(a){return a.charAt(0).toUpperCase()+a.slice(1)},underscore:function(a){return a.replace(c,"/").replace(d,"$1_$2").replace(e,"$1_$2").replace(f,"_").toLowerCase()},sub:function(b,c,d){var e=[];return b=b||"",e.push(b.replace(g,function(b,f){var g=a.getObject(f,c,d===!0?!1:undefined);return g===undefined?(e=null,""):k(g)&&e?(e.push(g),""):""+g})),null===e?e:e.length<=1?e[0]:e},replacer:g,undHash:b}),a}(__m3),__m1=function(a){var b=0;return a.Construct=function(){return arguments.length?a.Construct.extend.apply(a.Construct,arguments):void 0},a.extend(a.Construct,{newInstance:function(){var a,b=this.instance();return b.setup&&(a=b.setup.apply(b,arguments)),b.init&&b.init.apply(b,a||arguments),b},_inherit:function(b,c,d){a.extend(d||b,b||{})},_overwrite:function(a,b,c,d){a[c]=d},setup:function(b){this.defaults=a.extend(!0,{},b.defaults,this.defaults)},instance:function(){b=1;var a=new this;return b=0,a},extend:function(c,d,e){function f(){return b?void 0:this.constructor!==f&&arguments.length?arguments.callee.extend.apply(arguments.callee,arguments):this.constructor.newInstance.apply(this.constructor,arguments)}"string"!=typeof c&&(e=d,d=c,c=null),e||(e=d,d=null),e=e||{};var g,h,i,j,k=this,l=this.prototype;j=this.instance(),a.Construct._inherit(e,l,j);for(g in k)k.hasOwnProperty(g)&&(f[g]=k[g]);if(a.Construct._inherit(d,k,f),c){var m=c.split("."),h=m.pop(),n=a.getObject(m.join("."),window,!0),i=n,o=a.underscore(c.replace(/\./g,"_")),p=a.underscore(h);n[h]=f}a.extend(f,{constructor:f,prototype:j,namespace:i,_shortName:p,fullName:c,_fullName:o}),h!==undefined&&(f.shortName=h),f.prototype.constructor=f;var q=[k].concat(a.makeArray(arguments)),r=f.setup.apply(f,q);return f.init&&f.init.apply(f,r||q),f}}),a.Construct}(__m2),__m8=function(a){return a.bindAndSetup=function(){return a.addEvent.apply(this,arguments),this._init||(this._bindings?this._bindings++:(this._bindings=1,this._bindsetup&&this._bindsetup())),this},a.unbindAndTeardown=function(){return a.removeEvent.apply(this,arguments),this._bindings--,this._bindings||this._bindteardown&&this._bindteardown(),this},a}(__m3),__m7=function(a){var b=function(b){return b&&!a.isDeferred(b)&&(a.isArray(b)||a.isPlainObject(b)||b instanceof a.Observe)},c=function(b,c){return a.each(b,function(a){a&&a.unbind&&a.unbind("change"+c)})},d=function(b,d,g,h,i){return h=h||f,i=i||f.List,b instanceof f?g._bindings&&c([b],g._cid):b=a.isArray(b)?new i(b):new h(b),g._bindings&&e(b,d,g),b},e=function(b,c,d){b.bind("change"+d._cid,function(){var e=a.makeArray(arguments),f=e.shift();e[0]=("*"===c?[d.indexOf(b),e[0]]:[c,e[0]]).join("."),f.triggeredNS=f.triggeredNS||{},f.triggeredNS[d._cid]||(f.triggeredNS[d._cid]=!0,a.trigger(d,f,e))})};observeId=0,serialize=function(c,d,e){return c.each(function(c,f){e[f]=b(c)&&a.isFunction(c[d])?c[d]():c}),e},attrParts=function(b,c){return c?[b]:a.isArray(b)?b:(""+b).split(".")},batchNum=1,transactions=0,batchEvents=[],stopCallbacks=[],makeBindSetup=function(a){return function(){var b=this;this._each(function(c,d){c&&c.bind&&e(c,a||d,b)})}};var f=a.Map=a.Observe=a.Construct({bind:a.bindAndSetup,unbind:a.unbindAndTeardown,id:"id",canMakeObserve:b,startBatch:function(a){transactions++,a&&stopCallbacks.push(a)},stopBatch:function(b,c){if(b?transactions=0:transactions--,0==transactions){var d=batchEvents.slice(0),e=stopCallbacks.slice(0);batchEvents=[],stopCallbacks=[],batchNum++,c&&this.startBatch(),a.each(d,function(b){a.trigger.apply(a,b)}),a.each(e,function(a){a()})}},triggerBatch:function(b,c,d){if(!b._init){if(0==transactions)return a.trigger(b,c,d);c="string"==typeof c?{type:c}:c,c.batchNum=batchNum,batchEvents.push([b,c,d])}},keys:function(a){var b=[];f.__reading&&f.__reading(a,"__keys");for(var c in a._data)b.push(c);return b}},{setup:function(b){this._data={},a.cid(this,".observe"),this._init=1,this.attr(b),this.bind("change"+this._cid,a.proxy(this._changes,this)),delete this._init},_bindsetup:makeBindSetup(),_bindteardown:function(){var a=this._cid;this._each(function(b){c([b],a)})},_changes:function(a,b,c,d,e){f.triggerBatch(this,{type:b,batchNum:a.batchNum},[d,e])},_triggerChange:function(){f.triggerBatch(this,"change",a.makeArray(arguments))},_each:function(a){var b=this.__get();for(var c in b)b.hasOwnProperty(c)&&a(b[c],c)},attr:function(a,b){var c=typeof a;return"string"!==c&&"number"!==c?this._attrs(a,b):b===undefined?(f.__reading&&f.__reading(this,a),this._get(a)):(this._set(a,b),this)},each:function(){return f.__reading&&f.__reading(this,"__keys"),a.each.apply(undefined,[this.__get()].concat(a.makeArray(arguments)))},removeAttr:function(b){var c=this instanceof a.Observe.List,d=attrParts(b),e=d.shift(),g=c?this[e]:this._data[e];return d.length?g.removeAttr(d):(c?this.splice(e,1):e in this._data&&(delete this._data[e],e in this.constructor.prototype||delete this[e],f.triggerBatch(this,"__keys"),this._triggerChange(e,"remove",undefined,g)),g)},_get:function(a){var b="string"==typeof a&&!!~a.indexOf(".")&&this.__get(a);if(b)return b;var c=attrParts(a),d=this.__get(c.shift());return c.length?d?d._get(c):undefined:d},__get:function(a){return a?this._data[a]:this._data},_set:function(a,c,d){var e=attrParts(a,d),f=e.shift(),g=this.__get(f);if(b(g)&&e.length)g._set(e,c);else{if(e.length)throw"can.Observe: Object does not exist";this.__convert&&(c=this.__convert(f,c)),this.__set(f,c,g)}},__set:function(a,e,g){if(e!==g){var h=this.__get().hasOwnProperty(a)?"set":"add";this.___set(a,b(e)?d(e,a,this):e),"add"==h&&f.triggerBatch(this,"__keys",undefined),this._triggerChange(a,h,e,g),g&&c([g],this._cid)}},___set:function(a,b){this._data[a]=b,a in this.constructor.prototype||(this[a]=b)},bind:a.bindAndSetup,unbind:a.unbindAndTeardown,serialize:function(){return serialize(this,"serialize",{})},_attrs:function(c,d){if(c===undefined)return serialize(this,"attr",{});c=a.extend({},c);var e,g,h=this;f.startBatch(),this.each(function(e,f){return g=c[f],g===undefined?(d&&h.removeAttr(f),void 0):(h.__convert&&(g=h.__convert(f,g)),g instanceof a.Observe?h.__set(f,g,e):b(e)&&b(g)&&e.attr?e.attr(g,d):e!=g&&h.__set(f,g,e),delete c[f],void 0)});for(var e in c)g=c[e],this._set(e,g,!0);return f.stopBatch(),this},compute:function(b){return a.compute(this,b)}}),g=[].splice,h=f({setup:function(b,c){this.length=0,a.cid(this,".observe"),this._init=1,a.isDeferred(b)?this.replace(b):this.push.apply(this,a.makeArray(b||[])),this.bind("change"+this._cid,a.proxy(this._changes,this)),a.extend(this,c),delete this._init},_triggerChange:function(a,b,c,d){f.prototype._triggerChange.apply(this,arguments),~a.indexOf(".")||("add"===b?(f.triggerBatch(this,b,[c,+a]),f.triggerBatch(this,"length",[this.length])):"remove"===b?(f.triggerBatch(this,b,[d,+a]),f.triggerBatch(this,"length",[this.length])):f.triggerBatch(this,b,[c,+a]))},__get:function(a){return a?this[a]:this},___set:function(a,b){this[a]=b,+a>=this.length&&(this.length=+a+1)},_each:function(a){for(var b=this.__get(),c=0;c<b.length;c++)a(b[c],c)},_bindsetup:makeBindSetup("*"),serialize:function(){return serialize(this,"serialize",[])},splice:function(e,f){var h,i=a.makeArray(arguments);for(h=2;h<i.length;h++){var j=i[h];b(j)&&(i[h]=d(j,"*",this,this.constructor.Observe,this.constructor))}f===undefined&&(f=i[1]=this.length-e);var k=g.apply(this,i);return a.Observe.startBatch(),f>0&&(this._triggerChange(""+e,"remove",undefined,k),c(k,this._cid)),i.length>2&&this._triggerChange(""+e,"add",i.slice(2),k),a.Observe.stopBatch(),k},_attrs:function(b,c){return b===undefined?serialize(this,"attr",[]):(b=a.makeArray(b),f.startBatch(),this._updateAttrs(b,c),f.stopBatch(),void 0)},_updateAttrs:function(a,c){for(var d=Math.min(a.length,this.length),e=0;d>e;e++){var f=this[e],g=a[e];b(f)&&b(g)?f.attr(g,c):f!=g&&this._set(e,g)}a.length>this.length?this.push.apply(this,a.slice(this.length)):a.length<this.length&&c&&this.splice(a.length)}}),i=function(b){return b[0]&&a.isArray(b[0])?b[0]:a.makeArray(b)};return a.each({push:"length",unshift:0},function(a,c){var e=[][c];h.prototype[c]=function(){var c,f,g=[],h=a?this.length:0,i=arguments.length;for(this.constructor;i--;)f=arguments[i],g[i]=b(f)?d(f,"*",this,this.constructor.Observe,this.constructor):f;return c=e.apply(this,g),(!this.comparator||g.length)&&this._triggerChange(""+h,"add",g,undefined),c}}),a.each({pop:"length",shift:0},function(a,b){h.prototype[b]=function(){var c=i(arguments),d=a&&this.length?this.length-1:0,e=[][b].apply(this,c);return this._triggerChange(""+d,"remove",undefined,[e]),e&&e.unbind&&e.unbind("change"+this._cid),e}}),a.extend(h.prototype,{indexOf:function(b){return this.attr("length"),a.inArray(b,this)},join:[].join,reverse:[].reverse,slice:function(){var a=Array.prototype.slice.apply(this,arguments);return new this.constructor(a)},concat:function(){var b=[];return a.each(a.makeArray(arguments),function(c,d){b[d]=c instanceof a.Observe.List?c.serialize():c}),new this.constructor(Array.prototype.concat.apply(this.serialize(),b))},forEach:function(b,c){a.each(this,b,c||this)},replace:function(b){return a.isDeferred(b)?b.then(a.proxy(this.replace,this)):this.splice.apply(this,[0,this.length].concat(a.makeArray(b||[]))),this}}),a.List=f.List=h,f.setup=function(){a.Construct.setup.apply(this,arguments),this.List=f.List({Observe:this},{})},f}(__m3,__m8,__m1),__m9=function(a){var b=function(b,c){var d;a.Observe&&(d=a.Observe.__reading,a.Observe.__reading=function(a,b){e.push({obj:a,attr:b+""})});var e=[],f=b.call(c);return a.Observe&&(a.Observe.__reading=d),{value:f,observed:e}},c=function(c,d,e,f){var g,h={},i=!0,j={value:undefined,teardown:function(){for(var a in h){var b=h[a];b.observe.obj.unbind(b.observe.attr,k),delete h[a]}}},k=function(a){if(!(f&&!f.bound||a.batchNum!==undefined&&a.batchNum===g)){var b=j.value,c=l();j.value=c,c!==b&&e(c,b),g=g=a.batchNum}},l=function(){var e=b(c,d),f=e.observed,g=e.value;i=!i,a.each(f,function(a){h[a.obj._cid+"|"+a.attr]?h[a.obj._cid+"|"+a.attr].matched=i:(h[a.obj._cid+"|"+a.attr]={matched:i,observe:a},a.obj.bind(a.attr,k))});for(var j in h){var l=h[j];l.matched!==i&&(l.observe.obj.unbind(l.observe.attr,k),delete h[j])}return g};return j.value=l(),j.isListening=!a.isEmptyObject(h),j};return a.compute=function(d,e,f){if(d&&d.isComputed)return d;var g,h,i,j={bound:!1,hasDependencies:!1},k=function(){},l=function(){},m=function(){return i},n=function(a){i=a},o=!0;if(h=function(b){if(arguments.length){var c=i,d=n.call(e,b,c);return h.hasDependencies?m.call(e):(i=d===undefined?m.call(e):d,c!==i&&a.Observe.triggerBatch(h,"change",[i,c]),i)}return a.Observe.__reading&&o&&a.Observe.__reading(h,"change"),j.bound?i:m.call(e)},"function"==typeof d)n=d,m=d,o=f===!1?!1:!0,h.hasDependencies=!1,k=function(a){g=c(d,e||this,a,j),h.hasDependencies=g.isListening,i=g.value},l=function(){g.teardown()};else if(e)if("string"==typeof e){var p=e,q=d instanceof a.Observe;q&&(h.hasDependencies=!0),m=function(){return q?d.attr(p):d[p]},n=function(a){q?d.attr(p,a):d[p]=a};var r;k=function(c){r=function(){c(m(),i)},a.bind.call(d,f||p,r),i=b(m).value},l=function(){a.unbind.call(d,f||p,r)}}else if("function"==typeof e)i=d,n=e;else{i=d;var s=e;m=s.get||m,n=s.set||n,k=s.on||k,l=s.off||l}else i=d;h.isComputed=!0,a.cid(h,"compute");var t=function(b,c){i=b,a.Observe.triggerBatch(h,"change",[b,c])};return a.extend(h,{_bindsetup:function(){j.bound=!0,k.call(this,t)},_bindteardown:function(){l.call(this,t),j.bound=!1},bind:a.bindAndSetup,unbind:a.unbindAndTeardown})},a.compute.binder=c,a.compute}(__m3,__m8),__m10=function(a){var b=function(b,c,d){var e=new a.Deferred;return b.then(function(){var b=a.makeArray(arguments);b[0]=c[d](b[0]),e.resolveWith(e,b)},function(){e.rejectWith(this,arguments)}),"function"==typeof b.abort&&(e.abort=function(){return b.abort()}),e},c=0,d=function(b){return a.Observe.__reading&&a.Observe.__reading(b,b.constructor.id),b.__get(b.constructor.id)},e=function(b,c,d,e,f,g){var h={};if("string"==typeof b){var i=b.split(/\s+/);h.url=i.pop(),i.length&&(h.type=i.pop())}else a.extend(h,b);return h.data="object"!=typeof c||a.isArray(c)?c:a.extend(h.data||{},c),h.url=a.sub(h.url,h.data,!0),a.ajax(a.extend({type:d||"post",dataType:e||"json",success:f,error:g},h))},f=function(b,c,e,f,g){var h;a.isArray(b)?(h=b[1],b=b[0]):h=b.serialize(),h=[h];var i,j,k=b.constructor;return"destroy"==c&&h.shift(),"create"!==c&&h.unshift(d(b)),j=k[c].apply(k,h),i=j.pipe(function(a){return b[g||c+"d"](a,j),b}),j.abort&&(i.abort=function(){j.abort()}),i.then(e,f),i},g={create:{url:"_shortName",type:"post"},update:{data:function(b,c){c=c||{};var d=this.id;return c[d]&&c[d]!==b&&(c["new"+a.capitalize(b)]=c[d],delete c[d]),c[d]=b,c},type:"put"},destroy:{type:"delete",data:function(a){var b={};return b.id=b[this.id]=a,b}},findAll:{url:"_shortName"},findOne:{}},h=function(a,b){return function(c){return c=a.data?a.data.apply(this,arguments):c,e(b||this[a.url||"_url"],c,a.type||"get")}};a.Model=a.Observe({fullName:"can.Model",_reqs:0,setup:function(b){if(this.store={},a.Observe.setup.apply(this,arguments),a.Model){this.List=i({Observe:this},{});var d=this,e=a.proxy(this._clean,d);a.each(g,function(c,f){if(a.isFunction(d[f])||(d[f]=h(c,d[f])),d["make"+a.capitalize(f)]){var g=d["make"+a.capitalize(f)](d[f]);a.Construct._overwrite(d,b,f,function(){a.Model._reqs++;var b=g.apply(this,arguments),c=b.then(e,e);return c.abort=b.abort,c})}}),"can.Model"!=d.fullName&&d.fullName||(d.fullName="Model"+ ++c),a.Model._reqs=0,this._url=this._shortName+"/{"+this.id+"}"}},_ajax:h,_makeRequest:f,_clean:function(){if(a.Model._reqs--,!a.Model._reqs)for(var b in this.store)this.store[b]._bindings||delete this.store[b];return arguments[0]},models:function(b,c){if(a.Model._reqs++,b){if(b instanceof this.List)return b;var d=this,e=[],f=c instanceof a.Observe.List?c:new(d.List||i),g=a.isArray(b),h=b instanceof i,j=g?b:h?b.serialize():b.data;return f.length&&f.splice(0),a.each(j,function(a){e.push(d.model(a))}),f.push.apply(f,e),g||a.each(b,function(a,b){"data"!==b&&f.attr(b,a)}),setTimeout(a.proxy(this._clean,this),1),f}},model:function(b){if(b){b instanceof this&&(b=b.serialize());var c=b[this.id],d=(c||0===c)&&this.store[c]?this.store[c].attr(b,this.removeAttr||!1):new this(b);return a.Model._reqs&&(this.store[b[this.id]]=d),d}}},{isNew:function(){var a=d(this);return!(a||0===a)},save:function(a,b){return f(this,this.isNew()?"create":"update",a,b)},destroy:function(b,c){if(this.isNew()){var d=this,e=a.Deferred();return e.then(b,c),e.done(function(a){d.destroyed(a)}).resolve(d)}return f(this,"destroy",b,c,"destroyed")},_bindsetup:function(){return this.constructor.store[this.__get(this.constructor.id)]=this,a.Observe.prototype._bindsetup.apply(this,arguments)},_bindteardown:function(){return delete this.constructor.store[d(this)],a.Observe.prototype._bindteardown.apply(this,arguments)},___set:function(b,c){a.Observe.prototype.___set.call(this,b,c),b===this.constructor.id&&this._bindings&&(this.constructor.store[d(this)]=this)}}),a.each({makeFindAll:"models",makeFindOne:"model",makeCreate:"model",makeUpdate:"model"},function(c,d){a.Model[d]=function(d){return function(){var e=a.makeArray(arguments),f=a.isFunction(e[1])?e.splice(0,1):e.splice(0,2),g=b(d.apply(this,f),this,c);return g.then(e[0],e[1]),g}}}),a.each(["created","updated","destroyed"],function(b){a.Model.prototype[b]=function(c){var d,e=this.constructor;d=c&&"object"==typeof c&&this.attr(c.attr?c.attr():c),a.trigger(this,"change",b),a.trigger(e,b,this)}});var i=a.Model.List=a.Observe.List({setup:function(b){a.isPlainObject(b)&&!a.isArray(b)?(a.Observe.List.prototype.setup.apply(this),this.replace(this.constructor.Observe.findAll(b))):a.Observe.List.prototype.setup.apply(this,arguments)},_changes:function(b,c){if(a.Observe.List.prototype._changes.apply(this,arguments),/\w+\.destroyed/.test(c)){var d=this.indexOf(b.target);-1!=d&&this.splice(d,1)}}});return a.Model}(__m3,__m7),__m11=function(a){var b=a.isFunction,c=a.makeArray,d=1,e=a.view=a.template=function(c,d,f,g){b(f)&&(g=f,f=undefined);var h=function(a){return e.frag(a)},i=b(g)?function(a){g(h(a))}:null,j=e.render(c,d,f,i),k=a.Deferred();return b(j)?j:a.isDeferred(j)?(j.then(function(a,b){k.resolve.call(k,h(a),b)},function(){k.fail.apply(k,arguments)}),k):h(j)};a.extend(e,{frag:function(a,b){return e.hookup(e.fragment(a),b)},fragment:function(b){var c=a.buildFragment(b,document.body);return c.childNodes.length||c.appendChild(document.createTextNode("")),c},toId:function(b){return a.map(b.toString().split(/\/|\./g),function(a){return a?a:void 0}).join("_")},hookup:function(b,c){var d,f,g=[];return a.each(b.childNodes?a.makeArray(b.childNodes):b,function(b){1===b.nodeType&&(g.push(b),g.push.apply(g,a.makeArray(b.getElementsByTagName("*"))))}),a.each(g,function(a){a.getAttribute&&(d=a.getAttribute("data-view-id"))&&(f=e.hookups[d])&&(f(a,c,d),delete e.hookups[d],a.removeAttribute("data-view-id"))}),b},hookups:{},hook:function(a){return e.hookups[++d]=a," data-view-id='"+d+"'"},cached:{},cachedRenderers:{},cache:!0,register:function(a){this.types["."+a.suffix]=a},types:{},ext:".ejs",registerScript:function(){},preload:function(){},render:function(d,f,j,k){b(j)&&(k=j,j=undefined);var l=h(f);if(l.length){var m=new a.Deferred,n=a.extend({},f);return l.push(g(d,!0)),a.when.apply(a,l).then(function(b){var d,e=c(arguments),g=e.pop();if(a.isDeferred(f))n=i(b);else for(var h in f)a.isDeferred(f[h])&&(n[h]=i(e.shift()));d=g(n,j),m.resolve(d,n),k&&k(d,n)},function(){m.reject.apply(m,arguments)}),m}var o,p=b(k),m=g(d,p);if(p)o=m,m.then(function(a){k(f?a(f,j):a)});else{if("resolved"===m.state()&&m.__view_id){var q=e.cachedRenderers[m.__view_id];return f?q(f,j):q}m.then(function(a){o=f?a(f,j):a})}return o},registerView:function(b,c,d,f){var g=(d||e.types[e.ext]).renderer(b,c);return f=f||new a.Deferred,e.cache&&(e.cached[b]=f,f.__view_id=b,e.cachedRenderers[b]=g),f.resolve(g)}});var f=function(a,b){if(!a.length)throw"can.view: No template or empty template:"+b},g=function(b,c){var d,g,h,i=b.match(/\.[\w\d]+$/);if(b.match(/^#/)&&(b=b.substr(1)),(g=document.getElementById(b))&&(i="."+g.type.match(/\/(x\-)?(.+)/)[2]),i||e.cached[b]||(b+=i=e.ext),a.isArray(i)&&(i=i[0]),h=e.toId(b),b.match(/^\/\//)){var j=b.substr(2);b=window.steal?steal.config().root.mapJoin(""+steal.id(j)):j}if(d=e.types[i],e.cached[h])return e.cached[h];if(g)return e.registerView(h,g.innerHTML,d);var k=new a.Deferred;return a.ajax({async:c,url:b,dataType:"text",error:function(a){f("",b),k.reject(a)},success:function(a){f(a,b),e.registerView(h,a,d,k)}}),k},h=function(b){var c=[];if(a.isDeferred(b))return[b];for(var d in b)a.isDeferred(b[d])&&c.push(b[d]);return c},i=function(b){return a.isArray(b)&&"success"===b[1]?b[0]:b};return window.steal&&steal.type("view js",function(a,b){var c=e.types["."+a.type],d=e.toId(a.id);a.text="steal('"+(c.plugin||"can/view/"+a.type)+"',function(can){return "+"can.view.preload('"+d+"',"+a.text+");\n})",b()}),a.extend(e,{register:function(b){this.types["."+b.suffix]=b,window.steal&&steal.type(b.suffix+" view js",function(a,b){var c=e.types["."+a.type],d=e.toId(a.id+"");a.text=c.script(d,a.text),b()}),e[b.suffix]=function(c,d){if(!d){var f=function(){return e.frag(f.render.apply(this,arguments))};return f.render=function(){var a=b.renderer(null,c);return a.apply(a,arguments)},f}return e.preload(c,b.renderer(c,d)),a.view(c)}},registerScript:function(a,b,c){return"can.view.preload('"+b+"',"+e.types["."+a].script(b,c)+");"},preload:function(b,c){function d(){return e.frag(c.apply(this,arguments))}return e.cached[b]=(new a.Deferred).resolve(function(a,b){return c.call(a,a,b)}),d.render=c,d}}),a}(__m3),__m14=function(){var a={tagToContentPropMap:{option:"textContent"in document.createElement("option")?"textContent":"innerText",textarea:"value"},attrMap:{"class":"className",value:"value",innerText:"innerText",textContent:"textContent",checked:!0,disabled:!0,readonly:!0,required:!0},defaultValue:["input","textarea"],tagMap:{"":"span",table:"tbody",tr:"td",ol:"li",ul:"li",tbody:"tr",thead:"tr",tfoot:"tr",select:"option",optgroup:"option"},reverseTagMap:{tr:"tbody",option:"select",td:"tr",th:"tr",li:"ul"},getParentNode:function(a,b){return b&&11===a.parentNode.nodeType?b:a.parentNode},setAttr:function(b,c,d){var e=b.nodeName.toString().toLowerCase(),f=a.attrMap[c];f===!0?b[c]=!0:f?(b[f]=d,"value"===f&&can.inArray(e,a.defaultValue)>=0&&(b.defaultValue=d)):b.setAttribute(c,d)},getAttr:function(b,c){return(a.attrMap[c]&&b[a.attrMap[c]]?b[a.attrMap[c]]:b.getAttribute(c))||""},removeAttr:function(b,c){a.attrMap[c]===!0?b[c]=!1:b.removeAttribute(c)},contentText:function(a){return"string"==typeof a?a:a||0===a?""+a:""}};return a}(),__m13=function(can,elements){var newLine=/(\r|\n)+/g,clean=function(a){return a.split("\\").join("\\\\").split("\n").join("\\n").split('"').join('\\"').split(" ").join("\\t")},getTag=function(a,b,c){if(a)return a;for(;c<b.length;){if("<"==b[c]&&elements.reverseTagMap[b[c+1]])return elements.reverseTagMap[b[c+1]];c++}return""},bracketNum=function(a){return--a.split("{").length- --a.split("}").length},myEval=function(script){eval(script)},attrReg=/([^\s]+)[\s]*=[\s]*$/,startTxt="var ___v1ew = [];",finishTxt="return ___v1ew.join('')",put_cmd="___v1ew.push(",insert_cmd=put_cmd,htmlTag=null,quote=null,beforeQuote=null,rescan=null,status=function(){return quote?"'"+beforeQuote.match(attrReg)[1]+"'":htmlTag?1:0};return can.view.Scanner=Scanner=function(a){can.extend(this,{text:{},tokens:[]},a),this.tokenReg=[],this.tokenSimple={"<":"<",">":">",'"':'"',"'":"'"},this.tokenComplex=[],this.tokenMap={};for(var b,c=0;b=this.tokens[c];c++)b[2]?(this.tokenReg.push(b[2]),this.tokenComplex.push({abbr:b[1],re:new RegExp(b[2]),rescan:b[3]})):(this.tokenReg.push(b[1]),this.tokenSimple[b[1]]=b[0]),this.tokenMap[b[0]]=b[1];this.tokenReg=new RegExp("("+this.tokenReg.slice(0).concat(["<",">",'"',"'"]).join("|")+")","g")},Scanner.prototype={helpers:[{name:/\s*\(([\$\w]+)\)\s*->([^\n]*)/,fn:function(a){var b=/\s*\(([\$\w]+)\)\s*->([^\n]*)/,c=a.match(b);return"can.proxy(function(__){var "+c[1]+"=can.$(__);"+c[2]+"}, this);"}}],scan:function(a,b){var c=[],d=0,e=this.tokenSimple,f=this.tokenComplex;a=a.replace(newLine,"\n"),this.transform&&(a=this.transform(a)),a.replace(this.tokenReg,function(b,g){var h=arguments[arguments.length-2];if(h>d&&c.push(a.substring(d,h)),e[b])c.push(b);else for(var i,j=0;i=f[j];j++)if(i.re.test(b)){c.push(i.abbr),i.rescan&&c.push(i.rescan(g));break}d=h+g.length}),d<a.length&&c.push(a.substr(d));var g,h,i,j="",k=[startTxt+(this.text.start||"")],l=function(a,b){k.push(put_cmd,'"',clean(a),'"'+(b||"")+");")},m=[],n=null,o=!1,p="",q=[],r=!1,s=0,t=this.tokenMap;for(htmlTag=quote=beforeQuote=null;(i=c[s++])!==undefined;){if(null===n)switch(i){case t.left:case t.escapeLeft:case t.returnLeft:o=htmlTag&&1;case t.commentLeft:n=i,j.length&&l(j),j="";break;case t.escapeFull:o=htmlTag&&1,rescan=1,n=t.escapeLeft,j.length&&l(j),rescan=c[s++],j=rescan.content||rescan,rescan.before&&l(rescan.before),c.splice(s,0,t.right);break;case t.commentFull:break;case t.templateLeft:j+=t.left;break;case"<":0!==c[s].indexOf("!--")&&(htmlTag=1,o=0),j+=i;break;case">":htmlTag=0;var u="/"==j.substr(j.length-1)||"--"==j.substr(j.length-2);o||!r&&elements.tagToContentPropMap[q[q.length-1]]?(u?l(j.substr(0,j.length-1),',can.view.pending(),"/>"'):l(j,',can.view.pending(),">"'),j="",o=0):j+=i,(u||r)&&(q.pop(),p=q[q.length-1],r=!1);break;case"'":case'"':htmlTag&&(quote&"e===i?quote=null:null===quote&&(quote=i,beforeQuote=g));default:"<"===g&&(p=i.split(/\s/)[0],0===p.indexOf("/")&&q[q.length-1]===p.substr(1)?(p=q[q.length-1],r=!0):q.push(p)),j+=i}else switch(i){case t.right:case t.returnRight:switch(n){case t.left:h=bracketNum(j),1==h?(k.push(insert_cmd,"can.view.txt(0,'"+getTag(p,c,s)+"',"+status()+",this,function(){",startTxt,j),m.push({before:"",after:finishTxt+"}));\n"})):(d=m.length&&-1==h?m.pop():{after:";"},d.before&&k.push(d.before),k.push(j,";",d.after));break;case t.escapeLeft:case t.returnLeft:h=bracketNum(j),h&&m.push({before:finishTxt,after:"}));"});for(var v=n===t.escapeLeft?1:0,w={insert:insert_cmd,tagName:getTag(p,c,s),status:status()},x=0;x<this.helpers.length;x++){var y=this.helpers[x];if(y.name.test(j)){j=y.fn(j,w),y.name.source==/^>[\s]*\w*/.source&&(v=0);break}}"object"==typeof j?j.raw&&k.push(j.raw):k.push(insert_cmd,"can.view.txt("+v+",'"+p+"',"+status()+",this,function(){ "+(this.text.escape||"")+"return ",j,h?startTxt:"}));"),rescan&&rescan.after&&rescan.after.length&&(l(rescan.after.length),rescan=null)}n=null,j="";break;case t.templateLeft:j+=t.left;break;default:j+=i}g=i}j.length&&l(j),k.push(";");var z=k.join(""),A={out:"with(_VIEW) { with (_CONTEXT) {"+z+" "+finishTxt+"}}"};return myEval.call(A,"this.fn = (function(_CONTEXT,_VIEW){"+A.out+"});\r\n//@ sourceURL="+b+".js"),A}},Scanner}(__m11,__m14),__m17=function(a){var b=!0;try{document.createTextNode("")._=0}catch(c){b=!1}var d={},e={},f={},g="ejs_"+Math.random(),h=0,i=function(a){if(b||3!==a.nodeType)return a[g]?a[g]:a[g]=(a.nodeName?"element_":"obj_")+ ++h;for(var c in e)if(e[c]===a)return c;return e["text_"+ ++h]=a,"text_"+h},j=function(b,c){var e=d[i(b)];if(e){var f=a.inArray(c,e);f>=0&&e.splice(f,1),e.length||delete d[i(b)]}},k=function(a,b){var c=d[i(a)];c||(c=d[i(a)]=[]),c.push(b)},l={id:i,replace:function(b,c){b=a.makeArray(b);var e=b[0];a.each(a.makeArray(d[i(e)]),function(d){var g=f[d],h=a.inArray(e,g),i=a.inArray(b[b.length-1],g);if(h>=0&&i>=0){for(var m=h;i>=m;m++){var n=g[m];j(n,d)}g.splice.apply(g,[h,i-h+1].concat(c)),a.each(c,function(a){k(a,d)})}else l.unregister(g)})},register:function(b){var c=i(b);f[c]=b,a.each(b,function(a){k(a,c)})},unregister:function(b){var c=i(b);a.each(b,function(a){j(a,c)}),delete f[c]},nodeMap:d,nodeListMap:f};return l}(__m3),__m16=function(a,b,c,d){var e=function(b,c,d){var e=function(){d(f),a.unbind.call(b,"destroyed",e)},f={teardownCheck:function(a){a||e()}};return a.bind.call(b,"destroyed",e),c(f),f},f=function(a,b,c){return e(a,function(){b.bind("change",c)},function(a){b.unbind("change",c),a.nodeList&&d.unregister(a.nodeList)})},g=function(a){return(a||"").replace(/['"]/g,"").split("=")};insertElementsAfter=function(a,b){var c=a[a.length-1];c.nextSibling?c.parentNode.insertBefore(b,c.nextSibling):c.parentNode.appendChild(b)};var h={nodeLists:d,list:function(c,f,g,h,i){var j=[],k=function(b,c,e){var f=document.createDocumentFragment(),k=[];if(a.each(c,function(b){var c=g.call(h,b),d=a.view.frag(c,i);k.push(a.makeArray(d.childNodes)),f.appendChild(d)}),j[e]){var l=j[e][0];l.parentNode.insertBefore(f,l)}else insertElementsAfter(0==e?[m]:j[e-1],f);a.each(k,function(a){d.register(a)}),[].splice.apply(j,[e,0].concat(k))},l=function(b,c,e){var f=j.splice(e,c.length),g=[];a.each(f,function(a){[].push.apply(g,a),d.replace(a,[]),d.unregister(a)}),a.remove(a.$(g))},i=b.getParentNode(c,i),m=document.createTextNode("");e(i,function(){f.bind("add",k).bind("remove",l)},function(){f.unbind("add",k).unbind("remove",l),a.each(j,function(a){d.unregister(a)})}),insertElementsAfter([c],m),a.remove(a.$(c)),k({},f,0)},html:function(c,e,g){var h,g=b.getParentNode(c,g),i=f(g,e,function(a,b){var c=h[0].parentNode;c&&j(b),i.teardownCheck(h[0].parentNode)}),j=function(b){var e=a.view.frag(b,g),f=a.makeArray(e.childNodes);if(insertElementsAfter(h||[c],e),h){var j=a.makeArray(h);d.replace(h,f),a.remove(a.$(j))}else a.remove(a.$(c)),h=f,i.nodeList=h,d.register(h)};j(e(),[c])},text:function(a,c,d){var e=b.getParentNode(a,d),g=f(a.parentNode!==e?a.parentNode:e,c,function(a,b){"unknown"!=typeof h.nodeValue&&(h.nodeValue=""+b),g.teardownCheck(h.parentNode)}),h=document.createTextNode(c());a.parentNode!==e?(e=a.parentNode,e.insertBefore(h,a),e.removeChild(a)):(e.insertBefore(h,a),e.removeChild(a))},attributes:function(a,c,d){var e=function(c){var d=g(c),e=d.shift();e!=h&&h&&b.removeAttr(a,h),e&&(b.setAttr(a,e,d.join("=")),h=e)};if(f(a,c,function(a,b){e(b)}),arguments.length>=3)var h=g(d)[0];else e(c())},attributePlaceholder:"__!!__",attributeReplace:/__!!__/g,attribute:function(c,d,e){f(c,e,function(){b.setAttr(c,d,j.render())});var g,i=a.$(c);g=a.data(i,"hooks"),g||a.data(i,"hooks",g={});var j,k=b.getAttr(c,d),l=k.split(h.attributePlaceholder),m=[];m.push(l.shift(),l.join(h.attributePlaceholder)),g[d]?g[d].computes.push(e):g[d]={render:function(){var a=0,c=k?k.replace(h.attributeReplace,function(){return b.contentText(j.computes[a++]())}):b.contentText(j.computes[a++]());return c},computes:[e],batchNum:undefined},j=g[d],m.splice(1,0,e()),b.setAttr(c,d,m.join(""))}};return h}(__m3,__m14,__m11,__m17),__m15=function(a,b,c){var d=[],e=function(a){var c=b.tagMap[a]||"span";return"span"===c?"@@!!@@":"<"+c+">"+e(c)+"</"+c+">"},f=function(b,c){if("string"==typeof b)return b;if(!b&&0!==b)return"";var e=b.hookup&&function(a,c){b.hookup.call(b,a,c)}||"function"==typeof b&&b;return e?c?"<"+c+" "+a.view.hook(e)+"></"+c+">":(d.push(e),""):""+b},g=function(b){return"string"==typeof b||"number"==typeof b?a.esc(b):f(b)};return a.extend(a.view,{live:c,setupLists:function(){var b,c=a.view.lists;return a.view.lists=function(a,c){b={list:a,renderer:c}},function(){return a.view.lists=c,b}},pending:function(){var b=d.slice(0);return lastHookups=b,d=[],a.view.hook(function(c){a.each(b,function(a){a(c)})})},txt:function(h,i,j,k,l){var m=a.view.setupLists(),n=function(){},o=function(){p.unbind("change",n)},p=a.compute(l,k,!1);p.bind("change",n);var q=b.tagMap[i]||"span",r=m(),s=p();if(r)return"<"+q+a.view.hook(function(a,b){c.list(a,r.list,r.renderer,k,b)})+"></"+q+">";if(!p.hasDependencies)return o(),(h||0!==j?g:f)(s,0===j&&q);var t=b.tagToContentPropMap[i];if(0!==j||t){if(1===j)return d.push(function(a){c.attributes(a,p,p()),o()}),p();var u=0===j?t:j;return(0===j?lastHookups:d).push(function(a){c.attribute(a,u,p),o()
+}),c.attributePlaceholder}return"<"+q+a.view.hook(h?function(a,b){c.text(a,p,b),o()}:function(a,b){c.html(a,p,b),o()})+">"+e(q)+"</"+q+">"}}),a}(__m11,__m14,__m16,__m2),__m12=function(a){var b=a.extend,c=function(a){if(this.constructor!=c){var d=new c(a);return function(a,b){return d.render(a,b)}}return"function"==typeof a?(this.template={fn:a},void 0):(b(this,a),this.template=this.scanner.scan(this.text,this.name),void 0)};return a.EJS=c,c.prototype.render=function(a,b){return a=a||{},this.template.fn.call(a,a,new c.Helpers(a,b||{}))},b(c.prototype,{scanner:new a.view.Scanner({tokens:[["templateLeft","<%%"],["templateRight","%>"],["returnLeft","<%=="],["escapeLeft","<%="],["commentLeft","<%#"],["left","<%"],["right","%>"],["returnRight","%>"]],transform:function(a){return a.replace(/<%([\s\S]+?)%>/gm,function(a,b){var c,d,e=[];b.replace(/[{}]/gm,function(a,b){e.push([a,b])});do for(c=!1,d=e.length-2;d>=0;d--)if("{"==e[d][0]&&"}"==e[d+1][0]){e.splice(d,2),c=!0;break}while(c);if(e.length>=2){var f,g=["<%"],h=0;for(d=0;f=e[d];d++)g.push(b.substring(h,h=f[1])),"{"==f[0]&&d<e.length-1||"}"==f[0]&&d>0?g.push("{"==f[0]?"{ %><% ":" %><% }"):g.push(f[0]),++h;return g.push(b.substring(h),"%>"),g.join("")}return"<%"+b+"%>"})}})}),c.Helpers=function(a,c){this._data=a,this._extras=c,b(this,c)},c.Helpers.prototype={list:function(b,c){a.each(b,function(a,d){c(a,d,b)})},each:function(b,c){a.isArray(b)?this.list(b,c):a.view.lists(b,c)}},a.view.register({suffix:"ejs",script:function(a,b){return"can.EJS(function(_CONTEXT,_VIEW) { "+new c({text:b,name:a}).template.out+" })"},renderer:function(a,b){return c({text:b,name:a})}}),a}(__m3,__m11,__m2,__m9,__m13,__m15),__m18=function(a){var b,c=function(b,c,d){return a.bind.call(b,c,d),function(){a.unbind.call(b,c,d)}},d=a.isFunction,e=a.extend,f=a.each,g=[].slice,h=/\{([^\}]+)\}/g,i=a.getObject("$.event.special",[a])||{},j=function(b,c,d,e){return a.delegate.call(b,c,d,e),function(){a.undelegate.call(b,c,d,e)}},k=function(b,d,e,f){return f?j(b,a.trim(f),d,e):c(b,d,e)},l=a.Control=a.Construct({setup:function(){if(a.Construct.setup.apply(this,arguments),a.Control){var b,c=this;c.actions={};for(b in c.prototype)c._isAction(b)&&(c.actions[b]=c._action(b))}},_shifter:function(b,c){var e="string"==typeof c?b[c]:c;return d(e)||(e=b[e]),function(){return b.called=c,e.apply(b,[this.nodeName?a.$(this):this].concat(g.call(arguments,0)))}},_isAction:function(a){var b=this.prototype[a],c=typeof b;return"constructor"!==a&&("function"==c||"string"==c&&d(this.prototype[b]))&&!!(i[a]||m[a]||/[^\w]/.test(a))},_action:function(c,d){if(h.lastIndex=0,d||!h.test(c)){var e=d?a.sub(c,[d,window]):c;if(!e)return null;var f=a.isArray(e),g=f?e[1]:e,i=g.split(/\s+/g),j=i.pop();return{processor:m[j]||b,parts:[g,i.join(" "),j],delegate:f?e[0]:undefined}}},processors:{},defaults:{}},{setup:function(b,c){var d,f=this.constructor,g=f.pluginName||f._fullName;return this.element=a.$(b),g&&"can_control"!==g&&this.element.addClass(g),(d=a.data(this.element,"controls"))||a.data(this.element,"controls",d=[]),d.push(this),this.options=e({},f.defaults,c),this.on(),[this.element,this.options]},on:function(b,c,d,e){if(!b){this.off();var f,g,h=this.constructor,i=this._bindings,j=h.actions,l=this.element,m=a.Control._shifter(this,"destroy");for(f in j)j.hasOwnProperty(f)&&(g=j[f]||h._action(f,this.options))&&i.push(g.processor(g.delegate||l,g.parts[2],g.parts[1],f,this));return a.bind.call(l,"destroyed",m),i.push(function(b){a.unbind.call(b,"destroyed",m)}),i.length}return"string"==typeof b&&(e=d,d=c,c=b,b=this.element),e===undefined&&(e=d,d=c,c=null),"string"==typeof e&&(e=a.Control._shifter(this,e)),this._bindings.push(k(b,d,e,c)),this._bindings.length},off:function(){var a=this.element[0];f(this._bindings||[],function(b){b(a)}),this._bindings=[]},destroy:function(){if(null!==this.element){var b,c=this.constructor,d=c.pluginName||c._fullName;this.off(),d&&"can_control"!==d&&this.element.removeClass(d),b=a.data(this.element,"controls"),b.splice(a.inArray(this,b),1),a.trigger(this,"destroyed"),this.element=null}}}),m=a.Control.processors,b=function(b,c,d,e,f){return k(b,c,a.Control._shifter(f,e),d)};return f(["change","click","contextmenu","dblclick","keydown","keyup","keypress","mousedown","mousemove","mouseout","mouseover","mouseup","reset","resize","scroll","select","submit","focusin","focusout","mouseenter","mouseleave","touchstart","touchmove","touchcancel","touchend","touchleave"],function(a){m[a]=b}),l}(__m3,__m1),__m20=function(a){var b=/^\d+$/,c=/([^\[\]]+)|(\[\])/g,d=/([^?#]*)(#.*)?$/,e=function(a){return decodeURIComponent(a.replace(/\+/g," "))};return a.extend(a,{deparam:function(f){var g,h,i={};return f&&d.test(f)&&(g=f.split("&"),a.each(g,function(a){var d=a.split("="),f=e(d.shift()),g=e(d.join("=")),j=i;if(f){d=f.match(c);for(var k=0,l=d.length-1;l>k;k++)j[d[k]]||(j[d[k]]=b.test(d[k+1])||"[]"==d[k+1]?[]:{}),j=j[d[k]];h=d.pop(),"[]"==h?j.push(g):j[h]=g}})),i}}),a}(__m3,__m2),__m19=function(a){var b=/\:([\w\.]+)/g,c=/^(?:&[^=]+=[^&]*)+/,d=function(b){var c=[];return a.each(b,function(b,d){c.push(("className"===d?"class":d)+'="'+("href"===d?b:a.esc(b))+'"')}),c.join(" ")},e=function(a,b){var c=0,d=0,e={};for(var f in a.defaults)a.defaults[f]===b[f]&&(e[f]=1,c++);for(;d<a.names.length;d++){if(!b.hasOwnProperty(a.names[d]))return-1;e[a.names[d]]||c++}return c},f=!0,g=window.location,h=function(a){return(a+"").replace(/([.?*+\^$\[\]\\(){}|\-])/g,"\\$1")},i=a.each,j=a.extend;a.route=function(c,d){d=d||{};var e=[],f=c.replace(b,function(b,f,g){e.push(f);var h="\\"+(c.substr(g+b.length,1)||a.route._querySeparator);return"([^"+h+"]"+(d[f]?"*":"+")+")"});return a.route.routes[c]={test:new RegExp("^"+f+"($|"+h(a.route._querySeparator)+")"),route:c,names:e,defaults:d,length:c.split("/").length},a.route},j(a.route,{_querySeparator:"&",_paramsMatcher:c,param:function(c,d){var f,g,h=0,k=c.route,l=0;if(delete c.route,i(c,function(){l++}),i(a.route.routes,function(a){return g=e(a,c),g>h&&(f=a,h=g),g>=l?!1:void 0}),a.route.routes[k]&&e(a.route.routes[k],c)===h&&(f=a.route.routes[k]),f){var m,n=j({},c),o=f.route.replace(b,function(a,b){return delete n[b],c[b]===f.defaults[b]?"":encodeURIComponent(c[b])});return i(f.defaults,function(a,b){n[b]===a&&delete n[b]}),m=a.param(n),d&&a.route.attr("route",f.route),o+(m?a.route._querySeparator+m:"")}return a.isEmptyObject(c)?"":a.route._querySeparator+a.param(c)},deparam:function(b){var c={length:-1};if(i(a.route.routes,function(a){a.test.test(b)&&a.length>c.length&&(c=a)}),c.length>-1){var d=b.match(c.test),e=d.shift(),f=b.substr(e.length-(d[d.length-1]===a.route._querySeparator?1:0)),g=f&&a.route._paramsMatcher.test(f)?a.deparam(f.slice(1)):{};return g=j(!0,{},c.defaults,g),i(d,function(b,d){b&&b!==a.route._querySeparator&&(g[c.names[d]]=decodeURIComponent(b))}),g.route=c.route,g}return b.charAt(0)!==a.route._querySeparator&&(b=a.route._querySeparator+b),a.route._paramsMatcher.test(b)?a.deparam(b.slice(1)):{}},data:new a.Observe({}),routes:{},ready:function(b){return b===!1&&(f=b),(b===!0||f===!0)&&(a.route._setup(),o()),a.route},url:function(b,c){return c&&(b=j({},l,b)),"#!"+a.route.param(b)},link:function(b,c,e,f){return"<a "+d(j({href:a.route.url(c,f)},e))+">"+b+"</a>"},current:function(b){return g.hash=="#!"+a.route.param(b)},_setup:function(){a.bind.call(window,"hashchange",o)},_getHash:function(){return g.href.split(/#!?/)[1]||""},_setHash:function(b){var c=a.route.param(b,!0);return g.hash="#!"+c,c}}),i(["bind","unbind","delegate","undelegate","attr","removeAttr"],function(b){a.route[b]=function(){return a.route.data[b]?a.route.data[b].apply(a.route.data,arguments):void 0}});var k,l,m,n,o=a.route.setState=function(){var b=a.route._getHash();l=a.route.deparam(b),n&&b===m||a.route.attr(l,!0)};return a.route.bind("change",function(){n=1,clearTimeout(k),k=setTimeout(function(){n=0;var b=a.route.data.serialize();m=a.route._setHash(b)},1)}),a.bind.call(document,"ready",a.route.ready),"complete"!==document.readyState&&"interactive"!==document.readyState||!f||a.route.ready(),a.route.constructor.canMakeObserve=a.Observe.canMakeObserve,a.route}(__m3,__m7,__m20),__m21=function(a){return a.Control.processors.route=function(b,c,d,e,f){d=d||"",a.route(d);var g,h=function(b){if(a.route.attr("route")===d&&(b.batchNum===undefined||b.batchNum!==g)){g=b.batchNum;var c=a.route.attr();delete c.route,a.isFunction(f[e])?f[e](c):f[f[e]](c)}};return a.route.bind("change",h),function(){a.route.unbind("change",h)}},a}(__m3,__m19,__m18);window.can=__m5}();
\ No newline at end of file
Added: html5videoplayer/js/libs/can.object.js
===================================================================
--- html5videoplayer/js/libs/can.object.js (rev 0)
+++ html5videoplayer/js/libs/can.object.js 2013-06-07 16:16:19 UTC (rev 660)
@@ -0,0 +1,137 @@
+/*!
+ * CanJS - 1.1.6
+ * http://canjs.us/
+ * Copyright (c) 2013 Bitovi
+ * Wed, 29 May 2013 18:59:29 GMT
+ * Licensed MIT
+ * Includes: can/util/object
+ * Download from: http://canjs.com
+ */
+(function(can) {
+
+ var isArray = can.isArray,
+ // essentially returns an object that has all the must have comparisons ...
+ // must haves, do not return true when provided undefined
+ cleanSet = function(obj, compares) {
+ var copy = can.extend({}, obj);
+ for (var prop in copy) {
+ var compare = compares[prop] === undefined ? compares["*"] : compares[prop];
+ if (same(copy[prop], undefined, compare)) {
+ delete copy[prop]
+ }
+ }
+ return copy;
+ },
+ propCount = function(obj) {
+ var count = 0;
+ for (var prop in obj) count++;
+ return count;
+ };
+
+ can.Object = {};
+
+ var same = can.Object.same = function(a, b, compares, aParent, bParent, deep) {
+ var aType = typeof a,
+ aArray = isArray(a),
+ comparesType = typeof compares,
+ compare;
+
+ if (comparesType == 'string' || compares === null) {
+ compares = compareMethods[compares];
+ comparesType = 'function'
+ }
+ if (comparesType == 'function') {
+ return compares(a, b, aParent, bParent)
+ }
+ compares = compares || {};
+
+ if (a instanceof Date) {
+ return a === b;
+ }
+ if (deep === -1) {
+ return aType === 'object' || a === b;
+ }
+ if (aType !== typeof b || aArray !== isArray(b)) {
+ return false;
+ }
+ if (a === b) {
+ return true;
+ }
+ if (aArray) {
+ if (a.length !== b.length) {
+ return false;
+ }
+ for (var i = 0; i < a.length; i++) {
+ compare = compares[i] === undefined ? compares["*"] : compares[i]
+ if (!same(a[i], b[i], a, b, compare)) {
+ return false;
+ }
+ };
+ return true;
+ } else if (aType === "object" || aType === 'function') {
+ var bCopy = can.extend({}, b);
+ for (var prop in a) {
+ compare = compares[prop] === undefined ? compares["*"] : compares[prop];
+ if (!same(a[prop], b[prop], compare, a, b, deep === false ? -1 : undefined)) {
+ return false;
+ }
+ delete bCopy[prop];
+ }
+ // go through bCopy props ... if there is no compare .. return false
+ for (prop in bCopy) {
+ if (compares[prop] === undefined || !same(undefined, b[prop], compares[prop], a, b, deep === false ? -1 : undefined)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ };
+
+ can.Object.subsets = function(checkSet, sets, compares) {
+ var len = sets.length,
+ subsets = [],
+ checkPropCount = propCount(checkSet),
+ setLength;
+
+ for (var i = 0; i < len; i++) {
+ //check this subset
+ var set = sets[i];
+ if (can.Object.subset(checkSet, set, compares)) {
+ subsets.push(set)
+ }
+ }
+ return subsets;
+ };
+
+ can.Object.subset = function(subset, set, compares) {
+ // go through set {type: 'folder'} and make sure every property
+ // is in subset {type: 'folder', parentId :5}
+ // then make sure that set has fewer properties
+ // make sure we are only checking 'important' properties
+ // in subset (ones that have to have a value)
+
+ var setPropCount = 0,
+ compares = compares || {};
+
+ for (var prop in set) {
+
+ if (!same(subset[prop], set[prop], compares[prop], subset, set)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ var compareMethods = {
+ "null": function() {
+ return true;
+ },
+ i: function(a, b) {
+ return ("" + a).toLowerCase() == ("" + b).toLowerCase()
+ }
+ }
+
+ return can.Object;
+
+ })(can);
\ No newline at end of file
Added: html5videoplayer/js/libs/can.observe.attributes.js
===================================================================
--- html5videoplayer/js/libs/can.observe.attributes.js (rev 0)
+++ html5videoplayer/js/libs/can.observe.attributes.js 2013-06-07 16:16:19 UTC (rev 660)
@@ -0,0 +1,174 @@
+/*!
+ * CanJS - 1.1.6
+ * http://canjs.us/
+ * Copyright (c) 2013 Bitovi
+ * Wed, 29 May 2013 18:59:29 GMT
+ * Licensed MIT
+ * Includes: can/observe/attributes
+ * Download from: http://canjs.com
+ */
+(function(can, Observe) {
+
+ can.each([can.Observe, can.Model], function(clss) {
+ // in some cases model might not be defined quite yet.
+ if (clss === undefined) {
+ return;
+ }
+ var isObject = function(obj) {
+ return typeof obj === 'object' && obj !== null && obj;
+ };
+
+ can.extend(clss, {
+
+ attributes: {},
+
+
+ convert: {
+ "date": function(str) {
+ var type = typeof str;
+ if (type === "string") {
+ return isNaN(Date.parse(str)) ? null : Date.parse(str)
+ } else if (type === 'number') {
+ return new Date(str)
+ } else {
+ return str
+ }
+ },
+ "number": function(val) {
+ return parseFloat(val);
+ },
+ "boolean": function(val) {
+ if (val === 'false' || val === '0' || !val) {
+ return false;
+ }
+ return true;
+ },
+ "default": function(val, oldVal, error, type) {
+ var construct = can.getObject(type),
+ context = window,
+ realType;
+ // if type has a . we need to look it up
+ if (type.indexOf(".") >= 0) {
+ // get everything before the last .
+ realType = type.substring(0, type.lastIndexOf("."));
+ // get the object before the last .
+ context = can.getObject(realType);
+ }
+ return typeof construct == "function" ? construct.call(context, val, oldVal) : val;
+ }
+ },
+
+ serialize: {
+ "default": function(val, type) {
+ return isObject(val) && val.serialize ? val.serialize() : val;
+ },
+ "date": function(val) {
+ return val && val.getTime()
+ }
+ }
+ });
+
+ // overwrite setup to do this stuff
+ var oldSetup = clss.setup;
+
+
+ clss.setup = function(superClass, stat, proto) {
+ var self = this;
+ oldSetup.call(self, superClass, stat, proto);
+
+ can.each(["attributes"], function(name) {
+ if (!self[name] || superClass[name] === self[name]) {
+ self[name] = {};
+ }
+ });
+
+ can.each(["convert", "serialize"], function(name) {
+ if (superClass[name] != self[name]) {
+ self[name] = can.extend({}, superClass[name], self[name]);
+ }
+ });
+ };
+ });
+
+ var oldSetup = can.Observe.prototype.setup;
+
+ can.Observe.prototype.setup = function(obj) {
+
+ var diff = {};
+
+ oldSetup.call(this, obj);
+
+ can.each(this.constructor.defaults, function(value, key) {
+ if (!this.hasOwnProperty(key)) {
+ diff[key] = value;
+ }
+ }, this);
+
+ this._init = 1;
+ this.attr(diff);
+ delete this._init;
+ };
+
+ can.Observe.prototype.__convert = function(prop, value) {
+ // check if there is a
+
+ var Class = this.constructor,
+ oldVal = this.attr(prop),
+ type, converter;
+
+ if (Class.attributes) {
+ // the type of the attribute
+ type = Class.attributes[prop];
+ converter = Class.convert[type] || Class.convert['default'];
+ }
+
+ return value === null || !type ?
+ // just use the value
+ value :
+ // otherwise, pass to the converter
+ converter.call(Class, value, oldVal, function() {}, type);
+ };
+
+ can.Observe.prototype.serialize = function(attrName, stack) {
+ var where = {},
+ Class = this.constructor,
+ attrs = {};
+
+ stack = can.isArray(stack) ? stack : [];
+ stack.push(this._cid);
+
+ if (attrName !== undefined) {
+ attrs[attrName] = this[attrName];
+ } else {
+ attrs = this.__get();
+ }
+
+ can.each(attrs, function(val, name) {
+ var type, converter;
+
+ // If this is an observe, check that it wasn't serialized earlier in the stack.
+ if (val instanceof can.Observe && can.inArray(val._cid, stack) > -1) {
+ // Since this object has already been serialized once,
+ // just reference the id (or undefined if it doesn't exist).
+ where[name] = val.attr('id');
+ } else {
+ type = Class.attributes ? Class.attributes[name] : 0;
+ converter = Class.serialize ? Class.serialize[type] : 0;
+
+ // if the value is an object, and has a attrs or serialize function
+ where[name] = val && typeof val.serialize == 'function' ?
+ // call attrs or serialize to get the original data back
+ val.serialize(undefined, stack) :
+ // otherwise if we have a converter
+ converter ?
+ // use the converter
+ converter(val, type) :
+ // or return the val
+ val;
+ }
+ });
+
+ return attrName != undefined ? where[attrName] : where;
+ };
+ return can.Observe;
+ })(can);
\ No newline at end of file
Added: html5videoplayer/js/libs/can.observe.delegate.js
===================================================================
--- html5videoplayer/js/libs/can.observe.delegate.js (rev 0)
+++ html5videoplayer/js/libs/can.observe.delegate.js 2013-06-07 16:16:19 UTC (rev 660)
@@ -0,0 +1,215 @@
+/*!
+ * CanJS - 1.1.6
+ * http://canjs.us/
+ * Copyright (c) 2013 Bitovi
+ * Wed, 29 May 2013 18:59:29 GMT
+ * Licensed MIT
+ * Includes: can/observe/delegate
+ * Download from: http://canjs.com
+ */
+(function(can) {
+
+
+
+ // ** - 'this' will be the deepest item changed
+ // * - 'this' will be any changes within *, but * will be the
+ // this returned
+
+ // tells if the parts part of a delegate matches the broken up props of the event
+ // gives the prop to use as 'this'
+ // - parts - the attribute name of the delegate split in parts ['foo','*']
+ // - props - the split props of the event that happened ['foo','bar','0']
+ // - returns - the attribute to delegate too ('foo.bar'), or null if not a match
+ var delegateMatches = function(parts, props) {
+ //check props parts are the same or
+ var len = parts.length,
+ i = 0,
+ // keeps the matched props we will use
+ matchedProps = [],
+ prop;
+
+ // if the event matches
+ for (i; i < len; i++) {
+ prop = props[i]
+ // if no more props (but we should be matching them)
+ // return null
+ if (typeof prop !== 'string') {
+ return null;
+ } else
+ // if we have a "**", match everything
+ if (parts[i] == "**") {
+ return props.join(".");
+ } else
+ // a match, but we want to delegate to "*"
+ if (parts[i] == "*") {
+ // only do this if there is nothing after ...
+ matchedProps.push(prop);
+ } else if (prop === parts[i]) {
+ matchedProps.push(prop);
+ } else {
+ return null;
+ }
+ }
+ return matchedProps.join(".");
+ },
+ // gets a change event and tries to figure out which
+ // delegates to call
+ delegateHandler = function(event, prop, how, newVal, oldVal) {
+ // pre-split properties to save some regexp time
+ var props = prop.split("."),
+ delegates = (this._observe_delegates || []).slice(0),
+ delegate,
+ attr,
+ matchedAttr,
+ hasMatch,
+ valuesEqual;
+ event.attr = prop;
+ event.lastAttr = props[props.length - 1];
+
+ // for each delegate
+ for (var i = 0; delegate = delegates[i++];) {
+
+ // if there is a batchNum, this means that this
+ // event is part of a series of events caused by a single
+ // attrs call. We don't want to issue the same event
+ // multiple times
+ // setting the batchNum happens later
+ if ((event.batchNum && delegate.batchNum === event.batchNum) || delegate.undelegated) {
+ continue;
+ }
+
+ // reset match and values tests
+ hasMatch = undefined;
+ valuesEqual = true;
+
+ // yeah, all this under here has to be redone v
+
+ // for each attr in a delegate
+ for (var a = 0; a < delegate.attrs.length; a++) {
+
+ attr = delegate.attrs[a];
+
+ // check if it is a match
+ if (matchedAttr = delegateMatches(attr.parts, props)) {
+ hasMatch = matchedAttr;
+ }
+ // if it has a value, make sure it's the right value
+ // if it's set, we should probably check that it has a
+ // value no matter what
+ if (attr.value && valuesEqual) {
+ valuesEqual = attr.value === "" + this.attr(attr.attr)
+ } else if (valuesEqual && delegate.attrs.length > 1) {
+ // if there are multiple attributes, each has to at
+ // least have some value
+ valuesEqual = this.attr(attr.attr) !== undefined
+ }
+ }
+
+
+ // if there is a match and valuesEqual ... call back
+ if (hasMatch && valuesEqual) {
+ // how to get to the changed property from the delegate
+ var from = prop.replace(hasMatch + ".", "");
+
+ // if this event is part of a batch, set it on the delegate
+ // to only send one event
+ if (event.batchNum) {
+ delegate.batchNum = event.batchNum
+ }
+
+ // if we listen to change, fire those with the same attrs
+ // TODO: the attrs should probably be using from
+ if (delegate.event === 'change') {
+ arguments[1] = from;
+ event.curAttr = hasMatch;
+ delegate.callback.apply(this.attr(hasMatch), can.makeArray(arguments));
+ } else if (delegate.event === how) {
+
+ // if it's a match, callback with the location of the match
+ delegate.callback.apply(this.attr(hasMatch), [event, newVal, oldVal, from]);
+ } else if (delegate.event === 'set' &&
+ how == 'add') {
+ // if we are listening to set, we should also listen to add
+ delegate.callback.apply(this.attr(hasMatch), [event, newVal, oldVal, from]);
+ }
+ }
+
+ }
+ };
+
+ can.extend(can.Observe.prototype, {
+
+ delegate: function(selector, event, handler) {
+ selector = can.trim(selector);
+ var delegates = this._observe_delegates || (this._observe_delegates = []),
+ attrs = [],
+ selectorRegex = /([^\s=,]+)(?:=("[^",]*"|'[^',]*'|[^\s"',]*))?(,?)\s*/g,
+ matches;
+
+ // parse each property in the selector
+ while (matches = selectorRegex.exec(selector)) {
+ // we need to do a little doctoring to make up for the quotes.
+ if (matches[2] && can.inArray(matches[2].substr(0, 1), ['"', "'"]) >= 0) {
+ matches[2] = matches[2].substr(1, -1);
+ }
+
+ attrs.push({
+ // the attribute name
+ attr: matches[1],
+ // the attribute name, pre-split for speed
+ parts: matches[1].split('.'),
+ // the value associated with this property (if there was one given)
+ value: matches[2],
+ // whether this selector combines with the one after it with AND or OR
+ or: matches[3] === ','
+ });
+ }
+
+ // delegates has pre-processed info about the event
+ delegates.push({
+ // the attrs name for unbinding
+ selector: selector,
+ // an object of attribute names and values {type: 'recipe',id: undefined}
+ // undefined means a value was not defined
+ attrs: attrs,
+ callback: handler,
+ event: event
+ });
+ if (delegates.length === 1) {
+ this.bind("change", delegateHandler)
+ }
+ return this;
+ },
+
+ undelegate: function(selector, event, handler) {
+ selector = selector && can.trim(selector);
+
+ var i = 0,
+ delegates = this._observe_delegates || [],
+ delegateOb;
+ if (selector) {
+ while (i < delegates.length) {
+ delegateOb = delegates[i];
+ if (delegateOb.callback === handler ||
+ (!handler && delegateOb.selector === selector)) {
+ delegateOb.undelegated = true;
+ delegates.splice(i, 1)
+ } else {
+ i++;
+ }
+ }
+ } else {
+ // remove all delegates
+ delegates = [];
+ }
+ if (!delegates.length) {
+ //can.removeData(this, "_observe_delegates");
+ this.unbind("change", delegateHandler)
+ }
+ return this;
+ }
+ });
+ // add helpers for testing ..
+ can.Observe.prototype.delegate.matches = delegateMatches;
+ return can.Observe;
+ })(can);
\ No newline at end of file
Added: html5videoplayer/js/models/comments.js
===================================================================
--- html5videoplayer/js/models/comments.js (rev 0)
+++ html5videoplayer/js/models/comments.js 2013-06-07 16:16:19 UTC (rev 660)
@@ -0,0 +1,48 @@
+var Comment = can.Model({
+ findAll: 'GET /poll/{pollId}/comments',
+// findOne: 'GET /comments/{commentId}',
+ create : "POST /polls/{pollId}/comments",
+ update : "PUT /comments",
+ destroy : "DELETE /comments/{commentId}"
+},{});
+
+var COMMENTS = [
+ [{
+ text: "This is the end of the world",
+ author: "Maya",
+ postDate: "21/12/12"
+ },{
+ text: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.",
+ author: "Sacha",
+ postDate: "03/12/11"
+ }],
+ [{
+ text: "azztyuiopfghj",
+ author: "yyy",
+ postDate: ""
+ },{
+ text: "aqwxszedv",
+ author: "sdsqdqsdqsdqdqsd",
+ postDate: ""
+ }]
+];
+
+can.fixture('GET /poll/{pollId}/comments', function(orig) {
+ return COMMENTS[orig.data.pollId - 1];
+});
+
+var idToInc= 3;
+can.fixture("POST /polls/{pollId}/comments", function() {
+ console.log("create comment " + idToInc);
+ return {id: (idToInc++)}
+});
+
+can.fixture("PUT /comments", function(orig) {
+ console.log("update comment " + orig.data.id);
+ return {};
+});
+
+can.fixture("DELETE /comments/{commentId}", function(orig){
+ console.log("delete comment " + orig.data.commentId);
+ return {};
+});
\ No newline at end of file
Copied: html5videoplayer/js/models/polls.js (from rev 653, html5videoplayer/js/models/video.js)
===================================================================
--- html5videoplayer/js/models/polls.js (rev 0)
+++ html5videoplayer/js/models/polls.js 2013-06-07 16:16:19 UTC (rev 660)
@@ -0,0 +1,70 @@
+var Poll = can.Model({
+ findAll: 'GET /polls',
+ findOne: "GET /polls/{id}",
+ create : "POST /polls",
+ update : "PUT /polls/{id}",
+ destroy : "DELETE /polls/{id}"
+},{});
+
+var POLLS = [
+ {
+ id: 1,
+ title: 'Titre 1',
+ description: "Desc 1",
+ creatorName: "Kevin",
+ choices: [
+ {
+ id: 1,
+ name: "Choix 1",
+ description: "desc du choix 1"
+ },
+ {
+ id: 2,
+ name: "Choix 2",
+ description: "desc du choix 2"
+ }
+ ]
+ },
+ {
+ id: 2,
+ title: 'Lorem Ipsum',
+ description: "description très longue, mais vraiment très longue pour qu'elle passe en dessous. Enfin j'espère que ce sera assez long",
+ creatorName: "moi",
+ choices: [
+ {
+ id: 3,
+ name: "Choix 1",
+ description: "desc du choix 1"
+ },
+ {
+ id: 4,
+ name: "Choix 2",
+ description: "desc du choix 2"
+ }
+ ]
+ },
+];
+
+can.fixture('GET /polls', function(){
+ return POLLS;
+});
+
+can.fixture('GET /polls/{id}', function(orig) {
+ return POLLS[orig.data.id - 1];
+});
+
+var idToInc= 3;
+can.fixture("POST /polls", function() {
+ console.log("create poll " + idToInc);
+ return {id: (idToInc++)}
+});
+
+can.fixture("PUT /polls/{id}", function(orig) {
+ console.log("update poll " + orig.data.id);
+ return {};
+});
+
+can.fixture("DELETE /polls/{id}", function(orig){
+ console.log("delete poll " + orig.data.id);
+ return {};
+});
Deleted: html5videoplayer/js/models/video.js
===================================================================
--- html5videoplayer/js/models/video.js 2013-06-07 15:15:29 UTC (rev 659)
+++ html5videoplayer/js/models/video.js 2013-06-07 16:16:19 UTC (rev 660)
@@ -1,20 +0,0 @@
-var videos = new can.Observe.List([
- {
- thumb: "http://media.w3.org/2010/05/sintel/poster.png",
- mp4: "http://media.w3.org/2010/05/sintel/trailer.mp4",
- ogv: "http://media.w3.org/2010/05/sintel/trailer.ogv",
- webm: "http://media.w3.org/2010/05/sintel/trailer.webm"
- },
- {
- thumb: "http://media.w3.org/2010/05/bunny/poster.png",
- mp4: "http://media.w3.org/2010/05/bunny/trailer.mp4",
- ogv: "http://media.w3.org/2010/05/bunny/trailer.ogv",
- webm: "http://media.w3.org/2010/05/bunny/trailer.webm"
- },
- {
- thumb: "http://media.w3.org/2010/05/video/poster.png",
- mp4: "http://media.w3.org/2010/05/video/movie_300.mp4",
- ogv: "http://media.w3.org/2010/05/video/movie_300.ogv",
- webm: "http://media.w3.org/2010/05/video/movie_300.webm"
- }
-]);
\ No newline at end of file
Added: html5videoplayer/js/models/votes.js
===================================================================
--- html5videoplayer/js/models/votes.js (rev 0)
+++ html5videoplayer/js/models/votes.js 2013-06-07 16:16:19 UTC (rev 660)
@@ -0,0 +1,138 @@
+var Vote = can.Model({
+ findAll: 'GET /poll/{pollId}/votes',
+// findOne: 'GET /comments/{commentId}',
+ create : "POST /poll/{pollId}/votes",
+ update : "PUT /votes",
+ destroy : "DELETE /votes/{voteId}"
+},{});
+
+var VOTES = [
+ [{
+ id: 1,
+ voterListMember: {
+ name: "Joe",
+ email: "joe(a)dalt.on"
+ },
+ voteToChoices: [{
+ voteValue: 0,
+ choice: 1
+ },{
+ voteValue: 0,
+ choice: 2
+ }]
+
+ }, {
+ id: 2,
+ voterListMember: {
+ name: "Jack",
+ email: "jack(a)dalt.on"
+ },
+ voteToChoices: [{
+ voteValue: 1,
+ choice: 1
+ },{
+ voteValue: 1,
+ choice: 2
+ }]
+ },{
+ id: 3,
+ voterListMember: {
+ name: "William",
+ email: "william(a)dalt.on"
+ },
+ voteToChoices: [{
+ voteValue: 1,
+ choice: 1
+ },{
+ voteValue: 0,
+ choice: 2
+ }]
+ }, {
+ id: 4,
+ voterListMember: {
+ name: "Avrel",
+ email: "avrel(a)dalt.on"
+ },
+ voteToChoices: [{
+ voteValue: 0,
+ choice: 1
+ },{
+ voteValue: 1,
+ choice: 2
+ }]
+ }],
+ [{
+ id: 5,
+ voterListMember: {
+ name: "Joe",
+ email: "joe(a)dalt.on"
+ },
+ voteToChoices: [{
+ voteValue: 0,
+ choice: 3
+ },{
+ voteValue: 0,
+ choice: 4
+ }]
+
+ }, {
+ id: 6,
+ voterListMember: {
+ name: "Jack",
+ email: "jack(a)dalt.on"
+ },
+ voteToChoices: [{
+ voteValue: 1,
+ choice: 3
+ },{
+ voteValue: 1,
+ choice: 4
+ }]
+ },{
+ id: 7,
+ voterListMember: {
+ name: "William",
+ email: "william(a)dalt.on"
+ },
+ voteToChoices: [{
+ voteValue: 1,
+ choice: 3
+ },{
+ voteValue: 0,
+ choice: 4
+ }]
+ }, {
+ id: 8,
+ voterListMember: {
+ name: "Avrel",
+ email: "avrel(a)dalt.on"
+ },
+ voteToChoices: [{
+ voteValue: 0,
+ choice: 3
+ },{
+ voteValue: 1,
+ choice: 4
+ }]
+ }]
+];
+
+can.fixture('GET /poll/{pollId}/votes', function(orig) {
+ return VOTES[orig.data.pollId - 1];
+});
+
+var idToInc= 3;
+can.fixture("POST /polls/{pollId}/votes", function() {
+ console.log("create vote " + idToInc);
+ return {id: (idToInc++)}
+});
+
+can.fixture("PUT /votes", function(orig) {
+ console.log("update vote " + orig.data.id);
+ return {};
+});
+
+can.fixture("DELETE /votes/{voteId}", function(orig){
+ console.log("delete vote " + orig.data.vote);
+ return {};
+});
\ No newline at end of file
Added: html5videoplayer/js/route.js
===================================================================
--- html5videoplayer/js/route.js (rev 0)
+++ html5videoplayer/js/route.js 2013-06-07 16:16:19 UTC (rev 660)
@@ -0,0 +1,14 @@
+var Routing = can.Control({
+ 'route': function() {
+ // Matches every routing change, but gets passed no data.
+ console.log("route")
+ },
+
+ ':type route': function(data) {
+ console.log(":type route " + data)
+ },
+
+ ':type/:id route': function(data) {
+ console.log(":type/:id route" + data)
+ }
+})
\ No newline at end of file
Added: html5videoplayer/views/menu.ejs
===================================================================
--- html5videoplayer/views/menu.ejs (rev 0)
+++ html5videoplayer/views/menu.ejs 2013-06-07 16:16:19 UTC (rev 660)
@@ -0,0 +1,4 @@
+<ul>
+ <li><%== can.route.link('Sondage', { type: 'poll', action: 'edit' }) %></li>
+ <li><%== can.route.link('Autre', { type: 'other', action: 'donothing' }) %></li>
+</ul>
\ No newline at end of file
Added: html5videoplayer/views/poll_form.ejs
===================================================================
--- html5videoplayer/views/poll_form.ejs (rev 0)
+++ html5videoplayer/views/poll_form.ejs 2013-06-07 16:16:19 UTC (rev 660)
@@ -0,0 +1,30 @@
+<h1>Création de sondage</h1>
+
+<form id='pollCreationForm' class="form-horizontal">
+
+ <div class="control-group">
+ <label class="control-label" for="pollCreationFormTitle">Title</label>
+ <div class="controls">
+ <input type='text' name='title' id='pollCreationFormTitle' placeholder='title'
+ <%= poll.attr("title") ? "value='" + poll.attr("title") + "'" : "class='empty'" %>/>
+ </div>
+ </div>
+
+ <div class="control-group">
+ <label class="control-label" for='pollCreationFormDescription'>Description</label>
+ <div class="controls">
+ <textarea id='pollCreationFormDescription' name='description'
+ <% if (!poll.attr("description")) {%>
+ class='empty'
+ <% } %>><%= poll.attr('description') %></textarea>
+ </div>
+ </div>
+
+ <div class="form-actions">
+ <a href="javascript://" class="btn btn-primary save">Save</a>
+ <a href="javascript://" class="btn btn-primary create">New poll</a>
+ <a href="javascript://" data-id="1" class="btn btn">Edit poll 1</a>
+ <a href="javascript://" data-id="2" class="btn btn">Edit poll 2</a>
+ </div>
+
+</form>
\ No newline at end of file
Added: html5videoplayer/views/summary.ejs
===================================================================
--- html5videoplayer/views/summary.ejs (rev 0)
+++ html5videoplayer/views/summary.ejs 2013-06-07 16:16:19 UTC (rev 660)
@@ -0,0 +1,35 @@
+<h1>Sondage <%= poll.title %></h1>
+
+<div class="control-group">
+ <label class="control-label" for='pollSummaryLink'>Lien pour participer</label>
+ <input type='url' id='pollSummaryLink' value="<%== window.location.href.split('#')[0] + can.route.url({ type: 'poll', action: 'vote', id: poll.id }) %>"/>
+</div>
+
+<div class='row-fluid'>
+ <div class='span4'>
+ <h2>Sondage</h2>
+ <ul class='noListStyle'>
+ <li><%== can.route.link('<i class="icon-ok"></i>Clore', {}) %></li>
+ <li><%== can.route.link('<i class="icon-pencil"></i>Modifer', {type: 'poll', action: 'edit', id: poll.id}) %></li>
+ <li><%== can.route.link('<i class="icon-envelope"></i>Notification', {}) %></li>
+ <li><%== can.route.link('<i class="icon-time"></i>Historique', {}) %></li>
+ <li><%== can.route.link('<i class="icon-clone"></i>Créer un duplicata', {}) %></li>
+ <li><%== can.route.link('<i class="icon-trash"></i>Effacer', {}) %></li>
+ </ul>
+ </div>
+
+ <div class='span4'>
+ <h2>Participants</h2>
+ <ul class='noListStyle'>
+ <li><%== can.route.link('<i class="icon-user"></i>Inviter des participants', {}) %></li>
+ <li><%== can.route.link('<i class="icon-envelope"></i>Contacter les invités', {}) %></li>
+ </ul>
+ </div>
+
+ <div class='span4'>
+ <h2>Export</h2>
+ <ul class='noListStyle'>
+ <li><i class="icon-upload"></i>clore</li>
+ </ul>
+ </div>
+</div>
\ No newline at end of file
Deleted: html5videoplayer/views/video.ejs
===================================================================
--- html5videoplayer/views/video.ejs 2013-06-07 15:15:29 UTC (rev 659)
+++ html5videoplayer/views/video.ejs 2013-06-07 16:16:19 UTC (rev 660)
@@ -1,15 +0,0 @@
-<video id='video' width='800' height='600'
- autoplay preload='auto'
- poster="<%= videos[index.attr('index')].thumb %>"
- onended="videoControl.next();">
- <source id='mp4'
- src="<%= videos[index.attr('index')].mp4 %>"
- type='video/mp4'>
- <source id='webm'
- src="<%= videos[index.attr('index')].webm %>"
- type='video/webm'>
- <source id='ogv'
- src="<%= videos[index.attr('index')].ogv %>"
- type='video/ogg'>
- <p>Your user agent does not support the HTML5 Video element.</p>
-</video>
\ No newline at end of file
Added: html5videoplayer/views/vote.ejs
===================================================================
--- html5videoplayer/views/vote.ejs (rev 0)
+++ html5videoplayer/views/vote.ejs 2013-06-07 16:16:19 UTC (rev 660)
@@ -0,0 +1,53 @@
+<div class="page-header">
+ <h1><%= poll.title %></h1>
+ <p>Sondage lancé par <%= poll.creatorName %>
+ | <i class='icon-user'></i> 0
+ | <i class='icon-comment'></i> 0
+ | <i class='icon-time'></i> il y a 2 minutes</p>
+ <p><%= poll.description %></p>
+</div>
+
+<form>
+
+ <table class="table table-bordered table-striped">
+ <caption>Votes</caption>
+ <thead>
+ <tr>
+ <th>Votant</th>
+ <% poll.choices.each(function(choice) { %>
+ <th><%= choice.attr('name') %></th>
+ <% }); %>
+ </tr>
+ </thead>
+ <tbody>
+ <% votes.each(function(vote) { %>
+ <tr>
+ <td><%= vote.attr('voterListMember.name') %></td>
+ <% vote.voteToChoices.each(function(choice) { %>
+ <td><%= choice.attr('voteValue') %></td>
+ <% }); %>
+ </tr>
+ <% }); %>
+ <tr>
+ <td><input type='text'/></td>
+ <% poll.choices.each(function(choice) { %>
+ <td><input type='checkbox'/></td>
+ <% }); %>
+ </tr>
+ </tbody>
+ </table>
+
+ <div class="form-actions">
+ <button class="btn btn-primary">Voter</button>
+ </div>
+
+</form>
+
+<div>
+<h2>Commentaires</h2>
+<% comments.each(function(comment) { %>
+
+<p><strong><%= comment.attr('author') %></strong> : <%= comment.attr('text') %></p>
+
+<% }); %>
+</div>
\ No newline at end of file
1
0
r659 - nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/hibernate
by bleny@users.nuiton.org June 7, 2013
by bleny@users.nuiton.org June 7, 2013
June 7, 2013
Author: bleny
Date: 2013-06-07 17:15:29 +0200 (Fri, 07 Jun 2013)
New Revision: 659
Url: http://nuiton.org/projects/sandbox/repository/revisions/659
Log:
show jdbc url in debug in HibernateUtil
Modified:
nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/hibernate/HibernateUtil.java
Modified: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/hibernate/HibernateUtil.java
===================================================================
--- nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/hibernate/HibernateUtil.java 2013-06-07 15:13:25 UTC (rev 658)
+++ nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/hibernate/HibernateUtil.java 2013-06-07 15:15:29 UTC (rev 659)
@@ -105,10 +105,13 @@
if (log.isTraceEnabled()) {
log.trace("will store H2 data in " + h2dataPath);
- log.trace("jdbc url is\n" + jdbcUrl);
log.trace("allJpaParameters = " + allJpaParameters);
}
+ if (log.isDebugEnabled()) {
+ log.debug("jdbc url is\n" + jdbcUrl);
+ }
+
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory(persistenceUnitName, allJpaParameters);
return entityManagerFactory;
1
0
r658 - nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/hibernate
by bleny@users.nuiton.org June 7, 2013
by bleny@users.nuiton.org June 7, 2013
June 7, 2013
Author: bleny
Date: 2013-06-07 17:13:25 +0200 (Fri, 07 Jun 2013)
New Revision: 658
Url: http://nuiton.org/projects/sandbox/repository/revisions/658
Log:
when creating a temporary database use hibernate in update to prevent excessive logging
Modified:
nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/hibernate/HibernateUtil.java
Modified: nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/hibernate/HibernateUtil.java
===================================================================
--- nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/hibernate/HibernateUtil.java 2013-06-06 20:21:28 UTC (rev 657)
+++ nuiton-jpa/nuiton-jpa-api/src/main/java/org/nuiton/jpa/api/hibernate/HibernateUtil.java 2013-06-07 15:13:25 UTC (rev 658)
@@ -66,7 +66,7 @@
hibernateH2Config.put(AvailableSettings.JDBC_USER, "sa");
hibernateH2Config.put(AvailableSettings.JDBC_PASSWORD, "");
hibernateH2Config.put(Environment.DIALECT, org.hibernate.dialect.H2Dialect.class.getName());
- hibernateH2Config.put(Environment.HBM2DDL_AUTO, HBM2DDL_AUTO_CREATE);
+ hibernateH2Config.put(Environment.HBM2DDL_AUTO, HBM2DDL_AUTO_UPDATE);
HIBERNATE_H2_CONFIG = Collections.unmodifiableMap(hibernateH2Config);
1
0
r657 - nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates
by tchemit@users.nuiton.org June 6, 2013
by tchemit@users.nuiton.org June 6, 2013
June 6, 2013
Author: tchemit
Date: 2013-06-06 22:21:28 +0200 (Thu, 06 Jun 2013)
New Revision: 657
Url: http://nuiton.org/projects/sandbox/repository/revisions/657
Log:
fix entity super class tag value
Modified:
nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java
Modified: nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java
===================================================================
--- nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java 2013-06-06 10:06:36 UTC (rev 656)
+++ nuiton-jpa/nuiton-jpa-templates/src/main/java/org/nuiton/jpa/templates/JpaEntityTransformer.java 2013-06-06 20:21:28 UTC (rev 657)
@@ -132,7 +132,7 @@
} else {
// try to find a super class by tag-value
- superClass = JpaTemplatesGeneratorUtil.getDaoSuperClassTagValue(
+ superClass = JpaTemplatesGeneratorUtil.getEntitySuperClassTagValue(
model, input);
if (superClass == null) {
1
0